Spaces:
Sleeping
Sleeping
| 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() |