A Python-based portfolio optimization system using LSTM neural networks, ARIMA baseline models, and GARCH volatility weighting for Indian stock market analysis.
This project implements a strict train/test validation framework for forecasting 9 Indian NSE stocks (RELIANCE, TCS, HDFCBANK, SUNPHARMA, ITC, BHARTIARTL, LTTS, ASIANPAINT, ICICIBANK) using:
- LSTM (Stacked Long Short-Term Memory) - Deep learning time series forecaster
- ARIMA(5,1,0) - Baseline statistical model for comparison
- GARCH(1,1) - Volatility forecasting for portfolio weighting
- ADF Test - Stationarity diagnostics
- STL Decomposition - Seasonal-Trend analysis
Capital Limit: ₹10,00,000 (10 lakh rupees)
Central module for all data operations. Implements the strict train/test split as required by the academic rubric.
Key Components:
STOCKS- List of 9 NSE tickersTARGET_STOCKS- Subset of 6 stocks for ADF analysisTRAIN_START = '2021-01-01'TRAIN_END = '2025-06-30'TEST_START = '2025-07-01'TEST_END = '2025-12-31'
Functions:
fetch_data(start, end)- Downloads Yahoo Finance close prices with auto-adjustment and forward-fill handlingsplit_train_test(data)- Splits data into training (Jan 2021 – Jun 2025) and test (Jul–Dec 2025) periodsget_latest_price(stock_name, fallback_series)- Real-time price with 3-tier fallback strategy
Executable portfolio engine. Run this to validate, forecast, and allocate capital.
Workflow:
- Fetch Data - Download 5+ years of historical prices
- Validate Models - Compare LSTM vs ARIMA on the explicit test period
- Calculate Metrics - MAPE, RMSE, Directional Accuracy for each model
- Forecast - Next 2 trading days using LSTM
- Weight Portfolio - Inverse-volatility allocation using GARCH
- Print Allocation Table - Stock, Current Price, Forecasted Price
Key Functions:
train_lstm(series)- Train stacked LSTM (50→50 neurons, 2 Dropout layers)forecast_lstm(model, scaler, series, steps)- Rolling forecast for n steps aheadforecast_arima(series, steps, order=(5,1,0))- ARIMA baselinecalculate_metrics(actual, predicted)- MAPE%, RMSE, Direction Accuracy%validate_models(data)- Print comparison tableget_volatility_weight(series)- GARCH(1,1) inverse-volatility weightingrun_system(data)- Execute full portfolio pipeline
Architecture (LSTM):
Input(60×1)
→ LSTM(50, return_seq=True)
→ Dropout(0.2)
→ LSTM(50, return_seq=False)
→ Dropout(0.2)
→ Dense(1 output)
Training: 5 epochs, batch_size=32, Adam optimizer, MSE loss
Time series analysis and stationarity testing.
Functions:
check_stationarity(stock_name, series)- ADF test (p-value ≤ 0.05 = stationary)plot_decomposition(stock_name, series)- STL decomposition with 252-day seasonal periodrun_other_models()- Execute ADF for all target stocks, STL plot for BHARTIARTL.NS
Output:
- Terminal: ADF statistics and p-values
- File:
bhartiartl_ns_stl.png- Seasonal-Trend-Residual plot
Ensure your Python environment is configured:
pip install tensorflow pandas numpy scikit-learn yfinance statsmodels archpython Model.pyOutput:
- Data fetch confirmation
- VALIDATION REPORT table: | Stock | LSTM_MAPE | LSTM_RMSE | LSTM_Dir% | ARIMA_MAPE | ARIMA_RMSE | ARIMA_Dir% | Winner |
- Win summary (LSTM vs ARIMA count)
- Per-stock analysis (current price, forecast, volatility weight)
- FINAL PORTFOLIO ALLOCATION table: | Stock | Final Weight (%) | Number of Shares | Current Price | Forecasted Price |
python otherModels.pyOutput:
- ADF test results for all 6 target stocks
bhartiartl_ns_stl.pngplot (if 252+ observations available)
| Parameter | Value | Purpose |
|---|---|---|
SEQ_LENGTH |
60 days | LSTM lookback window |
CAPITAL |
₹10,00,000 | Portfolio investment amount |
LSTM epochs |
5 | Training iterations |
LSTM batch_size |
32 | Samples per update |
GARCH(p,q) |
(1,1) | Volatility model order |
ARIMA order |
(5,1,0) | Baseline AR-I-MA configuration |
STL period |
252 days | Trading days per year |
- LSTM_MAPE - Mean Absolute Percentage Error (%)
- LSTM_RMSE - Root Mean Squared Error (₹)
- LSTM_Dir% - Directional accuracy (% correct up/down predictions)
- ARIMA_MAPE, ARIMA_RMSE, ARIMA_Dir% - Same metrics for baseline
- Winner - Model with lower MAPE on the test period
- Stock - NSE ticker name
- Final Weight (%) - Inverse-volatility normalized portfolio weight
- Number of Shares - Integer shares sized using ₹10,00,000 capital limit
- Current Price - Real-time price (3-tier fallback: intraday → fast_info → historical)
- Forecasted Price - LSTM prediction for next trading day
- Train LSTM + GARCH on full history
- Forecast next 2 trading days
- Calculate volatility (GARCH)
- Weight inversely:
weight = 1/volatility / Σ(1/volatility_all) - Allocate capital proportionally
- Missing Data: Forward-fill then backward-fill (
ffill().bfill()) - Price Adjustment: Yahoo Finance
auto_adjust=True(splits/dividends included) - Series Validation: Drops NaN, checks minimum length thresholds
- Scaler: MinMaxScaler (0,1) for LSTM training only
- Task 2 & 3 (Train/Test Split): ✓ Strict Jan 2021 – Jun 2025 train; Jul–Dec 2025 test
- Task 4 (Preprocessing): ✓ ADF stationarity tests, STL decomposition
- Task 5 (Portfolio Sizing): ✓ GARCH weighting, ₹10L capital allocation
- Task 6 & 8 (Baseline & Metrics): ✓ ARIMA(5,1,0), MAPE/RMSE/Direction Accuracy
- Task 2 (Data Pipeline): ✓ Centralized market_data.py with ffill/bfill
- The test period (Jul–Dec 2025) is explicitly hard-coded in
market_data.pyfor reproducibility - LSTM is retrained on each run; results vary slightly due to random initialization
- GARCH may warn if volatility is very low; falls back to std deviation
- STL decomposition requires ≥252 observations (skipped otherwise)
- Real-time price fetches may fail in offline environments; uses historical fallback
tensorflow>=2.21.0
pandas>=3.0.3
numpy>=2.4.5
scikit-learn>=1.8.0
yfinance>=1.3.0
statsmodels>=0.14.6
arch>=8.0.0
| Issue | Solution |
|---|---|
ImportError: No module named 'tensorflow' |
pip install tensorflow |
yfinance: No data found |
Check ticker format (use .NS for NSE) |
GARCH fitting error |
Reduce returns smoothing or skip stock |
STL insufficient data |
Need ≥252 trading days (about 1 year) |
Real-time price fetch timeout |
Script falls back to historical close |
This project demonstrates:
- Time series forecasting with deep learning (LSTM)
- Statistical baseline comparison (ARIMA)
- Volatility modeling (GARCH)
- Portfolio optimization principles
- Proper train/test validation methodology
- Handling real market data with YFinance API
Capstone Focus: Rigorous train/test separation with explicit dates, side-by-side model evaluation, and production-grade error handling.