Skip to content

How a script runs ​

When does your script run, and what does it see on each bar? It runs once for every bar on the chart, from the oldest to the newest, and each run executes the whole text from top to bottom with that bar's prices. On a live chart the newest bar is still forming, so the script runs on it again with every price update, and each of those runs starts from where the bar began.

pine
//@version=6
indicator("Crosses on closed bars", overlay = true)
float fast = ta.ema(close, 9)
float slow = ta.ema(close, 21)
plot(fast, "Fast", color.teal)
plot(slow, "Slow", color.orange)
bool crossed = ta.crossover(fast, slow)
// a cross on the forming bar can still vanish: wait for the close
plotshape(crossed and barstate.isconfirmed, "Cross", shape.triangleup,
     location.belowbar, color.teal)

One run a bar ​

On each run, open, high, low, close, volume and time hold the bar the run is on, and bar_index counts that bar from 0. A variable declared the plain way is worked out afresh on every run. One declared with var starts from what the bar before left it: see var and varip.

close[1] reads the bar before this one, and close[k] the bar k bars back. Nothing reads a later bar. An offset below zero, such as close[-1], reads na on every bar here. TradingView stops the script there when it runs, so keep k at 0 or more.

The chart's oldest loaded bar is bar 0. On timeframes under an hour a chart loads at most 50,000 bars by default, which Settings can change, and from an hour up it loads all the history it has.

Where a run is: barstate ​

The barstate.* values tell a run where it is. barstate.isfirst is true on bar 0 alone. The rest change as the chart goes live. The table follows one chart from the moment the script loads, through the live bars that come after.

FlagClosed bars at loadForming bar at loadA new bar's first updateIts later updatesA bar's closing run
barstate.isconfirmedtruefalsefalsefalsetrue
barstate.islastfalsetruetruetruetrue
barstate.islastconfirmedhistorytrue on the last of themfalsefalsefalsefalse
barstate.ishistorytruetruefalsefalsefalse
barstate.isrealtimefalsefalsetruetruetrue
barstate.isnewtruetruetruefalsefalse

When the market is closed at load, the last bar has closed, so it reads isconfirmed, islast and islastconfirmedhistory all at once. Each flag has its entry in barstate.

The forming bar ​

The forming bar is the chart's last bar while it's still open: its close is the latest price, and its high, low and volume grow until it closes. Everything your script works out from it moves with it. A cross, a breakout or a colour on that bar can appear on one update and be gone on the next, and the bar can close without it.

barstate.isconfirmed is false on the forming bar and true on every closed one. Test it, as the example does, to act only on what a closed bar says. Other symbols explains the same rule for a value read from another series.

Each update of the live bar ​

Each update of the forming bar runs the script on that bar again, from the state the bar started with. Before the run, the engine puts back the state the last closed bar left, so the earlier updates leave no trace:

  • a var variable goes back to its value at the bar's start, so a var counter counts bars, not updates;
  • a label, line or box the last update drew on this bar is gone, and this update draws its own;
  • a varip variable is the one thing kept, which is what it's for. See varip.

When the bar closes, the script runs on it once more with its final prices, barstate.isconfirmed true. Then the new bar's first run follows. From then on each new bar reads barstate.islast and is its own last_bar_index, so a block under if barstate.islast runs again on each bar that arrives live, and the bars before it keep what their own last run drew.

When everything runs again ​

The chart runs the whole script again from bar 0 when you add it or change an input, when the symbol or timeframe changes, when older history loads, and when a series the script asked for with request.* arrives. A whole run builds every bar's state from scratch, so whatever the live updates added to a varip is gone.

What a run can see ​

A run sees the bar it's on and the bars before it, and nothing later. A few names break that rule on purpose. They say where the data ends or what the clock reads, so on an old bar they know what that bar couldn't have known:

NameOn a bar in the past it reads
last_bar_index, last_bar_timethe chart's last bar as it was when the script loaded. A bar that arrives live later reads itself
barstate.islast, barstate.islastconfirmedhistorywhether this bar is at the end of the data
barstate.ishistory, barstate.isrealtimewhether this bar arrived before or after the load
timenowthe wall clock at the moment the run happens, never the bar's own time

Use them for drawings, such as a label on the last bar. A plot or a decision that rests on one reads one way on history and another live, so a Pine script that plots one or decides on one gets a leak warning. A leak-safe AmenoScript run refuses a decision on one: see live-only names.

Strategies run at the close ​

A strategy runs once a bar, at its close, unless it sets calc_on_every_tick = true. On a live chart it takes no run on the forming bar until that bar closes, so its plots stop at the last closed bar. When your script runs has the rule, and Strategies the walk-through.

Bar replay ​

In bar replay, the replay's time is the run's present. Every series stops at what was known then, the chart's own included. A bar that closes exactly at that time hasn't closed yet: it's the forming bar. A step forward runs the new bar from the last closed bar's state, so a step and a jump to the same time draw the same. A varip acts as a var there, and timenow still reads the wall clock.

Leak-safe runs ​

An AmenoScript text runs leak-safe, and there your code never runs on the forming bar. Every bar runs once, closed, live as in history, so barstate.islast, last_bar_index and last_bar_time read the last closed bar, and a live chart's newest candle has no point of yours. Your code runs on closed bars has the rules.

Traps ​

A signal on the forming bar can repaint

Anything worked out from the forming bar's prices can change before the bar closes, so an alert or mark it raises can vanish. Gate it on barstate.isconfirmed, or read the closed bar with close[1].

  • barstate.isnew isn't "a new bar arrived". It's true on every bar at load, so a block under it runs on every history bar. Only on live bars does it single out a bar's first update.
  • An islast block runs again on each live bar. Each new bar is the last when it arrives, so a label made there is drawn again on each one. Delete the old one, or keep one label in a var and move it.
  • A count from bar 0 depends on bar 0. ta.cum or a var counter starts at the oldest loaded bar, so the same script reads a different total on a chart with more history, or after older bars load.
  • last_bar_index on history. bar_index == last_bar_index - 10 picks a bar by where the data ends, which moves as bars arrive. Fine for drawing, wrong for a signal.

See also ​

AmenoScript is compatible with Pine Script v6. Pine Script is a trademark of TradingView, Inc., which has no part in AmenoScript.