Skip to content

Navigation Menu

Sign in
Sign up

Latest commit

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Volatility Waves 〰️

A dual-head Transformer that forecasts 21-day realised volatility and classifies the current volatility regime (Low / Normal / High Stress), then injects that forecast into a Monte Carlo simulation engine to generate realistic price paths.

The core innovation is replacing the fixed σ in standard Geometric Brownian Motion with a time-varying σ(t) produced by the model:

×ばつ exp( (μ − σ2/2)dt + σ√dt ×ばつ Z ) # Volatility Waves — σ(t) comes from the Transformer forecast S(t+1) = S(t) ×ばつ exp( (μ − σ(t)2/2)dt + σ(t)√dt ×ばつ Z )">
# Standard GBM — σ is a single historical constant
S(t+1) = S(t) ×ばつ exp( (μ − σ2/2)dt + σ√dt ×ばつ Z )
# Volatility Waves — σ(t) comes from the Transformer forecast
S(t+1) = S(t) ×ばつ exp( (μ − σ(t)2/2)dt + σ(t)√dt ×ばつ Z )

Pre-trained checkpoints are included for: SPY · AAPL · NVDA · MSFT · AMZN · GOOGL · GLD · QQQ · TLT · XOM · BTC-USD


Demo

streamlit run app.py

Pick a ticker, simulation horizon (5–63 days), number of paths (1k / 5k / 10k), and simulation mode. The app generates a percentile fan chart (5th / 25th / 50th / 75th / 95th) plus VaR, CVaR, and a regime probability table in real time.


Architecture

×ばつ TransformerEncoderLayer (4 heads, GELU, dropout = 0.1) └─ Last token (current market state) ├─ Vol head: LayerNorm → Linear(64,32) → GELU → Linear(32,1) → scalar vol forecast └─ Regime head: LayerNorm → Linear(64,32) → GELU → Linear(32,3) → softmax regime probs ~250 k parameters. Trains in ≈5 min on CPU, ≈90 s on MPS/CUDA. Loss = 0.7 ×ばつ MSE(vol) + 0.3 ×ばつ CrossEntropy(regime)">
Input: (batch, 63 days, 9 features)
 └─ Linear projection + LayerNorm → d = 64
 └─ Learnable positional embedding
 └─ ×ばつ TransformerEncoderLayer (4 heads, GELU, dropout = 0.1)
 └─ Last token (current market state)
 ├─ Vol head: LayerNorm → Linear(64,32) → GELU → Linear(32,1) → scalar vol forecast
 └─ Regime head: LayerNorm → Linear(64,32) → GELU → Linear(32,3) → softmax regime probs
~250 k parameters. Trains in ≈5 min on CPU, ≈90 s on MPS/CUDA.
Loss = 0.7 ×ばつ MSE(vol) + 0.3 ×ばつ CrossEntropy(regime)

Simulation modes

Mode σ source
AI vol Time-varying σ(t) interpolated from current realised vol to Transformer forecast
Regime switch Per-path regime drawn from the model's softmax probabilities, each regime has its own σ and drift
GBM baseline Constant σ from trailing 21-day realised vol (standard GBM)

Features

Feature Description
log_ret Daily log return
rvol_5 5-day realised vol (annualised)
rvol_10 10-day realised vol (annualised)
rvol_21 21-day realised vol — also the regression target
rvol_63 63-day realised vol (annualised)
park_vol Parkinson high-low estimator
vvol Vol-of-vol: rolling std of rvol_21 — regime transition signal
vix VIX level (implied vol)
vix_ratio rvol_21 / VIX — > 1 means realised exceeded implied

Project Structure

volatility-waves/
├── app.py # Streamlit dashboard
├── requirements.txt
│
├── src/
│ ├── data/
│ │ └── fetch.py # Download OHLCV via yfinance → data/raw/
│ ├── features/
│ │ └── build.py # Leakage-safe feature engineering → data/processed/
│ ├── models/
│ │ ├── dataset.py # VolDataset — sliding window over features
│ │ ├── vol_transformer.py # Dual-head Transformer definition
│ │ └── inference.py # load_bundle, infer_latest, infer_rolling
│ ├── simulation/
│ │ └── paths.py # gbm_paths, ai_vol_paths, regime_paths, risk_metrics
│ ├── benchmarking.py # GARCH(1,1), EWMA, Kupiec LR test
│ └── train.py # Walk-forward CV, final model, ablation study
│
├── scripts/
│ └── backtest.py # Rolling 1-day VaR backtest over holdout period
│
├── notebooks/
│ └── 01_eda.ipynb # Feature inspection, regime plots, lookahead sanity check
│
├── data/
│ ├── raw/ # Yahoo Finance parquet files (git-ignored)
│ └── processed/ # Engineered features (git-ignored)
│
├── checkpoints/ # Model weights + metrics JSON (git-ignored by default)
│ ├── SPY_best.pt
│ ├── SPY_metrics.json
│ └── ...
│
└── tests/
 ├── test_simulation.py
 ├── test_features.py
 ├── test_dataset.py
 ├── test_vol_transformer.py
 ├── test_benchmarking.py
 └── test_train_config.py

