eshan6704 commited on
Commit
f361c54
·
verified ·
1 Parent(s): 53624bd

Update index_live_html.py

Browse files
Files changed (1) hide show
  1. index_live_html.py +39 -115
index_live_html.py CHANGED
@@ -3,12 +3,14 @@ from nsepython import *
3
  import pandas as pd
4
 
5
  def build_index_live_html():
6
- p = nse_index_live("NIFTY 50")
 
7
 
8
  full_df = p.get("data", pd.DataFrame())
9
  rem_df = p.get("rem", pd.DataFrame())
10
  print(rem_df)
11
  print(full_df)
 
12
  if full_df.empty:
13
  main_df = pd.DataFrame()
14
  const_df = pd.DataFrame()
@@ -18,13 +20,13 @@ def build_index_live_html():
18
  if not const_df.empty:
19
  const_df = const_df.iloc[:, 1:] # Remove first column
20
 
21
- # Columns to move from constituents to info
22
  move_to_info = [c for c in ['segment', 'equityTime', 'preOpenTime'] if c in const_df.columns]
23
  if move_to_info:
24
  rem_df = pd.concat([rem_df, const_df[move_to_info].iloc[[0]]], axis=1)
25
  const_df = const_df.drop(columns=move_to_info)
26
 
27
- # Drop unnecessary columns from Constituents
28
  drop_cols_const = [
29
  "identifier", "ffmc", "stockIndClosePrice", "lastUpdateTime",
30
  "chartTodayPath", "chart30dPath", "chart365dPath", "series",
@@ -35,7 +37,7 @@ def build_index_live_html():
35
  ]
36
  const_df = const_df.drop(columns=[c for c in drop_cols_const if c in const_df.columns])
37
 
38
- # Drop unnecessary columns from Main Data
39
  drop_cols_main = [
40
  "series", "symbol_meta", "companyName", "industry", "activeSeries", "debtSeries",
41
  "isFNOSec", "isCASec", "isSLBSec", "isDebtSec", "isSuspended", "tempSuspendedSeries",
@@ -44,16 +46,17 @@ def build_index_live_html():
44
  ]
45
  main_df = main_df.drop(columns=[c for c in drop_cols_main if c in main_df.columns])
46
 
47
- # Ensure pChange is numeric and sort
48
  if 'pChange' in const_df.columns:
49
  const_df['pChange'] = pd.to_numeric(const_df['pChange'], errors='coerce')
50
  const_df = const_df.sort_values('pChange', ascending=False)
51
 
52
- # ================= HELPER FUNCTION: COLOR-CODE AND FORMAT NUMERIC =================
53
  def df_to_html_color(df, metric_col=None):
54
  df_html = df.copy()
55
  top3_up = []
56
  top3_down = []
 
57
  if metric_col and metric_col in df_html.columns and pd.api.types.is_numeric_dtype(df_html[metric_col]):
58
  col_numeric = df_html[metric_col].dropna()
59
  top3_up = col_numeric.nlargest(3).index.tolist()
@@ -63,45 +66,47 @@ def build_index_live_html():
63
  for col in df_html.columns:
64
  val = row[col]
65
  style = ""
66
- if pd.api.types.is_numeric_dtype(type(val)) or isinstance(val, (int, float)):
 
67
  val_fmt = f"{val:.2f}"
68
  if val > 0:
69
  style = "numeric-positive"
70
  elif val < 0:
71
  style = "numeric-negative"
 
72
  if metric_col and col == metric_col:
73
  if idx in top3_up:
74
  style += " top-up"
75
  elif idx in top3_down:
76
  style += " top-down"
 
77
  df_html.at[idx, col] = f'<span class="{style.strip()}">{val_fmt}</span>'
78
  else:
79
  df_html.at[idx, col] = str(val)
 
80
  return df_html.to_html(index=False, escape=False, classes="compact-table")
81
 
82
- # ================= MERGE INFO AND MAIN KEYS INTO MINI CARDS =================
83
  def merge_info_main_cards(rem_df, main_df):
84
  combined = pd.concat([rem_df, main_df], axis=1)
85
- # Remove duplicate columns
86
  combined = combined.loc[:, ~combined.columns.duplicated()]
