◆ New — Strategy Validator, Code Fixer & Prop Compliance Checker are live. Try one free →
Home / Learn / Calculate.OnEachTick vs OnBarClose in NinjaScript
NinjaScript

Calculate.OnEachTick vs OnBarClose in NinjaScript

Calculate controls how often OnBarUpdate() runs: OnBarClose fires once when a bar closes, OnEachTick fires on every tick, and OnPriceChange fires once per price change. OnBarClose is stable and reproducible in backtests; OnEachTick is responsive but can repaint. This article is educational only and is not trading advice; it makes no claim about profitability.

What is the difference between Calculate.OnEachTick and OnBarClose?

Calculate sets how frequently NinjaTrader calls your OnBarUpdate() method. There are three modes. Calculate.OnBarClose calls OnBarUpdate() exactly once, when the current bar closes. Calculate.OnEachTick calls it on every incoming tick. Calculate.OnPriceChange calls it once each time the traded price changes — less often than every tick, more often than every bar.

The short version: OnBarClose trades responsiveness for stability, and OnEachTick trades stability for responsiveness. Under OnBarClose, Close[0] is always a settled, final value when your code reads it, so nothing can repaint. Under OnEachTick, Close[0] is the live, moving price of the developing bar, so anything you compute from it can change before the bar closes.

You set the mode in State.SetDefaults inside OnStateChange():

protected override void OnStateChange()
{
    if (State == State.SetDefaults)
    {
        Name = "MyStrategy";
        Calculate = Calculate.OnBarClose;
    }
}

Choosing the wrong mode is one of the most common reasons a NinjaScript strategy behaves differently live than in the [/ninjascript](/ninjascript) validator or the Strategy Analyzer.

What does each mode mean for when OnBarUpdate runs?

Under Calculate.OnBarClose, imagine a 5-minute chart. OnBarUpdate() runs at 10:05:00, 10:10:00, 10:15:00 — once per closed bar. When it runs, Close[0] is the final close of the bar that just completed. There is no intrabar activity to react to, and IsFirstTickOfBar is not meaningful because you are already operating one call per bar.

Under Calculate.OnEachTick, the same 5-minute bar might generate hundreds of OnBarUpdate() calls. Close[0] starts at the bar's open and moves with every trade until 10:05:00, when it freezes at the final close and the next bar begins. IsFirstTickOfBar is true only on that very first call of each new bar.

Under Calculate.OnPriceChange, OnBarUpdate() runs whenever the price prints a new value — so identical-price ticks are collapsed. It is a middle ground: more updates than per-bar, fewer than per-tick, useful when you want responsiveness without processing every duplicate-price tick. In all three modes, barsAgo indexing is identical: Close[0] is the current bar, Close[1] is one bar ago. What differs is only how settled Close[0] is at the moment your code runs.

What is the repaint and accuracy trade-off?

OnBarClose is reproducible. Because your code only ever reads settled bars, the Strategy Analyzer replaying closed-bar data produces the same decisions your live strategy makes. Backtest and live agree, and nothing repaints. The cost is latency: you cannot react until the bar closes, so a 5-minute strategy waits up to five minutes to act on a move.

OnEachTick is responsive but hazardous for entries. It sees every tick, so you can act the instant price moves — but if your entry logic reads the developing Close[0], it can fire and un-fire intrabar, and the default Strategy Analyzer (bar data, no Tick Replay) will not reproduce that churn. See [/learn/repainting](/learn/repainting) and [/learn/why-most-backtests-fail](/learn/why-most-backtests-fail) for why this produces optimistic, misleading test results.

There is a further subtlety worth knowing: fill assumptions. Under OnBarClose in the Analyzer, intrabar fills are estimated from OHLC, which can flatter stop/target sequencing. OnEachTick with Tick Replay models fills more granularly. Neither is a licence to trust a backtest blindly — validate first at [/ninjascript](/ninjascript). None of this implies any configuration produces profit; it only affects whether your test measures the same strategy you will run live.

When is each mode the correct choice?

Use Calculate.OnBarClose when your logic is inherently bar-based — moving-average crosses, closing-price breakouts, end-of-bar patterns. It gives you a strategy whose backtest and live behavior match, with no repaint to reason about. This is the safest default for anyone whose signals are defined on closed bars.

Use Calculate.OnEachTick when you genuinely need intrabar responsiveness: trailing stops that must react between bars, tick-level indicators, or execution logic that watches price continuously. The correct pattern is to keep the tick-level updates but gate the decisions to closed bars using IsFirstTickOfBar, so entries read Close[1] rather than the moving Close[0]:

protected override void OnBarUpdate()
{
    if (CurrentBar < 1) return;
    if (IsFirstTickOfBar)
    {
        // decision reads the just-closed bar
        if (Close[1] > Open[1])
            EnterLong();
    }
    // trailing-stop management can still run every tick here
}

Use Calculate.OnPriceChange when you want responsiveness but want to avoid processing duplicate-price ticks. Whichever you pick, confirm the live and backtest decision surfaces agree before trusting results. This is educational content, not trading advice, and asserts nothing about profitability.

Key takeaways

Educational only — not financial advice. Trading involves substantial risk of loss.

Catch the bug that compiles.Run auditGet Pro