The hidden lie inside every fundamental backtest
You design a quality-factor strategy on Indian equities. You backtest it on the last 14 years. The returns look great. Sharpe is comfortable. Drawdown is acceptable.
There's a good chance the backtest is wrong — not by a rounding error, but materially. The reason is almost certainly lookahead bias on the fundamental data, specifically on XBRL filings. The strategy is "trading" on quarterly results that, in real life, had not yet been filed with the exchange on the simulated date.
This bug is invisible in the result table. There is no warning, no error, no obvious tell. It quietly inflates every return number, and the inflation grows the more your strategy depends on quarterly data.
What is lookahead bias on a quarterly result?
Lookahead bias means the backtest engine reads data on a date before that data was actually known in real life. For price data this is rarely a problem — yesterday's close was published yesterday. For fundamental data it is everywhere.
A typical Indian listed company's Q1 result (period ending June 30) is filed with the exchange somewhere between mid-July and mid-August — let's say 35 days after the quarter end on average. A naive backtest tool stores Q1 results indexed by the period_end date (June 30) and lets the strategy use it on or after July 1. That is lookahead bias of approximately 35 days.
The strategy "knew" the Q1 figures on July 1. In reality, no human investor or fund could have known them on July 1, because the company hadn't published them yet.
How XBRL filings actually work in India
Indian listed companies file quarterly results in XBRL (eXtensible Business Reporting Language) format with the stock exchanges under SEBI's LODR Regulations. The relevant timeline:
- Period end — the last day of the financial quarter (March 31, June 30, September 30, December 31).
- Board meeting / approval — the day the board approves the standalone or consolidated financials. Always after the period end. Typically 30-50 days later.
- Filing date / submission date — the date the company actually submits the XBRL filing to the exchange. Usually within 24-48 hours of board approval.
- Public availability — the date the filing becomes publicly readable on the exchange website. Usually the same day as the filing date.
Under SEBI rules, companies have 45 days from period end to file Q1, Q2, and Q3 results, and 60 days from period end to file Q4 (annual) results. Many companies file later than this and pay the late-filing penalty.
For a backtest to be unbiased, the strategy must only see a quarterly row on or after that filing date. Anything else is lookahead.
How much does this bias inflate returns?
The magnitude depends on the strategy's reliance on quarterly data. As a rough order of magnitude:
- Pure technical strategies (only price/volume): zero impact. Lookahead is not a problem.
- Annual-fundamentals strategies (only ratios refreshed once a year): small impact, ~0.3-0.8% CAGR inflation.
- Quarterly-fundamentals strategies (rebalanced monthly using latest quarterly results): meaningful impact, often 1.5-3.5% CAGR inflation on Indian universes.
- Earnings-surprise / momentum-on-fundamentals strategies: largest impact, sometimes 4-7% CAGR inflation, because the strategy explicitly trades the post-filing repricing.
Compounded over 10 years, a 2.5% CAGR inflation turns a strategy that genuinely returned 12% per year into one that looks like it returned 14.5%. That is the difference between a credible alpha story and a deceptive one.
Three subtle forms of XBRL lookahead bias
1. period_end as the data anchor
The most common form. Quarterly data is stored in the database keyed only by ISIN + period_end. The backtest filter is "give me all rows with period_end <= today." This silently includes filings that don't exist yet.
The fix is to also store filing_date (or submission_date) on every row and filter "period_end <= today AND filing_date <= today." The second condition is the one that matters.
2. Restatement bias
Companies sometimes refile a previous quarter's result with corrected numbers — usually within 60-90 days of the original filing. Most fundamental data providers store only the latest version of each row. A backtest reading those rows in 2018 actually sees the 2019-corrected version, not the version that was public in 2018.
This is harder to fix because it requires storing every historical version of every filing with the date each version became public. Most retail-grade backtest tools don't do this.
3. Late-filing companies
A subset of small-cap and mid-cap companies file 10-30 days after the SEBI deadline. If your data ingestion uses period_end + 45 days as a proxy for filing_date, those late filings get used 30 days early. The bias is small for any single company, but it concentrates in exactly the kinds of companies (small-caps, troubled firms) that drive a lot of factor-strategy performance.
Why most retail backtest tools have this bug
It is not malice — it is data engineering cost. To do it correctly you need to:
- Parse every XBRL filing from primary exchange feeds, not pre-cleaned data exports from a third-party vendor.
- Capture the broadcast/submission timestamp from the exchange announcement, not just the period_end inside the XBRL document.
- Store every quarterly row with both period_end and filing_date as separate fields.
- At backtest time, filter by filing_date for visibility but use period_end for fundamental ratio calculation.
- Handle the corner cases: missing filing dates (use submission_date or broadcast_date as fallback), restatements (store version history), and late filings (don't proxy with period_end + N days).
This is a non-trivial pipeline. Most retail tools skip it because their users don't ask, and the inflated returns make their platforms look more attractive in marketing.
How ftInvstr handles XBRL lookahead bias
ftInvstr's fundamental data pipeline parses Indian exchange XBRL filings directly and stores the broadcast/submission date alongside every quarterly row. Specifically:
- Bias-safe collections — every fundamental row carries an
available_from_datefield equal to the actual exchange broadcast/submission timestamp. The backtest engine reads only rows whereavailable_from_date <= simulated_date. - Filing-date-anchored joins — when the strategy expression refers to a fundamental field, the engine looks up the most recent row whose
available_from_dateis on or before the simulated date. If a company hasn't filed yet, the previous quarter's value is used (forward-fill from the previous filing). - Schema-version coverage — Indian XBRL schemas changed several times (2018, 2019, 2020, 2022, 2025). The parser handles all variants and recovers filing dates from older filings that lack a
submissionDatetag by falling back to the exchange broadcast timestamp or, in rare cases, period_end + 30 days as a last-resort proxy. - 80+ fundamental fields across P&L, balance sheet, cash flow, ratios, and shareholding — each tagged with its filing date so backtests can use any of them without leaking future data.
The result is that a quality-factor strategy on Indian equities, run on ftInvstr, returns numbers that reflect what an investor could have actually traded on each historical date — not the inflated version that ignores filing latency.
Five questions to ask any backtesting tool
Before trusting a backtest result on Indian equities, ask the platform:
- Do you store the actual filing date for every quarterly result, separately from period_end?
- When the backtest reads fundamental data on a simulated date, is it filtered by filing_date or by period_end?
- How do you handle restatements — do you keep version history, or only the latest values?
- For small-cap or late-filing companies, do you proxy filing_date as period_end + 45 days, or do you use the actual exchange timestamp?
- What is the typical lag between period_end and filing_date in your data, and is that lag visible to me as a user?
If the platform cannot answer the first two clearly, your backtest results from that platform are likely overstated.
Summary
Lookahead bias on Indian XBRL filings is one of the most common and most invisible sources of backtest inflation on fundamental strategies. It is caused by anchoring quarterly data to the period-end date instead of the date the filing actually became public. The typical inflation is 1.5-3.5% CAGR for quarterly-rebalanced strategies — enough to turn a mediocre strategy into one that looks publishable.
The fix is straightforward in concept (anchor every row to its filing_date) but expensive in data engineering (parse XBRL directly, capture broadcast timestamps, handle restatements and late filings). Few retail platforms do it correctly. ftInvstr was built specifically to do it correctly, because backtest results that rely on fundamental data are otherwise quietly fictional.
This article is for educational research review only and is not investment advice. ftInvstr is a research and backtesting platform, not a SEBI-registered investment adviser or research analyst.
Backtest fundamentals without lookahead bias
ftInvstr anchors every XBRL filing to the date it was actually submitted to the exchange. 80+ fundamental fields, point-in-time, no lookahead. Free to start, no credit card required. Educational research only.
Start free — no credit card needed