ML Arc Capstone — Forecasting Realized Volatility
Python · scikit-learn · XGBoost · SHAP · Open the notebook
One Problem, the Whole Toolkit
The capstone runs the whole machine-learning arc on one real problem — forecasting S&P 500 realized volatility — the way a desk actually would: engineered features, the full model roster, three escalating validation schemes, calibrated uncertainty, and an explanation of what drives the forecast. The target is next-day log realized volatility. Realized volatility is how much the market actually moved on a given day, computed from high-frequency returns rather than implied from option prices; the log is taken because volatility is bounded below by zero and its raw distribution is heavily right-skewed, while its logarithm is close to symmetric and roughly Gaussian, which is what squared-error loss assumes. Every tabular model sees the same engineered matrix, so the comparison is about models rather than about who got better inputs. One consequence worth carrying into the tables below: because the target is in logs, an RMSE (the root mean squared error, the typical size of a miss) of 0.33 means the forecasts are typically out by about a third of a log unit — a factor of roughly 1.4 in volatility terms, so a day whose true volatility is 1% is typically forecast somewhere between about 0.7% and 1.4%. These are not precise forecasts; the question is only which method is least imprecise.
The features encode the known structure of volatility: Corsi's HAR components (heterogeneous autoregressive: today's log realized volatility plus trailing weekly and monthly averages, on the theory that traders operate on daily, weekly and monthly horizons), short lags, return-based terms for the leverage channel, a rolling dispersion — and a fractionally-differenced log-price carried over from the Financial ML subsection, which injects a price-level signal the pure-volatility features lack.
The fractional order matters and the obvious rule picks the wrong one. Selecting the smallest that clears an ADF test (augmented Dickey–Fuller, the standard test for whether a series still wanders rather than reverting to a stable level) gives about 0.35 on this series, but that result still measures — above the 0.5 boundary at which a fractionally integrated series becomes stationary at all. The order that genuinely crosses it is , which is also the order maximising out-of-sample on this exact target. Two independent criteria, one answer.
The eleven features
Every tabular model receives the same eleven columns, so nothing in the comparison turns on feature access. Ten of them are built from the volatility series and the returns; one is not, and that one turns out to matter.
| feature | definition | what it encodes |
|---|---|---|
RV_d | today’s log realized volatility | Corsi’s HAR components — the daily, weekly and monthly horizons on which different traders operate. Between them they carry 51% of the model’s attribution. |
RV_w | 5-day rolling mean of log RV | |
RV_m | 22-day rolling mean of log RV | |
lag1, lag2, lag5 | log RV lagged 1, 2 and 5 days | short-run persistence at a finer grain than the HAR averages, which smooth it away |
absret | |return| today | the leverage channel: the magnitude of today’s move, which predicts tomorrow’s volatility independently of realized volatility itself |
absret_w | 5-day rolling mean of |return| | |
ret2 | squared return | the same channel squared — and the one feature SHAP scores at exactly 0.000, wholly redundant given the two above |
disp10 | 10-day rolling standard deviation of log RV | volatility of volatility — how unsettled the recent regime has been |
fd_price | fractionally differenced log price, d = 0.50 | the only price-level signal in the matrix, and the only one not derived from volatility history. Ranked 2 of 11 by SHAP |
Two things about that matrix are worth noticing before the results. It is deliberately collinear — RV_d, RV_w, RV_m, the three lags and disp10 all measure recent volatility, and correlated predictors are exactly the setting in which unregularized least squares becomes unstable and ridge earns its place. And ten of the eleven are functions of the volatility path alone; fd_price is the sole carrier of information about the price level. HAR-RV, which sees only the first kind, therefore has no access to the signal the SHAP ranking puts second — which is the mechanical reason the roster beats it rather than a vague appeal to flexibility.
The three results the capstone exists to produce
Every value is committed notebook output. The sequence models in A are deliberately absent: they are trained on a different split, and their figures are given in the text rather than plotted here, precisely so the bar chart cannot imply a comparison that was never run.
A is the arc’s verdict on itself. Nine models on identical features, ranked and then tested, because a ranking says nothing about whether its gaps are real. Four challengers are statistically indistinguishable from a plain ridge regression; four are beaten. The one beaten hardest is the classical benchmark, and by 0.0163 at p < 0.001 — not the “matched but narrowly” result usually reported. What beats it is the simplest model in the roster: the gradient booster, the support-vector regression and the neural network all lose to that ridge. The gain came from the features, and three lines of regularized regression were enough to collect it.
B corrects the slogan this page inherited. Shuffled cross-validation is measurably optimistic — 0.0085 RMSE, about 3% — so the warning is real. It is also, on this problem, the small effect. The three honest schemes disagree with each other by 0.0507, six times as much, because each scores a different stretch of history and volatility is far more forecastable in some years than others. Leakage is small here for a specific reason: the label is one day ahead, so label windows barely overlap and purging has almost nothing to remove. It would not be small with multi-day labels, which is exactly the case the purged cross-validation example builds where the truth is known. The transferable caution is narrower than the usual one: an RMSE is not comparable across validation schemes that do not share a test period.
C is the pair of questions a forecast has to answer after the point estimate. On the left, how much the model knows about its own error. The Gaussian process supplies a full predictive distribution at no extra cost and is overconfident, covering 0.81 against a 90% target; conformal prediction drops the assumption that the model is correct and does better at 0.84, but still falls short, because the calibration window is calm and the test period is a crisis — a regime shift is precisely what breaks exchangeability, the assumption the guarantee rests on. On the right, what the forecast is made of. The three HAR terms carry 51% of the attribution, so the model substantially rediscovers what the classical benchmark hard-codes — but the fractionally differenced price ranks second of eleven, ahead of two of the three HAR components. That is the mechanism behind panel A: HAR-RV has no price-level feature, and volatility history does not substitute for one.
The Roster, Tested Rather Than Ranked
A ranking by RMSE says nothing about whether the gaps are real, so each model is tested against the leader with a Diebold–Mariano test on squared-error loss — which takes the two models' errors on the same days, forms the difference series, and asks whether its mean is distinguishable from zero once autocorrelation is allowed for. It behaves like a t-statistic, so beyond about ±1.96 the ordering is real and inside it the two models are tied however different their RMSEs look. That turns "the roster converges" from an impression into a claim that can be checked — and it does not entirely survive.
| model | OOS RMSE | gap vs leader | DM t | p | verdict |
|---|---|---|---|---|---|
| Ridge | 0.3299 | — | — | — | leader |
| Elastic Net | 0.3306 | +0.0007 | 1.33 | 0.184 | not distinguishable |
| Lasso | 0.3307 | +0.0008 | 1.46 | 0.144 | not distinguishable |
| Gaussian process | 0.3327 | +0.0029 | 1.45 | 0.148 | not distinguishable |
| Random forest | 0.3362 | +0.0063 | 1.86 | 0.063 | not distinguishable |
| XGBoost | 0.3374 | +0.0075 | 1.99 | 0.046 | significantly worse |
| MLP (feature-fed) | 0.3381 | +0.0083 | 2.17 | 0.030 | significantly worse |
| SVR (RBF) | 0.3448 | +0.0149 | 3.58 | <0.001 | significantly worse |
| HAR-RV (classical) | 0.3462 | +0.0163 | 4.69 | <0.001 | significantly worse |
Four of the eight challengers are statistically indistinguishable from a plain ridge regression: the other two regularized linear models (elastic net, lasso), the Gaussian process at 0.3327, and the random forest. The other four are significantly worse, and one of them is the classical benchmark.
HAR-RV is not "matched but barely beaten" here — it loses by 0.0163 RMSE at . What beats it is not a neural network but three lines of regularized regression on better inputs. Complexity bought nothing: XGBoost, the SVR (support-vector regression with an RBF kernel) and the MLP (multilayer perceptron, a small feedforward neural network) all lose to that ridge significantly. The features did the work, and the simplest model in the roster was enough to collect it.
The LSTM and Transformer are reported outside the ranking, deliberately. They are trained on the raw 22-day sequence in the deep-learning examples, on those notebooks' own splits, so placing them in the same bar chart would imply a like-for-like comparison that was never run. HAR is fitted in both setups and bridges them: 0.3473 there against 0.3462 here, a difference of 0.0011. That gap is an order of magnitude smaller than the effects being discussed, which is what makes the comparison worth making at all. On those notebooks’ 688 test days the LSTM scores 0.3465 against HAR’s 0.3473 — a Diebold–Mariano statistic of −0.35, so statistically tied, and reached with 4,513 parameters against HAR’s four. The Transformer scores 0.3531, behind HAR. Neither, therefore, comes close to the ridge’s 0.3299: the sequence models tie or lose to the classical benchmark that this page’s ridge beats by 0.0163 at p < 0.001. The raw 22-day sequence does not contain what the engineered matrix contains.
Where the Validation Slogan Needs Narrowing
The validation section produces a corrective to its own slogan. Shuffled cross-validation is measurably optimistic — about 0.0085 RMSE, some 3% — but on this problem that is the small effect.
| the same XGBoost, scored four ways | RMSE |
|---|---|
| shuffled k-fold leaky | 0.2782 |
| purged + embargo strictest honest | 0.2867 |
| walk-forward honest | 0.3015 |
| temporal split honest | 0.3374 |
| spread among the three honest schemes | 0.0507 vs a leakage gap of 0.0085 |
The three honest schemes disagree with each other by roughly six times as much. They are honest in different ways and, crucially, they score different periods: a temporal split trains on the first 80% of the timeline and tests on the last 20%; walk-forward refits repeatedly on an expanding window and averages six successive out-of-sample stretches; purged and embargoed cross-validation tests on every period including the calm early years, deleting training rows whose label windows touch the test fold. Because volatility is far harder to forecast in some years than others, that choice of test period moves the number more than the choice of scheme does. With a one-day-ahead label there is almost nothing for purging to remove; purging earns its keep on multi-day labels, which is what the purged cross-validation example demonstrates in a setting where the truth is known by construction. Comparing RMSEs across validation schemes is meaningless unless they score the same period — a caveat worth more here than the leakage warning itself.
Uncertainty and Explanation
On uncertainty, three lessons converge. The Gaussian process returns a predictive distribution for free, but a fixed-noise GP is overconfident and covers 0.81 against a 90% target. Split-conformal drops the model-correctness assumption and does better at 0.84 — yet a volatility regime shift between the calm calibration window and the crisis test period still pushes it below nominal, because exchangeability is exactly what a non-stationary market breaks. On a genuinely exchangeable split it recovers to 0.88 — on 652 test points the standard error of an empirical coverage is 0.012, so that sits 1.9 standard errors below nominal — inside the noise, but not comfortably on target. The guarantee is sound; the assumption is what markets violate.
SHAP (SHapley Additive exPlanations, which splits each prediction into signed per-feature contributions that sum back to it) confirms the HAR persistence terms carry about half the total attribution — the model does rediscover what the classical model hard-codes. But it also puts the fractionally-differenced price second of eleven features, ahead of two of the three HAR components. That is the clearest evidence in the collection for the López de Prado feature transform, and it explains the ranking: HAR has no access to a price-level feature, and volatility history does not substitute for it.
Where this sits
The roster comes from Regularized & Kernel Learning, Trees and Ensembles and Neural Networks; the feature transform from Fractional Differentiation; the validation from Purged & Embargoed Cross-Validation; the interval from Conformal Prediction; and the attribution from Interpretability. The same volatility series is modelled classically in Realized Volatility and Recurrent Networks & LSTMs — both on different splits and losses, which is why their figures are not interchangeable with these.
Notebook
Downloads
References
- Corsi, F. (2009). A simple approximate long-memory model of realized volatility. Journal of Financial Econometrics 7(2), 174–196. — HAR-RV, the benchmark
- Diebold, F. X. & Mariano, R. S. (1995). Comparing predictive accuracy. Journal of Business & Economic Statistics 13(3), 253–263. — the test that decides which gaps are real
- Andersen, T. G. & Bollerslev, T. (1998). Answering the skeptics: yes, standard volatility models do provide accurate forecasts. International Economic Review 39(4), 885–905. — realized volatility as the target
- López de Prado, M. (2018). Advances in Financial Machine Learning. Wiley. — fractional differentiation, purging and embargo
- Lei, J. et al. (2018). Distribution-free predictive inference for regression. JASA 113(523), 1094–1111. — split conformal
- Lundberg, S. M. et al. (2020). From local explanations to global understanding with explainable AI for trees. Nature Machine Intelligence 2, 56–67. — TreeSHAP