Lookahead, and how trades are timed

A backtest cheats if a decision uses a price it could not have known. The exact timing rule our engine follows, and the one place hindsight still gets in.

On this page4 sections
  1. 1The timing rule
  2. 2Other ways lookahead gets in, and how each is handled
  3. 3The leak we cannot close
  4. 4Both engines agree

Lookahead is when a test makes a decision using information from after the decision. It is the easiest way to produce a backtest that looks excellent and means nothing.

The timing rule

  • Signals at a rebalance use closing prices up to and including the signal session, which is the last session of the week, month or quarter. Nothing later.
  • Trades fill at the next session's close.
  • The comparison fund is bought at the first fill and held.
One monthly rebalance
  1. Fri Jan 31, close: the signal session. Rankings are computed from prices up to this close.
  2. Mon Feb 3, close: the trades fill at this price.
  3. The move between the two closes is not credited to the picks.

Filling at the next close costs a little return compared with filling at the signal close. That is the point. You cannot trade at a close you needed in order to decide.

Other ways lookahead gets in, and how each is handled

LeakOur handling
Using restated financials as if known at the timeRules that read financials are not backtested at all.
Using a disclosure on its trade dateCongress and fund signals use the filing date, the first day the public could know.
Using a price for a day the stock did not tradeA stale price older than five sessions is not used to rank a stock.
Testing before a stock existedA stock joins the pool once it has enough history for the rule. Missing prices are never invented.

The leak we cannot close

The rules themselves were written today, by people who know how the last fifteen years went. Momentum, low volatility and trend filters are well-known because they worked. That is hindsight in the choice of rule, and no timing discipline removes it. The live record is the only test free of it.

Both engines agree

The same rules run in two implementations, one in Python for the published strategies and one in TypeScript for the backtester in the app. A shared fixture is checked by both test suites and the results must match to nine decimal places, so the number on a strategy page and the number you get yourself come from the same arithmetic.

Something here wrong or unclear? Tell us. Informational only, not investment advice.

After hours

That's a wrap.

17hrs23min08sec

Market opens Friday, Nov 13 at 9:30 AM ET