Spaces:
Runtime error
Runtime error
import torch | |
import yfinance as yf | |
import matplotlib.pyplot as plt | |
import mplfinance as mpf | |
from PIL import Image, ImageDraw, ImageFont | |
import gradio as gr | |
import datetime | |
import logging | |
from transformers import AutoProcessor, AutoModelForPreTraining | |
import tempfile | |
import os | |
import spaces | |
import pandas as pd | |
import numpy as np | |
from scipy import stats | |
import seaborn as sns | |
import base64 | |
from io import BytesIO | |
# Configure logging | |
logging.basicConfig(filename='debug.log', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') | |
# Load the chart_analysis model and processor | |
processor = AutoProcessor.from_pretrained("mobenta/chart_analysis") | |
model = AutoModelForPreTraining.from_pretrained("mobenta/chart_analysis") | |
def predict(image, input_text): | |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
model.to(device) | |
image = image.convert("RGB") | |
inputs = processor(text=input_text, images=image, return_tensors="pt") | |
inputs = {k: v.to(device) for k, v in inputs.items()} | |
prompt_length = inputs['input_ids'].shape[1] | |
generate_ids = model.generate(**inputs, max_new_tokens=512) | |
output_text = processor.batch_decode(generate_ids[:, prompt_length:], skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] | |
return output_text | |
def fetch_stock_data(ticker='TSLA', start='2010-01-01', end=None, interval='1d'): | |
if end is None: | |
end = datetime.date.today().isoformat() | |
try: | |
logging.debug(f"Fetching data for {ticker} from {start} to {end} with interval {interval}") | |
stock = yf.Ticker(ticker) | |
data = stock.history(start=start, end=end, interval=interval) | |
if data.empty: | |
logging.warning(f"No data fetched for {ticker} in the range {start} to {end}") | |
return pd.DataFrame() | |
logging.debug(f"Fetched data with {len(data)} rows") | |
return data | |
except Exception as e: | |
logging.error(f"Error fetching data: {e}") | |
return pd.DataFrame() | |
def create_stock_chart(data, ticker, filename='chart.png', timeframe='1d', indicators=None): | |
try: | |
logging.debug(f"Creating chart for {ticker} with timeframe {timeframe} and saving to {filename}") | |
title = f"{ticker.upper()} Price Data (Timeframe: {timeframe})" | |
plt.rcParams["axes.titlesize"] = 10 | |
my_style = mpf.make_mpf_style(base_mpf_style='charles') | |
# Calculate indicators if selected | |
addplot = [] | |
if indicators: | |
if 'RSI' in indicators: | |
delta = data['Close'].diff(1) | |
gain = delta.where(delta > 0, 0) | |
loss = -delta.where(delta < 0, 0) | |
avg_gain = gain.rolling(window=14).mean() | |
avg_loss = loss.rolling(window=14).mean() | |
rs = avg_gain / avg_loss | |
rsi = 100 - (100 / (1 + rs)) | |
addplot.append(mpf.make_addplot(rsi, panel=2, color='orange', ylabel='RSI')) | |
if 'SMA21' in indicators: | |
logging.debug("Calculating SMA 21") | |
sma_21 = data['Close'].rolling(window=21).mean() | |
addplot.append(mpf.make_addplot(sma_21, color='purple', linestyle='dashed')) | |
if 'SMA50' in indicators: | |
logging.debug("Calculating SMA 50") | |
sma_50 = data['Close'].rolling(window=50).mean() | |
addplot.append(mpf.make_addplot(sma_50, color='orange', linestyle='dashed')) | |
if 'SMA200' in indicators: | |
logging.debug("Calculating SMA 200") | |
sma_200 = data['Close'].rolling(window=200).mean() | |
addplot.append(mpf.make_addplot(sma_200, color='brown', linestyle='dashed')) | |
if 'VWAP' in indicators: | |
logging.debug("Calculating VWAP") | |
vwap = (data['Volume'] * (data['High'] + data['Low'] + data['Close']) / 3).cumsum() / data['Volume'].cumsum() | |
addplot.append(mpf.make_addplot(vwap, color='blue', linestyle='dashed')) | |
if 'Bollinger Bands' in indicators: | |
logging.debug("Calculating Bollinger Bands") | |
sma = data['Close'].rolling(window=20).mean() | |
std = data['Close'].rolling(window=20).std() | |
upper_band = sma + (std * 2) | |
lower_band = sma - (std * 2) | |
addplot.append(mpf.make_addplot(upper_band, color='green', linestyle='dashed')) | |
addplot.append(mpf.make_addplot(lower_band, color='green', linestyle='dashed')) | |
fig, axlist = mpf.plot(data, type='candle', style=my_style, volume=True, addplot=addplot, returnfig=True) | |
fig.suptitle(title, y=0.98) | |
# Save chart image | |
fig.savefig(filename, dpi=300) | |
plt.close(fig) | |
# Open and add financial data to the image | |
image = Image.open(filename) | |
draw = ImageDraw.Draw(image) | |
font = ImageFont.load_default() # Use default font, you can also use custom fonts if available | |
# Financial metrics to add | |
metrics = { | |
"Ticker": ticker, | |
"Latest Close": f"${data['Close'].iloc[-1]:,.2f}", | |
"Volume": f"{data['Volume'].iloc[-1]:,.0f}" | |
} | |
# Add additional metrics if indicators are present | |
if 'SMA21' in indicators: | |
metrics["SMA 21"] = f"${data['Close'].rolling(window=21).mean().iloc[-1]:,.2f}" | |
if 'SMA50' in indicators: | |
metrics["SMA 50"] = f"${data['Close'].rolling(window=50).mean().iloc[-1]:,.2f}" | |
if 'SMA200' in indicators: | |
metrics["SMA 200"] = f"${data['Close'].rolling(window=200).mean().iloc[-1]:,.2f}" | |
# Draw metrics on the image | |
y_text = image.height - 50 # Starting y position for text | |
for key, value in metrics.items(): | |
text = f"{key}: {value}" | |
draw.text((10, y_text), text, font=font, fill=(255, 255, 255)) # White color text | |
y_text += 20 | |
# Resize image | |
new_size = (image.width * 3, image.height * 3) | |
resized_image = image.resize(new_size, Image.LANCZOS) | |
resized_image.save(filename) | |
logging.debug(f"Resized image with timeframe {timeframe} and ticker {ticker} saved to {filename}") | |
except Exception as e: | |
logging.error(f"Error creating or resizing chart: {e}") | |
raise | |
def combine_images(image_paths, output_path='combined_chart.png'): | |
try: | |
logging.debug(f"Combining images {image_paths} into {output_path}") | |
images = [Image.open(path) for path in image_paths] | |
# Calculate total width and max height for combined image | |
total_width = sum(img.width for img in images) | |
max_height = max(img.height for img in images) | |
combined_image = Image.new('RGB', (total_width, max_height)) | |
x_offset = 0 | |
for img in images: | |
combined_image.paste(img, (x_offset, 0)) | |
x_offset += img.width | |
combined_image.save(output_path) | |
logging.debug(f"Combined image saved to {output_path}") | |
return output_path | |
except Exception as e: | |
logging.error(f"Error combining images: {e}") | |
raise | |
def perform_trend_analysis(data): | |
# Perform trend analysis | |
close_prices = data['Close'] | |
time_index = np.arange(len(close_prices)) | |
slope, intercept, r_value, p_value, std_err = stats.linregress(time_index, close_prices) | |
trend_line = slope * time_index + intercept | |
plt.figure(figsize=(12, 6)) | |
plt.plot(close_prices.index, close_prices, label='Close Price') | |
plt.plot(close_prices.index, trend_line, color='red', label='Trend Line') | |
plt.title('Trend Analysis') | |
plt.xlabel('Date') | |
plt.ylabel('Price') | |
plt.legend() | |
trend_filename = 'trend_analysis.png' | |
plt.savefig(trend_filename) | |
plt.close() | |
trend_strength = abs(r_value) | |
trend_direction = "upward" if slope > 0 else "downward" | |
analysis_text = f"Trend Analysis:\n" | |
analysis_text += f"The stock shows a {trend_direction} trend.\n" | |
analysis_text += f"Trend strength (R-squared): {trend_strength:.2f}\n" | |
analysis_text += f"Slope: {slope:.4f}\n" | |
return analysis_text, trend_filename | |
def perform_correlation_analysis(data_dict): | |
# Perform correlation analysis | |
combined_data = pd.DataFrame({ticker: data['Close'] for ticker, data in data_dict.items()}) | |
correlation_matrix = combined_data.corr() | |
plt.figure(figsize=(10, 8)) | |
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', vmin=-1, vmax=1, center=0) | |
plt.title('Correlation Analysis') | |
corr_filename = 'correlation_analysis.png' | |
plt.savefig(corr_filename) | |
plt.close() | |
analysis_text = f"Correlation Analysis:\n" | |
for i in range(len(correlation_matrix.columns)): | |
for j in range(i+1, len(correlation_matrix.columns)): | |
ticker1 = correlation_matrix.columns[i] | |
ticker2 = correlation_matrix.columns[j] | |
corr = correlation_matrix.iloc[i, j] | |
analysis_text += f"Correlation between {ticker1} and {ticker2}: {corr:.2f}\n" | |
return analysis_text, corr_filename | |
def comprehensive_investment_strategy(): | |
strategy = """ | |
Comprehensive Investment Strategy Analysis: | |
1. Fundamental Analysis: | |
- Assess financial health using key metrics like P/E ratio, EPS growth, debt-to-equity ratio, and free cash flow. | |
- Analyze quarterly and annual earnings reports, focusing on revenue growth, profit margins, and management guidance. | |
- Consider industry trends such as technological disruption, regulatory changes, and shifting consumer preferences. | |
2. Technical Analysis: | |
- Utilize chart patterns like head and shoulders, double tops/bottoms, and cup and handle. | |
- Employ technical indicators including Moving Averages, RSI, MACD, and Bollinger Bands. | |
- Incorporate volume analysis to confirm trend strength and potential reversals. | |
3. Macroeconomic Analysis: | |
- Monitor key economic indicators: GDP growth, inflation rates, unemployment figures, and consumer sentiment indices. | |
- Track central bank policies, particularly interest rate decisions and quantitative easing programs. | |
- Evaluate geopolitical events' impact through news analysis and global market correlations. | |
4. Risk Management: | |
- Implement diversification across sectors, geographies, and asset classes. | |
- Use position sizing based on account size and individual stock volatility. | |
- Set stop-loss orders at key technical levels, typically 5-15% below purchase price depending on stock volatility. | |
5. Sentiment Analysis: | |
- Gauge market sentiment through tools like the VIX, put/call ratio, and investor surveys. | |
- Monitor social media trends and financial news sentiment using natural language processing tools. | |
- Apply contrarian strategies when extreme bullish or bearish sentiment is detected, supported by fundamental and technical analysis. | |
6. Options Trading: | |
- Employ covered calls for income generation on long-term holds. | |
- Use protective puts to hedge downside risk on larger positions. | |
- Implement iron condors or credit spreads to take advantage of high implied volatility environments. | |
7. Long-Term Investing: | |
- Identify companies with strong competitive advantages, consistent revenue growth, and solid balance sheets. | |
- Focus on businesses with high return on invested capital (ROIC) and effective management teams. | |
- Include dividend aristocrats and growth stocks at a reasonable price (GARP) for a balanced approach. | |
8. Market Psychology: | |
- Apply principles of behavioral finance, recognizing common biases like herd mentality and recency bias. | |
- Maintain a trading journal to track decisions and emotions, promoting self-awareness and improvement. | |
- Develop and stick to a rules-based system to minimize emotional decision-making. | |
This comprehensive strategy aims to balance various analytical approaches, providing a robust framework for investment decisions across different market conditions. | |
""" | |
return strategy | |
def analyze_uploaded_image(image, query): | |
try: | |
logging.debug(f"Analyzing uploaded image with query: {query}") | |
insights = predict(image, query) | |
return insights, image | |
except Exception as e: | |
logging.error(f"Error analyzing uploaded image: {e}") | |
return f"Error analyzing uploaded image: {e}", None | |
def gradio_interface(ticker1, ticker2, ticker3, ticker4, start_date, end_date, query, analysis_type, interval, indicators, uploaded_image): | |
try: | |
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}") | |
if analysis_type == 'Comprehensive Investment Strategy': | |
return comprehensive_investment_strategy(), None | |
if uploaded_image is not None: | |
return analyze_uploaded_image(uploaded_image, query) | |
tickers = [ticker.split(':')[0].strip() for ticker in [ticker1, ticker2, ticker3, ticker4] if ticker] | |
chart_paths = [] | |
data_dict = {} | |
for i, ticker in enumerate(tickers): | |
if ticker: | |
data = fetch_stock_data(ticker, start=start_date, end=end_date, interval=interval) | |
if data.empty: | |
return f"No data available for {ticker} in the specified date range.", None | |
data_dict[ticker] = data | |
with tempfile.NamedTemporaryFile(delete=False, suffix='.png') as temp_chart: | |
chart_path = temp_chart.name | |
create_stock_chart(data, ticker, chart_path, timeframe=interval, indicators=indicators) | |
chart_paths.append(chart_path) | |
if analysis_type == 'Comparative Analysis' and len(chart_paths) > 1: | |
with tempfile.NamedTemporaryFile(delete=False, suffix='.png') as temp_combined_chart: | |
combined_chart_path = temp_combined_chart.name | |
combine_images(chart_paths, combined_chart_path) | |
insights = predict(Image.open(combined_chart_path), query) | |
return insights, combined_chart_path | |
elif analysis_type == 'Trend Analysis': | |
if len(data_dict) > 0: | |
first_ticker = list(data_dict.keys())[0] | |
analysis_text, trend_chart = perform_trend_analysis(data_dict[first_ticker]) | |
return analysis_text, trend_chart | |
else: | |
return "No data available for trend analysis.", None | |
elif analysis_type == 'Correlation Analysis': | |
if len(data_dict) > 1: | |
analysis_text, corr_chart = perform_correlation_analysis(data_dict) | |
return analysis_text, corr_chart | |
else: | |
return "At least two tickers are required for correlation analysis.", None | |
else: | |
# Single ticker analysis | |
if chart_paths: | |
insights = predict(Image.open(chart_paths[0]), query) | |
return insights, chart_paths[0] | |
else: | |
return "No tickers provided.", None | |
except Exception as e: | |
logging.error(f"Error in Gradio interface: {e}") | |
return f"Error processing image or query: {e}", None | |
def gradio_app(): | |
with gr.Blocks() as demo: | |
gr.Markdown(""" | |
## 📈 Advanced Stock Analysis Dashboard | |
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: | |
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. | |
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. | |
3. **Trend Analysis**: Performs trend analysis on a single stock, showing the trend line and providing information about the trend strength and direction. | |
4. **Correlation Analysis**: Analyzes the correlation between multiple stocks, providing a correlation matrix and heatmap. | |
5. **Comprehensive Investment Strategy**: Provides a detailed investment strategy based on fundamental analysis, technical analysis, macroeconomic factors, risk management, and more. | |
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. | |
7. **Logging and Debugging**: Detailed logging helps in debugging and tracking the application's processes. | |
8. **Enhanced Image Processing**: The app adds financial metrics and annotations to the generated charts, ensuring clear presentation of data. | |
9. **Custom Chart Analysis**: Users can upload their own chart images for analysis. | |
This tool leverages various analysis techniques to provide detailed insights into stock market trends, offering an interactive and educational experience for users. | |
""") | |
ticker_options = [ | |
"ES=F: E-Mini S&P 500 Sep 24", | |
"YM=F: Mini Dow Jones Indus.-$5 Sep 24", | |
"NQ=F: Nasdaq 100 Sep 24", | |
"RTY=F: E-mini Russell 2000 Index Future", | |
"ZB=F: U.S. Treasury Bond Futures, Sep-", | |
"ZN=F: 10-Year T-Note Futures, Sep-2024", | |
"ZF=F: Five-Year US Treasury Note Future", | |
"ZT=F: 2-Year T-Note Futures, Sep-2024", | |
"GC=F: Gold", | |
"MGC=F: Micro Gold Futures, Dec-2024", | |
"SI=F: Silver", | |
"SIL=F: Micro Silver Futures, Sep-2024", | |
"PL=F: Platinum Oct 24", | |
"HG=F: Copper Sep 24", | |
"PA=F: Palladium Sep 24", | |
"CL=F: Crude Oil", | |
"HO=F: Heating Oil Aug 24", | |
"NG=F: Natural Gas Aug 24", | |
"RB=F: RBOB Gasoline Aug 24", | |
"BZ=F: Brent Crude Oil Last Day Financ", | |
"BO=F: Mont Belvieu LDH Propane (OPIS)", | |
"ZC=F: Corn Futures, Dec-2024", | |
"ZO=F: Oat Futures, Dec-2024", | |
"KE=F: KC HRW Wheat Futures, Sep-2024", | |
"ZR=F: Rough Rice Futures, Sep-2024", | |
"ZM=F: S&P Composite 1500 ESG Tilted I", | |
"ZL=F: Soybean Oil Futures, Dec-2024", | |
"ZS=F: Soybean Futures, Nov-2024", | |
"GF=F: WisdomTree International High D", | |
"HE=F: Lean Hogs Futures, Aug-2024", | |
"LE=F: Live Cattle Futures, Aug-2024", | |
"CC=F: Cocoa Sep 24", | |
"KC=F: Coffee Sep 24", | |
"CT=F: Cotton Oct 24", | |
"LBS=F: Random Length Lumber Futures", | |
"OJ=F: Orange Juice Sep 24", | |
"^IRX: 13 WEEK TREASURY BILL", | |
"^FVX: Treasury Yield 5 Years", | |
"^TNX: CBOE Interest Rate 10 Year T No", | |
"^TYX: Treasury Yield 30 Years", | |
"EURUSD=X: EUR/USD", | |
"JPY=X: USD/JPY", | |
"GBPUSD=X: GBP/USD", | |
"AUDUSD=X: AUD/USD", | |
"NZDUSD=X: NZD/USD", | |
"EURJPY=X: EUR/JPY", | |
"GBPJPY=X: GBP/JPY", | |
"EURGBP=X: EUR/GBP", | |
"EURCAD=X: EUR/CAD", | |
"EURSEK=X: EUR/SEK", | |
"EURCHF=X: EUR/CHF", | |
"EURHUF=X: EUR/HUF", | |
"EURJPY=X: EUR/JPY", | |
"CNY=X: USD/CNY", | |
"HKD=X: USD/HKD", | |
"SGD=X: USD/SGD", | |
"INR=X: USD/INR", | |
"MXN=X: USD/MXN", | |
"PHP=X: USD/PHP", | |
"IDR=X: USD/IDR", | |
"THB=X: USD/THB", | |
"MYR=X: USD/MYR", | |
"ZAR=X: USD/ZAR", | |
"RUB=X: USD/RUB", | |
"BTC-USD: Bitcoin USD", | |
"ETH-USD: Ethereum USD", | |
"USDT-USD: Tether USDT USD", | |
"BNB-USD: BNB USD", | |
"SOL-USD: Solana USD", | |
"USDC-USD: USD Coin USD", | |
"XRP-USD: XRP", | |
"STETH-USD: Lido Staked ETH USD", | |
"DOGE-USD: Dogecoin USD", | |
"TON11419-USD: Toncoin USD", | |
"ADA-USD: Cardano USD", | |
"WSTETH-USD: Lido wstETH USD", | |
"WTRX-USD: Wrapped TRON USD", | |
"TRX-USD: TRON USD", | |
"AVAX-USD: Avalanche USD", | |
"WETH-USD: Wrapped Bitcoin USD", | |
"SHIB-USD: Shiba Inu USD", | |
"DOT-USD: Polkadot USD", | |
"LINK-USD: Chainlink USD", | |
"BCH-USD: Bitcoin Cash USD", | |
"EDLC-USD: Edelman USD", | |
"NEAR-USD: NEAR Protocol USD", | |
"EETH-USD: staked.fi ETH USD", | |
"LEO-USD: UNUS SED LEO USD", | |
"TSLA: Tesla, Inc.", | |
"NVDA: NVIDIA Corporation", | |
"F: Ford Motor Company", | |
"DXCM: DexCom, Inc.", | |
"SWN: Southwestern Energy Company", | |
"AAL: American Airlines Group Inc.", | |
"AMD: Advanced Micro Devices, Inc.", | |
"PLUG: Plug Power Inc.", | |
"BAC: Bank of America Corporation", | |
"MARA: Marathon Digital Holdings, Inc.", | |
"GOOGL: Alphabet Inc.", | |
"AAPL: Apple Inc.", | |
"MMM: 3M Company", | |
"NKE: NIKE, Inc.", | |
"PFE: Pfizer Inc.", | |
"SMYMY: Sirius XM Holdings Inc.", | |
"INTC: Intel Corporation", | |
"SOFI: SoFi Technologies, Inc.", | |
"BTGR: BTS Group Holdings Public Company Limited", | |
"LCID: Lucid Group, Inc.", | |
"PLTR: Palantir Technologies Inc.", | |
"NWL: Newell Brands Inc.", | |
"VALE: Vale S.A.", | |
"CLSK: CleanSpark, Inc.", | |
"BTE: Baytex Energy Corp.", | |
"ASTS: AST SpaceMobile, Inc.", | |
"ET: Energy Transfer LP", | |
"AMZN: Amazon.com, Inc.", | |
"HBI: Hanesbrands Inc.", | |
"CMG: Chipotle Mexican Grill, Inc.", | |
"GOOG: Alphabet Inc.", | |
"AGNC: AGNC Investment Corp.", | |
"RIVN: Rivian Automotive, Inc.", | |
"GOLD: Barrick Gold Corporation", | |
"AVTR: Avantor, Inc.", | |
"CMCSA: Comcast Corporation", | |
"RIG: Transocean Ltd.", | |
"MUV2: Micron Technology, Inc.", | |
"WBD: Warner Bros. Discovery, Inc.", | |
"AVGO: Broadcom Inc.", | |
"CCL: Carnival Corporation & plc", | |
"MSFT: Microsoft Corporation", | |
"WMT: Walmart Inc.", | |
"HBAN: Huntington Bancshares Incorporated", | |
"GM: General Motors Company", | |
"BN: Brookfield Corporation", | |
"CSCO: Cisco Systems, Inc.", | |
"ERIC: Telefonaktiebolaget LM Ericsson (publ)", | |
"INFY: Infosys Limited" | |
] | |
with gr.Row(): | |
ticker1 = gr.Dropdown(label="Primary Ticker", choices=ticker_options, value="AAPL: Apple Inc.") | |
ticker2 = gr.Dropdown(label="Secondary Ticker", choices=ticker_options, value="MSFT: Microsoft Corporation") | |
ticker3 = gr.Dropdown(label="Third Ticker", choices=ticker_options, value="GOOGL: Alphabet Inc.") | |
ticker4 = gr.Dropdown(label="Fourth Ticker", choices=ticker_options, value="AMZN: Amazon.com, Inc.") | |
with gr.Row(): | |
start_date = gr.Textbox(label="Start Date", value="2022-01-01") | |
end_date = gr.Textbox(label="End Date", value=datetime.date.today().isoformat()) | |
interval = gr.Dropdown(label="Interval", choices=['1m', '2m', '5m', '15m', '30m', '60m', '90m', '1h', '1d', '5d', '1wk', '1mo', '3mo'], value='1d') | |
with gr.Row(): | |
indicators = gr.CheckboxGroup(label="Indicators", choices=['RSI', 'SMA21', 'SMA50', 'SMA200', 'VWAP', 'Bollinger Bands'], value=['SMA21', 'SMA50']) | |
analysis_type = gr.Radio(label="Analysis Type", choices=['Single Ticker', 'Comparative Analysis', 'Trend Analysis', 'Correlation Analysis', 'Comprehensive Investment Strategy', 'Custom Chart Analysis'], value='Single Ticker') | |
query = gr.Textbox(label="Analysis Query", value="Analyze the price trends.") | |
uploaded_image = gr.Image(label="Upload Custom Chart (optional)", type="pil") | |
analyze_button = gr.Button("Analyze") | |
output_image = gr.Image(label="Analysis Chart") | |
output_text = gr.Textbox(label="Generated Insights", lines=10) | |
analyze_button.click( | |
fn=gradio_interface, | |
inputs=[ticker1, ticker2, ticker3, ticker4, start_date, end_date, query, analysis_type, interval, indicators, uploaded_image], | |
outputs=[output_text, output_image] | |
) | |
demo.launch() | |
if __name__ == "__main__": | |
gradio_app() |