How much look-ahead bias is in your fundamentals backtest?
We measured it across about 5,285 US companies a month, 2012–2023, using nothing but SEC filings. The short answer: dating fundamentals by quarter end puts 13%–24% of companies in the wrong quintile. Restated numbers add much less than people expect. And the usual fix, a fixed reporting lag, still leaks.
Two different ways to see the future
A backtest that ranks stocks on fundamentals can use information before it existed in two ways:
- Timing. A quarter's numbers become public when the 10-Q or 10-K is filed, weeks after the quarter ends. Most free and many paid databases index fundamentals by fiscal period end, so a backtest that rebalances on March 31 can pick up first-quarter numbers that nobody saw until May.
- Restatements. Companies revise prior periods: accounting corrections, discontinued operations, spin-offs, mergers, stock splits. A current database shows the latest number for each period, not the number investors had at the time.
We measured both, separately and together, on Varve Fundamentals, which keeps each number as first filed, the filing date, and every later revision.
1. Timing: the numbers arrive 6 to 10 weeks late
Days from quarter end to filing, 2012–2023
229,021 quarterly reports and 74,279 annual reports.
The median 10-Q is filed 40 days after the quarter ends, and the median 10-K 70 days after the fiscal year ends. Large companies are faster and small companies slower, but almost nobody files in under a month. The tail matters too: 3.5% of 10-Qs and 16.7% of 10-Ks come in well after the deadlines, often because something went wrong.
2. Restatements: about 1 in 10 numbers changes later
| Field | Changed later | Changed by over 10% | Median size of change | Revised down | Median days until changed |
|---|---|---|---|---|---|
| Revenue | 10.7% | 4.6% | 6.8% | 71% | 490 |
| Net income | 10.1% | 4.7% | 7.5% | 54% | 482 |
| Operating income | 12.4% | 5.9% | 8.7% | 52% | 376 |
| Operating cash flow | 10.2% | 3.9% | 4.2% | 46% | 376 |
| Shareholders' equity | 17.9% | 5.9% | 2.8% | 29% | 459 |
| Total assets | 4.6% | 0.9% | 0.7% | 61% | 366 |
| Diluted EPS | 8.5% | 6.0% | 55.6% | 67% | 380 |
| Diluted shares | 8.6% | 6.3% | 91.7% | 59% | 367 |
Quarterly, annual and balance-sheet values for periods ending 2010–2022, as first filed vs. as in the latest filing that reports the same period. Rounding differences (4,843,000 vs 4,843,349) are not counted.
Roughly one in ten first-reported figures for revenue, net income or operating income differs from the number a current database shows for the same period, and over half of all companies have at least one. The changes are usually small (a median of 7.5% for net income) and arrive more than a year later.
Two patterns are worth knowing:
- Revenue is revised down 71% of the time. Most of these aren't accounting errors. When a company sells or spins off a business, it re-presents earlier years without it. ConocoPhillips reported 2011 revenue of $245 billion; after spinning off Phillips 66, its filings show 2011 revenue of $66 billion. Investors in 2012 saw the first number.
- EPS and share counts change by large amounts (median 56% and 92%) because of stock splits. A current database restates them to today's share basis. That's harmless in a ratio of two restated numbers, and a trap if you combine restated EPS with prices that aren't split-adjusted.
3. What it does to a strategy
To see the effect on a portfolio without needing prices, we ranked companies at every month end from January 2012 to December 2023 on four well-known signals built from SEC data alone: return on assets, gross profitability, accruals and asset growth, each from the latest four quarters. We built each ranking twice: once point-in-time (only filings public on that date, each number as known that day) and once with a common shortcut. Then we counted how many companies land in a different quintile.
Share of companies in a different quintile than point-in-time
Average of the four signals; the line shows the range across them.
Dating by quarter end does almost all the damage: on its own it moves 17% of companies on average, against 3.5% for restated numbers alone. Together they move 13%–24% of companies depending on the signal. Accruals and asset growth are hit hardest, with about a quarter of companies moving; return on assets and gross profitability least. Even then, one in ten of the top-quintile companies is a different company.
| Compared with point-in-time | Return on assets | Gross profitability | Accruals | Asset growth |
|---|---|---|---|---|
| Period-end dates + restated numbers | 13.5% · 89% | 13.6% · 92% | 24.1% · 78% | 24.4% · 82% |
| Period-end dates only | 12.3% · 90% | 11.1% · 93% | 22.2% · 80% | 24.2% · 82% |
| Restated numbers only | 2.9% · 98% | 5.3% · 98% | 5.1% · 95% | 0.9% · 99% |
| 45-day lag + restated numbers | 5.2% · 96% | 7.1% · 96% | 8.9% · 91% | 5.8% · 96% |
| 90-day lag + restated numbers | 8.1% · 93% | 9.2% · 95% | 14.8% · 87% | 13.1% · 91% |
Each cell: share of companies in a different quintile · share of the top quintile that is the same companies. Monthly rebalancing, Jan 2012–Dec 2023, about 5,285 companies per month.
4. The usual fix still leaks
Many backtests apply a fixed lag instead: assume each quarter is known 45 or 90 days after it ends. That helps a lot, but it's wrong in both directions. It's too slow for the companies that file early, and too fast for the ones that file late, which are disproportionately companies with problems.
| Dating rule | Uses a quarter not yet filed | Uses an older quarter than was available | Companies with nothing filed yet |
|---|---|---|---|
| Period-end dates + restated numbers | 61.6% | 0.0% | 11.0% |
| Period-end dates only | 61.6% | 0.0% | 10.9% |
| 45-day lag + restated numbers | 7.7% | 3.4% | 9.7% |
| 90-day lag + restated numbers | 3.7% | 28.9% | 8.9% |
With a 45-day lag, 7.7% of companies still get a quarter that hadn't been filed, mostly 10-Ks, which usually take longer than 45 days. With a 90-day lag that falls to 3.7%, the late filers, but 29% of companies are now ranked on stale numbers. Either way, the companies whose data is late are the ones most likely to be in trouble, so the leak isn't random noise.
Doing it right
Use the date each number became public, not the period it describes. With Varve Fundamentals, every value carries its filing date (filed, plus the exact accepted timestamp), the value as first filed and every later version:
import pandas as pd
f = pd.read_parquet("varve_fundamentals_facts.parquet",
columns=["cik", "field", "duration", "period_end", "value", "filed"])
ni = f[(f["field"] == "net_income") & (f["duration"] == "Q")]
# one row per company per month-end: the latest quarter FILED on or before that date
dates = pd.date_range("2015-01-31", "2023-12-31", freq="ME")
grid = pd.MultiIndex.from_product([ni["cik"].unique(), dates],
names=["cik", "date"]).to_frame(index=False)
pit = pd.merge_asof(grid.sort_values("date"), ni.sort_values("filed"),
left_on="date", right_on="filed", by="cik")
# `value` is the number as first filed. For "as known on that date" including
# restatements already public, use fact_versions: known_from <= date < known_to.
The same works with the free sample, which has the full history for 25 companies, including delisted ones.
Method and caveats
- Data: Varve Fundamentals release 0.1.1 built 2026-10-17, built from SEC's Financial Statement data sets. No price or vendor data was used.
- Point-in-time: for each company and date, the latest quarter whose four trailing quarters and balance sheet were all filed by that date; a restated number counts only if the restating filing was public by then.
- Universe: every company with the inputs available (total assets over $1 million); about 5,285 a month for return on assets. Gross profitability covers fewer companies because many don't report gross profit.
- What this doesn't measure: returns. Different quintiles mean a different portfolio, not necessarily a different return; how much the bias inflates a backtest depends on the strategy. Because late filers and restaters are disproportionately troubled companies, the bias tends to flatter strategies that avoid them.
- Reproduce it: the analysis is a short Python script over the Varve Fundamentals tables. We'll publish it with example notebooks.
Point-in-time fundamentals for every SEC filer since 2009
Varve Fundamentals keeps every number as first filed, with its filing timestamp and every later revision. Survivorship-bias-free from 2012.