rajat5ranjan commited on
Commit
1f5a9cd
Β·
verified Β·
1 Parent(s): bb7fddb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +340 -318
app.py CHANGED
@@ -39,345 +39,367 @@ gemini_embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
39
  llm = ChatGoogleGenerativeAI(model="gemini-2.5-pro",google_api_key = GOOGLE_API_KEY)
40
  #llm_vis = ChatGoogleGenerativeAI(model="gemini-pro-vision",google_api_key = GOOGLE_API_KEY)
41
 
42
- def get_tradingview_analysis(symbol, exchange, screener, interval):
43
- try:
44
- stock = TA_Handler(
45
- symbol=symbol,
46
- screener=screener,
47
- exchange=exchange,
48
- interval=interval,
49
- )
50
- analysis_summary = stock.get_analysis()
51
- return analysis_summary
52
- except Exception as e:
53
- return {"error": str(e)}
54
 
55
-
56
- if ticker_user!="":
57
- url1 = f"https://www.google.com/finance/quote/{ticker_user}:NSE?hl=en"
58
- url2 = f"https://in.tradingview.com/symbols/NSE-{ticker_user}/"
59
- url3 = f"https://in.tradingview.com/symbols/NSE-{ticker_user}/news/"
60
- url4 = f"https://in.tradingview.com/symbols/NSE-{ticker_user}/minds/"
61
-
62
- loader = WebBaseLoader([url1,url2,url3,url4])
63
- docs = loader.load()
64
-
 
 
 
 
65
 
66
- st.divider()
67
- # llm_prompt_template = """You are an expert Stock Market Trader for stock market insights based on fundamental, analytical, profit based and company financials.
68
- # Based on the context below
69
- # {context}, Summarize the stock based on Historical data based on fundamental, price, news, sentiment , any red flags and suggest rating of the Stock in a 1 to 10 Scale"""
 
 
70
 
