Detecting Look-Ahead Baked Into Vendor Timestamps
Vendor data often carries a timestamp that says when a number describes, not when you actually could have known it — and the gap between the two is where a backtest quietly cheats without anyone writing a bug.
Prerequisites: Point-in-Time Data
A vendor sends a file of quarterly earnings-per-share numbers, each row stamped with the fiscal quarter it describes: "Q2 2019 EPS: $1.42." A researcher joins that file to prices on the last day of Q2, backtests a signal, and gets a strong result. The signal doesn't work live. The reason is almost always the same one: the fiscal-quarter date on the row is not the date the number became public. Companies report Q2 results four to eight weeks after the quarter ends. The backtest used a number on the day it describes, not the day the market actually saw it — and that gap, quietly, is where the edge came from.
The timestamp you were given is rarely the one you need
Vendor data typically ships with one or more of these dates on a row, and they are not interchangeable:
- The period the data describes — "Q2 2019," "the week of March 4th." This is almost never the right join key.
- The date the vendor received or processed it — closer, but can lag the true public release by hours or days, especially for anything requiring vendor cleanup (restatements, currency conversion, entity matching).
- The date the information was actually public — the filing timestamp, the press-release timestamp, the exchange announcement time. This is the one a backtest needs, and it is the one vendors document worst, because it's the least convenient for them to guarantee.
A field literally named "report_date" or "as_of_date" is not proof it's the third kind. The only way to know is to check.
How to actually check it
Pull a handful of individual filings and compare by hand. Take ten companies' Q1 earnings dates from the vendor file and cross-check against the actual 8-K or press-release timestamp from the company or the exchange. A consistent lag of even a few hours matters for anything traded intraday; a lag of days matters for almost everything.
Look for revisions without a corresponding new row. If a data point silently changes value in a later vendor pull without an accompanying revision timestamp, the vendor is serving you their current best estimate, not a point-in-time snapshot — and every historical backtest query is contaminated with information from the future by construction.
Check whether index membership or classification fields are "as of today" or "as of then." A common leak: a stock's sector or index-inclusion flag reflects its current classification, applied retroactively across the whole history. A stock that joined the S&P 500 in 2022 will show up as an S&P member in 2015 data pulls, silently erasing the survivorship and inclusion effects the backtest was supposed to capture.
Ask the vendor directly, and get it in writing. "What is the latency between an event occurring and this field being populated in your database, and does a later revision overwrite the historical value or append a new one?" A vendor that can't answer precisely, or answers with marketing language, is telling you the answer is probably worse than you'd hope.
A vendor field's name is a claim, not a fact. Before trusting "report_date," "as_of," or "effective_date" in any backtest, verify against a handful of primary sources by hand — the gap between "what a number describes" and "when the market could have known it" is the single most common source of a backtest result that evaporates in live trading.
A concrete case
A desk builds a signal on analyst estimate revisions, using a vendor's "estimate_date" field. It backtests well — IC of 0.05, clean and stable across ten years. Before shipping it, a researcher pulls twenty individual analyst notes from a separate data source and compares timestamps. The vendor's "estimate_date" turns out to be the date the estimate was effective as of, not the date the analyst actually published it — analysts often backdate estimates to align with a fiscal period, and the vendor faithfully preserved that backdating instead of recording publication time. The true publication lag averages four trading days. Re-running the backtest with a four-day lag added drops the IC to 0.01 — statistically indistinguishable from noise. The original 0.05 was not a signal; it was four days of look-ahead, dressed up as one.
The most dangerous look-ahead is the kind that survives a naive out-of-sample test. Because the timestamp bug is baked into the whole history uniformly, a train/test split on the same contaminated data won't catch it — both halves cheat the same way. Only an external, independently-timestamped check catches it.
Related concepts
Practice in interviews
Further reading
- Isichenko, Quantitative Portfolio Management (ch. 2, data hygiene)
- Bailey, López de Prado et al., The Probability of Backtest Overfitting