arjunanand13's picture
Update app.py
973f2b8 verified
import gradio as gr
import yfinance as yf
import pandas as pd
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from datetime import datetime, timedelta
import warnings
warnings.filterwarnings('ignore')
# List of companies with their symbols
COMPANIES = {
'Apple (AAPL)': 'AAPL',
'Microsoft (MSFT)': 'MSFT',
'Amazon (AMZN)': 'AMZN',
'Google (GOOGL)': 'GOOGL',
'Meta (META)': 'META',
'Tesla (TSLA)': 'TSLA',
'NVIDIA (NVDA)': 'NVDA',
'JPMorgan Chase (JPM)': 'JPM',
'Johnson & Johnson (JNJ)': 'JNJ',
'Walmart (WMT)': 'WMT',
'Visa (V)': 'V',
'Mastercard (MA)': 'MA',
'Procter & Gamble (PG)': 'PG',
'UnitedHealth (UNH)': 'UNH',
'Home Depot (HD)': 'HD',
'Bank of America (BAC)': 'BAC',
'Coca-Cola (KO)': 'KO',
'Pfizer (PFE)': 'PFE',
'Disney (DIS)': 'DIS',
'Netflix (NFLX)': 'NFLX'
}
def calculate_metrics(df):
"""Calculate technical indicators"""
data = df.copy()
# Basic metrics
data['Returns'] = data['Close'].pct_change()
data['SMA_20'] = data['Close'].rolling(window=20).mean()
data['SMA_50'] = data['Close'].rolling(window=50).mean()
# RSI
delta = data['Close'].diff()
gain = delta.clip(lower=0)
loss = -delta.clip(upper=0)
avg_gain = gain.rolling(window=14).mean()
avg_loss = loss.rolling(window=14).mean()
rs = avg_gain / avg_loss
data['RSI'] = 100 - (100 / (1 + rs))
# Bollinger Bands
data['BB_middle'] = data['Close'].rolling(window=20).mean()
bb_std = data['Close'].rolling(window=20).std()
data['BB_upper'] = data['BB_middle'] + (2 * bb_std)
data['BB_lower'] = data['BB_middle'] - (2 * bb_std)
return data
def create_plots(data):
"""Create analysis plots"""
# Price and Volume Plot
fig1 = make_subplots(
rows=2, cols=1,
shared_xaxes=True,
vertical_spacing=0.1,
subplot_titles=('Price and Moving Averages', 'Volume'),
row_heights=[0.7, 0.3]
)
fig1.add_trace(
go.Scatter(x=data.index, y=data['Close'], name='Close', line=dict(color='blue')),
row=1, col=1
)
fig1.add_trace(
go.Scatter(x=data.index, y=data['SMA_20'], name='SMA 20', line=dict(color='orange', dash='dash')),
row=1, col=1
)
fig1.add_trace(
go.Scatter(x=data.index, y=data['SMA_50'], name='SMA 50', line=dict(color='green', dash='dash')),
row=1, col=1
)
fig1.add_trace(
go.Bar(x=data.index, y=data['Volume'], name='Volume', marker_color='lightblue'),
row=2, col=1
)
fig1.update_layout(height=600, title_text="Price Analysis")
# Technical Analysis Plot
fig2 = make_subplots(
rows=2, cols=1,
shared_xaxes=True,
vertical_spacing=0.1,
subplot_titles=('RSI', 'Bollinger Bands'),
row_heights=[0.5, 0.5]
)
# RSI
fig2.add_trace(
go.Scatter(x=data.index, y=data['RSI'], name='RSI', line=dict(color='purple')),
row=1, col=1
)
fig2.add_hline(y=70, line_dash="dash", line_color="red", row=1, col=1)
fig2.add_hline(y=30, line_dash="dash", line_color="green", row=1, col=1)
# Bollinger Bands
fig2.add_trace(
go.Scatter(x=data.index, y=data['Close'], name='Close', line=dict(color='blue')),
row=2, col=1
)
for band, color in [('BB_upper', 'gray'), ('BB_middle', 'red'), ('BB_lower', 'gray')]:
fig2.add_trace(
go.Scatter(x=data.index, y=data[band], name=band, line=dict(color=color, dash='dash')),
row=2, col=1
)
fig2.update_layout(height=600, title_text="Technical Analysis")
return [fig1, fig2]
def generate_summary(data, symbol):
"""Generate analysis summary"""
try:
current_price = float(data['Close'].iloc[-1])
prev_price = float(data['Close'].iloc[-2])
daily_return = ((current_price - prev_price) / prev_price) * 100
rsi = float(data['RSI'].iloc[-1])
sma_20 = float(data['SMA_20'].iloc[-1])
sma_50 = float(data['SMA_50'].iloc[-1])
volume = float(data['Volume'].iloc[-1])
bb_position = "in middle range"
if current_price > float(data['BB_upper'].iloc[-1] * 0.95):
bb_position = "near upper band (potential resistance)"
elif current_price < float(data['BB_lower'].iloc[-1] * 1.05):
bb_position = "near lower band (potential support)"
summary = f"""Analysis Summary for {symbol}:
• Current Price: ${current_price:.2f}
• Daily Change: {daily_return:+.2f}%
• Trend: {"Bullish" if sma_20 > sma_50 else "Bearish"} (20-day MA vs 50-day MA)
• RSI: {rsi:.2f} ({"Overbought" if rsi > 70 else "Oversold" if rsi < 30 else "Neutral"})
• Volume: {volume:,.0f}
Technical Signals:
• Moving Averages: Price is {"above" if current_price > sma_20 else "below"} 20-day MA
• Bollinger Bands: Price is {bb_position}
"""
return summary
except Exception as e:
return f"Error generating summary: {str(e)}"
def analyze_stock(company, lookback_days=180):
"""Main analysis function"""
try:
symbol = COMPANIES[company]
end_date = datetime.now()
start_date = end_date - timedelta(days=lookback_days)
# Download data
data = yf.download(symbol, start=start_date, end=end_date)
if len(data) == 0:
return "No data available for the selected period.", None, None
# Calculate metrics and create analysis
data = calculate_metrics(data)
summary = generate_summary(data, symbol)
plots = create_plots(data)
return summary, plots[0], plots[1]
except Exception as e:
return f"Error analyzing stock: {str(e)}", None, None
def create_interface():
"""Create Gradio interface"""
with gr.Blocks() as interface:
gr.Markdown("# Stock Market Analysis Dashboard")
with gr.Row():
company = gr.Dropdown(
choices=list(COMPANIES.keys()),
label="Select Company",
value="Apple (AAPL)"
)
lookback = gr.Slider(
minimum=30,
maximum=365,
value=180,
step=1,
label="Lookback Period (days)"
)
refresh_btn = gr.Button("🔄 Refresh")
with gr.Row():
summary = gr.Textbox(label="Analysis Summary", lines=10)
with gr.Row():
plot1 = gr.Plot(label="Price Analysis")
plot2 = gr.Plot(label="Technical Analysis")
# Event handlers
refresh_btn.click(
fn=analyze_stock,
inputs=[company, lookback],
outputs=[summary, plot1, plot2]
)
company.change(
fn=analyze_stock,
inputs=[company, lookback],
outputs=[summary, plot1, plot2]
)
lookback.release(
fn=analyze_stock,
inputs=[company, lookback],
outputs=[summary, plot1, plot2]
)
return interface
if __name__ == "__main__":
interface = create_interface()
interface.launch(share=True)