ScriptingHow scripts are evaluatedBar-by-bar evaluation

Bar-by-bar evaluation

A chart is a sequence of bars. Your script is evaluated once per bar, in order.

   bar 1    bar 2    bar 3    bar 4    ...    bar n
     |        |        |        |               |
     v        v        v        v               v
   [run]    [run]    [run]    [run]           [run]
     ^                                          ^
  first bar                                  last bar

Each run sees one bar: the bar it is being evaluated on. The whole script runs again on the next bar. Nothing you compute survives from one run to the next unless you ask for it.

Where the current run sits

Three flags report where the current run sits in that sequence.

NameTypeReports
barstate.isfirstseries boolthe run is on the first bar
barstate.isnewseries boolthe run is on a new bar
barstate.ishistoryseries boolthe run is on a historical bar

Each is a series value, so its answer changes from bar to bar. Read one in a condition:

static float bars_seen = 0.0

if barstate.isnew {
    bars_seen := bars_seen + 1.0
}

A script that counts its own runs

Because the script runs once per bar, a value carried across runs counts bars.

indicator("Bar count")

static float count = 0.0
count := count + 1.0

plot(count)

What this page does not tell you

Nothing here is a timing claim. This page does not state how long a run takes, what arrives between runs, or how a bar that has not yet closed is handled.

For the flags that separate a bar still updating from one that has closed, see Recalculation and confirmation. For carrying a value across runs, see Values that persist across bars.

Ready to put this into practice?
Try GoCharting Premium
Unlock advanced orderflow, market profile, options desk, and real-time data — everything you just read about, live in your charts.
Upgrade