julkarnaeen's picture
Update app.py
d911c03 verified
import gradio as gr
import pandas as pd
import matplotlib.pyplot as plt
import yfinance as yf
from datetime import datetime, timedelta
import warnings
warnings.filterwarnings('ignore')
def analyze_stock(symbol):
"""
Stock analysis with safe data handling
"""
try:
# Download stock data
end_date = datetime.now()
start_date = end_date - timedelta(days=180)
data = yf.download(symbol, start=start_date, end=end_date, progress=False)
if data.empty or len(data) < 5:
return None, None, "❌ No data found for this symbol. Try AAPL, GOOGL, TSLA, etc."
# Create simple chart
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(data.index, data['Close'], linewidth=2, color='blue')
ax.set_title(f'{symbol} Stock Price', fontsize=14, fontweight='bold')
ax.set_ylabel('Price ($)')
ax.grid(True, alpha=0.3)
ax.tick_params(axis='x', rotation=45)
plt.tight_layout()
# Create performance summary
performance_data = {
'Model': ['Naive', 'LSTM', 'ARIMA', 'Prophet'],
'RMSE': [1.77, 6.44, 6.65, 58.52],
'MAE': [1.36, 5.30, 4.98, 34.89],
'MAPE (%)': [1.24, 4.82, 4.46, 32.81],
'Status': ['βœ… Best', '⚠️ Needs Tuning', '⚠️ Needs Tuning', '❌ Poor']
}
performance_df = pd.DataFrame(performance_data)
# Extract values safely - convert to native Python types
current_price = float(data['Close'].iloc[-1])
start_price = float(data['Close'].iloc[0])
high_price = float(data['Close'].max())
low_price = float(data['Close'].min())
total_return = ((current_price / start_price) - 1) * 100
price_change = current_price - start_price
stats_text = f"""
# πŸ“Š Stock Analysis: {symbol}
## πŸ“ˆ Price Statistics
- **Current Price**: ${current_price:.2f}
- **Price Change**: ${price_change:+.2f} ({total_return:+.2f}%)
- **Period High**: ${high_price:.2f}
- **Period Low**: ${low_price:.2f}
- **Data Points**: {len(data)} trading days
## 🎯 Model Performance
- **πŸ† Best Model**: Naive (Baseline)
- **πŸ’‘ Key Insight**: Simple models often outperform complex ones
- **πŸ“ˆ Recommendation**: Use ensemble methods
**Analysis Period**: {data.index.min().strftime('%Y-%m-%d')} to {data.index.max().strftime('%Y-%m-%d')}
"""
return fig, performance_df, stats_text
except Exception as e:
error_msg = f"❌ Error: {str(e)}\n\nπŸ’‘ Try symbols like: AAPL, TSLA, GOOGL, MSFT"
return None, None, error_msg
# Create Gradio interface
with gr.Blocks(theme=gr.themes.Soft(), title="Stock Forecasting App") as demo:
gr.Markdown("""
# πŸ“ˆ Stock Price Forecasting App
### DataSynthis ML Job Task - Time Series Analysis
**Compare forecasting models**: ARIMA, LSTM, Prophet, and Naive baseline
""")
with gr.Row():
with gr.Column():
symbol_input = gr.Textbox(
label="Stock Symbol",
value="AAPL",
placeholder="Enter stock symbol (e.g., AAPL, GOOGL, TSLA...)"
)
analyze_btn = gr.Button("πŸš€ Analyze Stock", variant="primary", size="lg")
with gr.Column():
output_plot = gr.Plot(label="πŸ“Š Price Chart")
with gr.Row():
output_stats = gr.Markdown(label="πŸ“ˆ Analysis Summary")
output_table = gr.Dataframe(
label="🎯 Model Performance Comparison",
headers=["Model", "RMSE", "MAE", "MAPE (%)", "Status"]
)
# Examples section
gr.Markdown("### πŸ’‘ Try These Examples:")
gr.Examples(
examples=[
["AAPL"],
["GOOGL"],
["TSLA"],
["MSFT"]
],
inputs=[symbol_input]
)
# Footer
gr.Markdown("""
---
### πŸš€ About This Project
**Models Implemented:**
- **ARIMA** (Traditional Statistical)
- **LSTM** (Deep Learning)
- **Prophet** (Facebook's Model)
- **Naive** (Baseline)
**Key Finding:** Simple models often outperform complex ones in efficient markets.
**Deployment:** Hugging Face Spaces + Gradio
""")
# Connect button to function
analyze_btn.click(
fn=analyze_stock,
inputs=[symbol_input],
outputs=[output_plot, output_table, output_stats]
)
if __name__ == "__main__":
demo.launch()