When coding TradingView Pine scripts, we often want to compare the current bar’s data against previous bars. But how do we access data from previous bars?

In this article:

Retrieving previous data with the history referencing operator

Without operators, our scripts would only perform very basic tasks. An operator is a code element that performs an operation on one or several values (Stephens, 2014). And the values that an operator ‘acts upon’ are what we call operands (Sharp, 2013). TradingView operators that you’ve probably already used are the arithmetic operators (+, -, /, and *) and the assignment operator (=).

One valuable operator is the history referencing operator. This operator consists out of two square brackets ([]) that are placed just behind a variable or function. In those square brackets we enter a positive integer that’s greater than 0. The history referencing operator then returns the value of the variable or function for that number of bars ago (Pine Script Language Tutorial, n.d.; TradingView, n.d.).

For example, close[1] returns the closing price of the previous bar and open[3] returns the open price from 3 bars ago. Likewise, ema(close, 10)[1] returns the previous bar value of the 10-bar Exponential Moving Average (EMA) based on closing prices. We can access the current bar’s value with the history referencing operator (like close[0] and volume[0]) or without it (close, volume).

The context-dependence of TradingView’s history referencing operator

TradingView scripts execute their calculations on each bar, starting from the oldest bar to the most recent, last bar (Pine Script Language Tutorial, n.d.). This makes the previous values returned by [] depend on the bar that the script is currently calculated on.

This is visually explained in the images below. Let’s say that the script is calculated on the bar highlighted with the arrow. Accessing previous closing prices with the history referencing operator then goes like this:

History referencing operator - example 1 History referencing operator - example 2 History referencing operator - example 3

This also shows that the value returned by the history referencing operator solely depends on the previous bar. And so expressions like month[1] do not return the previous month but rather the month of the previous bar.

Important features of TradingView’s history referencing operator

The [] operator has a few noteworthy features. First, we cannot apply this operator to the same operand repeatedly (Pine Script Language Tutorial, n.d.). So while open[1] is valid, retrieving the previous open price of 2 bars ago with open[1][2] isn’t allowed. Instead, we need to combine those values together (so open[3]).

Second, the history referencing operator can only use positive values (which indicate the amount of bars back). Negative values between its square brackets (such as high[-1]) aren’t allowed (Pine Script Language Tutorial, n.d.).

Third, the [] operator only works when placed behind a variable or function whose values are series of data (Pine Script Language Tutorial, n.d.). In other words, when a value doesn’t have historical values, then the history referencing operator won’t work. This means [] works with all values related to price bar data (like high[9], time[12], and highest(high, 10)[1]). But not with hard-coded values (like "my text message"[1]) or with variables like ticker, which returns the instrument’s symbol (TradingView, n.d.) and doesn’t have historical values since the symbol is the same on each bar.

Fourth and finally, the history referencing operator returns NaN values when we try to access a value that’s beyond the number of bars on the chart (Pine Script Language Tutorial, n.d.). For instance, when the script currently calculates on the third bar, then low[10] returns NaN (“not a number”) because there isn’t a bar yet 10 bars ago.

Values returned by the history referencing operator

Technically, the history referencing operator doesn’t return a single value but returns a series of values with a certain offset (Pine Script Language Tutorial, n.d.), even though we generally think that the history referencing operator accesses the nth element (Admin, 2014).

This means that, for example, close[5] doesn’t return a single closing price but a series of closing prices that are equal to the closing price of 5 bars ago. We can visualise this behaviour with a brief programming example:

study(title="History referencing operator", overlay=true)

plot(series=close[5], linewidth=2)

This code plots the closing price of 5 bars ago, and looks like this when added to a chart:

Example of plotting historical values in TradingView

Here we see that the value of close[5] is the same as the closing price, but just 5 bars later.

Because the history referencing operator returns a series of values, we can use the [] operator with arguments of functions. For example, calculating the 20-period EMA on the closing price of 5 bars ago can be done with ema(close[5], 20). Should close[5] only return one closing price (and not a series of prices), then we couldn’t calculate an exponential average with it.

Now, let’s look at two examples that apply the history referencing operator to variables and functions.

Getting the value of variables on previous bars in TradingView

The history referencing operator ([]) can access a variable’s previous values like this:

study(title="History referencing operator - 1", overlay=false)

