Backtesting & Walk-Forward Validation

Random cross-validation quietly trains on the future. This module covers the honest alternatives — walk-forward schemes, purging and embargoes for overlapping labels, and the multiple-testing arithmetic that makes most backtests too good to be true.

The most expensive mistake in financial machine learning isn’t a bad model — it’s a good-looking evaluation of a bad model. A model that fails honestly in validation costs you a few weeks. A model that passes a broken validation goes to production, books loans or takes positions for a year, and fails with money attached. This module is about the specific ways financial validation breaks, and the schemes that fix it.

Why the textbook method trains on the future

K-fold cross-validation — shuffle the data, split into folds, rotate the test fold — is correct when observations are exchangeable: when nothing about row 500 tells you it came “after” row 200. Financial data is the opposite of exchangeable. Time order carries regimes (Module 3’s whole subject), drifting relationships, and — in credit — outcome windows that stretch months into the future.

Shuffle that, and every fold trains on the future of its own test set. The model gets to learn 2025’s patterns and then be examined on 2024. Look at what the folds actually do:

Validation Scheme Visualizer

100 time-ordered observations, 5 folds. Green trains, red tests, grey is purged. The question for every scheme: does any green sit after red?

time → ■ train ■ test ■ purged
Train-after-test violations
Verdict

Select random k-fold and note the violation counter — then switch to expanding walk-forward and watch it go to zero. That counter is the entire argument of this module, made visual. Two distinct sins get mixed together in the k-fold case, and it’s worth separating them because they have different fixes:

  1. Regime leakage — training on later periods whose patterns (rate environment, competitive conditions, borrower mix) simply didn’t exist at the test date. The fix is chronology: walk-forward schemes.
  2. Label-overlap leakage — subtler and nastier. A credit label like “defaults within 12 months” (DS Module 2’s performance window) means an observation dated January contains information through the following January. A training row from November and a test row from December share most of an outcome window — same recession, same portfolio events. They are not independent, no matter how carefully you ordered them. The fix is surgical: purging (drop training observations whose label windows overlap the test set) plus an embargo (a further buffer after the test block, for serial correlation that outlives the window). Toggle it in the widget and watch the grey gap appear — that gap is the price of honesty, paid in training data.

The walk-forward family

All honest schemes share one property — training always precedes testing — and differ on one question: how much past do you keep?

Which to choose? For credit scoring: OOT for the headline, expanding walk-forward with purging for model selection, and a rolling variant as a regime-sensitivity probe. For anything resembling a trading signal: walk-forward only, and keep reading.

Backtest overfitting: the multiple-testing machine

There’s a second, entirely separate way to manufacture a beautiful backtest, and no split scheme prevents it: try enough things. Test 100 random, useless strategies against the same historical data and the best one will look excellent — at a 5% significance level, five of them clear the bar by construction. Every hyperparameter sweep, every feature set you tried and discarded, every “let’s just check one more variant” is a draw from this lottery, and the final reported backtest silently conditions on having won it.

This is why the field developed a dark statistic: the probability of backtest overfitting, deflated Sharpe ratios, and the rule of thumb that a backtested Sharpe should be mentally halved before believing it. You don’t need the full machinery to act on the insight:

Vintage analysis: credit’s native backtest

Credit has its own time-honest evaluation format worth knowing by name. A vintage is a cohort of loans booked in the same period; vintage analysis tracks each cohort’s cumulative default (or loss) curve by months-on-book, then compares curves across vintages. It answers the questions walk-forward metrics compress: Is the 2025-Q3 vintage tracking worse than 2024-Q3 at the same age? Did the new scorecard actually improve the vintages booked under it? Is deterioration coming from underwriting drift or the macro environment (all vintages bending together)? A model can hold its Gini while vintages deteriorate — ranking survives, calibration dies (Module 4’s distinction, in time-series form). Plot both.

Where this connects

Try it yourself

The notebook below quantifies every claim: a drifting synthetic credit panel where random k-fold overstates AUC versus purged walk-forward (the gap is the leakage, measured); the purge/embargo implementation from scratch with the label-overlap counter; the multiple-testing lottery — 200 noise strategies, the winner’s deflated glory, and the honest correction; and a vintage-curve builder that shows a stable-Gini model failing on calibration vintage by vintage. The final exercise hands you a broken published-style backtest and asks you to find all four things wrong with it. (There are five.)

Backtesting & Validation Lab (Jupyter notebook)
Free download — no signup required.
Download

Get new posts by email

One email per new article. No spam, no upsells, unsubscribe anytime.