The Bug That Made Every Strategy One Bar Late

One constant shifted every backtest by one bar. Here is how Kestrel's store read bar end times wrong, and the three-line fix.

Hook

One Constant

One constant. Every backtest, shifted by one bar.

  • Every backtest shifted
  • One bar late

Mechanism

Start Is Stored

In Kestrel, store files save only the bar's start time. The end is computed when the bar is read.

  • Files hold start only
  • End computed on read

Bug

The Wrong Width

Before the fix, every bar was read with a one second width. A one minute bar claimed to end one second after it began.

  • Read width: 1 second
  • Real width: 60 seconds

Completion Waits

A strategy resampling minute bars waits until the clock passes the end. So it only saw a minute complete when the next minute arrived.

  • Resampler waits for end
  • Sees bar when next begins

One Bar Late

The result: every decision came one bar late.

  • Every decision delayed

Fix

storeBarWidth

The fix is a tiny function, simplified here. Fyers returns sixty seconds. Fyers five S returns five.

  • fyers: 60 s
  • fyers_5s: 5 s

Decision Moves Earlier

Now end equals start plus width. The minute completes on time, and the decision moves one bar earlier.

  • end = start + width
  • Minute completes on time

Payoff

Check Your Boundaries

Same data, same code, different answers. Check your time boundaries. Follow for more Kestrel.

  • Same data, same code
  • Different answers