eshan6704 commited on
Commit
3723a67
ยท
verified ยท
1 Parent(s): e8b42fd

Delete yahooinfo3.py

Browse files
Files changed (1) hide show
  1. yahooinfo3.py +0 -351
yahooinfo3.py DELETED
@@ -1,351 +0,0 @@
1
- # ==============================
2
- # Imports
3
- # ==============================
4
- import yfinance as yf
5
- import pandas as pd
6
- import traceback
7
-
8
- # ==============================
9
- # Yahoo Finance info fetch
10
- # ==============================
11
- def yfinfo(symbol):
12
- try:
13
- t = yf.Ticker(symbol+".NS")
14
- info = t.info
15
- if not info or not isinstance(info, dict):
16
- return {}
17
- return info
18
- except Exception as e:
19
- return {"__error__": str(e)}
20
-
21
- # ==============================
22
- # Subgroup icons
23
- # ==============================
24
- SUBGROUP_ICONS = {
25
- "Live Price": "๐Ÿ’น",
26
- "Volume": "๐Ÿ“Š",
27
- "Moving Avg": "๐Ÿ“ˆ",
28
- "Range / Vol": "๐Ÿ“‰",
29
- "Bid / Analyst": "๐Ÿ“",
30
- "Other": "โ„น๏ธ"
31
- }
32
-
33
- # Main section icons
34
- MAIN_ICONS = {
35
- "Price / Volume": "๐Ÿ“ˆ",
36
- "Fundamentals": "๐Ÿ“Š",
37
- "Company Profile": "๐Ÿข"
38
- }
39
-
40
- # ==============================
41
- # HTML card renderer
42
- # ==============================
43
- def html_card(title, body, mini=False, shade=0):
44
- font = "12px" if mini else "14px"
45
- pad = "6px" if mini else "10px"
46
-
47
- # Card background shades
48
- shades = ["#e6f0fa", "#d7e3f5", "#c8d6f0", "#b9c9eb"]
49
- bg = shades[shade % len(shades)]
50
-
51
- # Gradient headers for background
52
- header_gradients = [
53
- "linear-gradient(to right, #1a4f8a, #4a7ac7)",
54
- "linear-gradient(to right, #1f5595, #5584d6)",
55
- "linear-gradient(to right, #205ca0, #6192e0)",
56
- "linear-gradient(to right, #2360ab, #6ba0e5)"
57
- ]
58
- header_bg = header_gradients[shade % len(header_gradients)]
59
-
60
- return f"""
61
- <div style="
62
- background:{bg};
63
- border:1px solid #a3c0e0;
64
- border-radius:8px;
65
- padding:{pad};
66
- margin:6px 0;
67
- color:#0d1f3c;
68
- font-size:{font};
69
- box-shadow: 0 2px 6px rgba(0,0,0,0.1);
70
- transition: transform 0.1s ease, box-shadow 0.2s ease;
71
- " onmouseover="this.style.transform='scale(1.02)';this.style.boxShadow='0 4px 12px rgba(0,0,0,0.15)';"
72
- onmouseout="this.style.transform='scale(1)';this.style.boxShadow='0 2px 6px rgba(0,0,0,0.1)';">
73
- <div style="
74
- font-weight:600;
75
- background:{header_bg};
76
- color:white;
77
- padding:4px 8px;
78
- border-radius:6px 6px 0 0;
79
- margin:-{pad}px -{pad}px {pad}px -{pad}px;
80
- ">
81
- {title}
82
- </div>
83
- <div>{body}</div>
84
- </div>
85
- """
86
-
87
- # ==============================
88
- # DataFrame โ†’ HTML table
89
- # ==============================
90
- def make_table(df, compact=False):
91
- if df is None or df.empty:
92
- return "<i>No data</i>"
93
-
94
- font = "11px" if compact else "13px"
95
- pad = "4px 8px" if compact else "6px 10px"
96
-
97
- th = "".join(
98
- f"<th style='padding:{pad};border-bottom:2px solid #a3c0e0;text-align:left;color:#1a4f8a;'>"
99
- f"{c}</th>"
100
- for c in df.columns
101
- )
102
-
103
- rows = ""
104
- for i, r in df.iterrows():
105
- bg = "#f5f9ff" if i%2==0 else "#e6f0fa" # alternate row colors
106
- tds = "".join(
107
- f"<td style='padding:{pad};border-bottom:1px solid #c0d4ee;background:{bg}'>{v}</td>"
108
- for v in r
109
- )
110
- rows += f"<tr>{tds}</tr>"
111
-
112
- return f"""
113
- <table style="
114
- width:100%;
115
- border-collapse:collapse;
116
- font-size:{font};
117
- color:#0d1f3c;
118
- ">
119
- <thead style='background:#c0d4ee'>{th}</thead>
120
- <tbody>{rows}</tbody>
121
- </table>
122
- """
123
-
124
- # ==============================
125
- # Number formatting
126
- # ==============================
127
- def format_number(x):
128
- try:
129
- if x is None:
130
- return "-"
131
- x = float(x)
132
- if abs(x) >= 100:
133
- return f"{x:,.0f}"
134
- if abs(x) >= 1:
135
- return f"{x:,.2f}"
136
- return f"{x:.4f}"
137
- except Exception:
138
- return str(x)
139
-
140
- def format_large_number(x):
141
- try:
142
- x = float(x)
143
- for u in ["", "K", "M", "B", "T"]:
144
- if abs(x) < 1000:
145
- return f"{x:.2f}{u}"
146
- x /= 1000
147
- return f"{x:.2f}P"
148
- except Exception:
149
- return str(x)
150
-
151
- # ==============================
152
- # HTML error block
153
- # ==============================
154
- def html_error(msg):
155
- return f"""
156
- <div style="
157
- background:#fdecea;
158
- color:#a00;
159
- border:1px solid #f5c0c0;
160
- border-radius:8px;
161
- padding:10px;
162
- font-weight:600;
163
- box-shadow: 0 1px 4px rgba(0,0,0,0.05);
164
- ">
165
- โŒ {msg}
166
- </div>
167
- """
168
-
169
- # ==============================
170
- # Noise keys
171
- # ==============================
172
- NOISE_KEYS = {
173
- "maxAge", "priceHint", "triggerable",
174
- "customPriceAlertConfidence",
175
- "sourceInterval", "exchangeDataDelayedBy",
176
- "esgPopulated"
177
- }
178
- def is_noise(k):
179
- return k in NOISE_KEYS
180
-
181
- # ==============================
182
- # Duplicate resolution priority
183
- # ==============================
184
- DUPLICATE_PRIORITY = {
185
- "price": ["regularMarketPrice", "currentPrice"],
186
- "prev": ["regularMarketPreviousClose", "previousClose"],
187
- "open": ["regularMarketOpen", "open"],
188
- "high": ["regularMarketDayHigh", "dayHigh"],
189
- "low": ["regularMarketDayLow", "dayLow"],
190
- "volume": ["regularMarketVolume", "volume"],
191
- }
192
- def resolve_duplicates(data):
193
- resolved = {}
194
- used = set()
195
- for _, keys in DUPLICATE_PRIORITY.items():
196
- for k in keys:
197
- if k in data:
198
- resolved[k] = data[k]
199
- used.update(keys)
200
- break
201
- for k, v in data.items():
202
- if k not in used:
203
- resolved[k] = v
204
- return resolved
205
-
206
- # ==============================
207
- # Short display names
208
- # ==============================
209
- SHORT_NAMES = {
210
- "regularMarketPrice": "Price",
211
- "regularMarketChange": "Chg",
212
- "regularMarketChangePercent": "Chg%",
213
- "regularMarketPreviousClose": "Prev",
214
- "regularMarketOpen": "Open",
215
- "regularMarketDayHigh": "High",
216
- "regularMarketDayLow": "Low",
217
- "regularMarketVolume": "Vol",
218
- "averageDailyVolume10Day": "AvgV10",
219
- "averageDailyVolume3Month": "AvgV3M",
220
- "fiftyDayAverage": "50DMA",
221
- "fiftyDayAverageChangePercent": "50DMA%",
222
- "twoHundredDayAverage": "200DMA",
223
- "twoHundredDayAverageChangePercent": "200DMA%",
224
- "fiftyTwoWeekLow": "52WL",
225
- "fiftyTwoWeekHigh": "52WH",
226
- "fiftyTwoWeekRange": "52WR",
227
- "beta": "Beta",
228
- "targetHighPrice": "TgtH",
229
- "targetLowPrice": "TgtL",
230
- "targetMeanPrice": "Tgt",
231
- "recommendationMean": "Reco",
232
- }
233
- def pretty_key(k):
234
- return SHORT_NAMES.get(k, k[:12])
235
-
236
- # ==============================
237
- # Subgroup classifier
238
- # ==============================
239
- def classify_price_volume_subgroup(key):
240
- k = key.lower()
241
- if any(x in k for x in ["price", "open", "close", "change", "day"]):
242
- return "Live Price"
243
- if "volume" in k:
244
- return "Volume"
245
- if "average" in k or "fiftyday" in k or "twohundredday" in k:
246
- return "Moving Avg"
247
- if any(x in k for x in ["week", "range", "high", "low", "alltime", "beta"]):
248
- return "Range / Vol"
249
- if any(x in k for x in ["bid", "ask", "target", "recommendation", "analyst"]):
250
- return "Bid / Analyst"
251
- return "Other"
252
-
253
- def build_price_volume_subgroups(data):
254
- sub = {}
255
- for k, v in data.items():
256
- sg = classify_price_volume_subgroup(k)
257
- sub.setdefault(sg, {})[k] = v
258
- return sub
259
-
260
- # ==============================
261
- # Main key classifier
262
- # ==============================
263
- def classify_key(key, value):
264
- k = key.lower()
265
- if isinstance(value, str) and len(value) > 80:
266
- return "long_text"
267
- if isinstance(value, (int, float)) and any(x in k for x in [
268
- "price", "volume", "avg", "average", "change",
269
- "percent", "market", "day", "week", "bid",
270
- "ask", "beta", "target", "recommendation"
271
- ]):
272
- return "price_volume"
273
- if any(x in k for x in [
274
- "revenue", "income", "earnings", "profit",
275
- "margin", "pe", "pb", "roe", "roa",
276
- "cash", "debt", "equity", "dividend",
277
- "ebitda", "growth", "ratio", "shares"
278
- ]):
279
- return "fundamental"
280
- return "profile"
281
-
282
- # ==============================
283
- # Group builder
284
- # ==============================
285
- def build_grouped_info(info):
286
- groups = {"price_volume": {}, "fundamental": {}, "profile": {}, "long_text": {}}
287
- for k, v in info.items():
288
- if v in [None, "", [], {}]:
289
- continue
290
- grp = classify_key(k, v)
291
- groups[grp][k] = v
292
- return groups
293
-
294
- # ==============================
295
- # Build DataFrame
296
- # ==============================
297
- def build_df_from_dict(data):
298
- rows = []
299
- for k, v in data.items():
300
- if is_noise(k):
301
- continue
302
- if isinstance(v, (int, float)):
303
- v = format_number(v)
304
- elif isinstance(v, list):
305
- v = ", ".join(map(str, v[:5]))
306
- rows.append([pretty_key(k), v])
307
- return pd.DataFrame(rows, columns=["Field", "Value"])
308
-
309
- # ==============================
310
- # MAIN FUNCTION
311
- # ==============================
312
- def fetch_info(symbol):
313
- try:
314
- info = yfinfo(symbol)
315
- if not info:
316
- return html_error(f"No information found for {symbol}")
317
-
318
- groups = build_grouped_info(info)
319
- final_html = ""
320
-
321
- # ---------------- PRICE / VOLUME ----------------
322
- price_data = groups["price_volume"]
323
- price_data = resolve_duplicates(price_data)
324
- price_subgroups = build_price_volume_subgroups(price_data)
325
- price_html = ""
326
- for i, (title, data) in enumerate(price_subgroups.items()):
327
- df = build_df_from_dict(data)
328
- if not df.empty:
329
- icon = SUBGROUP_ICONS.get(title, "โ„น๏ธ")
330
- price_html += html_card(f"{icon} {title}", make_table(df, compact=True), mini=True, shade=i)
331
- if price_html:
332
- final_html += html_card(f"{MAIN_ICONS['Price / Volume']} Price / Volume", price_html, shade=0)
333
-
334
- # ---------------- FUNDAMENTALS ----------------
335
- if groups["fundamental"]:
336
- df = build_df_from_dict(groups["fundamental"])
337
- final_html += html_card(f"{MAIN_ICONS['Fundamentals']} Fundamentals", make_table(df, compact=True), shade=1)
338
-
339
- # ---------------- PROFILE ----------------
340
- if groups["profile"]:
341
- df = build_df_from_dict(groups["profile"])
342
- final_html += html_card(f"{MAIN_ICONS['Company Profile']} Company Profile", make_table(df, compact=True), shade=2)
343
-
344
- # ---------------- LONG TEXT ----------------
345
- for i, (k, v) in enumerate(groups["long_text"].items()):
346
- final_html += html_card(pretty_key(k), f"<div class='long-text'>{v}</div>", shade=3)
347
-
348
- return final_html
349
-
350
- except Exception as e:
351
- return html_error(f"INFO ERROR: {e}<br><pre>{traceback.format_exc()}</pre>")