Quant Terminal
D4-04D4·intermediate·~22 min

Walk-forward testing and out-of-sample discipline

backtestingwalk-forwardout-of-samplepurgingembargoholdout

▸ Pretest — guess, even if you don't know

You tune a strategy's lookback window to maximize Sharpe on 2010-2020 data, then report that same 2010-2020 Sharpe. What is the reported number?

In-sample vs out-of-sample

In-sample (IS) — the data you used to make any choice: parameters, features, even which strategy idea to keep. Out-of-sample (OOS) — data that influenced no decision at all. Only OOS performance estimates what happens next. Why? IS performance is contaminated by selection — you kept whatever looked good on that data, so of course it looks good on that data. The IS number measures your picking process, not the strategy.

The subtlety from D4-01's failure mode #6: "choices" include soft ones. If you glanced at the full history before designing the strategy, the design is partly in-sample everywhere — your eyes already tuned it.

The walk-forward loop

Walk-forward analysis — fit on one slice of history, test on the slice right after it, then slide both slices forward and repeat — manufactures a sequence of honest OOS windows:

  1. Take the first training window; fit/tune there.
  2. Apply those frozen parameters to the test window immediately after.
  3. Slide forward by one test-window length; refit; repeat.
  4. Concatenate all test-window returns. That concatenation is your OOS track record.

With 10 periods, train width 4, test width 2 (rolling) — capital T marks a training period, lowercase t a test period:

index:    0  1  2  3  4  5  6  7  8  9
split 1: [T  T  T  T][t  t]
split 2:       [T  T  T  T][t  t]
split 3:             [T  T  T  T][t  t]

Rolling windows (shown above) keep the training width fixed. Old data falls out the back, so the fit adapts when the market changes character — what traders call regime change, a shift in the market's persistent behavior. Anchored windows always start at index 0, so the training set grows with each split — more data, less adaptivity. Both are defensible. Pick one before looking at results, so the choice can't become one more thing you tuned.

Purging and the embargo

Adjacent train/test windows still leak — information from the test period seeps into training. Two reasons. First, returns are autocorrelated — nearby days are statistically related, so the last training days carry a whiff of the first test days. Second, labels often span several bars: a 5-day forward return computed on the last training day literally uses days inside the test window. López de Prado's fix has two parts. Purge — delete the training samples whose information overlaps the test window. Embargo — leave a buffer gap of a few bars after the test window before training data resumes. Without them, the test set quietly grades the training set's homework.

The one-shot rule

Beyond walk-forward, keep a final holdout — a reserved slice of data, typically the most recent year or two, that nothing touches until you are completely done. The rule: you get to open it once. Evaluate, then accept the verdict. Suppose you peek, dislike the result, tweak the strategy, and peek again. Now you have selected against the holdout — it has become training data, and A2-05's multiple-testing arithmetic applies to it. Touch it twice and it's contaminated.

Calibrate your expectations

Empirically, strategies that survive honest evaluation typically deliver OOS Sharpe around 30–70% of in-sample. Bailey and López de Prado's work on backtest overfitting shows this haircut — the shrinkage from backtest number to real-world number — is the norm, not the exception. Concretely: an in-sample Sharpe of 1.0 should make you plan for something like 0.3 to 0.7 live. And the final OOS test is one you can't simulate: paper trading — running the strategy with fake money in real time — and then live trading. Divergence from the backtest there is the market grading your methodology. If your plan requires the IS number to hold up, you don't have a plan.

Try it

The bookkeeping of walk-forward is index arithmetic — get it exactly right once. Pure Python is fine here; no numpy needed.

▮ EXERCISE · d4-04-ex1

Implement walk_forward_splits(n, train, test): return a list of (train_start, train_end, test_start, test_end) tuples with exclusive ends, rolling forward by the test size. Start train_start at 0 and keep going while a full test window still fits (train_start + train + test <= n).

⧉ Review card
What makes a data point out-of-sample?
It influenced no decision: not parameter tuning, not feature selection, not the choice of which strategy idea to keep. Any data that shaped a choice is in-sample, and performance on it is biased upward by selection.
⧉ Review card
Describe the walk-forward loop.
Fit parameters on a training window, apply them frozen to the test window right after, slide forward by the test width, repeat. Concatenated test-window returns are the honest track record. Rolling = fixed train width; anchored = train always starts at 0 and grows.
⧉ Review card
What are purging and embargo, and why are they needed?
Purging removes training samples whose information (e.g., multi-day forward returns) overlaps the test window; the embargo adds a buffer gap after the test window. Both stop leakage through autocorrelation between adjacent train and test data (López de Prado).
⧉ Review card
What is the one-shot rule for the final holdout?
You may evaluate on the held-out period exactly once. Peek, tweak, and peek again, and you have selected against the holdout — it is now training data, and multiple-testing bias applies to it.
⧉ Review card
How much in-sample Sharpe typically survives out of sample?
Roughly 30-70 percent, per Bailey and López de Prado's backtest-overfitting research. Budget for the haircut; the final OOS test is paper and then live trading.

Map the concepts

Your generative activity: draw a concept map connecting these eight nodes — in-sample, out-of-sample, walk-forward, rolling window, anchored window, purging, embargo, final holdout. Label each edge with the relationship (for example, "protects against leakage into"). Add one edge back to A2-05 multiple testing showing where its bias enters.

Predict before the next lesson

D4-05 quantifies selection bias. Predict:

◈ Calibration check

Could you set up a walk-forward evaluation, explain purging and embargo, and state the one-shot rule for a holdout?

1 = guessing · 5 = could teach it

⏻ End of lesson

Mark it read to book its 5 review cards into your deck.

Sources & further reading