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’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 have an array data structure, but it is a completely different concept than a time series.
Time series in Pine Script™, combined with its special runtime engine and built-in functions, make it easy to compute calculations across bars without needing a for loop. For example, we can calculate the cumulative total of close values by using the ta.cum() function. 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 it continues adding the close values of each new bar. When the script reaches the rightmost bar of the chart, ta.cum(close)
returns the sum of the close values from all bars on the chart.
Similarly, Pine scripts can calculate the mean of the difference between the last 14 high and low values using the ta.sma() function (ta.sma(high - low, 14)
), or the distance in bars since the last time the chart made five consecutive higher highs by combining ta.barssince() and ta.rising() calls (ta.barssince(ta.rising(high, 5))
).
The result of function calls on successive bars leaves a succession of values in a time series that scripts can reference 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 > ta.highest(close, 10)[1]
. The same statement could also be written as breach = close > ta.highest(close[1], 10)
.
The same logic of executing a single code statement on all bars applies to function calls such as plot(open), which will repeat on each bar to successively plot the values of the open time series on the chart.
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 from 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 does 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 "1D"
for a daily chart, for example. Even though its value cannot change during
the script’s execution, 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.
Programmers can define complex calculations using little code by using Pine’s syntax and execution model to efficiently handle time series.