Appearance
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.
| Flag | Closed bars at load | Forming bar at load | A new bar's first update | Its later updates | A bar's closing run |
|---|---|---|---|---|---|
barstate.isconfirmed | true | false | false | false | true |
barstate.islast | false | true | true | true | true |
barstate.islastconfirmedhistory | true on the last of them | false | false | false | false |
barstate.ishistory | true | true | false | false | false |
barstate.isrealtime | false | false | true | true | true |
barstate.isnew | true | true | true | false | false |
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
varvariable goes back to its value at the bar's start, so avarcounter 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
varipvariable 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:
| Name | On a bar in the past it reads |
|---|---|
last_bar_index, last_bar_time | the chart's last bar as it was when the script loaded. A bar that arrives live later reads itself |
barstate.islast, barstate.islastconfirmedhistory | whether this bar is at the end of the data |
barstate.ishistory, barstate.isrealtime | whether this bar arrived before or after the load |
timenow | the 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.isnewisn'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
islastblock 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 avarand move it. - A count from bar 0 depends on bar 0.
ta.cumor avarcounter 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_indexon history.bar_index == last_bar_index - 10picks a bar by where the data ends, which moves as bars arrive. Fine for drawing, wrong for a signal.
See also
- var and varip, what survives from one bar or update to the next
- barstate, each flag's entry
- Other symbols, repainting in a request
- When your script runs, a strategy's runs
- Leak-safe runs, AmenoScript's closed-bar rule