71
- llm_prompt_template = """You are an expert Stock Market Trader specializing in stock market insights derived from fundamental analysis, analytical trends, profit-based evaluations, news indicators from different sites and detailed company financials.
72
- Using your expertise, please analyze the stock based on the provided context below.
73
-
74
- Context:
75
- {input_documents}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
- Task:
78
- Summarize the stock based on its historical and current data. Keep it CONCISE & BRIEF.
79
- Evaluate the stock on the following parameters:
80
- 1. Company Fundamentals: Assess the stock's intrinsic value, growth potential, and financial health.
81
- 2. Current & Future Price Trends: Analyze historical price movements and current price trends.
82
- 3. News and Sentiment: Review recent news articles, press releases, and social media sentiment.
83
- 4. Red Flags: Identify any potential risks or warning signs.
84
- 5. Provide a rating for the stock on a scale of 1 to 10.
85
- 6. Advise if the stock is a good buy for the next 1,5, 10 weeks.
86
- 7. Suggest at what price we need to buy and hold or sell the stock
87
-
88
- PROVIDE THE DETAILS based on just the FACTS present in the document
89
- PROVIDE THE DETAILS IN an JSON Object. Stick to the below JSON object
90
- {{
91
- "stock_summary": {{
92
- "company_name": "",
93
- "ticker": "",
94
- "exchange": "",
95
- "description": "",
96
- "current_price": "",
97
- "market_cap": "",
98
- "historical_performance": {{
99
- "5_day": "",
100
- "1_month": "",
101
- "6_months": "",
102
- "1_year": "",
103
- "5_years": ""
104
- }}
105
- }},
106
- "evaluation_parameters": {{
107
- "company_fundamentals": {{
108
- "assessment": "",
109
- "key_metrics": {{
110
- "pe_ratio": "",
111
- "volume":"",
112
- "revenue_growth_yoy": "",
113
- "net_income_growth_yoy": "",
114
- "eps_growth_yoy": "",
115
- "dividend_yield": "",
116
- "balance_sheet": "",
117
- "return_on_capital": ""
118
- }}
119
- }},
120
- "current_and_future_price_trends": {{
121
- "assessment": "",
122
- "historical_trends": "",
123
- "current_trends": "",
124
- "technical_analysis_notes": "",
125
- "technical_indicators":""
126
- }},
127
- "news_and_sentiment": {{
128
- "assessment": "",
129
- "positive_sentiment": [
130
- "",
131
- "",
132
- ""
133
- ],
134
- "negative_sentiment": [
135
- "",
136
- "",
137
- ""
138
- ]
139
- }},
140
- "red_flags": [
141
- {{
142
- "flag": "",
143
- "details": ""
144
  }},
145
- {{
146
- "flag": "",
147
- "details": ""
148
  }},
149
- {{
150
- "flag": "",
151
- "details": ""
 
 
 
 
 
 
152
  }}
153
- ]
154
- }},
155
- "overall_rating": {{
156
- "rating": "X/10",
157
- "justification": ""
158
- }},
159
- "investment_advice": {{
160
- "next_1_weeks_outlook": "",
161
- "next_5_weeks_outlook": "",
162
- "next_10_weeks_outlook": "",
163
- "price_action_suggestions": {{
164
- "buy": "",
165
- "hold": "",
166
- "sell": ""
167
  }}
168
- }}
169
- }}
170
- """
171
-
172
- # st.sidebar.subheader('Prompt')
173
- # user_prompt = st.sidebar.text_area("Enter Prompt",llm_prompt_template)
174
- #https://huggingface.co/spaces/pradeepodela/Stock-Analyser/blob/main/app.py
175
- interval = Interval.INTERVAL_1_DAY
176
- analysis_summary = get_tradingview_analysis(
177
- symbol=ticker_user,
178
- exchange="NSE",
179
- screener="india",
180
- interval=interval,
181
- )
182
-
183
- # st.title("Analysis Summary")
184
- # st.dataframe(analysis_summary.summary)
185
- # query = f"{ticker_user} stock"
186
-
187
- details = {
188
- "symbol": ticker_user,
189
- "exchange": "NSE",
190
- "screener": "india",
191
- "interval": interval,
192
- }
193
- # st.title("Details")
194
- # st.dataframe(details)
195
-
196
- # st.title("Oscillator Analysis")
197
- # st.dataframe(analysis_summary.oscillators)
198
-
199
- # st.title("Moving Averages")
200
- # st.dataframe(analysis_summary.moving_averages)
201
-
202
- # st.title("Summary")
203
- # st.dataframe(analysis_summary.summary)
204
-
205
- # st.title("Indicators")
206
- # st.dataframe(analysis_summary.indicators)
207
-
208
- # Page Title
209
- st.header(f"πŸ“Š TradingView Analysis: {ticker_user}:{interval} ({details['exchange']})")
210
-
211
- # --- Row 1: Details + Summary ---
212
- col1, col2 = st.columns([1, 3])
213
- with col1:
214
- st.subheader("πŸ“ Summary")
215
- # st.write(analysis_summary.summary)
216
- summary= analysis_summary.summary
217
- # Prepare data for stacked bar chart: each category with its count
218
- data = pd.DataFrame({
219
- 'category': ['BUY', 'SELL', 'NEUTRAL'],
220
- 'count': [summary['BUY'], summary['SELL'], summary['NEUTRAL']]
221
- })
222
-
223
- # Add a constant key to create a single stacked bar
224
- data['key'] = 'Recommendations'
225
- chart = alt.Chart(data).mark_bar().encode(
226
- y=alt.Y('key:N', axis=None), # single bar, no y axis
227
- x=alt.X('count:Q'),
228
- color=alt.Color('category:N', scale=alt.Scale(
229
- domain=['BUY', 'SELL', 'NEUTRAL'],
230
- range=['green', 'red', 'gold']
231
- )),
232
- tooltip=['category', 'count']
233
- ).properties(
234
- width=600,
235
- height=50
236
- )
237
 
238
- st.altair_chart(chart, use_container_width=True)
 
 
 
 
 
 
 
 
 
239
 
240
- # --- Row 2: Oscillators + Moving Averages ---
241
- # col3, col4 = st.columns(2)
242
- # with col3:
243
- # st.subheader("βš™οΈ Oscillator Analysis")
244
- # st.dataframe(analysis_summary.oscillators, use_container_width=True)
245
 
