Quant Terminal
D4-01D4·intermediate·~20 min

Backtesting — first principles and how to fool yourself

backtestingmethodologyoverfitlook-ahead-biassurvivorship-bias

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

You backtest a strategy on SPY from 2010–2024 and get Sharpe 1.5. Which is the most likely explanation?

The fundamental problem

A backtest — a simulation of how a strategy would have performed on past data — is the core research tool of quant trading. It is easy to write a backtest that earns 30% per year. It is extremely hard to write one whose conclusions match what would happen with real money.

The gap between a backtest and reality is closed by being relentlessly honest about every place the backtest could lie.

The Big Six failure modes

1. Look-ahead bias

Look-ahead bias — using information in the simulation that you could not actually have had at the moment the trade was placed. It is the single most common backtest bug. Examples:

The fix: lag every signal by one period — delay it, so the trade happens strictly after the data that triggered it. Say the signal is "buy when the 20-day MA crosses above the 50-day MA" (MA — moving average, the average of the last N closing prices). Then the trade must execute at the next day's open, using yesterday's MA values.

2. Survivorship bias

Survivorship bias — testing only on companies that survived to today, so the failures silently vanish from your data. Backtest on the current S&P 500 member list and you only get stocks that made it. Lehman Brothers, WaMu, Enron — gone from the dataset. A "buy everything in the S&P 500" strategy backtested with current constituents (the stocks in the index now) systematically excludes the failures.

The fix: use a point-in-time index constituent dataset — one that records which stocks were in the index on each historical date, including companies that later died. Bloomberg and CRSP have this; affordable paid options include Norgate Data and Nasdaq Data Link (formerly Quandl). There is no good free point-in-time source — with free yfinance data you're limited to currently-listed stocks, and your results are biased. Know this limitation and be conservative in interpreting results.

3. Optimistic transaction costs

Most retail backtests assume zero or laughably low trading costs. Costs are quoted in bps (basis points — 1 bp = 0.01%, so 10 bps means one tenth of one percent). Real costs for retail:

Now the arithmetic. Say a strategy turns over 5× per year — meaning it replaces its entire portfolio five times a year — and pays an 8 bps round-trip cost (a round trip is one buy plus the matching sell). It loses 40 bps/year to costs alone. Many "edges" don't survive.

4. Parameter overfitting

Parameter overfitting — tuning your strategy's settings until they fit the random noise of the past instead of a real, repeatable pattern. This is the most common quant-trading sin. You try 50 lookback windows, 20 entry thresholds, and 10 exit rules. You find the combination that produces the best historical Sharpe and declare it the winner. You haven't found an edge; you've found the best of 10,000 noise patterns.

The deflated Sharpe ratio (Bailey & López de Prado 2014) — a Sharpe ratio marked down for how many combinations you tried — corrects for this. The cleanest workaround: choose parameters from theory or prior literature, not optimization, and test only that one final set of parameter values.

5. Multiple testing

Multiple testing — running many separate experiments and reporting only the winner. You backtest 100 strategies. By chance alone, ~5 will have p < 0.05 (read: a p-value below 0.05 — a result that pure luck would produce less than 5% of the time in any single test. Run 100 tests and luck hands you about 5 of them for free). You report the best.

This is the same disease as parameter overfitting, and often worse. The strategies look superficially different, so the multiplicity — how many things you actually tried — hides in the number of ideas tested, not in the parameters within one idea.

The fix: keep a written log of every strategy idea tested. At the end, apply a multiple-testing correction — Bonferroni (demand a p-value threshold divided by the number of tests), FDR (false discovery rate control, which caps the share of reported wins that are flukes), or the DSR from above. The pruned best-of-100 is dramatically less impressive than the unadjusted best.

6. Backtest contamination from current information

This one's subtle. Your backtest period ends today. You set up the strategy today, with full knowledge of what happened in the last 15 years. So your very choice of which strategy to test is already shaped by knowing which strategies worked.

The fix is walk-forward analysis — re-fitting the strategy periodically on rolling windows, described next — plus a true out-of-sample period: a stretch of data you never look at while designing, and don't peek at until you're committed.

Walk-forward analysis

The right way to evaluate a strategy that needs any parameter tuning:

  1. Split history into rolling windows (e.g., 3 years training, 1 year test).
  2. Fit / tune parameters on the training window.
  3. Apply those exact parameters to the test window.
  4. Roll forward.
  5. Concatenate test-window returns. This is your honest performance.

Important: the test windows must be non-overlapping with the training data. López de Prado's "purged" CV (cross-validation) goes further: it adds a time buffer between the training and test windows. The buffer matters because returns are autocorrelated — correlated with their own recent past — so data right at the boundary can leak information across it.

The honest checklist

Before you trust any backtest, ask:

A backtest that passes all of these is worth taking seriously. A backtest that fails any one is suspect. A backtest that fails three is probably noise.

We'll cover each correction technique in detail in the rest of Track D4.

Try it

See look-ahead bias with your own hands. The signal array below "predicts" the returns perfectly when the two arrays line up — the signal is 1 on every positive-return day. Multiply signals by returns with no shift, sum them up, and you get a fantastic +0.08. But in real life, yesterday's signal trades into today's return. Shifted honestly, the same signal earns −0.02:

▮ EXERCISE · d4-01-ex1

Implement honest_pnl(signals, returns): the P&L of trading yesterday's signal into today's return — the sum of signals[:-1] * returns[1:]. This one-period lag is the fix for look-ahead bias; the biased version np.sum(signals * returns) uses information you couldn't have had at trade time.

⧉ Review card
What is look-ahead bias?
Using information in a backtest that wouldn't have been available at decision time. Fix: lag every signal by at least one period relative to the returns it predicts.
⧉ Review card
What is survivorship bias?
Backtesting only on currently-listed stocks excludes companies that went bankrupt or got delisted. The historical average performance is biased upward.
⧉ Review card
What is the deflated Sharpe ratio (DSR)?
A correction to Sharpe that accounts for the number of trials tested, variance of Sharpe across trials, and higher moments. Penalizes the 'best of many' backtest result. (Bailey & López de Prado, 2014)
⧉ Review card
What is walk-forward analysis?
Split history into rolling train/test windows. Fit parameters on train, apply unchanged to non-overlapping test. Concatenate test returns. Avoids the parameter-tuning-on-the-same-data problem.
⧉ Review card
What's a realistic round-trip transaction cost for liquid US large-cap equities?
~5–10 bps total (spread + slippage). For small-caps, 30–100 bps. For crypto, 10–50 bps depending on venue. A strategy turning over 5x/year at 8 bps loses 40 bps annually to costs.

Predict before the next lesson

Tomorrow we start linear regression (A2-06) — the workhorse of factor analysis. Predict:

◈ Calibration check

Could you list at least 4 of the Big Six backtest failure modes from memory?

1 = guessing · 5 = could teach it

⏻ End of lesson

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

Sources & further reading