Time series
Much of the power of Pine Script™ stems from the fact that it is designed to process time series efficiently. Time series are not a qualified type; they are the fundamental structure Pine Script™ uses to store the successive values of a variable over time, where each value is tethered to a point in time. Since charts are composed of bars, each representing a particular point in time, time series are the ideal data structure to work with values that may change with time.
The notion of time series is intimately linked to Pine Script™‘s execution model and type system concepts. Understanding all three is key to making the most of the power of Pine Script™.
Take the built-in
open
variable, which contains the “open” price of each bar in the dataset,
the dataset being all the bars on any given chart. If your script is
running on a 5min chart, then each value in the
open
time series is the “open” price of the consecutive 5min chart bars.
When your script refers to
open,
it is referring to the “open” price of the bar the script is executing
on. To refer to past values in a time series, we use the
[]
history-referencing operator. When a script is executing on a given bar,
open[1]
refers to the value of the
open
time series on the previous bar.
While time series may remind programmers of arrays, they are totally different. Pine Script™ does use an array data structure, but it is a completely different concept than a time series.
Time series in Pine Script™, combined with its special type of runtime
engine and built-in functions, are what makes it easy to compute the
cumulative total of
close
values without using a
for
loop, with only ta.cum(close)
. This is possible because although
ta.cum(close)
appears rather static in a script, it is in fact
executed on each bar, so its value becomes increasingly larger as the
close
value of each new bar is added to it. When the script reaches the
rightmost bar of the chart, ta.cum(close)
returns the sum of the
close
value from all bars on the chart.
Similarly, the mean of the difference between the last 14
high
and low
values can be expressed as ta.sma(high - low, 14)
, or the distance in
bars since the last time the chart made five consecutive higher highs as
barssince(rising(high, 5))
.
Even the result of function calls on successive bars leaves a trace of
values in a time series that can be referenced using the
[]
history-referencing operator. This can be useful, for example, when
testing the
close
of the current bar for a breach of the highest
high
in the last 10 bars, but excluding the current bar, which we could write
as breach = close > highest(close, 10)[1]
. The same statement could
also be written as breach = close > highest(close[1], 10)
.
The same looping logic on all bars is applied to function calls such as
plot(open)
which will repeat on each bar, successively plotting on the
chart the value of
open
for each bar.
Do not confuse “time series” with the “series” qualifier. The time
series concept explains how consecutive values of variables are stored
in Pine Script™; the “series” qualifier denotes variables whose values
can change bar to bar. Consider, for example, the
timeframe.period
built-in variable which has the “simple” qualifier and “string”
type, meaning it is of the “simple string” qualified type. The
“simple” qualifier entails that the variable’s value is established
on bar zero (the first bar where the script executes) and will not
change during the script’s execution on any of the chart’s bars. The
variable’s value is the chart’s timeframe in string format, so "D"
for a 1D chart, for example. Even though its value cannot change during
the script, it would be syntactically correct in Pine Script™ (though
not very useful) to refer to its value 10 bars ago using
timeframe.period[10]
. This is possible because the successive values
of
timeframe.period
for each bar are stored in a time series, even though all the values in
that particular time series are the same. Note, however, that when the
[]
operator is used to access past values of a variable, it yields a
“series” qualified value, even when the variable without an offset
uses a different qualifier, such as “simple” in the case of
timeframe.period.
When you grasp how time series can be efficiently handled using Pine Script™‘s syntax and its execution model, you can define complex calculations using little code.