SanguineLithium/spy-gru20-volatility-forecast
SPY GRU-20 Five-Day Volatility Forecast
A compact recurrent neural-network release that forecasts the annualized volatility magnitude of SPY over the next five trading days using only daily adjusted OHLCV-derived information available through market close on day t.
This repository packages the exact three final Keras checkpoints and exact StandardScaler artifact produced by the accepted ARIN 470 experiment. The release does not retrain, convert, quantize, or reserialize those files.
What the model predicts
For daily adjusted log return r_t = ln(Close_t / Close_{t-1}), the target is:
sqrt((252 / 5) * sum(r_{t+i}^2 for i = 1..5))The output is a decimal annualized five-trading-day forward volatility proxy. For display as a percentage, multiply by 100. It is not presented as high-frequency realized volatility, a price-direction forecast, a trading signal, or investment advice.
Release artifacts
The three checkpoints are repeated final fits, not three members of a separately validated ensemble. The experiment's primary neural summary is the arithmetic mean of the three seed-level error metrics.
Architecture
Input (20 steps × 7 features)
→ GRU(64)
→ Dropout(0.20)
→ Dense(16, ReLU)
→ Dense(1, Softplus)- Trainable parameters: 15,073
- Optimizer: Adam, learning rate 0.001
- Loss: MAE
- Batch size: 32
- Final epoch budget: 18
- Final seeds: 42, 52, 62
The 18-epoch budget was frozen as the median of the selected candidate's Fold-3 best epochs: 4, 25, 18 → 18.
Input contract
The model consumes the latest 20 valid feature rows in this exact order:
log_returnabs_returnlog_hl_rangelog_volume_changereturn_5dvol_5d_trailingvol_20d_trailing
The exact formulas and scaler contract are in `config/feature_spec.json`. The raw input is adjusted daily Open, High, Low, Close, and Volume data, ordered by trading date. Use completed daily bars only.
Model selection
Four recurrent candidates were evaluated across three forward development folds and three seeds each, producing 36 candidate/fold/seed fits.
Selection used the predeclared rule: minimum mean validation MAE; candidates within 1% relative MAE were treated as practically tied, then fewer trainable parameters, then shorter sequence length. That rule selected GRU-20.
Held-out evaluation
Final holdout: 1,641 daily anchors, 2019-06-17 through 2025-12-23.
Seed variability for the reported neural summary:
- MAE sample SD: 0.000344
- RMSE sample SD: 0.001895
Relative to the baselines, the mean neural metrics were approximately:
- 17.32% lower MAE than persistence
- 16.95% lower MAE than GARCH
- 8.00% lower RMSE than persistence
- 7.60% lower RMSE than GARCH
A predeclared every-fifth-anchor sensitivity retained the same overall ordering. Dependence-aware paired stationary-bootstrap intervals for neural-minus-baseline MAE loss differentials were entirely below zero in both planned comparisons:
- Neural − persistence: observed −0.010970, 97.5% interval [−0.016240, −0.006077]
- Neural − GARCH: observed −0.010689, 97.5% interval [−0.020343, −0.003296]
The 97.5% interval was used per pair as the Bonferroni-adjusted component of a 95% familywise procedure across the two planned comparisons. Full structured results are in `evaluation/holdout_metrics.json`.
Preprocessing boundary
The final scaler was fitted on 6,617 unique calendar feature rows from 1993-03-01 through 2019-06-07. The final holdout begins 2019-06-17. The stored scaler was independently reconstructed during forensic review and its means/scales matched the expected training-only fit population.
No feature clipping is used.
Quick local inference
Install the pinned release environment:
pip install -r requirements.txtRun an integrity check first:
python examples/verify_artifacts.py --loadThen provide a CSV containing completed adjusted daily bars with columns:
Date,Open,High,Low,Close,Volumeand run one checkpoint:
python examples/predict_from_ohlcv.py --csv /path/to/spy_adjusted_ohlcv.csv --seed 42Example output shape:
{
"ticker": "SPY",
"as_of": "YYYY-MM-DD",
"checkpoint_seed": 42,
"forecast_horizon_trading_days": 5,
"predicted_annualized_volatility": 0.0796,
"predicted_annualized_volatility_pct": 7.96,
"trailing_5d_volatility": 0.0612,
"trailing_5d_volatility_pct": 6.12
}The numeric example above is illustrative of the response schema; current forecasts depend on the supplied completed market history.
Loading directly from the Hugging Face Hub
After this directory is uploaded to a model repository:
python examples/predict_from_hub.py \
--repo-id YOUR_USERNAME/spy-gru20-volatility-forecast \
--csv /path/to/spy_adjusted_ohlcv.csv \
--seed 42The script uses huggingface_hub.snapshot_download() and then loads the unchanged .keras checkpoint and scaler locally.
Intended use
This release is intended for:
- reproducible demonstration of the accepted ARIN 470 forecasting system;
- educational or research analysis of short-horizon SPY volatility magnitude;
- programmatic inference through a future service layer that preserves this input contract.
It is not intended to provide:
- price direction or return forecasts;
- buy/sell recommendations;
- derivative pricing;
- personalized financial advice;
- an autonomous trading decision;
- claims of automatic generalization to other tickers, markets, or horizons.
Limitations
- The model was evaluated only on the fixed SPY experiment described here.
- The target is a daily-return-based five-day annualized volatility proxy, not intraday realized volatility.
- Market regimes can change; favorable historical holdout performance does not guarantee future error rates.
- The model uses engineered price/volume features only. It does not use options-implied volatility, VIX, macroeconomic releases, news, sentiment, fundamentals, or constituent-level information.
- The three saved seeds are separate repeated fits. Combining their predictions creates a distinct ensemble that should be evaluated explicitly before being described as the validated primary model.
- Current-data inference requires the same adjusted OHLCV semantics and exact feature order used during training.
Data provenance
The executed experiment used a frozen SPY daily adjusted OHLCV snapshot obtained through Yahoo Finance / yfinance, spanning 1993-01-29 through 2025-12-31 (8,288 raw rows). The raw dataset is not redistributed in this model repository. The release manifest records both the executed DataFrame hash and the local frozen CSV file SHA-256 for provenance.
Artifact integrity
The release-critical model/scaler hashes are recorded in `config/model_manifest.json` and `CHECKSUMS.sha256`. examples/verify_artifacts.py verifies the packaged bytes before optional deserialization.
Reproducibility note
The accepted execution environment recorded:
- Python 3.13.15
- TensorFlow 2.20.0
- Keras 3.13.2 (recorded inside the saved model artifacts)
- NumPy 2.1.3
- pandas 2.2.3
- scikit-learn 1.6.1
- yfinance 0.2.66
- arch 8.0.0 (evaluation baseline only; not required for inference)
The model repository intentionally contains the frozen inference artifacts and concise evaluation evidence rather than the full training dataset or entire development notebook.
License status
No explicit model license has been selected in this release package. Do not infer reuse permissions from public availability alone. Add a license before public release if broader reuse is intended.
Academic context
Developed as an ARIN 470 deep-learning project. The experiment asked whether a deep recurrent sequence model using only information available through market close on day t could forecast the magnitude of SPY volatility over the next five trading days more accurately than persistence and a conventional GARCH baseline under forward-only evaluation.
