quantverse.
Quantverse Research · updated 2026-09-22

Look-ahead bias in quantitative trading: six mechanisms and their fixes

Look-ahead bias is information a backtest uses before it existed. Six ways it leaks in, the timing mistakes that survive data-quality checks, and how purging and embargo work.

Look-ahead bias in quantitative trading is the use of information at decision time that was not available at decision time. It is not one mistake but a family of six: survivorship, restatement, revision, timestamp, feature-window and label leakage. All six produce the same symptom: research performance that live trading does not reproduce. The first three are fixed in the data store; the last three survive a clean data store and have to be fixed in how the backtest is assembled.

1. Survivorship leakage

The universe is chosen with hindsight. A 2010 screening universe built from the companies listed in 2026 has already removed everything that went bankrupt, was acquired or was delisted in between, so a long-only strategy is scored on names pre-filtered by their own future. A related defect is the missing delisting return: when a company stops trading, its final and often large negative return is absent rather than recorded. Both mechanisms are on the survivorship bias and delisted stocks pages.

2. Restatement leakage

A restatement publishes a new value for a period that already had one. If the database keeps a single row per period, the corrected value is what the backtest reads for the whole history. The direction matters stock by stock. A company whose earnings are later restated downward looks more expensive in the backtest than it looked at the time, because lower earnings at the same price mean a lower earnings yield, so a value screen that would have bought it skips it. The append-only versioning that fixes this is on the point-in-time data page.

3. Revision leakage

A revision is a routine update rather than a correction. Jobless claims, GDP, retail sales and inflation are published and then revised for months afterwards, and the latest figure is not the figure anyone saw at the time. The test is the same as for restatements: can the store return the version of the number that existed on a given date?

4. Timestamp leakage

This one survives data-quality checks because the data is not wrong. A daily bar labelled 2021-06-01 contains that day's closing price, which printed at 16:00 New York time. A backtest that computes a signal from that bar and trades at 09:30 on the same date is acting six and a half hours before the bar existed. Four patterns recur.

What the backtest assumesWhat it actually usedVerdict
signal from the close of day D, trade at the open of day Da price printed at 16:00look-ahead
signal from the close of day D, trade at the open of day D+1a completed barvalid
signal from the day's high and low, trade during the same daythe full day's rangelook-ahead
signal from the 09:30 one-minute bar, trade at 09:31a completed barvalid, if the bar had arrived

Two more variants. Bars timestamped at the start of their interval rather than the end, so a bar labelled 09:30 contains prices from 09:31. And publication lag treated as a constant: a fixed 45 days after quarter end leaks whenever the filing arrived later, and smaller companies can legally file annual reports 90 days after year end.

5. Feature-window leakage

Future values enter through calculations as often as through raw data. Scaling a feature by the mean and standard deviation of the whole sample expresses every historical value in units of a distribution that did not exist yet. Any transform fitted once over the whole panel, such as principal components, leaks the same way. So does a cross-sectional rank computed over today's universe rather than the universe of the day. The fix: fit every transform on the training window only, re-fit it at each step forward, and compute cross-sectional statistics from the companies that existed at decision time.

6. Label leakage

A label is the thing a model is trained to predict. When labels span a horizon, folds that look separated by date are not separated in information. A label defined as "the sign of the return over the next 10 trading days" for date t depends on prices up to t+10. Split the sample at 2021-01-01 and the last ten training observations of 2020 have labels that resolve inside the test period.

Purging and embargo

A fold is one train-then-test split of the sample. Two repairs apply at its boundary, and which you need depends on the design.

Purging removes training rows whose label intervals overlap any test label's interval. Every label, in the test set as well as the training set, has an interval from its decision date to the date its outcome was known: a test decision on June 30 with a ten-day label is not resolved until mid-July. A training row is dropped if its interval overlaps any test row's interval, whether it sits before the test block or after it. A calendar cut at the block's edges misses the test labels that resolve after the block ends.

Embargo applies when training data also lies after the test block, as in cross-validation. Features built from trailing windows in the days after the block still contain test-period prices, so a gap is left before training resumes, counted by convention from the last test decision date and applied on top of purging. López de Prado, Advances in Financial Machine Learning (2018), chapter 7, suggests about 1% of the sample as a starting heuristic; matching the longest feature lookback is another. Neither is a guarantee, because serial dependence can outlast both.

In walk-forward validation every training row predates the test block, so there is nothing to embargo; purging is still required.

A worked example

Setting: US equities, the feature is 20-day price momentum, the label is the sign of the 10-day forward return, walk-forward validation with folds split by calendar half-year. Figures are invented to illustrate the mechanics, not to measure how much leakage was removed.

Under a naive split, training runs through 2020-12-31 and the test block is 2021-01-01 to 2021-06-30. The ten training dates from 2020-12-17 to 2020-12-31 carry labels that resolve in January 2021, inside the test block. Purging drops them, so the last usable training date is 2020-12-16. Were this cross-validation, with training resuming after the block, two rules apply on the right. Label overlap first: the last test decision, 2021-06-30, has a label that resolves on 2021-07-15, so any training row whose own label interval overlaps a test label's interval is purged. Then the embargo, counted from the last test decision date: 20 trading days after 2021-06-30 runs through 2021-07-29, so training could resume on 2021-07-30.

Fold constructionHit rateSharpe ratio
naive walk-forward58.2%2.1
purged walk-forward52.4%1.3

The Sharpe ratio here is annualized from daily excess returns, meaning returns over a cash rate, assuming they are uncorrelated from day to day. The mean is multiplied by 252 and the standard deviation by the square root of 252, which comes to the daily ratio times the square root of 252. A daily mean of 0.1% with a standard deviation of 1% gives an annualized Sharpe of about 1.6. Purging removes the part of the measured edge that came from the test period. What remains no longer benefits from that particular leak; it can still be inflated by other biases, including the number of variants tried. Unchanged numbers after purging do not prove there was no leakage.

Where each fix belongs

Point-in-time data removes survivorship, restatement, revision and identifier leakage, provided the store's coverage is complete and every query and downstream step uses the as-of pin. Purging and embargo remove label leakage at the fold level. Timestamp and feature-window leakage survive both, because only the alignment is wrong. They are caught by writing the decision time on every row and refusing to read any fact whose availability time is later.

Two catalog entries are designed around this. The labels package, listed as coming soon, records the entry and exit timestamps each label assumed. The point-in-time screener, also coming soon, replays the universe and features as of the query date. Tiers are on the pricing page.

← back to learn