Calculation cadence

Strategies

Calculation cadence

Decide how often OnBar fires — once per closed bar, on every price change, or on every tick — and tell a close from an intra-bar update when it matters.

Calculation cadence

The Calculate property controls how often your OnBar logic runs. Set it in OnInitialize. It mirrors an indicator's Calculate exactly — same enum, same three modes, same default — so you reason about strategy cadence the way you already do for indicators. The default, OnBarClose, fires once per completed bar and is what most strategies want: cheaper, deterministic, and free of noise from a bar that has not finished forming.

Mode When OnBar fires
CalculationMode.OnBarClose (default) Once per closed bar — today's behaviour.
CalculationMode.OnPriceChange Additionally, intra-bar whenever the developing bar's close moves.
CalculationMode.OnEachTick On every intra-bar tick.
C#protected override void OnInitialize()
{
    Calculate = CalculationMode.OnEachTick;
}

The closing OnBar for a bar always fires exactly once regardless of mode — an intra-bar mode never gives you fewer callbacks than OnBarClose, only more. So a strategy written for OnBarClose still gets its per-close callback under tick cadence.

Telling a close from an intra-bar update

Under OnPriceChange / OnEachTick the same OnBar hook fires both inside the forming bar and at its close, and CurrentBar is the still-developing bar during an intra-bar call. Two flags resolve which callback you are in:

  • IsBarClosed — true on a closed-bar callback (always true under OnBarClose), false during an intra-bar update. Gate once-per-bar work on it.
  • IsFirstTickOfBar — true on the first intra-bar tick of a freshly-opened bar (the moment it opened); always false on a closed-bar callback. Run "new bar opened" logic once with it.
C#protected override void OnBar()
{
    if (IsFirstTickOfBar) { /* a new bar just opened */ }

    // intra-bar: react to the developing close
    if (!IsBarClosed) { TightenStopIfNeeded(CurrentBar.Close); return; }

    // closed bar: the once-per-bar entry logic
    EvaluateSignal();
}
Backtest fidelity. Intra-bar cadence needs the data feed to supply intra-bar ticks — the backtester produces them from its replay resolution, a live feed from its tick stream (the runtime feature-detects an IIntrabarStrategyDataFeed). On a feed without intra-bar data the strategy still receives the closing OnBar, so it never silently breaks — it just runs at close cadence.
Default first. Leave Calculate at OnBarClose unless a specific entry or exit truly cannot wait for the bar to close — it keeps backtests fast and results reproducible. (Note: an attached ATM advances break-even and trailing strictly per closed bar, independent of your cadence.)