Look-ahead bias is when a backtest lets a trading decision use information that didn't exist yet at the moment the decision was made. A rule that buys at a candle's open because that candle will close higher, an indicator scaled with statistics from the whole history, a list of markets chosen because they survived: each lets the past see the future, and each makes the backtest look better than any live account running the same rules could have been.
You don't find it by staring at the equity curve. You find it by tracing every input back to the time it became known.
What is look-ahead bias in backtesting?
Every backtest makes thousands of small decisions on historical data. For each one, the rule is the same:
At the moment of decision, the strategy may only know what would have been known at that moment.
Look-ahead bias is any break of that rule. Machine-learning people call the general version data leakage. scikit-learn's guide (checked 2026-10-11) defines it as information "that would not be available at prediction time" being used to build the model, which "results in overly optimistic performance estimates".
It rarely looks like a bug. It looks like success: a smooth curve, small drawdowns, a high win rate, no ugly stretch where the strategy gets stuck. That's why the check has to be about timestamps, not results.
Two things it isn't:
- Overfitting. Overfitting is a search problem: try enough rule versions and one fits the noise. Look-ahead bias can sit inside a single, untuned test. Our AI backtest overfitting audit covers the search side.
- A live/backtest gap by itself. A gap can come from costs, fills, code differences or a different market. Look-ahead bias is one possible cause, and the backtest vs live comparison lists the others.
Where does look-ahead bias hide?
Check these five places first. Between them they cover the common ways a retail backtest, and code written by AI assistants in particular, gets to see the future.
| Leak | What the backtest does | How to check |
|---|---|---|
| Same-bar entry | decides and fills using a candle's final values before that candle closed | find the entry line; note which bar each value comes from and when the order fills |
| Repainting | trades signals plotted on candles they were only confirmed after | compare live markers with the reloaded chart; read how the indicator is calculated |
| Full-sample normalisation | scales, ranks or trains with statistics from the whole dataset | find every mean, standard deviation, min/max, rank or model fit, and the data window it uses |
| Survivorship and selection | tests only markets, symbols or periods picked with hindsight | ask how the universe and the test window were chosen, and when |
| LLM training-window leakage | asks a language model to judge events it may have read about afterwards | compare the model's training cutoff with the test period |
Each gets its own section below.
Is same-bar entry look-ahead bias?
It is when the decision needs a value that didn't exist yet. A rule that reads a candle's final close or high must wait for that candle to finish. If the backtest decides at the candle's open, or fills at a price from earlier in the candle whose close produced the signal, it has used the future.
// LEAK: at the open of bar N, read bar N's final close
if (finalClose[N] > band[N])
buyAtOpen(N);
// CAUSAL: after bar N closes, evaluate it, then trade the next tick
if (closedBar[N].close > band[N])
submitForNextAvailableTick();
Reading a forming candle isn't automatically a leak. A live intrabar system can use the ticks that have actually arrived. The question is always what was known, when the order was sent and when it could fill.
Platforms number bars differently, so check the convention before changing an index. In MT5 the timeseries docs (checked 2026-10-11) say index 0 "denotes data of the current bar", the one for "the unfinished time interval". An EA that reads the close at index 0 and treats it as final is reading a number that is still moving.
TradingView's strategy engine is explicit about fills. Its docs (checked 2026-10-11) say the earliest default fill is "on the next available tick", and that the optional process_orders_on_close setting lets orders created on a bar's close fill on that same tick, which "is typically unrealistic in real-world trading". The same page warns that letting some strategies recalculate after order fills "can cause lookahead bias on historical bars".
Do repainting indicators cause look-ahead bias?
Some do. TradingView defines repainting (checked 2026-10-11) as historical and realtime calculations or plots behaving differently, and sorts it into kinds:
- Often acceptable: a value that updates while its candle is still open.
- Misleading: scripts that plot into the past. Pivot scripts, the docs say, "go back in the past to plot pivot levels or values on the actual pivot". The display looks perfect, but the pivot was only known several candles later.
- Unacceptable: scripts that leak future information into the past. The docs' example is
request.security()with lookahead turned on and no[1]offset, which "will return data from the future on historical bars".
A backtest that trades the misleading or unacceptable kind is trading signals nobody could have seen in time. The test is simple: once a candle closes, does its signal stay where it is? Our repaint audit walks through it in twenty minutes, no code needed.
How does normalising the whole dataset leak the future?
Any statistic computed over the full history carries information from every bar in it. Scale an indicator by the mean and standard deviation of the whole test period, and each early bar's value now depends a little on bars that came years later. Rank markets by their full-period volatility, fit a model on all the data and then "test" inside the same period: same problem.
scikit-learn's rule is short: transformations must be learnt "only from the training data", and "the average should be the average of the train subset, not the average of all the data". Its page shows how big the effect can be. In a toy example with random targets, where honest accuracy is about 0.5, selecting features on the full dataset before splitting gave a test accuracy of 0.76. That's non-trading evidence, but the mechanism is the same in a backtest.
The fix is to compute every statistic from past data only, on a rolling or expanding window, and apply it forward.
Is survivorship bias a form of look-ahead bias?
Yes: it's the same leak, moved from the code to the choice of what to test. A stock strategy tested only on today's index members never meets the companies that were delisted or went bust, because they're no longer in the list. "Buy the dip" looks heroic when every name in the sample recovered.
Forex and gold traders meet it in a quieter form: picking the symbol, timeframe or start date after seeing which one worked. If you chose gold because gold trended, the test already knows the answer.
The fix is to test the universe as it existed at each date, delistings included, and to write down the symbol list and the test window before the first run.
Can an LLM leak the future into a backtest?
Yes, and without any future column in the data. If you ask a language model to score historical headlines, and the model was trained on text written after those events, it may already know how the story ended.
Two papers show how researchers approach it:
- Glasserman and Lin (2023) (checked 2026-10-11) tested GPT-based sentiment strategies on headlines with and without company names. Inside the model's training window, the anonymised headlines did better. The authors read that as a "distraction effect", the model's general knowledge of a company getting in the way, mattering more than look-ahead bias, especially for large companies. Out of sample, they found look-ahead bias was not a concern, though distraction could still occur. The leak is worth testing for; how much it matters depends on the setup.
- Li, Wang and Ma (2026) (checked 2026-10-11) name it "parametric look-ahead bias": the model carries memorised outcomes in its weights. They propose a correction that damps what the model remembers, and report that across five 7–14B models and five mega-cap stocks, "the largest model-level mean in-sample return correction is -67.1%". On their reading, part of that in-sample performance was memory, not skill.
Practical rule: treat any LLM result inside the model's training window as in-sample. Test on data after the model's training cutoff, or remove names and dates from the text, as Glasserman and Lin did.
How do you test for look-ahead bias? The one-bar shift test
Start with the trace, because it's the only step that can prove a leak:
- Find the line that fires each entry and exit.
- For every value it reads, write down the bar it comes from and when that value became final.
- Write down when the order is sent and when the backtest fills it.
- List every statistic, model fit and symbol choice, and the data window each one used.
Then run the one-bar shift test: delay every signal by one full bar, keep costs and everything else the same, and re-run.
Read the result as a sensitivity check, not a verdict:
| What happens after the shift | What it can mean |
|---|---|
| Results collapse | A leak that the delay removed, or a real signal whose opportunity lasts less than a bar, or changed fills. Go back to the trace. |
| Results barely change | Not a clean bill of health. A full-sample statistic, a survivors-only universe or LLM memory survives any delay. |
| Results improve | Also worth tracing: fills, costs or an indexing bug may have changed. |
Two illustrative code paths, not measured results, show why. A rule that reads a bar's final high at that bar's open is a leak, whatever the shift test says. A rule that uses only the completed bar and fills on the next tick is causal, yet it can still collapse when delayed if the move it trades lasts a few minutes.
After the audit, keep a later stretch of data you never touched while building, freeze the rules and test once. Walk-forward testing repeats that across several windows. Then judge the result with the sample-size arithmetic in how many trades you need to test a strategy.
How do you stop AI-written code from looking ahead?
Language models write code that compiles and resembles their training examples. Nothing makes them track what was knowable when, unless you ask. So put causality in the request, and make the model account for every data access. A condensed version of the contract we use for bar-close strategies:
Hard rules for this strategy code:
1. A decision on bar N uses only data final at the close of bar N-1
or earlier. Never the forming bar's close, high, low or indicator value.
2. Signals are computed on the last closed bar; fills happen at the
next bar's open or under an explicitly modelled rule.
3. Indicator values used for signals never change after their bar closes.
4. Every mean, standard deviation, rank, scale or model is fit on past
data only and applied forward. Nothing uses the full dataset.
5. Spread, commission and slippage are inputs with non-zero defaults.
6. The symbol list and test window are fixed before the test.
7. After the code, list every line that reads price, indicator or
feature data: which bar it reads and why that value was known.
8. Include a one-bar signal delay switch, and report the difference.
A delay failure alone is not proof of look-ahead.
Rule 7 matters most: making the model explain each data access puts every line that could leak in front of you, where you can check it. Intrabar strategies need a separate tick-by-tick contract. Our guide to building a trading system with AI covers the rest of the workflow, including keeping out-of-sample data away from the model.
Disclosure
We sell trading tools with full source code, which is how we'd want any system audited: you can't trace a leak in code you can't read. That doesn't make our code leak-free or profitable, and nothing on this page is financial advice. A backtest that passes every check above is still only a test of the past under stated assumptions.
Frequently asked questions
What is look-ahead bias in simple terms?
A backtest lets a past decision use information that wasn't available at that moment: a candle's final close, an indicator value fixed later, a statistic computed over the whole history, or a list of markets chosen because they survived. The test then looks better than any live account running the same rules could have been.
Is look-ahead bias the same as overfitting?
No. Overfitting is tuning rules to noise, usually by trying many versions and keeping the best. Look-ahead bias is using information from the future, even in a single untuned test. Both make a backtest look better than live trading, and one backtest can have both.
Does a repainting indicator mean the backtest has look-ahead bias?
Not always. A value that updates while its candle is still forming is normal. It becomes a leak when a signal plotted on a past candle relied on candles that came after it, or when higher-timeframe data is requested so that a finished bar's value appears before that bar closed.
How do you test a backtest for look-ahead bias?
Trace every input the entry rule reads back to the time it became known, and check when the order could have been sent and filled. Then delay every signal by one bar as a sensitivity check. A big change tells you where to look; it doesn't prove a leak.
If results collapse after a one-bar delay, is that proof of look-ahead bias?
No. A causal signal whose opportunity lasts less than a bar can also collapse when delayed, and a leaking strategy can survive a delay if its leak is somewhere else, such as a full-sample statistic or a survivors-only symbol list. The proof is an input that wasn't available at its timestamp.
Can ChatGPT or another LLM cause look-ahead bias?
Yes, in two ways. AI-written code can read the forming bar or fit statistics on the whole dataset. And a model asked to judge historical news may have been trained on text from after those events, so it can carry the outcome in its weights. Researchers call the second one parametric look-ahead bias.



