Volatility clustering, ARCH and GARCH — forecasting the forecastable
▸ Pretest — guess, even if you don't know
Daily stock returns show almost zero autocorrelation, yet SQUARED daily returns show strong positive autocorrelation out to many lags. What does this pair of facts mean?
The one stylized fact that pays
Recall the D1-01 experiment. The ACF — autocorrelation function, the lag-by-lag correlation of a series with its own past — of daily returns is a flatline of statistical dust. But the ACF of squared returns is significantly positive for weeks. This pattern is volatility clustering — calm days bunch with calm days, wild days with wild days. It is a stylized fact — quant-speak for a pattern so consistent across markets and decades that everyone accepts it as a basic feature of the data. Markets have weather: vol-quiet regimes (2017) and vol-storms (2008, March 2020) each persist for a while. A2-02 treated volatility as one number per asset. The truth is that volatility is a time series of its own — and a strongly autocorrelated one. By everything in this track, autocorrelated means forecastable.
Put formally: returns are (nearly) white noise — uncorrelated with their own past — but they are not independent of it. The variance of tomorrow's return depends on what happened today. The models below make that dependence explicit.
ARCH: variance with a memory
Engle's 1982 idea has two pieces. First, split each day's return into size times direction:
In words: the return on day t ("r sub t") equals that day's volatility ("sigma sub t") times a random shock ("epsilon sub t" — the Greek letter , a fresh white-noise draw with mean 0 and variance 1). The shock supplies the coin-flip direction; sigma supplies the size. Second, let the variance itself move from day to day:
In words: today's variance ("sigma sub t squared") equals a constant floor omega (the Greek letter ) plus alpha (the Greek letter , a fraction between 0 and 1) times yesterday's squared return. Concrete numbers: with and , a 2% move yesterday means , so today's variance is — a daily vol of about 1.5%. After a flat day it falls back to roughly the floor.
A big move yesterday raises today's expected variance — either sign, since it's squared — and a quiet day lowers it. That single mechanism produces vol clustering and fat tails from perfectly normal shocks. Why fat tails? A mixture of calm days and wild days has more extreme outcomes than a single fixed-vol normal distribution (the B1 fat-tails fact, here derived rather than assumed).
Pure ARCH has short memory: one bad day is forgotten after a single step, unless you pile on many lagged terms. The fix is the same trick that took AR to ARMA in D1-05 — add a recursive term.
GARCH(1,1): the workhorse
Bollerslev's generalization adds yesterday's variance estimate to the recipe:
In words: today's variance equals omega (the floor) plus alpha times yesterday's squared shock plus beta (the Greek letter ) times yesterday's variance. In practice yesterday's squared return stands in for the squared shock, exactly as in the exercise below. One naming warning: this is just GARCH's weight on yesterday's variance. It has nothing to do with finance beta — a stock's sensitivity to the overall market — which you will meet elsewhere. Same Greek letter, completely different job.
Three parameters, each with a job:
- (omega) — the trickle toward the long-run variance floor.
- (alpha) — the news term: how hard the forecast reacts to yesterday's squared shock. Typically ~0.05–0.10 for daily equities.
- (beta) — the memory term: how much of yesterday's variance estimate carries over. Typically ~0.85–0.93.
The sum ("alpha plus beta") is the persistence — how slowly a variance shock fades, playing exactly the role the AR(1) coefficient played in D1-04. For daily equity indexes it's typically 0.95–0.99. At that level a volatility spike decays with a half-life of weeks, not days — half-life meaning the time for half of the spike to fade. That slow decay is the clustering.
The long-run anchor
If , variance is mean-reverting. Its unconditional level — the long-run average it settles at, ignoring today's conditions — is:
In words: the long-run variance ("sigma-bar squared" — the bar on top marks a long-run average) equals omega divided by (1 minus alpha minus beta).
Worked example — take , , . Then and
In words: 0.00001 divided by 0.02 gives a long-run variance of 0.0005; take the square root and the long-run daily vol is about 2.24%. (That's roughly 35% annualized — quoted per year — so this is a high-vol stock.) Every GARCH forecast is a weighted tug-of-war between the latest shock and this anchor. Short-horizon forecasts track recent turbulence. Long-horizon forecasts glide back to at rate — read "alpha plus beta, raised to the power h," where is the forecast horizon in days: the fraction of a variance spike still standing after days.
Why this works when return forecasting doesn't — and what to do with it
Return forecasting fights the market. Any exploitable pattern in direction is someone else's free money, so it gets arbitraged toward zero (D1-02). Volatility is different. Knowing tomorrow will be turbulent doesn't tell you which way, so the pattern isn't directly an arbitrage, and nobody trades it away. High squared-return autocorrelation survives decades of being public knowledge.
The practical payoff is position sizing, not stock picking — a technique called vol targeting. Size positions inversely to forecast vol: half the vol forecast, twice the position; double the vol forecast, half the position. That way the dollar risk you carry stays roughly constant through calm and storm. It's the quant version of an old floor rule: trade smaller when the market is screaming. The full recipe, plus GARCH's pragmatic little sibling that most desks actually use, is the next lesson.
Try it
Iterate the GARCH(1,1) variance recursion by hand — the model is just a three-term loop:
Implement garch_variance_path(returns, omega, alpha, beta, initial_var): an array the same length as returns where var[0] = initial_var and var[t] = omega + alpha*returns[t-1]**2 + beta*var[t-1] for t >= 1. Returns act as the shocks.
⧉ Review cardState the volatility-clustering stylized fact in one sentence.
⧉ Review cardWrite the GARCH(1,1) variance equation and name each term's job.
⧉ Review cardWhat is GARCH persistence and what is its typical equity value?
⧉ Review cardUnconditional GARCH variance: formula and the worked example.
⧉ Review cardWhy does volatility forecasting work when return forecasting doesn't?
Explain it
Write three or four sentences, from memory, explaining to a fellow developer why a GARCH variance forecast is basically an AR(1) on squared shocks. Cover three things: what plays the role of the AR coefficient, what mean it reverts to, and why the half-life logic from D1-04 carries over.
Predict before the next lesson
Next is D1-08: EWMA and practical vol — the one-parameter shortcut most trading desks actually run. Predict: if you set omega = 0 and force alpha + beta = 1 in GARCH(1,1), what happens to the unconditional variance formula — and what might that imply about the model's long-horizon forecasts?
◈ Calibration check
Could you write down the GARCH(1,1) equation from memory, compute the unconditional variance for given parameters, and explain why vol is forecastable when returns aren't?
1 = guessing · 5 = could teach it
⏻ End of lesson
Mark it read to book its 5 review cards into your deck.
Sources & further reading
- paperEngle (1982), Autoregressive Conditional Heteroscedasticity with Estimates of the Variance of UK Inflation, Econometrica 50(4)
- paperBollerslev (1986), Generalized Autoregressive Conditional Heteroskedasticity, Journal of Econometrics 31(3)
- bookTsay (2010), Analysis of Financial Time Series, 3e — §3