87
- # Generate mini cards
88
- cards_html = '<div class="mini-card-container">'
89
  for col in combined.columns:
90
  val = combined.at[0, col] if not combined.empty else ""
91
- cards_html += f'''
92
  <div class="mini-card">
93
  <div class="card-key">{col}</div>
94
  <div class="card-val">{val}</div>
95
  </div>
96
- '''
97
- cards_html += '</div>'
98
- return cards_html
99
 
100
  info_cards_html = merge_info_main_cards(rem_df, main_df)
101
-
102
  cons_html = df_to_html_color(const_df)
103
 
104
- # ================= METRIC TABLES =================
105
  metric_cols = [
106
  "pChange", "totalTradedValue", "nearWKH", "nearWKL",
107
  "perChange365d", "perChange30d"
@@ -115,6 +120,7 @@ def build_index_live_html():
115
  df_const = const_df.copy()
116
  df_const[col] = pd.to_numeric(df_const[col], errors="ignore")
117
  df_const = df_const.sort_values(col, ascending=False)
 
118
  df_html = df_to_html_color(df_const[['symbol', col]], metric_col=col)
119
 
120
  metric_tables += f"""
@@ -124,14 +130,14 @@ def build_index_live_html():
124
  </div>
125
  """
126
 
127
- # ================= FINAL HTML =================
128
  html = f"""
129
  <!DOCTYPE html>
130
  <html>
131
  <head>
132
  <meta charset="UTF-8">
133
-
134
  <style>
 
135
  body {{
136
  font-family: Arial;
137
  margin: 12px;
@@ -139,127 +145,47 @@ body {{
139
  color: #222;
140
  font-size: 14px;
141
  }}
142
-
143
- h2, h3 {{
144
- margin: 12px 0 6px 0;
145
- font-weight: 600;
146
- }}
147
-
148
  table {{
149
  border-collapse: collapse;
150
  width: 100%;
151
- table-layout: auto;
152
  }}
153
-
154
  th, td {{
155
  border: 1px solid #bbb;
156
  padding: 5px 8px;
157
- text-align: left;
158
- font-size: 13px;
159
- }}
160
-
161
- th {{
162
- background: #333;
163
- color: white;
164
- font-weight: 600;
165
- }}
166
-
167
- .compact-table td.numeric-positive {{
168
- color: green;
169
- font-weight: bold;
170
- }}
171
- .compact-table td.numeric-negative {{
172
- color: red;
173
- font-weight: bold;
174
- }}
175
-
176
- /* Highlight top 3 gainers / losers */
177
- .compact-table td.top-up {{
178
- background: #a8f0a5; /* light green */
179
- }}
180
- .compact-table td.top-down {{
181
- background: #f0a8a8; /* light red */
182
  }}
183
-
184
- /* Fixed row height & clipping for Constituent Table */
185
- #constituents-table tr, #constituents-table td {{
186
- max-height: 25px;
187
- height: 25px;
188
- overflow: hidden;
189
- white-space: nowrap;
190
- text-overflow: ellipsis;
191
  }}
192
-
 
193
  .small-table {{
194
  background: white;
195
  border-radius: 6px;
196
  padding: 8px;
197
  box-shadow: 0px 1px 4px rgba(0,0,0,0.15);
198
- border: 1px solid #ddd;
199
- overflow-y: auto;
200
  }}
201
-
202
  .st-title {{
203
- font-size: 14px;
204
  text-align: center;
205
- margin-bottom: 6px;
206
- font-weight: bold;
207
  background: #222;
208
  color: white;
209
- padding: 5px 0;
210
  border-radius: 4px;
211
  }}
212
-
213
  .st-body {{
214
- max-height: 300px; /* vertical scroll for metric tables */
215
  overflow-y: auto;
216
- font-size: 12px;
217
- }}
218
-
219
- .compact-section {{
220
- background: white;
221
- padding: 8px;
222
- border-radius: 6px;
223
- box-shadow: 0 1px 4px rgba(0,0,0,0.12);
224
- border: 1px solid #ddd;
225
- margin-bottom: 15px;
226
- overflow-x: visible;
227
- }}
228
-
229
- .grid {{
230
- display: grid;
231
- grid-template-columns: repeat(5, 1fr);
232
- gap: 12px;
233
- margin-top: 12px;
234
- }}
235
-
236
- /* Mini cards for info + main */
237
- .mini-card-container {{
238
- display: flex;
239
- flex-wrap: wrap;
240
- gap: 10px;
241
- }}
242
- .mini-card {{
243
- background: #fff;
244
- padding: 8px 10px;
245
- border-radius: 6px;
246
- box-shadow: 0 1px 3px rgba(0,0,0,0.12);
247
- min-width: 120px;
248
- font-size: 13px;
249
- }}
250
- .card-key {{
251
- font-weight: bold;
252
- color: #333;
253
- margin-bottom: 2px;
254
- }}
255
- .card-val {{
256
- color: #222;
257
  }}
258
  </style>
259
  </head>
260
  <body>
261
 
262
- <h2>Live Index Data: {name or 'Default Index'}</h2>
263
 
264
  <div class="compact-section">
265
  <h3>Index Info + Main Data</h3>
@@ -268,9 +194,7 @@ th {{
268
 
269
  <div class="compact-section">
270
  <h3>Constituents</h3>
271
- <div id="constituents-table">
272
- {cons_html}
273
- </div>
274
  </div>
275
 
276
  <h3>Metric Tables (All Symbols)</h3>
 
3
  import pandas as pd
4
 
5
  def build_index_live_html():
6
+ index_name = "NIFTY 50"
7
+ p = nse_index_live(index_name)
8
 
9
  full_df = p.get("data", pd.DataFrame())
10
  rem_df = p.get("rem", pd.DataFrame())
11
  print(rem_df)
12
  print(full_df)
13
+
14
  if full_df.empty:
15
  main_df = pd.DataFrame()
16
  const_df = pd.DataFrame()
 
20
  if not const_df.empty:
21
  const_df = const_df.iloc[:, 1:] # Remove first column
22
 
23
+ # Move segment / time cols
24
  move_to_info = [c for c in ['segment', 'equityTime', 'preOpenTime'] if c in const_df.columns]
25
  if move_to_info:
26
  rem_df = pd.concat([rem_df, const_df[move_to_info].iloc[[0]]], axis=1)
27
  const_df = const_df.drop(columns=move_to_info)
28
 
29
+ # Drop cols (constituents)
30
  drop_cols_const = [
31
  "identifier", "ffmc", "stockIndClosePrice", "lastUpdateTime",
32
  "chartTodayPath", "chart30dPath", "chart365dPath", "series",
 
37
  ]
38
  const_df = const_df.drop(columns=[c for c in drop_cols_const if c in const_df.columns])
39
 
40
+ # Drop cols (main)
41
  drop_cols_main = [
42
  "series", "symbol_meta", "companyName", "industry", "activeSeries", "debtSeries",
43
  "isFNOSec", "isCASec", "isSLBSec", "isDebtSec", "isSuspended", "tempSuspendedSeries",
 
46
  ]
47
  main_df = main_df.drop(columns=[c for c in drop_cols_main if c in main_df.columns])
48
 
49
+ # Sort by pChange
50
  if 'pChange' in const_df.columns:
51
  const_df['pChange'] = pd.to_numeric(const_df['pChange'], errors='coerce')
52
  const_df = const_df.sort_values('pChange', ascending=False)
53
 
54
+ # ===== Helper: Convert DF to color-coded HTML =====
55
  def df_to_html_color(df, metric_col=None):
56
  df_html = df.copy()
57
  top3_up = []
58
  top3_down = []
59
+
60
  if metric_col and metric_col in df_html.columns and pd.api.types.is_numeric_dtype(df_html[metric_col]):
61
  col_numeric = df_html[metric_col].dropna()
62
  top3_up = col_numeric.nlargest(3).index.tolist()
 
66
  for col in df_html.columns:
67
  val = row[col]
68
  style = ""
69
+
70
+ if isinstance(val, (int, float)) or pd.api.types.is_number(val):
71
  val_fmt = f"{val:.2f}"
72
  if val > 0:
73
  style = "numeric-positive"
74
  elif val < 0:
75
  style = "numeric-negative"
76
+
77
  if metric_col and col == metric_col:
78
  if idx in top3_up:
79
  style += " top-up"
80
  elif idx in top3_down:
81
  style += " top-down"
82
+
83
  df_html.at[idx, col] = f'<span class="{style.strip()}">{val_fmt}</span>'
84
  else:
85
  df_html.at[idx, col] = str(val)
86
+
87
  return df_html.to_html(index=False, escape=False, classes="compact-table")
88
 
89
+ # ===== Merge info + main into cards =====
90
  def merge_info_main_cards(rem_df, main_df):
91
  combined = pd.concat([rem_df, main_df], axis=1)
 
92
  combined = combined.loc[:, ~combined.columns.duplicated()]
93
+
94
+ html = '<div class="mini-card-container">'
95
  for col in combined.columns:
96
  val = combined.at[0, col] if not combined.empty else ""
97
+ html += f"""
98
  <div class="mini-card">
99
  <div class="card-key">{col}</div>
100
  <div class="card-val">{val}</div>
101
  </div>
102
+ """
103
+ html += "</div>"
104
+ return html
105
 
106
  info_cards_html = merge_info_main_cards(rem_df, main_df)
 
107
  cons_html = df_to_html_color(const_df)
108
 
109
+ # ===== Metric tables =====
110
  metric_cols = [
111
  "pChange", "totalTradedValue", "nearWKH", "nearWKL",
112
  "perChange365d", "perChange30d"
 
120
  df_const = const_df.copy()
121
  df_const[col] = pd.to_numeric(df_const[col], errors="ignore")
122
  df_const = df_const.sort_values(col, ascending=False)
123
+
124
  df_html = df_to_html_color(df_const[['symbol', col]], metric_col=col)
125
 
126
  metric_tables += f"""
 
130
  </div>
131
  """
132
 
133
+ # ===== FINAL HTML =====
134
  html = f"""
135
  <!DOCTYPE html>
136
  <html>
137
  <head>
138
  <meta charset="UTF-8">
 
139
  <style>
140
+ /* CSS unchanged */
141
  body {{
142
  font-family: Arial;
143
  margin: 12px;
 
145
  color: #222;
146
  font-size: 14px;
147
  }}
 
 
 
 
 
 
148
  table {{
149
  border-collapse: collapse;
150
  width: 100%;
 
151
  }}
 
152
  th, td {{
153
  border: 1px solid #bbb;
154
  padding: 5px 8px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  }}
156
+ .compact-table td.numeric-positive {{ color: green; font-weight: bold; }}
157
+ .compact-table td.numeric-negative {{ color: red; font-weight: bold; }}
158
+ .compact-table td.top-up {{ background: #a8f0a5; }}
159
+ .compact-table td.top-down {{ background: #f0a8a8; }}
160
+ .mini-card-container {{ display: flex; flex-wrap: wrap; gap: 10px; }}
161
+ .mini-card {{
162
+ background: #fff; padding: 8px; border-radius: 6px;
163
+ box-shadow: 0 1px 3px rgba(0,0,0,0.12);
164
  }}
165
+ .card-key {{ font-weight: bold; }}
166
+ .grid {{ display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; }}
167
  .small-table {{
168
  background: white;
169
  border-radius: 6px;
170
  padding: 8px;
171
  box-shadow: 0px 1px 4px rgba(0,0,0,0.15);
 
 
172
  }}
 
173
  .st-title {{
 
174
  text-align: center;
 
 
175
  background: #222;
176
  color: white;
177
+ padding: 5px;
178
  border-radius: 4px;
179
  }}
 
180
  .st-body {{
181
+ max-height: 300px;
182
  overflow-y: auto;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  }}
184
  </style>
185
  </head>
186
  <body>
187
 
188
+ <h2>Live Index Data: NIFTY 50</h2>
189
 
190
  <div class="compact-section">
191
  <h3>Index Info + Main Data</h3>
 
194
 
195
  <div class="compact-section">
196
  <h3>Constituents</h3>
197
+ {cons_html}
 
 
198
  </div>
199
 
200
  <h3>Metric Tables (All Symbols)</h3>