246
- # with col4:
247
- # st.subheader("πŸ“ˆ Moving Averages")
248
- # st.dataframe(analysis_summary.moving_averages, use_container_width=True)
 
 
 
 
 
249
 
250
- # # --- Row 3: Indicators ---
251
- # st.subheader("πŸ” Indicators")
252
- # st.dataframe(analysis_summary.indicators, use_container_width=True)
253
-
254
- # url = "https://api.chart-img.com/v2/tradingview/advanced-chart"
255
- # api_key = "l0iUFRSeqC9z7nDPTd1hnafPh2RrdcEy6rl6tNqV"
256
- # headers = {
257
- # "x-api-key": api_key,
258
- # "content-type": "application/json"
259
- # }
260
- # data = {
261
- # "height": 400,
262
- # "theme": "light",
263
- # "interval": "1D",
264
- # "session": "extended",
265
- # "symbol": f"NSE:{ticker_user}"
266
- # }
267
 
268
- # response = requests.post(url, headers=headers, json=data)
 
269
 
270
- # if response.status_code == 200:
271
- # with open("chart_t1.jpg", "wb") as f:
272
- # f.write(response.content)
273
- # with col2:
274
- # st.image("chart_t1.jpg", caption='')
275
- # else:
276
- # st.warning(f"Failed to retrieve image. Status code: {response.status_code}")
277
- # st.warning("Response:", response.text)
278
 
279
- llm_prompt = PromptTemplate.from_template(llm_prompt_template)
280
-
281
- llm_chain = LLMChain(llm=llm,prompt=llm_prompt)
282
- stuff_chain = StuffDocumentsChain(llm_chain=llm_chain,document_variable_name="input_documents")
283
 
284
- # res = stuff_chain.invoke(docs)
285
- res = stuff_chain.invoke({"input_documents": docs})
286
- try:
287
- raw_text = res["output_text"]
288
-
289
- # Remove markdown code block delimiters if present
290
- if raw_text.startswith("```json"):
291
- raw_text = raw_text[len("```json"):]
292
-
293
- if raw_text.endswith("```"):
294
- raw_text = raw_text[:-3]
295
-
296
- # Also strip leading/trailing whitespace/newlines
297
- raw_text = raw_text.strip()
298
-
299
-
300
- data = json.loads(raw_text)
301
- # data = res["output_text"]
302
- # Header Info
303
- st.markdown(f"### {data['stock_summary']['company_name']} ({data['stock_summary']['ticker']}) | {data['stock_summary']['exchange']}")
304
- st.markdown(f"**Description**: {data['stock_summary']['description']}")
305
 
