mobenta commited on
Commit
aeaf850
·
verified ·
1 Parent(s): 097ad59

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +146 -355
app.py CHANGED
@@ -1,367 +1,158 @@
1
- import torch
2
- import yfinance as yf
3
- import matplotlib.pyplot as plt
4
- import mplfinance as mpf
5
- from PIL import Image, ImageDraw, ImageFont
6
- import gradio as gr
7
- import datetime
8
- import logging
9
- from transformers import AutoProcessor, AutoModelForPreTraining
10
- import tempfile
11
- import os
12
- import spaces
13
- import pandas as pd
14
- import numpy as np
15
- from scipy import stats
16
- import seaborn as sns
17
-
18
- # Configure logging
19
- logging.basicConfig(filename='debug.log', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
20
-
21
- # Load the chart_analysis model and processor
22
- processor = AutoProcessor.from_pretrained("mobenta/chart_analysis")
23
- model = AutoModelForPreTraining.from_pretrained("mobenta/chart_analysis")
24
-
25
- @spaces.GPU
26
- def predict(image, input_text):
27
- device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
28
- model.to(device)
29
-
30
- image = image.convert("RGB")
31
- inputs = processor(text=input_text, images=image, return_tensors="pt")
32
- inputs = {k: v.to(device) for k, v in inputs.items()}
33
-
34
- prompt_length = inputs['input_ids'].shape[1]
35
- generate_ids = model.generate(**inputs, max_new_tokens=512)
36
- output_text = processor.batch_decode(generate_ids[:, prompt_length:], skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
37
-
38
- return output_text
39
-
40
- def fetch_stock_data(ticker='TSLA', start='2010-01-01', end=None, interval='1d'):
41
- if end is None:
42
- end = datetime.date.today().isoformat()
43
- try:
44
- logging.debug(f"Fetching data for {ticker} from {start} to {end} with interval {interval}")
45
- stock = yf.Ticker(ticker)
46
- data = stock.history(start=start, end=end, interval=interval)
47
- if data.empty:
48
- logging.warning(f"No data fetched for {ticker} in the range {start} to {end}")
49
- return pd.DataFrame()
50
- logging.debug(f"Fetched data with {len(data)} rows")
51
- return data
52
- except Exception as e:
53
- logging.error(f"Error fetching data: {e}")
54
- return pd.DataFrame()
55
-
56
- def create_stock_chart(data, ticker, filename='chart.png', timeframe='1d', indicators=None):
57
- try:
58
- logging.debug(f"Creating chart for {ticker} with timeframe {timeframe} and saving to {filename}")
59
- title = f"{ticker.upper()} Price Data (Timeframe: {timeframe})"
60
-
61
- plt.rcParams["axes.titlesize"] = 10
62
- my_style = mpf.make_mpf_style(base_mpf_style='charles')
63
-
64
- # Calculate indicators if selected
65
- addplot = []
66
- if indicators:
67
- if 'RSI' in indicators:
68
- delta = data['Close'].diff(1)
69
- gain = delta.where(delta > 0, 0)
70
- loss = -delta.where(delta < 0, 0)
71
- avg_gain = gain.rolling(window=14).mean()
72
- avg_loss = loss.rolling(window=14).mean()
73
- rs = avg_gain / avg_loss
74
- rsi = 100 - (100 / (1 + rs))
75
- addplot.append(mpf.make_addplot(rsi, panel=2, color='orange', ylabel='RSI'))
76
- if 'SMA21' in indicators:
77
- logging.debug("Calculating SMA 21")
78
- sma_21 = data['Close'].rolling(window=21).mean()
79
- addplot.append(mpf.make_addplot(sma_21, color='purple', linestyle='dashed'))
80
- if 'SMA50' in indicators:
81
- logging.debug("Calculating SMA 50")
82
- sma_50 = data['Close'].rolling(window=50).mean()
83
- addplot.append(mpf.make_addplot(sma_50, color='orange', linestyle='dashed'))
84
- if 'SMA200' in indicators:
85
- logging.debug("Calculating SMA 200")
86
- sma_200 = data['Close'].rolling(window=200).mean()
87
- addplot.append(mpf.make_addplot(sma_200, color='brown', linestyle='dashed'))
88
- if 'VWAP' in indicators:
89
- logging.debug("Calculating VWAP")
90
- vwap = (data['Volume'] * (data['High'] + data['Low'] + data['Close']) / 3).cumsum() / data['Volume'].cumsum()
91
- addplot.append(mpf.make_addplot(vwap, color='blue', linestyle='dashed'))
92
- if 'Bollinger Bands' in indicators:
93
- logging.debug("Calculating Bollinger Bands")
94
- sma = data['Close'].rolling(window=20).mean()
95
- std = data['Close'].rolling(window=20).std()
96
- upper_band = sma + (std * 2)
97
- lower_band = sma - (std * 2)
98
- addplot.append(mpf.make_addplot(upper_band, color='green', linestyle='dashed'))
99
- addplot.append(mpf.make_addplot(lower_band, color='green', linestyle='dashed'))
100
-
101
- fig, axlist = mpf.plot(data, type='candle', style=my_style, volume=True, addplot=addplot, returnfig=True)
102
- fig.suptitle(title, y=0.98)
103
-
104
- # Save chart image
105
- fig.savefig(filename, dpi=300)
106
- plt.close(fig)
107
-
108
- # Open and add financial data to the image
109
- image = Image.open(filename)
110
- draw = ImageDraw.Draw(image)
111
- font = ImageFont.load_default() # Use default font, you can also use custom fonts if available
112
-
113
- # Financial metrics to add
114
- metrics = {
115
- "Ticker": ticker,
116
- "Latest Close": f"${data['Close'].iloc[-1]:,.2f}",
117
- "Volume": f"{data['Volume'].iloc[-1]:,.0f}"
118
- }
119
-
120
- # Add additional metrics if indicators are present
121
- if 'SMA21' in indicators:
122
- metrics["SMA 21"] = f"${data['Close'].rolling(window=21).mean().iloc[-1]:,.2f}"
123
- if 'SMA50' in indicators:
124
- metrics["SMA 50"] = f"${data['Close'].rolling(window=50).mean().iloc[-1]:,.2f}"
125
- if 'SMA200' in indicators:
126
- metrics["SMA 200"] = f"${data['Close'].rolling(window=200).mean().iloc[-1]:,.2f}"
127
-
128
- # Draw metrics on the image
129
- y_text = image.height - 50 # Starting y position for text
130
- for key, value in metrics.items():
131
- text = f"{key}: {value}"
132
- draw.text((10, y_text), text, font=font, fill=(255, 255, 255)) # White color text
133
- y_text += 20
134
-
135
- # Resize image
136
- new_size = (image.width * 3, image.height * 3)
137
- resized_image = image.resize(new_size, Image.LANCZOS)
138
- resized_image.save(filename)
139
-
140
- logging.debug(f"Resized image with timeframe {timeframe} and ticker {ticker} saved to {filename}")
141
- except Exception as e:
142
- logging.error(f"Error creating or resizing chart: {e}")
143
- raise
144
-
145
- def combine_images(image_paths, output_path='combined_chart.png'):
146
- try:
147
- logging.debug(f"Combining images {image_paths} into {output_path}")
148
- images = [Image.open(path) for path in image_paths]
149
-
150
- # Calculate total width and max height for combined image
151
- total_width = sum(img.width for img in images)
152
- max_height = max(img.height for img in images)
153
-
154
- combined_image = Image.new('RGB', (total_width, max_height))
155
- x_offset = 0
156
- for img in images:
157
- combined_image.paste(img, (x_offset, 0))
158
- x_offset += img.width
159
-
160
- combined_image.save(output_path)
161
- logging.debug(f"Combined image saved to {output_path}")
162
- return output_path
163
- except Exception as e:
164
- logging.error(f"Error combining images: {e}")
165
- raise
166
-
167
- def perform_trend_analysis(data):
168
- # Perform trend analysis
169
- close_prices = data['Close']
170
- time_index = np.arange(len(close_prices))
171
- slope, intercept, r_value, p_value, std_err = stats.linregress(time_index, close_prices)
172
-
173
- trend_line = slope * time_index + intercept
174
-
175
- plt.figure(figsize=(12, 6))
176
- plt.plot(close_prices.index, close_prices, label='Close Price')
177
- plt.plot(close_prices.index, trend_line, color='red', label='Trend Line')
178
- plt.title('Trend Analysis')
179
- plt.xlabel('Date')
180
- plt.ylabel('Price')
181
- plt.legend()
182
-
183
- trend_filename = 'trend_analysis.png'
184
- plt.savefig(trend_filename)
185
- plt.close()
186
-
187
- trend_strength = abs(r_value)
188
- trend_direction = "upward" if slope > 0 else "downward"
189
-
190
- analysis_text = f"Trend Analysis:\n"
191
- analysis_text += f"The stock shows a {trend_direction} trend.\n"
192
- analysis_text += f"Trend strength (R-squared): {trend_strength:.2f}\n"
193
- analysis_text += f"Slope: {slope:.4f}\n"
194
-
195
- return analysis_text, trend_filename
196
-
197
- def perform_correlation_analysis(data_dict):
198
- # Perform correlation analysis
199
- combined_data = pd.DataFrame({ticker: data['Close'] for ticker, data in data_dict.items()})
200
- correlation_matrix = combined_data.corr()
201
-
202
- plt.figure(figsize=(10, 8))
203
- sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', vmin=-1, vmax=1, center=0)
204
- plt.title('Correlation Analysis')
205
-
206
- corr_filename = 'correlation_analysis.png'
207
- plt.savefig(corr_filename)
208
- plt.close()
209
-
210
- analysis_text = f"Correlation Analysis:\n"
211
- for i in range(len(correlation_matrix.columns)):
212
- for j in range(i+1, len(correlation_matrix.columns)):
213
- ticker1 = correlation_matrix.columns[i]
214
- ticker2 = correlation_matrix.columns[j]
215
- corr = correlation_matrix.iloc[i, j]
216
- analysis_text += f"Correlation between {ticker1} and {ticker2}: {corr:.2f}\n"
217
-
218
- return analysis_text, corr_filename
219
-
220
- def comprehensive_investment_strategy():
221
- strategy = """
222
- Comprehensive Investment Strategy Analysis:
223
-
224
- 1. Fundamental Analysis:
225
- - Assess financial health using key metrics like P/E ratio, EPS growth, debt-to-equity ratio, and free cash flow.
226
- - Analyze quarterly and annual earnings reports, focusing on revenue growth, profit margins, and management guidance.
227
- - Consider industry trends such as technological disruption, regulatory changes, and shifting consumer preferences.
228
-
229
- 2. Technical Analysis:
230
- - Utilize chart patterns like head and shoulders, double tops/bottoms, and cup and handle.
231
- - Employ technical indicators including Moving Averages, RSI, MACD, and Bollinger Bands.
232
- - Incorporate volume analysis to confirm trend strength and potential reversals.
233
-
234
- 3. Macroeconomic Analysis:
235
- - Monitor key economic indicators: GDP growth, inflation rates, unemployment figures, and consumer sentiment indices.
236
- - Track central bank policies, particularly interest rate decisions and quantitative easing programs.
237
- - Evaluate geopolitical events' impact through news analysis and global market correlations.
238
-
239
- 4. Risk Management:
240
- - Implement diversification across sectors, geographies, and asset classes.
241
- - Use position sizing based on account size and individual stock volatility.
242
- - Set stop-loss orders at key technical levels, typically 5-15% below purchase price depending on stock volatility.
243
-
244
- 5. Sentiment Analysis:
245
- - Gauge market sentiment through tools like the VIX, put/call ratio, and investor surveys.
246
- - Monitor social media trends and financial news sentiment using natural language processing tools.
247
- - Apply contrarian strategies when extreme bullish or bearish sentiment is detected, supported by fundamental and technical analysis.
248
-
249
- 6. Options Trading:
250
- - Employ covered calls for income generation on long-term holds.
251
- - Use protective puts to hedge downside risk on larger positions.
252
- - Implement iron condors or credit spreads to take advantage of high implied volatility environments.
253
-
254
- 7. Long-Term Investing:
255
- - Identify companies with strong competitive advantages, consistent revenue growth, and solid balance sheets.
256
- - Focus on businesses with high return on invested capital (ROIC) and effective management teams.
257
- - Include dividend aristocrats and growth stocks at a reasonable price (GARP) for a balanced approach.
258
-
259
- 8. Market Psychology:
260
- - Apply principles of behavioral finance, recognizing common biases like herd mentality and recency bias.
261
- - Maintain a trading journal to track decisions and emotions, promoting self-awareness and improvement.
262
- - Develop and stick to a rules-based system to minimize emotional decision-making.
263
-
264
- This comprehensive strategy aims to balance various analytical approaches, providing a robust framework for investment decisions across different market conditions.
265
- """
266
- return strategy
267
-
268
- def gradio_interface(ticker1, ticker2, ticker3, ticker4, start_date, end_date, query, analysis_type, interval, indicators):
269
- try:
270
- logging.debug(f"Starting gradio_interface with tickers: {ticker1}, {ticker2}, {ticker3}, {ticker4}, start_date: {start_date}, end_date: {end_date}, query: {query}, analysis_type: {analysis_type}, interval: {interval}")
271
-
272
- if analysis_type == 'Comprehensive Investment Strategy':
273
- return comprehensive_investment_strategy(), None
274
-
275
- tickers = [ticker1, ticker2, ticker3, ticker4]
276
- chart_paths = []
277
- data_dict = {}
278
-
279
- for i, ticker in enumerate(tickers):
280
- if ticker:
281
- data = fetch_stock_data(ticker, start=start_date, end=end_date, interval=interval)
282
- if data.empty:
283
- return f"No data available for {ticker} in the specified date range.", None
284
- data_dict[ticker] = data
285
- with tempfile.NamedTemporaryFile(delete=False, suffix='.png') as temp_chart:
286
- chart_path = temp_chart.name
287
- create_stock_chart(data, ticker, chart_path, timeframe=interval, indicators=indicators)
288
- chart_paths.append(chart_path)
289
-
290
- if analysis_type == 'Comparative Analysis' and len(chart_paths) > 1:
291
- with tempfile.NamedTemporaryFile(delete=False, suffix='.png') as temp_combined_chart:
292
- combined_chart_path = temp_combined_chart.name
293
- combine_images(chart_paths, combined_chart_path)
294
- insights = predict(Image.open(combined_chart_path), query)
295
- return insights, combined_chart_path
296
- elif analysis_type == 'Trend Analysis':
297
- if len(data_dict) > 0:
298
- first_ticker = list(data_dict.keys())[0]
299
- analysis_text, trend_chart = perform_trend_analysis(data_dict[first_ticker])
300
- return analysis_text, trend_chart
301
- else:
302
- return "No data available for trend analysis.", None
303
- elif analysis_type == 'Correlation Analysis':
304
- if len(data_dict) > 1:
305
- analysis_text, corr_chart = perform_correlation_analysis(data_dict)
306
- return analysis_text, corr_chart
307
- else:
308
- return "At least two tickers are required for correlation analysis.", None
309
- else:
310
- # Single ticker analysis
311
- if chart_paths:
312
- insights = predict(Image.open(chart_paths[0]), query)
313
- return insights, chart_paths[0]
314
- else:
315
- return "No tickers provided.", None
316
- except Exception as e:
317
- logging.error(f"Error in Gradio interface: {e}")
318
- return f"Error processing image or query: {e}", None
319
-
320
  def gradio_app():
321
  with gr.Blocks() as demo:
322
  gr.Markdown("""
323
  ## 📈 Advanced Stock Analysis Dashboard
324
-
325
- This application provides a comprehensive stock analysis tool that allows users to input up to four stock tickers, specify date ranges, and select various financial indicators. The core functionalities include:
326
-
327
- 1. **Data Fetching and Chart Creation**: Historical stock data is fetched from Yahoo Finance, and candlestick charts are generated with optional financial indicators like RSI, SMA, VWAP, and Bollinger Bands.
328
-
329
- 2. **Text Analysis and Insights Generation**: The application uses a pre-trained model based on the Paligema architecture to analyze the input chart and text query, generating insightful analysis based on the provided financial data and context.
330
-
331
- 3. **Trend Analysis**: Performs trend analysis on a single stock, showing the trend line and providing information about the trend strength and direction.
332
-
333
- 4. **Correlation Analysis**: Analyzes the correlation between multiple stocks, providing a correlation matrix and heatmap.
334
-
335
- 5. **Comprehensive Investment Strategy**: Provides a detailed investment strategy based on fundamental analysis, technical analysis, macroeconomic factors, risk management, and more.
336
-
337
- 6. **User Interface**: Users can interactively select stocks, date ranges, intervals, and indicators. The app supports single ticker analysis, comparative analysis, trend analysis, correlation analysis, and comprehensive investment strategy.
338
-
339
- 7. **Logging and Debugging**: Detailed logging helps in debugging and tracking the application's processes.
340
-
341
- 8. **Enhanced Image Processing**: The app adds financial metrics and annotations to the generated charts, ensuring clear presentation of data.
342
-
343
- This tool leverages various analysis techniques to provide detailed insights into stock market trends, offering an interactive and educational experience for users.
344
  """)
345
 
346
- with gr.Row():
347
- ticker1 = gr.Textbox(label="Primary Ticker", value="AAPL")
348
- ticker2 = gr.Textbox(label="Secondary Ticker", value="MSFT")
349
- ticker3 = gr.Textbox(label="Third Ticker", value="GOOGL")
350
- ticker4 = gr.Textbox(label="Fourth Ticker", value="AMZN")
351
-
352
- with gr.Row():
353
- start_date = gr.Textbox(label="Start Date", value="2022-01-01")
354
- end_date = gr.Textbox(label="End Date", value=datetime.date.today().isoformat())
355
- interval = gr.Dropdown(label="Interval", choices=['1m', '2m', '5m', '15m', '30m', '60m', '90m', '1h', '1d', '5d', '1wk', '1mo', '3mo'], value='1d')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
 
357
  with gr.Row():
358
- indicators = gr.CheckboxGroup(label="Indicators", choices=['RSI', 'SMA21', 'SMA50', 'SMA200', 'VWAP', 'Bollinger Bands'], value=['SMA21', 'SMA50'])
359
- analysis_type = gr.Radio(label="Analysis Type", choices=['Single Ticker', 'Comparative Analysis', 'Trend Analysis', 'Correlation Analysis', 'Comprehensive Investment Strategy'], value='Single Ticker')
 
 
360
 
361
- query = gr.Textbox(label="Analysis Query", value="Analyze the price trends.")
362
- analyze_button = gr.Button("Analyze")
363
- output_image = gr.Image(label="Analysis Chart")
364
- output_text = gr.Textbox(label="Generated Insights", lines=10)
365
 
366
  analyze_button.click(
367
  fn=gradio_interface,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  def gradio_app():
2
  with gr.Blocks() as demo:
3
  gr.Markdown("""
4
  ## 📈 Advanced Stock Analysis Dashboard
5
+
6
+ [... rest of the markdown ...]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  """)
8
 
9
+ ticker_options = [
10
+ "ES=F: E-Mini S&P 500 Sep 24",
11
+ "YM=F: Mini Dow Jones Indus.-$5 Sep 24",
12
+ "NQ=F: Nasdaq 100 Sep 24",
13
+ "RTY=F: E-mini Russell 2000 Index Future",
14
+ "ZB=F: U.S. Treasury Bond Futures, Sep-",
15
+ "ZN=F: 10-Year T-Note Futures, Sep-2024",
16
+ "ZF=F: Five-Year US Treasury Note Future",
17
+ "ZT=F: 2-Year T-Note Futures, Sep-2024",
18
+ "GC=F: Gold",
19
+ "MGC=F: Micro Gold Futures, Dec-2024",
20
+ "SI=F: Silver",
21
+ "SIL=F: Micro Silver Futures, Sep-2024",
22
+ "PL=F: Platinum Oct 24",
23
+ "HG=F: Copper Sep 24",
24
+ "PA=F: Palladium Sep 24",
25
+ "CL=F: Crude Oil",
26
+ "HO=F: Heating Oil Aug 24",
27
+ "NG=F: Natural Gas Aug 24",
28
+ "RB=F: RBOB Gasoline Aug 24",
29
+ "BZ=F: Brent Crude Oil Last Day Financ",
30
+ "BO=F: Mont Belvieu LDH Propane (OPIS)",
31
+ "ZC=F: Corn Futures, Dec-2024",
32
+ "ZO=F: Oat Futures, Dec-2024",
33
+ "KE=F: KC HRW Wheat Futures, Sep-2024",
34
+ "ZR=F: Rough Rice Futures, Sep-2024",
35
+ "ZM=F: S&P Composite 1500 ESG Tilted I",
36
+ "ZL=F: Soybean Oil Futures, Dec-2024",
37
+ "ZS=F: Soybean Futures, Nov-2024",
38
+ "GF=F: WisdomTree International High D",
39
+ "HE=F: Lean Hogs Futures, Aug-2024",
40
+ "LE=F: Live Cattle Futures, Aug-2024",
41
+ "CC=F: Cocoa Sep 24",
42
+ "KC=F: Coffee Sep 24",
43
+ "CT=F: Cotton Oct 24",
44
+ "LBS=F: Random Length Lumber Futures",
45
+ "OJ=F: Orange Juice Sep 24",
46
+ "^IRX: 13 WEEK TREASURY BILL",
47
+ "^FVX: Treasury Yield 5 Years",
48
+ "^TNX: CBOE Interest Rate 10 Year T No",
49
+ "^TYX: Treasury Yield 30 Years",
50
+ "EURUSD=X: EUR/USD",
51
+ "JPY=X: USD/JPY",
52
+ "GBPUSD=X: GBP/USD",
53
+ "AUDUSD=X: AUD/USD",
54
+ "NZDUSD=X: NZD/USD",
55
+ "EURJPY=X: EUR/JPY",
56
+ "GBPJPY=X: GBP/JPY",
57
+ "EURGBP=X: EUR/GBP",
58
+ "EURCAD=X: EUR/CAD",
59
+ "EURSEK=X: EUR/SEK",
60
+ "EURCHF=X: EUR/CHF",
61
+ "EURHUF=X: EUR/HUF",
62
+ "EURJPY=X: EUR/JPY",
63
+ "CNY=X: USD/CNY",
64
+ "HKD=X: USD/HKD",
65
+ "SGD=X: USD/SGD",
66
+ "INR=X: USD/INR",
67
+ "MXN=X: USD/MXN",
68
+ "PHP=X: USD/PHP",
69
+ "IDR=X: USD/IDR",
70
+ "THB=X: USD/THB",
71
+ "MYR=X: USD/MYR",
72
+ "ZAR=X: USD/ZAR",
73
+ "RUB=X: USD/RUB",
74
+ "BTC-USD: Bitcoin USD",
75
+ "ETH-USD: Ethereum USD",
76
+ "USDT-USD: Tether USDT USD",
77
+ "BNB-USD: BNB USD",
78
+ "SOL-USD: Solana USD",
79
+ "USDC-USD: USD Coin USD",
80
+ "XRP-USD: XRP",
81
+ "STETH-USD: Lido Staked ETH USD",
82
+ "DOGE-USD: Dogecoin USD",
83
+ "TON11419-USD: Toncoin USD",
84
+ "ADA-USD: Cardano USD",
85
+ "WSTETH-USD: Lido wstETH USD",
86
+ "WTRX-USD: Wrapped TRON USD",
87
+ "TRX-USD: TRON USD",
88
+ "AVAX-USD: Avalanche USD",
89
+ "WETH-USD: Wrapped Bitcoin USD",
90
+ "SHIB-USD: Shiba Inu USD",
91
+ "DOT-USD: Polkadot USD",
92
+ "LINK-USD: Chainlink USD",
93
+ "BCH-USD: Bitcoin Cash USD",
94
+ "EDLC-USD: Edelman USD",
95
+ "NEAR-USD: NEAR Protocol USD",
96
+ "EETH-USD: staked.fi ETH USD",
97
+ "LEO-USD: UNUS SED LEO USD",
98
+ "TSLA: Tesla, Inc.",
99
+ "NVDA: NVIDIA Corporation",
100
+ "F: Ford Motor Company",
101
+ "DXCM: DexCom, Inc.",
102
+ "SWN: Southwestern Energy Company",
103
+ "AAL: American Airlines Group Inc.",
104
+ "AMD: Advanced Micro Devices, Inc.",
105
+ "PLUG: Plug Power Inc.",
106
+ "BAC: Bank of America Corporation",
107
+ "MARA: Marathon Digital Holdings, Inc.",
108
+ "GOOGL: Alphabet Inc.",
109
+ "AAPL: Apple Inc.",
110
+ "MMM: 3M Company",
111
+ "NKE: NIKE, Inc.",
112
+ "PFE: Pfizer Inc.",
113
+ "SMYMY: Sirius XM Holdings Inc.",
114
+ "INTC: Intel Corporation",
115
+ "SOFI: SoFi Technologies, Inc.",
116
+ "BTGR: BTS Group Holdings Public Company Limited",
117
+ "LCID: Lucid Group, Inc.",
118
+ "PLTR: Palantir Technologies Inc.",
119
+ "NWL: Newell Brands Inc.",
120
+ "VALE: Vale S.A.",
121
+ "CLSK: CleanSpark, Inc.",
122
+ "BTE: Baytex Energy Corp.",
123
+ "ASTS: AST SpaceMobile, Inc.",
124
+ "ET: Energy Transfer LP",
125
+ "AMZN: Amazon.com, Inc.",
126
+ "HBI: Hanesbrands Inc.",
127
+ "CMG: Chipotle Mexican Grill, Inc.",
128
+ "GOOG: Alphabet Inc.",
129
+ "AGNC: AGNC Investment Corp.",
130
+ "RIVN: Rivian Automotive, Inc.",
131
+ "GOLD: Barrick Gold Corporation",
132
+ "AVTR: Avantor, Inc.",
133
+ "CMCSA: Comcast Corporation",
134
+ "RIG: Transocean Ltd.",
135
+ "MUV2: Micron Technology, Inc.",
136
+ "WBD: Warner Bros. Discovery, Inc.",
137
+ "AVGO: Broadcom Inc.",
138
+ "CCL: Carnival Corporation & plc",
139
+ "MSFT: Microsoft Corporation",
140
+ "WMT: Walmart Inc.",
141
+ "HBAN: Huntington Bancshares Incorporated",
142
+ "GM: General Motors Company",
143
+ "BN: Brookfield Corporation",
144
+ "CSCO: Cisco Systems, Inc.",
145
+ "ERIC: Telefonaktiebolaget LM Ericsson (publ)",
146
+ "INFY: Infosys Limited"
147
+ ]
148
 
149
  with gr.Row():
150
+ ticker1 = gr.Dropdown(label="Primary Ticker", choices=ticker_options, value="AAPL: Apple Inc.")
151
+ ticker2 = gr.Dropdown(label="Secondary Ticker", choices=ticker_options, value="MSFT: Microsoft Corporation")
152
+ ticker3 = gr.Dropdown(label="Third Ticker", choices=ticker_options, value="GOOGL: Alphabet Inc.")
153
+ ticker4 = gr.Dropdown(label="Fourth Ticker", choices=ticker_options, value="AMZN: Amazon.com, Inc.")
154
 
155
+ # ... rest of the code ...
 
 
 
156
 
157
  analyze_button.click(
158
  fn=gradio_interface,