OmidSakaki commited on
Commit
bdb1f5b
Β·
verified Β·
1 Parent(s): fcf2839

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +485 -228
app.py CHANGED
@@ -5,333 +5,590 @@ import yfinance as yf
5
  import plotly.graph_objects as go
6
  from plotly.subplots import make_subplots
7
  from datetime import datetime, timedelta
 
 
8
  import warnings
9
  warnings.filterwarnings('ignore')
10
 
11
- # Market Data Provider
12
- class MarketDataProvider:
 
 
 
 
13
  def __init__(self, symbols=['AAPL', 'GOOGL', 'MSFT', 'TSLA']):
14
  self.symbols = symbols
15
  self.data_cache = {}
 
 
 
16
 
17
- def get_stock_data(self, symbol, period='1mo'):
18
- try:
19
- cache_key = f"{symbol}_{period}"
20
- if cache_key in self.data_cache:
21
- return self.data_cache[cache_key]
22
-
23
- ticker = yf.Ticker(symbol)
24
- hist_data = ticker.history(period=period)
25
-
26
- if hist_data.empty:
27
- return self.generate_simulated_data(symbol)
28
-
29
- data = {
30
- 'prices': hist_data['Close'].tolist(),
31
- 'dates': hist_data.index.strftime('%Y-%m-%d').tolist(),
32
- 'volume': hist_data['Volume'].tolist(),
33
- 'current_price': hist_data['Close'].iloc[-1],
34
- 'change': ((hist_data['Close'].iloc[-1] - hist_data['Close'].iloc[0]) / hist_data['Close'].iloc[0]) * 100
35
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
- self.data_cache[cache_key] = data
38
- return data
39
 
40
- except Exception as e:
41
- print(f"Error fetching {symbol}: {e}")
42
- return self.generate_simulated_data(symbol)
43
-
44
- def generate_simulated_data(self, symbol):
45
- base_price = np.random.uniform(100, 200)
46
- days = 30
47
- prices = [base_price * (1 + np.random.normal(0, 0.02)) for _ in range(days)]
48
- dates = [(datetime.now() - timedelta(days=i)).strftime('%Y-%m-%d') for i in range(days, 0, -1)]
49
 
50
  return {
51
  'prices': prices,
52
- 'dates': dates,
53
- 'volume': [np.random.randint(1000000, 5000000) for _ in range(days)],
54
  'current_price': prices[-1],
55
- 'change': ((prices[-1] - prices[0]) / prices[0]) * 100
 
 
 
56
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
- # AI Trading Agents
59
- class TradingAgents:
 
 
 
 
60
  def __init__(self):
61
- self.agents_config = {
62
  'research': {
63
  'name': 'Financial Research Agent',
64
  'emoji': 'πŸ“Š',
65
- 'prompt_template': """Analyze {symbol} stock:
66
- Price: ${current_price:.2f}
67
- Change: {change:+.2f}%
68
- Trend: {trend}
69
-
70
- Provide fundamental analysis and recommendation:"""
71
  },
72
  'technical': {
73
  'name': 'Technical Analysis Agent',
74
  'emoji': 'πŸ“ˆ',
75
- 'prompt_template': """Technical analysis for {symbol}:
76
- Price: ${current_price:.2f}
77
- Trend: {trend}
78
- Volatility: {volatility:.1f}%
79
-
80
- Provide technical levels and trading signals:"""
81
  },
82
  'risk': {
83
  'name': 'Risk Management Agent',
84
  'emoji': 'πŸ›‘οΈ',
85
- 'prompt_template': """Risk assessment for {symbol}:
86
- Price: ${current_price:.2f}
87
- Volatility: {volatility:.1f}%
88
-
89
- Provide risk management strategy:"""
 
90
  }
91
  }
 
 
 
 
 
92
 
93
- def calculate_metrics(self, price_data):
94
- prices = price_data['prices']
95
- if len(prices) < 2:
96
- return {"trend": "Neutral", "volatility": 0}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
- price_change = ((prices[-1] - prices[0]) / prices[0]) * 100
 
 
 
 
 
 
 
 
99
  returns = np.diff(prices) / prices[:-1]
100
- volatility = np.std(returns) * np.sqrt(252) * 100
 
 
 
 
 
 
 
 
101
 
102
- if price_change > 5:
103
- trend = "Strong Bullish"
104
- elif price_change > 0:
105
- trend = "Mild Bullish"
 
 
 
 
106
  else:
107
- trend = "Bearish"
 
 
 
 
 
 
 
 
 
 
108
 
109
  return {
110
- "trend": f"{trend} ({price_change:+.1f}%)",
111
- "volatility": volatility,
112
- "price_change": price_change
113
  }
114
 
115
- def analyze_stock(self, symbol, price_data):
116
- metrics = self.calculate_metrics(price_data)
117
- current_price = price_data['current_price']
 
 
 
 
118
 
119
- analyses = {}
120
-
121
- for agent_type, config in self.agents_config.items():
122
- prompt = config['prompt_template'].format(
123
- symbol=symbol,
124
- current_price=current_price,
125
- change=metrics['price_change'],
126
- trend=metrics['trend'],
127
- volatility=metrics['volatility']
128
- )
129
-
130
- analysis = self.get_agent_response(agent_type, prompt)
131
- analyses[agent_type] = {
132
- 'name': config['name'],
133
- 'emoji': config['emoji'],
134
- 'analysis': analysis
135
- }
136
-
137
- analyses['decision'] = self.generate_final_decision(symbol, current_price, analyses, metrics)
138
- return analyses
139
 
140
- def get_agent_response(self, agent_type, prompt):
141
- responses = {
142
- 'research': [
143
- "πŸ“Š STRONG FUNDAMENTALS: Positive earnings growth, market leadership position. Institutional accumulation visible. RECOMMENDATION: BUY with 80% confidence. Target 15-20% upside.",
144
- "πŸ“Š MIXED FUNDAMENTALS: Valuation concerns offset by solid cash flow. Competitive pressures increasing. RECOMMENDATION: HOLD and monitor for better entry.",
145
- "πŸ“Š EXCELLENT GROWTH: Innovative product pipeline, expanding market share. Strong balance sheet. RECOMMENDATION: STRONG BUY for long-term growth."
146
- ],
147
- 'technical': [
148
- "πŸ“ˆ BULLISH PATTERN: Breakout above resistance. Support at ${support:.2f}. RSI: 65. ENTRY: Current levels. TARGET: ${target:.2f}.",
149
- "πŸ“ˆ CONSOLIDATION PHASE: Trading range ${support:.2f}-${resistance:.2f}. Wait for breakout confirmation. Volume declining.",
150
- "πŸ“ˆ STRONG UPTREND: Higher highs and higher lows. Volume confirmation. Fibonacci target: ${target:.2f}. Stop: ${stop:.2f}."
151
- ],
152
- 'risk': [
153
- "πŸ›‘οΈ MODERATE RISK: Position size 3-4%. Stop-loss 8%. Risk-reward 1:2.5. Maximum drawdown 12%.",
154
- "πŸ›‘οΈ CONSERVATIVE: Position size 2-3%. Stop-loss 10% trailing. Monitor earnings date closely.",
155
- "πŸ›‘οΈ FAVORABLE: Position size 4-5%. Stop-loss 6%. Risk-reward 1:3.0. Low portfolio correlation."
156
- ]
157
  }
 
 
 
 
158
 
159
- response = np.random.choice(responses[agent_type])
160
- current_price = np.random.uniform(150, 250)
 
 
 
161
 
162
- return response.format(
163
- support=current_price * 0.95,
164
- resistance=current_price * 1.08,
165
- target=current_price * 1.15,
166
- stop=current_price * 0.92
167
- )
168
 
169
- def generate_final_decision(self, symbol, current_price, analyses, metrics):
170
- if metrics['price_change'] > 3 and metrics['volatility'] < 25:
 
171
  decision = "BUY"
 
 
 
 
172
  confidence = np.random.randint(75, 90)
173
- elif metrics['price_change'] < -3:
174
- decision = "SELL"
175
- confidence = np.random.randint(70, 85)
176
  else:
177
  decision = "HOLD"
178
- confidence = np.random.randint(60, 80)
 
179
 
180
- return {
181
- 'name': 'Final Decision',
182
- 'emoji': '🎯',
183
- 'analysis': f"""🎯 FINAL DECISION: {decision}
184
 
185
- Confidence: {confidence}%
186
- Price: ${current_price:.2f}
187
- Position Size: {max(2, min(5, 8 - metrics['volatility']/10))}%
188
 
189
- Action: {'Enter long position' if decision == 'BUY' else 'Wait for better setup'}"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  }
191
 
192
- # Initialize components
193
- market_data = MarketDataProvider()
194
- trading_agents = TradingAgents()
195
 
196
- # Gradio Interface Functions
197
- def create_stock_chart(symbol, price_data):
198
- fig = go.Figure()
199
-
200
- fig.add_trace(go.Scatter(
201
- x=price_data['dates'],
202
- y=price_data['prices'],
203
- mode='lines+markers',
204
- name=f'{symbol} Price',
205
- line=dict(color='#00D4AA', width=3),
206
- marker=dict(size=6)
207
- ))
208
 
209
- fig.update_layout(
210
- title=f'{symbol} Price Chart - 30 Days',
211
- xaxis_title='Date',
212
- yaxis_title='Price ($)',
213
- template='plotly_dark',
214
- height=300,
215
- margin=dict(l=50, r=50, t=50, b=50)
 
 
 
 
 
 
 
 
216
  )
217
 
218
- return fig
219
-
220
- def create_performance_dashboard(stocks_data):
221
- symbols = list(stocks_data.keys())
222
- changes = [stocks_data[symbol]['change'] for symbol in symbols]
223
- prices = [stocks_data[symbol]['current_price'] for symbol in symbols]
 
 
 
 
 
 
 
 
 
 
224
 
225
- fig = make_subplots(
226
- rows=1, cols=2,
227
- subplot_titles=['30-Day Performance (%)', 'Current Prices ($)'],
228
- specs=[[{"type": "bar"}, {"type": "bar"}]]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  )
230
 
231
- colors = ['#00D4AA' if x >= 0 else '#FF6B6B' for x in changes]
232
- fig.add_trace(go.Bar(x=symbols, y=changes, marker_color=colors), row=1, col=1)
233
- fig.add_trace(go.Bar(x=symbols, y=prices, marker_color='#636EFA'), row=1, col=2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
 
 
235
  fig.update_layout(
236
- title='Stock Performance Overview',
 
 
 
237
  template='plotly_dark',
238
- height=400,
239
- showlegend=False
240
  )
241
 
242
- return fig
243
-
244
- def analyze_single_stock(symbol):
245
- """Analyze a single stock"""
246
- price_data = market_data.get_stock_data(symbol)
247
- analyses = trading_agents.analyze_stock(symbol, price_data)
248
-
249
- chart = create_stock_chart(symbol, price_data)
250
-
251
- analysis_output = f"# {symbol} Analysis Report\n\n"
252
- analysis_output += f"**Current Price:** ${price_data['current_price']:.2f}\n"
253
- analysis_output += f"**30-Day Change:** {price_data['change']:+.2f}%\n\n"
254
 
255
- for agent_type, analysis in analyses.items():
256
- analysis_output += f"## {analysis['emoji']} {analysis['name']}\n"
257
- analysis_output += f"{analysis['analysis']}\n\n"
258
 
259
- return chart, analysis_output
260
 
261
- def analyze_all_stocks():
262
- """Analyze all tracked stocks"""
263
- stocks_data = {}
264
- for symbol in market_data.symbols:
265
- stocks_data[symbol] = market_data.get_stock_data(symbol)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
 
267
- dashboard = create_performance_dashboard(stocks_data)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
 
269
- analysis_output = "# Multi-Agent Trading Analysis\n\n"
 
270
 
271
- for symbol in market_data.symbols:
272
- analyses = trading_agents.analyze_stock(symbol, stocks_data[symbol])
273
- decision_line = analyses['decision']['analysis'].split('\n')[0]
274
-
275
- analysis_output += f"## {symbol}\n"
276
- analysis_output += f"**Price:** ${stocks_data[symbol]['current_price']:.2f} | "
277
- analysis_output += f"**Change:** {stocks_data[symbol]['change']:+.2f}%\n"
278
- analysis_output += f"**Decision:** {decision_line}\n\n"
279
 
280
- return dashboard, analysis_output
281
 
282
- def update_analysis(symbol_input):
283
- """Update analysis based on user input"""
284
- if symbol_input:
285
- symbol = symbol_input.upper().strip()
286
- return analyze_single_stock(symbol)
287
- else:
288
- return analyze_all_stocks()
289
-
290
- # Gradio Interface
291
- with gr.Blocks(theme=gr.themes.Soft(), title="AI Trading Agents") as demo:
 
 
 
 
 
 
 
 
 
292
  gr.Markdown("""
293
  # πŸ€– Multi-Agent AI Trading System
294
- **Professional stock analysis powered by AI agents**
 
 
295
  """)
296
 
297
  with gr.Row():
298
  with gr.Column(scale=1):
 
299
  symbol_input = gr.Textbox(
300
- label="Enter Stock Symbol (e.g., AAPL, TSLA)",
301
- placeholder="Leave empty for all tracked stocks...",
302
  max_lines=1
303
  )
304
- analyze_btn = gr.Button("Analyze Stock", variant="primary")
305
-
 
 
 
 
 
 
 
 
 
306
  with gr.Column(scale=2):
307
- gr.Markdown("### Live Market Analysis")
308
 
309
  with gr.Tabs():
310
- with gr.TabItem("πŸ“ˆ Charts"):
 
 
 
 
 
 
 
311
  with gr.Row():
312
- chart_output = gr.Plot(label="Price Chart")
313
- dashboard_output = gr.Plot(label="Performance Dashboard")
 
 
 
 
 
 
 
 
 
 
 
314
 
315
- with gr.TabItem("πŸ“Š Analysis"):
316
- analysis_output = gr.Markdown(label="AI Analysis Report")
317
 
318
  # Event handlers
319
  analyze_btn.click(
320
- fn=update_analysis,
321
  inputs=[symbol_input],
322
  outputs=[chart_output, analysis_output]
323
  )
324
 
325
- # Load initial analysis
326
  demo.load(
327
- fn=analyze_all_stocks,
328
- outputs=[dashboard_output, analysis_output]
 
 
329
  )
330
 
331
- # For Hugging Face Spaces
332
  if __name__ == "__main__":
333
  demo.launch(
334
  server_name="0.0.0.0",
335
  server_port=7860,
336
- share=True
 
337
  )
 
5
  import plotly.graph_objects as go
6
  from plotly.subplots import make_subplots
7
  from datetime import datetime, timedelta
8
+ import threading
9
+ import time
10
  import warnings
11
  warnings.filterwarnings('ignore')
12
 
13
+ class RealTimeMarketData:
14
+ """
15
+ Real-time market data provider with live streaming capabilities
16
+ Optimized for Hugging Face Spaces with efficient caching
17
+ """
18
+
19
  def __init__(self, symbols=['AAPL', 'GOOGL', 'MSFT', 'TSLA']):
20
  self.symbols = symbols
21
  self.data_cache = {}
22
+ self.last_update_time = None
23
+ self.update_interval = 30 # seconds
24
+ self.live_data = {}
25
 
26
+ # Initialize with current data
27
+ self._update_all_data()
28
+
29
+ def _update_all_data(self):
30
+ """Update all stock data with real-time information"""
31
+ current_time = datetime.now()
32
+
33
+ for symbol in self.symbols:
34
+ try:
35
+ # Fetch real-time data
36
+ ticker = yf.Ticker(symbol)
37
+ hist_data = ticker.history(period='1d', interval='1m')
38
+
39
+ if not hist_data.empty:
40
+ # Get last 30 minutes of data for real-time feel
41
+ prices = hist_data['Close'].tolist()[-30:]
42
+ volumes = hist_data['Volume'].tolist()[-30:] if 'Volume' in hist_data else []
43
+ timestamps = hist_data.index[-30:]
44
+
45
+ self.live_data[symbol] = {
46
+ 'prices': prices,
47
+ 'volumes': volumes,
48
+ 'timestamps': [ts.strftime('%H:%M:%S') for ts in timestamps],
49
+ 'current_price': prices[-1] if prices else 0,
50
+ 'previous_close': prices[0] if prices else 0,
51
+ 'change': ((prices[-1] - prices[0]) / prices[0] * 100) if len(prices) > 1 else 0,
52
+ 'volume': volumes[-1] if volumes else 0,
53
+ 'last_updated': current_time
54
+ }
55
+ else:
56
+ self.live_data[symbol] = self._generate_simulated_data(symbol)
57
+
58
+ except Exception as e:
59
+ print(f"Error fetching {symbol}: {e}")
60
+ self.live_data[symbol] = self._generate_simulated_data(symbol)
61
+
62
+ self.last_update_time = current_time
63
+
64
+ def _generate_simulated_data(self, symbol):
65
+ """Generate realistic simulated market data for demo purposes"""
66
+ base_price = np.random.uniform(150, 250)
67
+ current_time = datetime.now()
68
+
69
+ # Generate 30 minutes of price data with realistic volatility
70
+ prices = []
71
+ volumes = []
72
+ timestamps = []
73
+
74
+ current_price = base_price
75
+ for i in range(30):
76
+ # Realistic price movement with slight trend
77
+ change = np.random.normal(0.001, 0.005) # Small random walk
78
+ current_price = current_price * (1 + change)
79
+ prices.append(current_price)
80
 
81
+ # Volume with some randomness
82
+ volumes.append(np.random.randint(1000000, 5000000))
83
 
84
+ # Timestamps for last 30 minutes
85
+ timestamp = current_time - timedelta(minutes=29-i)
86
+ timestamps.append(timestamp.strftime('%H:%M:%S'))
 
 
 
 
 
 
87
 
88
  return {
89
  'prices': prices,
90
+ 'volumes': volumes,
91
+ 'timestamps': timestamps,
92
  'current_price': prices[-1],
93
+ 'previous_close': prices[0],
94
+ 'change': ((prices[-1] - prices[0]) / prices[0] * 100),
95
+ 'volume': volumes[-1],
96
+ 'last_updated': current_time
97
  }
98
+
99
+ def get_live_data(self):
100
+ """Get current live market data with auto-refresh"""
101
+ current_time = datetime.now()
102
+
103
+ # Auto-refresh data if it's stale
104
+ if (not self.last_update_time or
105
+ (current_time - self.last_update_time).seconds >= self.update_interval):
106
+ self._update_all_data()
107
+
108
+ return self.live_data
109
+
110
+ def get_single_stock_data(self, symbol):
111
+ """Get data for a single stock with real-time updates"""
112
+ if symbol.upper() not in self.symbols and symbol:
113
+ # Add new symbol temporarily
114
+ self.symbols.append(symbol.upper())
115
+ self._update_all_data()
116
+
117
+ data = self.get_live_data()
118
+ return data.get(symbol.upper(), self._generate_simulated_data(symbol))
119
 
120
+ class AI_TradingAgents:
121
+ """
122
+ Multi-Agent AI System for Stock Analysis
123
+ Four specialized agents working in coordination
124
+ """
125
+
126
  def __init__(self):
127
+ self.agents = {
128
  'research': {
129
  'name': 'Financial Research Agent',
130
  'emoji': 'πŸ“Š',
131
+ 'color': '#FF6B6B'
 
 
 
 
 
132
  },
133
  'technical': {
134
  'name': 'Technical Analysis Agent',
135
  'emoji': 'πŸ“ˆ',
136
+ 'color': '#4ECDC4'
 
 
 
 
 
137
  },
138
  'risk': {
139
  'name': 'Risk Management Agent',
140
  'emoji': 'πŸ›‘οΈ',
141
+ 'color': '#45B7D1'
142
+ },
143
+ 'decision': {
144
+ 'name': 'Decision Engine',
145
+ 'emoji': '🎯',
146
+ 'color': '#96CEB4'
147
  }
148
  }
149
+
150
+ def analyze_market(self, symbol, market_data):
151
+ """Comprehensive multi-agent market analysis"""
152
+ if symbol not in market_data:
153
+ return self._get_error_analysis(symbol)
154
 
155
+ data = market_data[symbol]
156
+ current_price = data['current_price']
157
+ price_change = data['change']
158
+
159
+ # Calculate additional metrics
160
+ volatility = self._calculate_volatility(data['prices'])
161
+ trend_strength = self._calculate_trend_strength(data['prices'])
162
+ support_resistance = self._calculate_support_resistance(data['prices'])
163
+
164
+ analyses = {}
165
+
166
+ # Research Agent Analysis
167
+ analyses['research'] = self._research_analysis(symbol, current_price, price_change, trend_strength)
168
+
169
+ # Technical Agent Analysis
170
+ analyses['technical'] = self._technical_analysis(symbol, current_price, support_resistance, volatility)
171
+
172
+ # Risk Agent Analysis
173
+ analyses['risk'] = self._risk_analysis(symbol, current_price, volatility, price_change)
174
 
175
+ # Final Decision Engine
176
+ analyses['decision'] = self._decision_engine(symbol, current_price, analyses, price_change, volatility)
177
+
178
+ return analyses
179
+
180
+ def _calculate_volatility(self, prices):
181
+ """Calculate price volatility"""
182
+ if len(prices) < 2:
183
+ return 0
184
  returns = np.diff(prices) / prices[:-1]
185
+ return np.std(returns) * 100
186
+
187
+ def _calculate_trend_strength(self, prices):
188
+ """Calculate trend strength indicator"""
189
+ if len(prices) < 5:
190
+ return "Neutral"
191
+
192
+ short_term = np.mean(prices[-5:])
193
+ long_term = np.mean(prices[-10:]) if len(prices) >= 10 else prices[0]
194
 
195
+ strength = (short_term - long_term) / long_term * 100
196
+
197
+ if strength > 2:
198
+ return "Strong Bullish"
199
+ elif strength > 0:
200
+ return "Mild Bullish"
201
+ elif strength > -2:
202
+ return "Mild Bearish"
203
  else:
204
+ return "Strong Bearish"
205
+
206
+ def _calculate_support_resistance(self, prices):
207
+ """Calculate support and resistance levels"""
208
+ if len(prices) < 10:
209
+ current = prices[-1] if prices else 100
210
+ return {'support': current * 0.95, 'resistance': current * 1.05}
211
+
212
+ recent_low = min(prices[-10:])
213
+ recent_high = max(prices[-10:])
214
+ current = prices[-1]
215
 
216
  return {
217
+ 'support': recent_low * 0.98,
218
+ 'resistance': recent_high * 1.02,
219
+ 'current': current
220
  }
221
 
222
+ def _research_analysis(self, symbol, price, change, trend):
223
+ """Research Agent: Fundamental analysis"""
224
+ templates = [
225
+ f"**Strong Fundamentals** βœ…\n\nβ€’ Revenue growth: +15% YoY\nβ€’ Profit margins expanding\nβ€’ Market leadership position\nβ€’ Institutional accumulation\nβ€’ **Recommendation: BUY** (85% confidence)\nβ€’ Target upside: 20-25%",
226
+ f"**Solid Fundamentals** ⚠️\n\nβ€’ Steady revenue growth: +8% YoY\nβ€’ Competitive pressures increasing\nβ€’ Valuation fair\nβ€’ **Recommendation: HOLD** (70% confidence)\nβ€’ Wait for better entry point",
227
+ f"**Excellent Growth Prospects** πŸš€\n\nβ€’ Innovative product pipeline\nβ€’ Market share expansion\nβ€’ Strong balance sheet\nβ€’ **Recommendation: STRONG BUY** (90% confidence)\nβ€’ Long-term compounder"
228
+ ]
229
 
230
+ return {
231
+ 'emoji': 'πŸ“Š',
232
+ 'title': 'Fundamental Analysis',
233
+ 'analysis': np.random.choice(templates),
234
+ 'confidence': np.random.randint(75, 95)
235
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
 
237
+ def _technical_analysis(self, symbol, price, levels, volatility):
238
+ """Technical Agent: Price action analysis"""
239
+ templates = [
240
+ f"**Bullish Technical Setup** πŸ“ˆ\n\nβ€’ Support: ${levels['support']:.2f}\nβ€’ Resistance: ${levels['resistance']:.2f}\nβ€’ RSI: Neutral (58)\nβ€’ Pattern: Breakout formation\nβ€’ **Entry**: Current levels\nβ€’ **Target**: ${levels['resistance'] * 1.1:.2f}",
241
+ f"**Consolidation Phase** ⏸️\n\nβ€’ Trading range: ${levels['support']:.2f}-${levels['resistance']:.2f}\nβ€’ Volume declining\nβ€’ Wait for breakout\nβ€’ Next 1-2 weeks decisive",
242
+ f"**Strong Uptrend** πŸ”₯\n\nβ€’ Higher highs & higher lows\nβ€’ Volume confirmation\nβ€’ All time highs approaching\nβ€’ **Strategy**: Buy on dips\nβ€’ **Stop-loss**: ${levels['support']:.2f}"
243
+ ]
244
+
245
+ return {
246
+ 'emoji': 'πŸ“ˆ',
247
+ 'title': 'Technical Analysis',
248
+ 'analysis': np.random.choice(templates),
249
+ 'confidence': np.random.randint(70, 90)
 
 
 
 
250
  }
251
+
252
+ def _risk_analysis(self, symbol, price, volatility, change):
253
+ """Risk Agent: Risk management assessment"""
254
+ position_size = max(2, min(5, 6 - volatility/10))
255
 
256
+ templates = [
257
+ f"**Moderate Risk Profile** 🟑\n\nβ€’ Position size: {position_size}%\nβ€’ Stop-loss: 8% below entry\nβ€’ Risk-reward: 1:2.5\nβ€’ Max drawdown: 12%\nβ€’ Volatility: {volatility:.1f}%\nβ€’ **Assessment**: Manageable risk",
258
+ f"**Conservative Approach** 🟒\n\nβ€’ Position size: {position_size-1}%\nβ€’ Stop-loss: 6% trailing\nβ€’ Risk-reward: 1:3.0\nβ€’ Correlation: Low\nβ€’ **Assessment**: Favorable setup",
259
+ f"**Elevated Risk** πŸ”΄\n\nβ€’ Position size: {position_size}%\nβ€’ Stop-loss: 10% fixed\nβ€’ Risk-reward: 1:2.0\nβ€’ Hedge recommended\nβ€’ **Assessment**: Higher vigilance needed"
260
+ ]
261
 
262
+ return {
263
+ 'emoji': 'πŸ›‘οΈ',
264
+ 'title': 'Risk Assessment',
265
+ 'analysis': np.random.choice(templates),
266
+ 'confidence': np.random.randint(65, 85)
267
+ }
268
 
269
+ def _decision_engine(self, symbol, price, analyses, change, volatility):
270
+ """Decision Engine: Final trading decision"""
271
+ if change > 3 and volatility < 25:
272
  decision = "BUY"
273
+ confidence = np.random.randint(80, 95)
274
+ rationale = "Strong bullish momentum with favorable risk metrics"
275
+ elif change < -2:
276
+ decision = "SELL"
277
  confidence = np.random.randint(75, 90)
278
+ rationale = "Bearish pressure with elevated downside risk"
 
 
279
  else:
280
  decision = "HOLD"
281
+ confidence = np.random.randint(65, 80)
282
+ rationale = "Neutral trend, awaiting clearer market direction"
283
 
284
+ analysis_text = f"""
285
+ **FINAL DECISION: {decision}** 🎯
 
 
286
 
287
+ **Confidence Level:** {confidence}%
288
+ **Current Price:** ${price:.2f}
289
+ **Rationale:** {rationale}
290
 
291
+ **Execution Plan:**
292
+ β€’ Position Size: {max(2, min(5, 6 - volatility/10))}% of portfolio
293
+ β€’ Timeframe: {'1-4 weeks' if decision == 'BUY' else 'Monitor daily'}
294
+ β€’ Risk Management: {'Trailing stop 8%' if decision == 'BUY' else 'Set alert levels'}
295
+ """
296
+
297
+ return {
298
+ 'emoji': '🎯',
299
+ 'title': 'Trading Decision',
300
+ 'analysis': analysis_text,
301
+ 'confidence': confidence,
302
+ 'decision': decision
303
+ }
304
+
305
+ def _get_error_analysis(self, symbol):
306
+ """Return error analysis when data is unavailable"""
307
+ error_msg = f"**Data Unavailable** ❌\n\nUnable to fetch real-time data for {symbol}.\n\nPlease check:\nβ€’ Stock symbol spelling\nβ€’ Market hours (9:30 AM - 4:00 PM ET)\nβ€’ Internet connection"
308
+
309
+ return {
310
+ 'research': {'emoji': 'πŸ“Š', 'title': 'Research', 'analysis': error_msg, 'confidence': 0},
311
+ 'technical': {'emoji': 'πŸ“ˆ', 'title': 'Technical', 'analysis': error_msg, 'confidence': 0},
312
+ 'risk': {'emoji': 'πŸ›‘οΈ', 'title': 'Risk', 'analysis': error_msg, 'confidence': 0},
313
+ 'decision': {'emoji': '🎯', 'title': 'Decision', 'analysis': error_msg, 'confidence': 0, 'decision': 'HOLD'}
314
  }
315
 
316
+ # Initialize Core Components
317
+ market_data = RealTimeMarketData()
318
+ trading_agents = AI_TradingAgents()
319
 
320
+ def create_real_time_dashboard(market_data_dict, selected_symbol=None):
321
+ """
322
+ Create interactive real-time dashboard with live market data
323
+ """
324
+ symbols = list(market_data_dict.keys())
 
 
 
 
 
 
 
325
 
326
+ # Create comprehensive dashboard
327
+ fig = make_subplots(
328
+ rows=2, cols=2,
329
+ subplot_titles=[
330
+ 'πŸ“Š Real-Time Price Movement',
331
+ 'πŸ“ˆ Performance Overview',
332
+ 'πŸ”„ Live Price Changes',
333
+ '🎯 Market Sentiment'
334
+ ],
335
+ specs=[
336
+ [{"type": "scatter"}, {"type": "bar"}],
337
+ [{"type": "scatter"}, {"type": "pie"}]
338
+ ],
339
+ vertical_spacing=0.1,
340
+ horizontal_spacing=0.1
341
  )
342
 
343
+ # 1. Real-time Price Lines
344
+ colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FECA57', '#FF9FF3']
345
+ for i, (symbol, data) in enumerate(market_data_dict.items()):
346
+ if i < 6: # Limit to 6 symbols for clarity
347
+ fig.add_trace(
348
+ go.Scatter(
349
+ x=data['timestamps'],
350
+ y=data['prices'],
351
+ mode='lines+markers',
352
+ name=symbol,
353
+ line=dict(color=colors[i % len(colors)], width=3),
354
+ marker=dict(size=4),
355
+ hovertemplate=f'<b>{symbol}</b><br>Time: %{{x}}<br>Price: $%{{y:.2f}}<extra></extra>'
356
+ ),
357
+ row=1, col=1
358
+ )
359
 
360
+ # 2. Performance Bars
361
+ performance_data = []
362
+ for symbol, data in market_data_dict.items():
363
+ performance_data.append({
364
+ 'symbol': symbol,
365
+ 'change': data['change'],
366
+ 'current_price': data['current_price']
367
+ })
368
+
369
+ performance_df = pd.DataFrame(performance_data)
370
+
371
+ fig.add_trace(
372
+ go.Bar(
373
+ x=performance_df['symbol'],
374
+ y=performance_df['change'],
375
+ marker_color=['#00CC96' if x > 0 else '#EF553B' for x in performance_df['change']],
376
+ text=[f"{x:+.2f}%" for x in performance_df['change']],
377
+ textposition='auto',
378
+ name='Daily Change'
379
+ ),
380
+ row=1, col=2
381
  )
382
 
383
+ # 3. Live Price Changes (Last 5 changes)
384
+ if selected_symbol and selected_symbol in market_data_dict:
385
+ selected_data = market_data_dict[selected_symbol]
386
+ if len(selected_data['prices']) >= 6:
387
+ recent_prices = selected_data['prices'][-6:]
388
+ price_changes = [((recent_prices[i] - recent_prices[i-1]) / recent_prices[i-1] * 100)
389
+ for i in range(1, len(recent_prices))]
390
+
391
+ fig.add_trace(
392
+ go.Scatter(
393
+ x=selected_data['timestamps'][-5:],
394
+ y=price_changes,
395
+ mode='lines+markers+text',
396
+ name=f'{selected_symbol} Changes',
397
+ line=dict(color='#FECA57', width=4),
398
+ marker=dict(size=8),
399
+ text=[f"{x:+.2f}%" for x in price_changes],
400
+ textposition='top center'
401
+ ),
402
+ row=2, col=1
403
+ )
404
+
405
+ # 4. Market Sentiment Pie Chart
406
+ sentiment_data = {
407
+ 'Bullish': len([d for d in market_data_dict.values() if d['change'] > 0]),
408
+ 'Bearish': len([d for d in market_data_dict.values() if d['change'] < 0]),
409
+ 'Neutral': len([d for d in market_data_dict.values() if d['change'] == 0])
410
+ }
411
+
412
+ fig.add_trace(
413
+ go.Pie(
414
+ labels=list(sentiment_data.keys()),
415
+ values=list(sentiment_data.values()),
416
+ hole=0.4,
417
+ marker_colors=['#00CC96', '#EF553B', '#636EFA'],
418
+ name='Market Sentiment'
419
+ ),
420
+ row=2, col=2
421
+ )
422
 
423
+ # Update layout for professional appearance
424
  fig.update_layout(
425
+ height=800,
426
+ title_text="πŸ€– LIVE AI TRADING DASHBOARD - Real-Time Market Data",
427
+ title_font_size=20,
428
+ showlegend=True,
429
  template='plotly_dark',
430
+ font=dict(family="Arial", size=12, color="white"),
431
+ margin=dict(t=100, b=50, l=50, r=50)
432
  )
433
 
434
+ # Update axes labels
435
+ fig.update_xaxes(title_text="Time (Last 30 Minutes)", row=1, col=1)
436
+ fig.update_xaxes(title_text="Stocks", row=1, col=2)
437
+ fig.update_xaxes(title_text="Time", row=2, col=1)
 
 
 
 
 
 
 
 
438
 
439
+ fig.update_yaxes(title_text="Price ($)", row=1, col=1)
440
+ fig.update_yaxes(title_text="Change (%)", row=1, col=2)
441
+ fig.update_yaxes(title_text="Price Change (%)", row=2, col=1)
442
 
443
+ return fig
444
 
445
+ def generate_agent_analysis(symbol, market_data_dict):
446
+ """Generate multi-agent analysis for a specific symbol"""
447
+ if not symbol:
448
+ # Analyze all symbols if none specified
449
+ all_analysis = "# πŸ“Š Multi-Stock Analysis Report\n\n"
450
+
451
+ for sym in market_data_dict.keys():
452
+ analysis = trading_agents.analyze_market(sym, market_data_dict)
453
+ decision = analysis['decision']
454
+
455
+ all_analysis += f"## {sym}\n"
456
+ all_analysis += f"**Price:** ${market_data_dict[sym]['current_price']:.2f} | "
457
+ all_analysis += f"**Change:** {market_data_dict[sym]['change']:+.2f}%\n"
458
+ all_analysis += f"**Decision:** {decision['decision']} ({decision['confidence']}% confidence)\n\n"
459
+
460
+ if sym == list(market_data_dict.keys())[0]: # Show full analysis for first symbol
461
+ all_analysis += "### Detailed Analysis:\n"
462
+ for agent_type, agent_analysis in analysis.items():
463
+ if agent_type != 'decision':
464
+ all_analysis += f"**{agent_analysis['emoji']} {agent_analysis['title']}**\n"
465
+ all_analysis += f"{agent_analysis['analysis']}\n\n"
466
+
467
+ return all_analysis
468
 
469
+ else:
470
+ # Analyze specific symbol
471
+ analysis = trading_agents.analyze_market(symbol.upper(), market_data_dict)
472
+
473
+ analysis_text = f"# 🎯 {symbol.upper()} - AI Trading Analysis\n\n"
474
+ analysis_text += f"**Current Price:** ${market_data_dict.get(symbol.upper(), {}).get('current_price', 'N/A'):.2f}\n"
475
+ analysis_text += f"**24h Change:** {market_data_dict.get(symbol.upper(), {}).get('change', 'N/A'):+.2f}%\n"
476
+ analysis_text += f"**Last Updated:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
477
+
478
+ for agent_type, agent_analysis in analysis.items():
479
+ analysis_text += f"## {agent_analysis['emoji']} {agent_analysis['title']}\n"
480
+ analysis_text += f"{agent_analysis['analysis']}\n\n"
481
+
482
+ return analysis_text
483
+
484
+ def update_interface(symbol_input):
485
+ """Main function to update the entire interface"""
486
+ # Get fresh market data
487
+ current_market_data = market_data.get_live_data()
488
 
489
+ # Create visualizations
490
+ dashboard = create_real_time_dashboard(current_market_data, symbol_input)
491
 
492
+ # Generate analysis
493
+ analysis = generate_agent_analysis(symbol_input, current_market_data)
 
 
 
 
 
 
494
 
495
+ return dashboard, analysis
496
 
497
+ # Create Gradio Interface
498
+ with gr.Blocks(
499
+ theme=gr.themes.Soft(
500
+ primary_hue="blue",
501
+ secondary_hue="slate"
502
+ ),
503
+ title="πŸ€– AI Trading Agents - Real-Time System",
504
+ css="""
505
+ .gradio-container {
506
+ max-width: 1200px !important;
507
+ }
508
+ .analysis-box {
509
+ border-left: 4px solid #4ECDC4;
510
+ padding-left: 15px;
511
+ margin: 10px 0;
512
+ }
513
+ """
514
+ ) as demo:
515
+
516
  gr.Markdown("""
517
  # πŸ€– Multi-Agent AI Trading System
518
+ ## *Real-Time Market Analysis & Trading Decisions*
519
+
520
+ **Professional stock analysis powered by multiple AI agents working in coordination**
521
  """)
522
 
523
  with gr.Row():
524
  with gr.Column(scale=1):
525
+ gr.Markdown("### 🎯 Stock Selection")
526
  symbol_input = gr.Textbox(
527
+ label="Enter Stock Symbol",
528
+ placeholder="e.g., AAPL, TSLA, NVDA... (leave empty for all)",
529
  max_lines=1
530
  )
531
+ analyze_btn = gr.Button(
532
+ "πŸ”„ Analyze Now",
533
+ variant="primary",
534
+ size="lg"
535
+ )
536
+ gr.Markdown("""
537
+ **Tracked Stocks:** AAPL, GOOGL, MSFT, TSLA
538
+
539
+ *Data updates every 30 seconds automatically*
540
+ """)
541
+
542
  with gr.Column(scale=2):
543
+ gr.Markdown("### πŸ“Š Live Market Dashboard")
544
 
545
  with gr.Tabs():
546
+ with gr.TabItem("πŸ“ˆ Live Charts"):
547
+ with gr.Row():
548
+ chart_output = gr.Plot(
549
+ label="Real-Time Market Dashboard",
550
+ show_label=True
551
+ )
552
+
553
+ with gr.TabItem("πŸ€– AI Analysis"):
554
  with gr.Row():
555
+ analysis_output = gr.Markdown(
556
+ label="Multi-Agent Analysis Report",
557
+ show_label=True
558
+ )
559
+
560
+ with gr.Row():
561
+ gr.Markdown("""
562
+ ---
563
+ **πŸ” System Features:**
564
+ - πŸ“Š **Research Agent**: Fundamental analysis & market sentiment
565
+ - πŸ“ˆ **Technical Agent**: Price patterns & trading signals
566
+ - πŸ›‘οΈ **Risk Agent**: Position sizing & risk management
567
+ - 🎯 **Decision Engine**: Final trading recommendations
568
 
569
+ *Last System Update: {time}*
570
+ """.format(time=datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
571
 
572
  # Event handlers
573
  analyze_btn.click(
574
+ fn=update_interface,
575
  inputs=[symbol_input],
576
  outputs=[chart_output, analysis_output]
577
  )
578
 
579
+ # Auto-refresh every 30 seconds
580
  demo.load(
581
+ fn=update_interface,
582
+ inputs=[symbol_input],
583
+ outputs=[chart_output, analysis_output],
584
+ every=30 # Refresh every 30 seconds
585
  )
586
 
587
+ # Launch for Hugging Face Spaces
588
  if __name__ == "__main__":
589
  demo.launch(
590
  server_name="0.0.0.0",
591
  server_port=7860,
592
+ share=True,
593
+ show_error=True
594
  )