306
- # === Row 1: Price and Market Cap ===
307
- row1 = st.columns(3)
308
- row1[0].metric("πŸ’° Current Price", data["stock_summary"]["current_price"])
309
- row1[1].metric("🏒 Market Cap", data["stock_summary"]["market_cap"])
310
- row1[2].metric("⭐ Rating", data["overall_rating"]["rating"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
 
312
- # === Row 2: Historical Performance ===
313
- st.subheader("πŸ“Š Historical Performance")
314
- perf_cols = st.columns(len(data["stock_summary"]["historical_performance"]))
315
- for i, (k, v) in enumerate(data["stock_summary"]["historical_performance"].items()):
316
- perf_cols[i].metric(k.replace("_", " ").title(), v)
317
 
318
- # === Row 3: Fundamentals ===
319
- st.subheader("πŸ“˜ Company Fundamentals")
320
- row3 = st.columns(4)
321
- metrics = data["evaluation_parameters"]["company_fundamentals"]["key_metrics"]
322
- row3[0].metric("P/E Ratio", metrics["pe_ratio"])
323
- row3[1].metric("EPS YoY", metrics["eps_growth_yoy"])
324
- row3[2].metric("Revenue YoY", metrics["revenue_growth_yoy"])
325
- row3[3].metric("Dividend Yield", metrics["dividend_yield"])
326
 
327
- row3b = st.columns(4)
328
- row3b[0].metric("Net Income YoY", metrics["net_income_growth_yoy"])
329
- row3b[1].metric("Volume", metrics["volume"])
330
- row3b[2].metric("Return on Capital", metrics["return_on_capital"])
331
- row3b[3].metric("Balance Sheet", metrics["balance_sheet"])
332
-
333
- st.info(data["evaluation_parameters"]["company_fundamentals"]["assessment"])
334
-
335
- # === Row 4: Trends and Technicals ===
336
- st.subheader("πŸ“ˆ Trends & Technical Analysis")
337
- row4 = st.columns(3)
338
- row4[0].markdown(f"**Historical Trends:** {data['evaluation_parameters']['current_and_future_price_trends']['historical_trends']}")
339
- row4[1].markdown(f"**Current Trends:** {data['evaluation_parameters']['current_and_future_price_trends']['current_trends']}")
340
- row4[2].markdown(f"**Technical Indicators:** {data['evaluation_parameters']['current_and_future_price_trends']['technical_indicators']}")
341
-
342
- st.success(data["evaluation_parameters"]["current_and_future_price_trends"]["assessment"])
343
- st.caption(f"πŸ“ Notes: {data['evaluation_parameters']['current_and_future_price_trends']['technical_analysis_notes']}")
344
-
345
- # === Row 5: Sentiment ===
346
- st.subheader("πŸ“° News & Sentiment")
347
- sentiment_cols = st.columns(2)
348
- with sentiment_cols[0]:
349
- st.success("πŸ‘ Positive Sentiment")
350
- for s in data["evaluation_parameters"]["news_and_sentiment"]["positive_sentiment"]:
351
- st.write(f"βœ… {s}")
352
- with sentiment_cols[1]:
353
- st.error("πŸ‘Ž Negative Sentiment")
354
- for s in data["evaluation_parameters"]["news_and_sentiment"]["negative_sentiment"]:
355
- st.write(f"❌ {s}")
356
- st.info(data["evaluation_parameters"]["news_and_sentiment"]["assessment"])
357
 
358
- # === Row 6: Red Flags ===
359
- st.subheader("🚩 Red Flags")
360
- red_flag_cols = st.columns(3)
361
- for i, flag in enumerate(data["evaluation_parameters"]["red_flags"]):
362
- red_flag_cols[i].warning(f"**{flag['flag']}**\n{flag['details']}")
363
 
364
- # === Row 7: Investment Advice ===
365
- st.subheader("πŸ’‘ Investment Advice")
366
- advice_cols = st.columns(3)
367
- advice = data["investment_advice"]
368
- advice_cols[0].markdown(f"**Next 1 Week**\n{advice['next_1_weeks_outlook']}")
369
- advice_cols[1].markdown(f"**Next 5 Weeks**\n{advice['next_5_weeks_outlook']}")
370
- advice_cols[2].markdown(f"**Next 10 Weeks**\n{advice['next_10_weeks_outlook']}")
 
371
 
372
- action_cols = st.columns(3)
373
- action_cols[0].success(f"**Buy:** {advice['price_action_suggestions']['buy']}")
374
- action_cols[1].info(f"**Hold:** {advice['price_action_suggestions']['hold']}")
375
- action_cols[2].error(f"**Sell:** {advice['price_action_suggestions']['sell']}")
376
 
377
- # === Footer ===
378
- st.markdown("---")
379
- st.caption("Generated by AI-powered financial analysis dashboard.")
380
- except json.JSONDecodeError as e:
381
- st.error(f"JSON decode error: {e}")
382
- st.write("Raw text was:")
383
- st.text(res["output_text"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  llm = ChatGoogleGenerativeAI(model="gemini-2.5-pro",google_api_key = GOOGLE_API_KEY)
40
  #llm_vis = ChatGoogleGenerativeAI(model="gemini-pro-vision",google_api_key = GOOGLE_API_KEY)
41
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
+ activities = ["Symbol Analysis","News Sentiment"]
44
+ if activities=="Symbol Analysis":
45
+ def get_tradingview_analysis(symbol, exchange, screener, interval):
46
+ try:
47
+ stock = TA_Handler(
48
+ symbol=symbol,
49
+ screener=screener,
50
+ exchange=exchange,
51
+ interval=interval,
52
+ )
53
+ analysis_summary = stock.get_analysis()
54
+ return analysis_summary
55
+ except Exception as e:
56
+ return {"error": str(e)}
57
 
58
+
59
+ if ticker_user!="":
60
+ url1 = f"https://www.google.com/finance/quote/{ticker_user}:NSE?hl=en"
61
+ url2 = f"https://in.tradingview.com/symbols/NSE-{ticker_user}/"
62
+ url3 = f"https://in.tradingview.com/symbols/NSE-{ticker_user}/news/"
63
+ url4 = f"https://in.tradingview.com/symbols/NSE-{ticker_user}/minds/"
64
 
65
+ loader = WebBaseLoader([url1,url2,url3,url4])
66
+ docs = loader.load()
67
+
68
+
69
+ st.divider()
70
+ # llm_prompt_template = """You are an expert Stock Market Trader for stock market insights based on fundamental, analytical, profit based and company financials.
71
+ # Based on the context below
72
+ # {context}, Summarize the stock based on Historical data based on fundamental, price, news, sentiment , any red flags and suggest rating of the Stock in a 1 to 10 Scale"""
73
+
74
+ llm_prompt_template = """You are an expert Stock Market Trader specializing in stock market insights derived from fundamental analysis, analytical trends, profit-based evaluations, news indicators from different sites and detailed company financials.
75
+ Using your expertise, please analyze the stock based on the provided context below.
76
+
77
+ Context:
78
+ {input_documents}
79
+
80
+ Task:
81
+ Summarize the stock based on its historical and current data. Keep it CONCISE & BRIEF.
82
+ Evaluate the stock on the following parameters:
83
+ 1. Company Fundamentals: Assess the stock's intrinsic value, growth potential, and financial health.
84
+ 2. Current & Future Price Trends: Analyze historical price movements and current price trends.
85
+ 3. News and Sentiment: Review recent news articles, press releases, and social media sentiment.
86
+ 4. Red Flags: Identify any potential risks or warning signs.
87
+ 5. Provide a rating for the stock on a scale of 1 to 10.
88
+ 6. Advise if the stock is a good buy for the next 1,5, 10 weeks.
89
+ 7. Suggest at what price we need to buy and hold or sell the stock
90
 
91
+ PROVIDE THE DETAILS based on just the FACTS present in the document
92
+ PROVIDE THE DETAILS IN an JSON Object. Stick to the below JSON object
93
+ {{
94
+ "stock_summary": {{
95
+ "company_name": "",
96
+ "ticker": "",
97
+ "exchange": "",
98
+ "description": "",
99
+ "current_price": "",
100
+ "market_cap": "",
101
+ "historical_performance": {{
102
+ "5_day": "",
103
+ "1_month": "",
104
+ "6_months": "",
105
+ "1_year": "",
106
+ "5_years": ""
107
+ }}
108
+ }},
109
+ "evaluation_parameters": {{
110
+ "company_fundamentals": {{
111
+ "assessment": "",
112
+ "key_metrics": {{
113
+ "pe_ratio": "",
114
+ "volume":"",
115
+ "revenue_growth_yoy": "",
116
+ "net_income_growth_yoy": "",
117
+ "eps_growth_yoy": "",
118
+ "dividend_yield": "",
119
+ "balance_sheet": "",
120
+ "return_on_capital": ""
121
+ }}
122
+ }},
123
+ "current_and_future_price_trends": {{
124
+ "assessment": "",
125
+ "historical_trends": "",
126
+ "current_trends": "",
127
+ "technical_analysis_notes": "",
128
+ "technical_indicators":""
129
+ }},
130
+ "news_and_sentiment": {{
131
+ "assessment": "",
132
+ "positive_sentiment": [
133
+ "",
134
+ "",
135
+ ""
136
+ ],
137
+ "negative_sentiment": [
138
+ "",
139
+ "",
140
+ ""
141
+ ]
142
+ }},
143
+ "red_flags": [
144
+ {{
145
+ "flag": "",
146
+ "details": ""
147
+ }},
148
+ {{
149
+ "flag": "",
150
+ "details": ""
151
+ }},
152
+ {{
153
+ "flag": "",
154
+ "details": ""
155
+ }}
156
+ ]
 
157
  }},
158
+ "overall_rating": {{
159
+ "rating": "X/10",
160
+ "justification": ""
161
  }},
162
+ "investment_advice": {{
163
+ "next_1_weeks_outlook": "",
164
+ "next_5_weeks_outlook": "",
165
+ "next_10_weeks_outlook": "",
166
+ "price_action_suggestions": {{
167
+ "buy": "",
168
+ "hold": "",
169
+ "sell": ""
170
+ }}
171
  }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  }}
173
+ """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
+ # st.sidebar.subheader('Prompt')
176
+ # user_prompt = st.sidebar.text_area("Enter Prompt",llm_prompt_template)
177
+ #https://huggingface.co/spaces/pradeepodela/Stock-Analyser/blob/main/app.py
178
+ interval = Interval.INTERVAL_1_DAY
179
+ analysis_summary = get_tradingview_analysis(
180
+ symbol=ticker_user,
181
+ exchange="NSE",
182
+ screener="india",
183
+ interval=interval,
184
+ )
185
 
186
+ # st.title("Analysis Summary")
187
+ # st.dataframe(analysis_summary.summary)
188
+ # query = f"{ticker_user} stock"
 
 
189
 
190
+ details = {
191
+ "symbol": ticker_user,
192
+ "exchange": "NSE",
193
+ "screener": "india",
194
+ "interval": interval,
195
+ }
196
+ # st.title("Details")
197
+ # st.dataframe(details)
198
 
199
+ # st.title("Oscillator Analysis")
200
+ # st.dataframe(analysis_summary.oscillators)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
 
202
+ # st.title("Moving Averages")
203
+ # st.dataframe(analysis_summary.moving_averages)
204
 
205
+ # st.title("Summary")
206
+ # st.dataframe(analysis_summary.summary)
 
 
 
 
 
 
207
 
208
+ # st.title("Indicators")
209
+ # st.dataframe(analysis_summary.indicators)
 
 
210
 
211
+ # Page Title
212
+ st.header(f"πŸ“Š TradingView Analysis: {ticker_user}:{interval} ({details['exchange']})")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
 
214
+ # --- Row 1: Details + Summary ---
215
+ col1, col2 = st.columns([1, 3])
216
+ with col1:
217
+ st.subheader("πŸ“ Summary")
218
+ # st.write(analysis_summary.summary)
219
+ summary= analysis_summary.summary
220
+ counts = {
221
+ "BUY": summary["BUY"],
222
+ "SELL": summary["SELL"],
223
+ "NEUTRAL": summary["NEUTRAL"]
224
+ }
225
+
226
+ total = sum(counts.values())
227
+
228
+ # Calculate percentage widths
229
+ percentages = {k: (v / total) * 100 for k, v in counts.items()}
230
+
231
+ # Color map
232
+ color_map = {
233
+ "BUY": "#4CAF50", # Green
234
+ "SELL": "#F44336", # Red
235
+ "NEUTRAL": "#FFC107" # Amber
236
+ }
237
+
238
+ # Create the stacked bar using HTML
239
+ bar_html = '<div style="display: flex; height: 30px; width: 100%; border: 1px solid #ccc; border-radius: 5px; overflow: hidden;">'
240
+ for key in ['BUY', 'SELL', 'NEUTRAL']:
241
+ bar_html += f'''
242
+ <div style="
243
+ width: {percentages[key]}%;
244
+ background-color: {color_map[key]};
245
+ display: flex;
246
+ justify-content: center;
247
+ align-items: center;
248
+ color: white;
249
+ font-size: 12px;
250
+ font-weight: bold;">
251
+ {key} {counts[key]}
252
+ </div>
253
+ '''
254
+ bar_html += '</div>'
255
+
256
+ st.markdown("### Recommendation Summary")
257
+ st.markdown(f"**Final Recommendation**: `{summary['RECOMMENDATION']}`")
258
+ st.markdown(bar_html, unsafe_allow_html=True)
259
 
260
+ # --- Row 2: Oscillators + Moving Averages ---
261
+ # col3, col4 = st.columns(2)
262
+ # with col3:
263
+ # st.subheader("βš™οΈ Oscillator Analysis")
264
+ # st.dataframe(analysis_summary.oscillators, use_container_width=True)
265
 
266
+ # with col4:
267
+ # st.subheader("πŸ“ˆ Moving Averages")
268
+ # st.dataframe(analysis_summary.moving_averages, use_container_width=True)
 
 
 
 
 
269
 
270
+ # # --- Row 3: Indicators ---
271
+ # st.subheader("πŸ” Indicators")
272
+ # st.dataframe(analysis_summary.indicators, use_container_width=True)
273
+
274
+ # url = "https://api.chart-img.com/v2/tradingview/advanced-chart"
275
+ # api_key = "l0iUFRSeqC9z7nDPTd1hnafPh2RrdcEy6rl6tNqV"
276
+ # headers = {
277
+ # "x-api-key": api_key,
278
+ # "content-type": "application/json"
279
+ # }
280
+ # data = {
281
+ # "height": 400,
282
+ # "theme": "light",
283
+ # "interval": "1D",
284
+ # "session": "extended",
285
+ # "symbol": f"NSE:{ticker_user}"
286
+ # }
 
 
 
 
 
 
 
 
 
 
 
 
 
287
 
288
+ # response = requests.post(url, headers=headers, json=data)
 
 
 
 
289
 
290
+ # if response.status_code == 200:
291
+ # with open("chart_t1.jpg", "wb") as f:
292
+ # f.write(response.content)
293
+ # with col2:
294
+ # st.image("chart_t1.jpg", caption='')
295
+ # else:
296
+ # st.warning(f"Failed to retrieve image. Status code: {response.status_code}")
297
+ # st.warning("Response:", response.text)
298
 
299
+ llm_prompt = PromptTemplate.from_template(llm_prompt_template)
300
+
301
+ llm_chain = LLMChain(llm=llm,prompt=llm_prompt)
302
+ stuff_chain = StuffDocumentsChain(llm_chain=llm_chain,document_variable_name="input_documents")
303
 
304
+ # res = stuff_chain.invoke(docs)
305
+ res = stuff_chain.invoke({"input_documents": docs})
306
+ try:
307
+ raw_text = res["output_text"]
308
+
309
+ # Remove markdown code block delimiters if present
310
+ if raw_text.startswith("```json"):
311
+ raw_text = raw_text[len("```json"):]
312
+
313
+ if raw_text.endswith("```"):
314
+ raw_text = raw_text[:-3]
315
+
316
+ # Also strip leading/trailing whitespace/newlines
317
+ raw_text = raw_text.strip()
318
+
319
+
320
+ data = json.loads(raw_text)
321
+ # data = res["output_text"]
322
+ # Header Info
323
+ st.markdown(f"### {data['stock_summary']['company_name']} ({data['stock_summary']['ticker']}) | {data['stock_summary']['exchange']}")
324
+ st.markdown(f"**Description**: {data['stock_summary']['description']}")
325
+
326
+ # === Row 1: Price and Market Cap ===
327
+ row1 = st.columns(3)
328
+ row1[0].metric("πŸ’° Current Price", data["stock_summary"]["current_price"])
329
+ row1[1].metric("🏒 Market Cap", data["stock_summary"]["market_cap"])
330
+ row1[2].metric("⭐ Rating", data["overall_rating"]["rating"])
331
+
332
+ # === Row 2: Historical Performance ===
333
+ st.subheader("πŸ“Š Historical Performance")
334
+ perf_cols = st.columns(len(data["stock_summary"]["historical_performance"]))
335
+ for i, (k, v) in enumerate(data["stock_summary"]["historical_performance"].items()):
336
+ perf_cols[i].metric(k.replace("_", " ").title(), v)
337
+
338
+ # === Row 3: Fundamentals ===
339
+ st.subheader("πŸ“˜ Company Fundamentals")
340
+ row3 = st.columns(4)
341
+ metrics = data["evaluation_parameters"]["company_fundamentals"]["key_metrics"]
342
+ row3[0].metric("P/E Ratio", metrics["pe_ratio"])
343
+ row3[1].metric("EPS YoY", metrics["eps_growth_yoy"])
344
+ row3[2].metric("Revenue YoY", metrics["revenue_growth_yoy"])
345
+ row3[3].metric("Dividend Yield", metrics["dividend_yield"])
346
+
347
+ row3b = st.columns(4)
348
+ row3b[0].metric("Net Income YoY", metrics["net_income_growth_yoy"])
349
+ row3b[1].metric("Volume", metrics["volume"])
350
+ row3b[2].metric("Return on Capital", metrics["return_on_capital"])
351
+ row3b[3].metric("Balance Sheet", metrics["balance_sheet"])
352
+
353
+ st.info(data["evaluation_parameters"]["company_fundamentals"]["assessment"])
354
+
355
+ # === Row 4: Trends and Technicals ===
356
+ st.subheader("πŸ“ˆ Trends & Technical Analysis")
357
+ row4 = st.columns(3)
358
+ row4[0].markdown(f"**Historical Trends:** {data['evaluation_parameters']['current_and_future_price_trends']['historical_trends']}")
359
+ row4[1].markdown(f"**Current Trends:** {data['evaluation_parameters']['current_and_future_price_trends']['current_trends']}")
360
+ row4[2].markdown(f"**Technical Indicators:** {data['evaluation_parameters']['current_and_future_price_trends']['technical_indicators']}")
361
+
362
+ st.success(data["evaluation_parameters"]["current_and_future_price_trends"]["assessment"])
363
+ st.caption(f"πŸ“ Notes: {data['evaluation_parameters']['current_and_future_price_trends']['technical_analysis_notes']}")
364
+
365
+ # === Row 5: Sentiment ===
366
+ st.subheader("πŸ“° News & Sentiment")
367
+ sentiment_cols = st.columns(2)
368
+ with sentiment_cols[0]:
369
+ st.success("πŸ‘ Positive Sentiment")
370
+ for s in data["evaluation_parameters"]["news_and_sentiment"]["positive_sentiment"]:
371
+ st.write(f"βœ… {s}")
372
+ with sentiment_cols[1]:
373
+ st.error("πŸ‘Ž Negative Sentiment")
374
+ for s in data["evaluation_parameters"]["news_and_sentiment"]["negative_sentiment"]:
375
+ st.write(f"❌ {s}")
376
+ st.info(data["evaluation_parameters"]["news_and_sentiment"]["assessment"])
377
+
378
+ # === Row 6: Red Flags ===
379
+ st.subheader("🚩 Red Flags")
380
+ red_flag_cols = st.columns(3)
381
+ for i, flag in enumerate(data["evaluation_parameters"]["red_flags"]):
382
+ red_flag_cols[i].warning(f"**{flag['flag']}**\n{flag['details']}")
383
+
384
+ # === Row 7: Investment Advice ===
385
+ st.subheader("πŸ’‘ Investment Advice")
386
+ advice_cols = st.columns(3)
387
+ advice = data["investment_advice"]
388
+ advice_cols[0].markdown(f"**Next 1 Week**\n{advice['next_1_weeks_outlook']}")
389
+ advice_cols[1].markdown(f"**Next 5 Weeks**\n{advice['next_5_weeks_outlook']}")
390
+ advice_cols[2].markdown(f"**Next 10 Weeks**\n{advice['next_10_weeks_outlook']}")
391
+
392
+ action_cols = st.columns(3)
393
+ action_cols[0].success(f"**Buy:** {advice['price_action_suggestions']['buy']}")
394
+ action_cols[1].info(f"**Hold:** {advice['price_action_suggestions']['hold']}")
395
+ action_cols[2].error(f"**Sell:** {advice['price_action_suggestions']['sell']}")
396
+
397
+ # === Footer ===
398
+ st.markdown("---")
399
+ st.caption("Generated by AI-powered financial analysis dashboard.")
400
+ except json.JSONDecodeError as e:
401
+ st.error(f"JSON decode error: {e}")
402
+ st.write("Raw text was:")
403
+ st.text(res["output_text"])
404
+ elif activities=="News Sentiment":
405
+ st.header("News Action : ")