dev2607 commited on
Commit
75b661f
·
verified ·
1 Parent(s): e195039

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +134 -156
app.py CHANGED
@@ -3,187 +3,165 @@ import yfinance as yf
3
  import pandas as pd
4
  from groq import Groq
5
  import os
6
- import requests
7
  from duckduckgo_search import DDGS
 
8
 
9
- # Streamlit App Configuration
10
- st.set_page_config(
11
- page_title="Financial Analysis AI Agent",
12
- page_icon="💹",
13
- layout="wide"
14
- )
15
-
16
- # Initialize Groq Client
17
- def get_groq_client():
18
- try:
19
- # Try to get API key from Hugging Face secrets first
20
- groq_api_key = st.secrets.get("GROQ_API_KEY") or os.getenv("GROQ_API_KEY")
21
-
22
- if not groq_api_key:
23
- st.error("Groq API Key is missing. Please set it in Secrets or .env file.")
24
- return None
25
-
26
- return Groq(api_key=groq_api_key)
27
- except Exception as e:
28
- st.error(f"Error initializing Groq client: {e}")
29
- return None
30
-
31
- # Fetch Stock Information
32
- def get_stock_info(symbol):
33
- try:
34
- stock = yf.Ticker(symbol)
35
-
36
- # Fetch key information
37
- info = stock.info
38
-
39
- # Create a structured dictionary of key financial metrics
40
- stock_data = {
41
- "Company Name": info.get('longName', 'N/A'),
42
- "Current Price": f"${info.get('currentPrice', 'N/A'):.2f}",
43
- "Market Cap": f"${info.get('marketCap', 'N/A'):,}",
44
- "PE Ratio": info.get('trailingPE', 'N/A'),
45
- "Dividend Yield": f"{info.get('dividendYield', 'N/A'):.2%}",
46
- "52 Week High": f"${info.get('fiftyTwoWeekHigh', 'N/A'):.2f}",
47
- "52 Week Low": f"${info.get('fiftyTwoWeekLow', 'N/A'):.2f}",
48
- "Sector": info.get('sector', 'N/A'),
49
- "Industry": info.get('industry', 'N/A')
50
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
- return stock_data
53
- except Exception as e:
54
- st.error(f"Error fetching stock information: {e}")
55
- return None
56
-
57
- # Fetch News Using DuckDuckGo
58
- def get_duckduckgo_news(symbol, limit=5):
59
- try:
60
- with DDGS() as ddgs:
61
- # Search for recent news about the stock
62
- news_results = list(ddgs.news(f"{symbol} stock recent news", max_results=limit))
63
-
64
- # Transform results to a consistent format
65
- formatted_news = [
66
- {
67
- "title": result.get('title', 'N/A'),
68
- "link": result.get('url', ''),
69
- "publisher": result.get('source', 'N/A'),
70
- "source": "DuckDuckGo"
71
- } for result in news_results
72
- ]
73
-
74
- return formatted_news
75
- except Exception as e:
76
- st.warning(f"DuckDuckGo news search error: {e}")
77
- return []
78
-
79
- # Generate AI Analysis
80
- def generate_ai_analysis(stock_info, news, query_type):
81
- client = get_groq_client()
82
- if not client:
83
- return "Unable to generate AI analysis due to client initialization error."
84
-
85
- try:
86
- # Prepare context for AI
87
- stock_context = "\n".join([f"{k}: {v}" for k, v in stock_info.items()])
88
-
89
- # Prepare news context
90
- news_context = "Recent News:\n" + "\n".join([
91
- f"- {news['title']} (Source: {news['publisher']})"
92
- for news in news
93
- ])
94
 
95
- # Full context
96
- full_context = f"{stock_context}\n\n{news_context}"
97
 
98
- # Generate prompt based on query type
99
- if query_type == "Analyst Recommendations":
100
- prompt = f"Provide a comprehensive analysis of analyst recommendations for this stock. Consider the following details:\n{full_context}\n\nFocus on: current analyst ratings, price targets, and recent sentiment changes."
101
- elif query_type == "Latest News Analysis":
102
- prompt = f"Analyze the latest news and its potential impact on the stock. Consider these details:\n{full_context}\n\nProvide insights on how recent news might affect the stock's performance."
103
- elif query_type == "Comprehensive Analysis":
104
- prompt = f"Provide a holistic analysis of the stock, integrating financial metrics and recent news:\n{full_context}\n\nOffer a balanced perspective on investment potential."
105
- else:
106
- prompt = f"Generate a detailed financial and news-based analysis:\n{full_context}"
107
 
108
- # Generate response using Groq
109
- response = client.chat.completions.create(
110
- model="llama3-70b-8192",
111
- messages=[
112
- {"role": "system", "content": "You are a professional financial analyst providing nuanced stock insights."},
113
- {"role": "user", "content": prompt}
114
- ]
115
  )
116
 
117
- return response.choices[0].message.content
118
- except Exception as e:
119
- return f"Error generating AI analysis: {e}"
120
 
121
- # Main Streamlit App
122
  def main():
123
- st.title("🚀 Advanced Financial Insight AI")
124
- st.markdown("Comprehensive stock analysis with DuckDuckGo news search")
125
 
126
- # Sidebar Configuration
127
- st.sidebar.header("🔍 Stock Analysis")
128
 
 
 
 
 
 
 
 
129
  # Stock Symbol Input
130
- stock_symbol = st.sidebar.text_input(
131
  "Enter Stock Symbol",
132
  value="NVDA",
133
- help="Enter a valid stock ticker (e.g., AAPL, GOOGL)"
134
- )
135
-
136
- # Analysis Type Selection
137
- query_type = st.sidebar.selectbox(
138
- "Select Analysis Type",
139
- [
140
- "Comprehensive Analysis",
141
- "Analyst Recommendations",
142
- "Latest News Analysis"
143
- ]
144
  )
145
 
146
- # Generate Analysis Button
147
- if st.sidebar.button("Generate Analysis"):
148
- with st.spinner("Fetching and analyzing stock data..."):
149
  try:
150
- # Fetch Stock Information
151
- stock_info = get_stock_info(stock_symbol)
152
-
153
- if stock_info:
154
- # Display Stock Information
155
- st.subheader(f"Financial Snapshot: {stock_symbol}")
156
- info_df = pd.DataFrame.from_dict(stock_info, orient='index', columns=['Value'])
157
- st.table(info_df)
158
-
159
- # Fetch News via DuckDuckGo
160
- real_time_news = get_duckduckgo_news(stock_symbol)
161
-
162
  # Display News
163
- st.subheader("📰 Latest News")
164
- for news in real_time_news:
165
- st.markdown(f"**{news['title']}**")
166
- st.markdown(f"*Source: {news['publisher']}*")
167
- st.markdown(f"[Read more]({news['link']})")
168
  st.markdown("---")
169
-
170
- # Generate AI Analysis
171
- ai_analysis = generate_ai_analysis(stock_info, real_time_news, query_type)
172
-
173
- # Display AI Analysis
174
- st.subheader("🤖 AI-Powered Insights")
175
- st.write(ai_analysis)
176
-
 
177
  except Exception as e:
178
- st.error(f"An error occurred: {e}")
179
 
180
- # Disclaimer
181
- st.sidebar.markdown("---")
182
  st.sidebar.warning(
183
- "🚨 Disclaimer: This is an AI-generated analysis. "
184
- "Always consult with a financial advisor before making investment decisions."
185
  )
186
 
187
- # Run the Streamlit app
188
  if __name__ == "__main__":
189
  main()
 
3
  import pandas as pd
4
  from groq import Groq
5
  import os
 
6
  from duckduckgo_search import DDGS
7
+ import json
8
 
9
+ class FinancialIntelligentAgent:
10
+ def __init__(self, api_key):
11
+ self.groq_client = Groq(api_key=api_key)
12
+ self.tools = {
13
+ "stock_info": self.get_stock_info,
14
+ "news_search": self.get_duckduckgo_news,
15
+ "market_sentiment": self.analyze_market_sentiment,
16
+ "risk_assessment": self.assess_investment_risk
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
+
19
+ def get_stock_info(self, symbol):
20
+ """Retrieve comprehensive stock information"""
21
+ try:
22
+ stock = yf.Ticker(symbol)
23
+ info = stock.info
24
+ return {
25
+ "basic_info": {
26
+ "Company Name": info.get('longName', 'N/A'),
27
+ "Current Price": f"${info.get('currentPrice', 'N/A'):.2f}",
28
+ "Market Cap": f"${info.get('marketCap', 'N/A'):,}",
29
+ "Sector": info.get('sector', 'N/A'),
30
+ "Industry": info.get('industry', 'N/A')
31
+ },
32
+ "financial_metrics": {
33
+ "PE Ratio": info.get('trailingPE', 'N/A'),
34
+ "Dividend Yield": f"{info.get('dividendYield', 'N/A'):.2%}",
35
+ "52 Week Range": f"${info.get('fiftyTwoWeekLow', 'N/A')} - ${info.get('fiftyTwoWeekHigh', 'N/A')}"
36
+ }
37
+ }
38
+ except Exception as e:
39
+ return {"error": str(e)}
40
+
41
+ def get_duckduckgo_news(self, symbol, limit=5):
42
+ """Search and retrieve news about the stock"""
43
+ try:
44
+ with DDGS() as ddgs:
45
+ news_results = list(ddgs.news(f"{symbol} stock recent news", max_results=limit))
46
+ return [
47
+ {
48
+ "title": result.get('title', 'N/A'),
49
+ "link": result.get('url', ''),
50
+ "source": result.get('source', 'N/A')
51
+ } for result in news_results
52
+ ]
53
+ except Exception as e:
54
+ return [{"error": str(e)}]
55
+
56
+ def analyze_market_sentiment(self, symbol, news):
57
+ """Analyze market sentiment based on news"""
58
+ try:
59
+ news_context = "\n".join([news['title'] for news in news])
60
+ response = self.groq_client.chat.completions.create(
61
+ model="llama3-70b-8192",
62
+ messages=[
63
+ {"role": "system", "content": "You are a market sentiment analyst."},
64
+ {"role": "user", "content": f"Analyze the market sentiment for {symbol} based on these news headlines:\n{news_context}"}
65
+ ]
66
+ )
67
+ return response.choices[0].message.content
68
+ except Exception as e:
69
+ return f"Sentiment analysis error: {e}"
70
+
71
+ def assess_investment_risk(self, stock_info):
72
+ """Perform comprehensive risk assessment"""
73
+ try:
74
+ stock_context = json.dumps(stock_info, indent=2)
75
+ response = self.groq_client.chat.completions.create(
76
+ model="llama3-70b-8192",
77
+ messages=[
78
+ {"role": "system", "content": "You are a risk assessment expert in financial investments."},
79
+ {"role": "user", "content": f"Conduct a detailed investment risk assessment based on these stock details:\n{stock_context}"}
80
+ ]
81
+ )
82
+ return response.choices[0].message.content
83
+ except Exception as e:
84
+ return f"Risk assessment error: {e}"
85
+
86
+ def generate_comprehensive_analysis(self, symbol):
87
+ """Generate a comprehensive financial analysis using multiple tools"""
88
+ # Autonomous tool selection and execution
89
+ analysis_results = {}
90
 
91
+ # Step 1: Gather Stock Information
92
+ analysis_results['stock_info'] = self.tools['stock_info'](symbol)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
+ # Step 2: Retrieve News
95
+ analysis_results['news'] = self.tools['news_search'](symbol)
96
 
97
+ # Step 3: Analyze Market Sentiment
98
+ analysis_results['market_sentiment'] = self.tools['market_sentiment'](
99
+ symbol,
100
+ analysis_results['news']
101
+ )
 
 
 
 
102
 
103
+ # Step 4: Assess Investment Risk
104
+ analysis_results['risk_assessment'] = self.tools['risk_assessment'](
105
+ analysis_results['stock_info']
 
 
 
 
106
  )
107
 
108
+ return analysis_results
 
 
109
 
110
+ # Streamlit Application
111
  def main():
112
+ st.title("🤖 Agentic AI Financial Analyst")
113
+ st.markdown("Advanced autonomous financial intelligence platform")
114
 
115
+ # API Key Management
116
+ groq_api_key = st.secrets.get("GROQ_API_KEY") or os.getenv("GROQ_API_KEY")
117
 
118
+ if not groq_api_key:
119
+ st.error("Groq API Key is required!")
120
+ return
121
+
122
+ # Initialize Intelligent Agent
123
+ agent = FinancialIntelligentAgent(groq_api_key)
124
+
125
  # Stock Symbol Input
126
+ stock_symbol = st.text_input(
127
  "Enter Stock Symbol",
128
  value="NVDA",
129
+ help="Enter a valid stock ticker"
 
 
 
 
 
 
 
 
 
 
130
  )
131
 
132
+ # Analysis Button
133
+ if st.button("Generate Comprehensive Analysis"):
134
+ with st.spinner("Autonomous analysis in progress..."):
135
  try:
136
+ # Execute Agentic Analysis
137
+ analysis_results = agent.generate_comprehensive_analysis(stock_symbol)
138
+
139
+ # Display Stock Information
140
+ st.subheader(f"📊 Stock Overview: {stock_symbol}")
141
+ st.json(analysis_results['stock_info'])
142
+
 
 
 
 
 
143
  # Display News
144
+ st.subheader("📰 Recent News")
145
+ for news in analysis_results['news']:
146
+ st.markdown(f"**{news.get('title', 'N/A')}**")
147
+ st.markdown(f"[Read more]({news.get('link', '#')})")
 
148
  st.markdown("---")
149
+
150
+ # Display Market Sentiment
151
+ st.subheader("📈 Market Sentiment Analysis")
152
+ st.write(analysis_results['market_sentiment'])
153
+
154
+ # Display Risk Assessment
155
+ st.subheader("⚖️ Investment Risk Assessment")
156
+ st.write(analysis_results['risk_assessment'])
157
+
158
  except Exception as e:
159
+ st.error(f"Analysis failed: {e}")
160
 
 
 
161
  st.sidebar.warning(
162
+ "🚨 Disclaimer: AI-generated insights. "
163
+ "Consult financial professionals for decisions."
164
  )
165
 
 
166
  if __name__ == "__main__":
167
  main()