priceDiff = hl2 - hl2[10]

colour = (priceDiff > priceDiff[1]) ? orange : blue

plot(series=priceDiff, color=colour, style=histogram, 
     linewidth=3)

We start with the study() function to set the script’s properties. The priceDiff variable that’s created next holds the price difference between the current value of hl2 and its value 10 bars ago. We get that historical value by putting 10 inside the square brackets of the history referencing operator (hl2[10]). This hl2 built-in variable returns the bar’s midpoint ([high + low] / 2; TradingView, n.d.), and the 10-bar difference gives an indication of momentum with positive values for rising midpoint values and negative values signalling dropping midpoint momentum.

Then we make the colour variable and store in it one of two colours (orange or blue) with the conditional ternary operator (?:). This operator evaluates a true/false condition (its first operand). When that condition is true, it returns its second operator (orange here); otherwise, its third operand is returned (blue). The condition that we check here is whether the current value of priceDiff is greater than (>) its previous value. We get that previous value by placing the [] operator behind our variable (priceDiff[1]).

The example ends with the plot() function that plots a series of data on the chart (TradingView, n.d.). We set its series argument to the value of the priceDiff variable. Its color argument is set to the colour variable so that the plot is either orange or blue, depending on the bar’s midpoint momentum difference. With style set to histogram we get a histogram plot (instead of a line plot), and with linewidth set to 3 we get thick histogram bars.

This example looks as follows when added to a chart:

History referencing operator example

Using the history referencing operator with functions in TradingView

The [ ] operator can also be used with both the arguments of functions (like ema(close[2], 20)) and placed just after the function (ema(close, 20)[2]) (see Pine Script Language Tutorial, n.d.). For example:

study(title="History referencing operator - 2", overlay=true)

highestHigh = highest(high, 20)[1]
lowestLow = lowest(low[1], 20)

plot(series=highestHigh, color=green)
plot(series=lowestLow, color=red)

We first use the required study() function here. Then we create two variables. The first, highestHigh, is set to the value returned by highest(), a function that returns the highest value for a certain amount of bars back (TradingView, n.d.). By setting its arguments to high and 20 it returns the 20-bar highest high.

But because this 20-bar high also includes the current bar, a bar’s high can never cross above highest(high, 20). That’s why we place the history referencing operator with a value of 1 just behind the function. Now it returns the high of the preceding 20 bars, without the current bar’s high included.

Likewise, the lowestLow variable is set to the value calculated by lowest(), a function that returns the lowest value for a given number of bars back (TradingView, n.d.). This can give the same issue: if lowest() includes the current bar, then a bar’s low can never drop below the 20-bar low. But because we calculate the lowest low on low[1], we introduce a 1-bar lag with the history referencing operator. And so lowest(low[1], 20) doesn’t include the low of the current bar.

With the variables calculated, we display them on the chart with plot(). The highestHigh values are plotted as a green line while the lowestLow values display as a red line.

When we add this example to a chart, we can see how the history referencing operator makes the highest high and lowest low values lag with 1 bar:

TradingView example of history referencing operator

Other commonly used operators besides the history referencing operator are the conditional ternary operator (?:) for if/else logic, the comparison operators that compare two values against each other, and the arithmetic operators for performing calculations.

Summary

The history referencing operator ([]), with a positive integer between its square brackets, returns previous bar values. This operator can be used with any built-in variable, user-made variable, standard function, or custom function that returns a series of values. The history referencing operator returns NaN when we try to access more data than there are bars on the chart.


References

Admin (2014, April 25). Accumulator function code does not behave as expected - forum discussion. Retrieved on September 14, 2015, from https://getsatisfaction.com/tradingview/topics/accumulator_function_code_does_not_behave_as_expected#reply_14201645

Pine Script Language Tutorial (n.d.). Retrieved on August 13, 2015, from https://docs.google.com/document/d/1sCfC873xJEMV7MGzt1L70JTStTE9kcG2q-LDuWWkBeY/

Sharp, J. (2013). Microsoft Visual C# 2013 Step by Step. Microsoft Press.

Stephens, R. (2014). C# 5.0 Programmer Reference. Indianapolis, IN: John Wiley & Sons.

TradingView (n.d.). Script Language Reference Manual. Retrieved on September 14, 2015, from https://www.tradingview.com/study-script-reference/