Model the time-varying volatility of financial returns with a GARCH(1,1) process, forecast future volatility, and turn it into a Value-at-Risk (VaR) estimate that is then backtested for calibration. Covers the time-series and risk-management toolkit central to a quant analyst.
⚠️ Academic / personal research project. Not investment advice.
Returns exhibit volatility clustering — calm and turbulent periods come in runs. GARCH(1,1) models the conditional variance as:
sigma2_t = omega + alpha * eps2_{t-1} + beta * sigma2_{t-1}
alpha(ARCH) — reaction to the latest shockbeta(GARCH) — persistence of volatilityalpha + beta— persistence; < 1 means variance mean-reverts- long-run variance =
omega / (1 - alpha - beta)
omega = 2.60e-06
alpha (ARCH) = 0.0765
beta (GARCH)= 0.8949
persistence = 0.9714 (true value 0.98)
long-run vol = 15.16% annualized
VaR backtest (95%):
expected breaches = 5.00%
actual breaches = 4.87% (73/1499) -> well-calibrated
The estimator recovers the true persistence, and the VaR breach rate matches the 95% level — evidence the volatility model is sound.
- Parameter recovery is tested. The model is fit to data simulated from a known GARCH process; tests assert it recovers the true persistence.
- VaR is backtested, not just computed. A Kupiec-style coverage check uses the prior day's volatility (genuinely one-step-ahead), so the calibration test is honest.
- Graceful fallback. Uses the
archpackage if installed; otherwise a self-contained maximum-likelihood estimator keeps the project runnable. - Mean-reverting forecasts. Multi-step forecasts decay toward long-run vol.
pip install -r requirements.txt
# Synthetic series from a true GARCH process (no network)
python examples/run_garch.py
# Real series, e.g. the S&P 500 ETF
python examples/run_garch.py --ticker SPY --start 2015-01-01 --end 2024-12-31from garch import fit_garch, forecast_volatility
from risk import value_at_risk, var_backtest
fit = fit_garch(returns)
print(fit.summary())
var = value_at_risk(fit.conditional_vol, confidence=0.95)
print(var_backtest(returns, var, confidence=0.95).summary())python tests/test_garch.pyConfirms the estimator recovers known persistence, detects volatility clustering, produces a well-calibrated 95% VaR, and yields mean-reverting forecasts.
src/
garch.py # GARCH(1,1) fit (arch + MLE fallback) and vol forecast
risk.py # parametric VaR + calibration backtest
data_loader.py # Yahoo! Finance + synthetic GARCH simulator
examples/
run_garch.py # fit -> forecast -> VaR -> backtest
tests/
test_garch.py # parameter recovery + VaR calibration checks
- EGARCH / GJR-GARCH to capture the leverage effect (asymmetric vol)
- Student-t innovations for fatter tails in VaR
- Expected Shortfall (CVaR) alongside VaR