Why Pine Strategies Change After Reload: Historical vs Realtime Execution and Rollback
A Pine strategy processes confirmed historical bars in sequence and, by default, calculates a realtime bar at its close. With `calc_on_every_tick`, it can execute on each open-bar update, but most temporary state is rolled back before the next update and the underlying intrabar ticks are not retained when the script reloads over historical data. Orders or plots observed live can therefore change after reload. This guide focuses on the runtime state machine—execution, rollback, commit and reload—rather than repeating a general repainting glossary.
Who this guide is for: Pine users whose strategy markers change after reload, developers using calc_on_every_tick or varip, and traders separating a historical backtest from forward observation
Key points to understand first
- Historical bars contain confirmed data, while high, low, close and other values evolve on an open realtime bar.
- Rollback restores ordinary temporary state to the last commit before recalculating the open bar on the latest update.
- varip and order events have important exceptions, yet their intrabar information cannot be reproduced identically from historical OHLC.
- calc_on_every_tick, calc_on_order_fills and process_orders_on_close define separate execution or fill contracts and should be changed one at a time.
- Keep a bar-close backtest and timestamped forward log as separate evidence sets because they have different event granularity.
An open bar’s temporary state is not final until close
- 01Historical passExecute confirmed bars from old to new
- 02Realtime updateUpdate H/L/C and other fluid values
- 03RollbackRestore the last commit, then recalculate
- 04Closing updateFinalize the bar result
Strategy default: execute at realtime close
calc_on_every_tick: execute on every update
Reload changes results when past intrabar updates are no longer available
A realtime bar has interim updates; a historical bar generally retains only confirmed final values. If a `calc_on_every_tick = true` strategy creates an order during an interim condition, the same elapsed bar is recalculated from historical data after reload without that full tick sequence. The order can disappear or move as a direct consequence of the execution model.
Historical testing and forward observation are therefore different evidence. Preserve source, settings, symbol, timeframe, session and start time together with execution mode and observation state. Identical code does not imply an identical event stream.
Historical and realtime bars expose different event sequences
When loaded, Pine executes accessible historical bars from old to new using confirmed OHLC. On an open market, high, low, close and volume can change with each update. Indicators normally execute on every update; strategies normally execute on the realtime closing update unless their calculation behavior is changed.
| Field | Historical bar | Open realtime bar | Evidence |
|---|---|---|---|
| Prices | Confirmed OHLC | H/L/C evolve | Timestamped snapshot |
| Default strategy | Bar-by-bar | Usually at close | Execution mode |
| Every-tick strategy | No complete tick archive | Each update | Update count |
| After reload | Recalculated as history | Elapsed bar changes class | Before/after diff |
Later provider revisions can also cause differences outside the execution model.
Result = function(source, settings, dataset, execution events, fill events)Historical events != complete realtime tick sequenceReload mismatch rate = changed bars / compared bars × 100A mismatch is an investigation flag, not a quality or profitability score.Separate price updates, script executions, order events and external alerts. A changing open-bar price does not imply the strategy executed; an execution does not imply an order; an order does not imply a fill. A server-side alert also runs from its creation-time script and input snapshot, which can differ from the current chart.
The open bar returns to its last committed state before recalculation
Before each realtime recalculation, Pine normally restores variables, expressions and drawings to the latest committed state. It then executes the bar with the newest prices and replaces temporary output. The closing update commits the final state to the time series for later history references.
`var` controls one-time initialization across bars but does not generally escape open-bar rollback. `varip` can persist across intrabar updates, yet those updates do not exist in the same form on historical bars. Document both its usefulness and the portion that cannot be backtested.
| Field | Value for each execution | Post-reload check |
|---|---|---|
| Bar identity | Ticker ID, timeframe, bar time and index | Does it identify the same market bar? |
| Bar state | isnew, isrealtime, isconfirmed and islast | What changed when the bar became historical? |
| Runtime state | Update number, var, varip and condition | Can committed and interim state be separated? |
| Order state | Order ID, creation, fill and position | What explains a moved marker? |
| Settings | All recalculation/fill switches | Is the execution contract identical? |
| Observation | Capture time, close relation and reload time | Are checkpoints comparable? |
Retain one row per execution. Aggregating immediately by bar destroys intrabar conditions and post-fill recalculations.
Seal the immediate closing update with source hash, bar time, condition, position, order ID and cumulative P/L; never overwrite it with an open-bar snapshot. After the next reload, diff against that seal and assign separate reason codes for varip-only counts, post-fill recalculation and provider revision. Unknown differences remain unresolved rather than becoming zeros or being discarded only on losing bars.
Do not enable three execution options as one bundle
`calc_on_every_tick` changes execution on realtime price updates; `calc_on_order_fills` adds recalculation after simulated fills; `process_orders_on_close` changes processing around the closing tick. Their purposes differ and combinations can create several executions and order events inside one bar. Record a default baseline and change one option at a time.
| Option | Changed event | Primary risk | Audit |
|---|---|---|---|
| calc_on_every_tick | Realtime update | Intrabar condition disappears after reload | Compare close-only version |
| calc_on_order_fills | After simulated fill | Additional same-bar orders | Fill log and execution count |
| process_orders_on_close | Around bar close | Timing differs from live provider | Separate creation and fill time |
Confirm exact current behavior in the official declaration and Strategies manual.
Order events do not behave exactly like ordinary variables under rollback. A Broker Emulator fill can persist and trigger another execution. Pair this runtime audit with TV12’s fill path, keeping code calculation and simulated order execution in separate columns.
A failure combination is an every-tick condition creating an order, followed by a fill-triggered recalculation that creates another order on the same bar. Changing close processing can compress creation and fill into one historical bar. Enable the three switches one at a time and identify the first version where executions, order IDs or position changes multiply.
Count realtime updates while restricting the order to a confirmed bar
The Pine v6 sample executes on every realtime update and uses `varip` to count updates inside the open bar. Its fictional EMA-cross orders require `barstate.isconfirmed`. The script demonstrates state; it does not recommend the EMA length or use the update count as a historical trading feature.
//@version=6
strategy(
"Execution audit demo",
overlay = true,
calc_on_every_tick = true,
calc_on_order_fills = false,
process_orders_on_close = false
)
varip int intrabarUpdates = 0
if barstate.isnew
intrabarUpdates := 1
else
intrabarUpdates += 1
float baseline = ta.ema(close, 20)
bool confirmedLong = ta.crossover(close, baseline) and barstate.isconfirmed
bool confirmedExit = ta.crossunder(close, baseline) and barstate.isconfirmed
if confirmedLong
strategy.entry("L", strategy.long)
if confirmedExit
strategy.close("L")
plot(baseline, "EMA", color.orange)
plotchar(
barstate.isrealtime ? intrabarUpdates : na,
"Realtime update count",
"",
location.top
)Update frequency varies by feed and market state and is not a proxy for traded volume or elapsed time.
Save a `calc_on_every_tick = false` baseline before observing the true version. Confirmed orders may match while temporary plots and counts do not. Removing bar confirmation from the order condition can introduce intrabar trades that disappear after reload.
Run the close-only and every-tick versions during the same market window while freezing signal, symbol, period and orders. Keep every-tick updates as forward evidence and never backfill them onto historical bars. Reconcile order IDs immediately after close and again after next-day reload, preserving conditions that existed only intrabar as such.
Build a per-bar before-close-reload diff
| Checkpoint | State to preserve | Primary class |
|---|---|---|
| Baseline | Every-tick, order-fill and process-on-close settings | Execution configuration |
| Open update | Timestamp, condition, update count and order ID | Fluid price / varip |
| Closing update | Plot, position, order and alert state | Commit / fill |
| After reload | Same-bar value, marker and trade ID | Rollback / requested data / revision |
Place one bar ID across the row and retain an unobserved state as missing rather than zero.
Keep every compared bar in the denominator. If only profitable live markers survive while losing intrabar orders disappear, the sample has severe selection bias. An alert instance also runs from a creation-time snapshot, so do not confuse chart reload differences with the separate server-side alert contract in TV05.
- Freeze a close-only baseline
Record source hash, all three switches, starting bar and session; export Strategy Tester.
- Pre-register the forward window
Choose bar count and fields before results; do not select only winning bars.
- Capture every execution
Store update, condition, order, fill and position with timestamps.
- Seal the close state
Preserve the immediate closing snapshot instead of overwriting it after reload.
- Classify reload differences
Use rollback, varip, requested data, fills, provider revision and alert snapshot.
Do not delete mismatch rows to improve the rate. Bind forward and backtest evidence to one version family but keep separate tables because their event granularity differs. Use missing rather than zero for unavailable fields, repeat the same classification in a second forward window, and reject a public baseline whose causes cannot be reproduced.
Analyze a stable baseline separately from forward observations
Keep the close-based Strategy Tester CSV/XLSX separate from the intrabar forward-observation log. Load the reproducible baseline into the Backtest & Robustness Lab, then compare profit metrics, drawdown, stress and OOS across execution-setting fingerprints. Paid saved-analysis and version workflows become useful only after more than one reproducible execution version exists.
Free indicators can help contrast an open bar with its confirmed state, but their plots do not supply Strategy Tester trade output. Reimplementing an observed condition as a strategy creates a new contract for orders, fills and execution timing.
Separate reload mismatches from intrabar execution events
Enter compared bars, bars changed after reload, observed realtime updates and extra post-fill recalculations. This organizes runtime evidence.
Reproducibility = max(A-B,0)/A; mismatches = B; intrabar events = C+D. Update and post-fill execution can overlap, so this is not a unique execution count or strategy-quality score.
Frequently asked questions
Does calc_on_every_tick make historical backtesting tick-based?
No. Historical feeds do not contain the full realtime tick sequence, so an intrabar condition observed live may not reproduce after reload.
What is the difference between var and varip?
`var` controls initialization across bars but normally participates in rollback. `varip` can persist within the open bar, yet that state may not be reproducible historically.
Does barstate.isconfirmed eliminate every difference?
No. It can restrict chart-bar intrabar conditions, but HTF requests, fills, provider revisions and session differences need separate audits.
Should a backtest CSV and forward log be merged into one dataset?
Not directly. A bar-close history and realtime update log have different event granularity. Bind them with one version ID while keeping populations and column definitions separate.
Primary sources and verification links
- TradingView Pine Script | Execution modelOfficial historical/realtime execution, rollback, commit and reload model
- TradingView Pine Script | Bar statesOfficial barstate variables and strategy timing
- TradingView Pine Script | RepaintingOfficial historical/realtime, varip and calc_on_every_tick cautions
- TradingView Pine Script | Declaration statementsOfficial calc_on_every_tick, calc_on_order_fills and process_orders_on_close reference
- TradingView | Strategy alert and chart-order mismatchesOfficial support on realtime/historical differences from recalculation settings
Edited and published by: SG Group · Editorial approach: We prioritize official TradingView Help Center and Pine Script documentation, then use exchange, regulator and other primary materials for market and product context. Features, data, pricing and connection terms change, so verify the current interface and linked sources before use.
Important notice: This article provides general education about TradingView interfaces, charts, alerts, screeners, paper trading and Pine Script. It is not investment advice, a trading signal, a recommendation of any instrument, data source or broker, or a guarantee of future price or profit. Features, pricing, data, exchange coverage, notifications, order integrations and Pine Script behavior vary by plan, region, connection and date and may change. Before risking money, verify current TradingView documentation and the terms of the relevant data source and connected provider, then rehearse the workflow with fictional data or paper trading.