Setup

git clone https://github.com/YOUR_USERNAME/volatility-waves.git
cd volatility-waves
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt

PyTorch backend

requirements.txt installs the default PyTorch build. For a specific backend:

# CUDA (Linux / Windows)
pip install torch --index-url https://download.pytorch.org/whl/cu121
# MPS is bundled in the standard macOS wheel — no extra step
pip install torch
# CPU only (e.g. Streamlit Cloud free tier)
pip install torch --index-url https://download.pytorch.org/whl/cpu

Training auto-detects the best device in order: CUDA → MPS → CPU. Override with --device cuda|mps|cpu.


Workflow

1 — Fetch data

python -m src.data.fetch

Downloads SPY, AAPL, NVDA, GLD, and ^VIX from Yahoo Finance (2010–2024) into data/raw/.

Optional — custom tickers or date range:

python -m src.data.fetch --tickers SPY AAPL VIX --start 2015年01月01日 --end 2024年12月31日

2 — Build features

python -m src.features.build

Computes all vol features per ticker with rolling quantile regime labels. All quantiles use only past data — no lookahead leakage.

3 — Run tests

pytest tests/ -v

The test suite covers feature leakage, dataset shapes, simulation properties (VaR coverage rate, CVaR ≥ VaR), and Kupiec test calibration.

4 — Train

python -m src.train --ticker SPY

Runs 5-fold walk-forward cross-validation, trains the final model on the selection set, evaluates on a 252-day holdout, and saves to checkpoints/SPY_best.pt.

Key flags:

Flag Default Description
--ticker SPY Ticker to train on
--epochs 100 Training epochs
--lookback 63 Input window (trading days)
--horizon 21 Forecast horizon (trading days)
--alpha 0.3 Regime classification loss weight
--device auto Force cuda, mps, or cpu
--run-ablation off 4-way ablation study
--n-splits 5 Walk-forward folds
--test-size 252 Holdout days
--seed 42 Global random seed

Ablation study:

python -m src.train --ticker SPY --run-ablation

Trains 4 variants (full / no regime head / no VIX / 1-layer encoder) and reports mean ± std vol MAE for each.

5 — Backtest

python scripts/backtest.py --ticker SPY

Rolls a 1-day VaR backtest over the 252-day holdout, comparing the AI vol model against GARCH(1,1) and EWMA via the Kupiec likelihood-ratio test.

Example output:

==============================================================
 VaR Backtest — SPY (95% confidence)
==============================================================
Model Breach Expected Kupiec LR p-val Result
--------------------------------------------------------------
AI vol 4.76% 5.00% 0.412 0.5211 PASS
GARCH 5.16% 5.00% 0.181 0.6706 PASS
EWMA 6.35% 5.00% 9.241 0.0024 FAIL
==============================================================

Optional flags: --conf 0.99, --test-size 504, --save.

6 — Dashboard

streamlit run app.py

7 — EDA notebook

jupyter notebook notebooks/01_eda.ipynb

Deploying to Streamlit Cloud

  1. Push the repo to GitHub.
  2. Go to share.streamlit.ioNew app → point to app.py.
  3. Confirm requirements.txt is detected in Advanced settings → Packages.
  4. The app falls back to GBM baseline automatically if no checkpoint is found — safe to deploy without weights.

For CPU-only deployment, replace the torch line in requirements.txt:

--index-url https://download.pytorch.org/whl/cpu
torch==2.5.1+cpu

Inference on the ~250k-parameter model runs in under 50ms on CPU.


License

MIT — see LICENSE.


Disclaimer

This project is for educational and research purposes only. It is not financial advice and should not be used to make investment decisions.

About

Dual-head Transformer for volatility forecasting & regime classification, injected into Monte Carlo price path simulation. Streamlit dashboard included.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

AltStyle によって変換されたページ (->オリジナル) /