Each TradingView indicator uses a certain number of price bars with its calculations. Most of the time, TradingView can successfully determine that number of bars. But what if that value cannot be determined automatically?

In this article:

Setting the historical price bars used by an indicator’s calculations

In TradingView we set the properties of an indicator, like its name and the price scale it uses, with the study() function (Pine Script Language Tutorial, n.d.). This function needs to be in the code of every indicator (Pine Script Language Tutorial, n.d.) and its title argument, which sets the indicator’s name, always needs to be given a value (TradingView, n.d.).

Another argument of the study() function is max_bars_back. This sparsely documented argument sets the maximum number of price bars that are available for the indicator to reference (TradingView, n.d.). This means that max_bars_back specifies how many bars an indicator uses for its calculations.

For example, a 10-bar moving average needs 10 previous historical price bars before it can calculate the moving average on the 11th bar. And so the ‘maximum bars back’ value specifies how many bars there need to be available before a script can begin its calculations.

A basic example of the max_bars_back argument is:

study(title="Example of Max bars back", max_bars_back=20)

Before discussing more theory and features of max_bars_back, let’s first look at a visual example of the number of historical bars that a TradingView script uses.

Visual example: the number of historical bars an indicator references

With max_bars_back specifying how many bars the script uses in its historical calculations, this argument is closely related to the history referencing operator ([]) (see Vitvlkv, 2016). That operator returns a historical value from a series of values (Pine Script Language Tutorial, n.d.). For instance, high[5] returns the high price of 5 bars ago. In that case, max_bars_back needs to be at least 5; otherwise, that high price cannot be retrieved.

Let’s consider the following quick example to better understand this point:

study(title="Example of Max bars back", overlay=true)

plot(series=close[10], color=teal, linewidth=2)

Here we set indicator’s properties with study(): the title argument defines the indicator’s name and with overlay set to true the indicator displays on the chart’s instrument.

Then we display data on the chart with plot() (TradingView, n.d.). This function’s series argument is set to close[10], which uses the history referencing operator ([]) to return the closing price of 10 bars ago. We set this plot’s colour to the teal basic TradingView colour, and with linewidth set to 2 the plotted line is a bit bigger than normal (TradingView, n.d.).

Now when we add this example to the chart and scroll all the way back to the first bar, we see the following:

Example of max bars back in a TradingView indicator

Here the indicator starts plotting on the 11th bar. That’s because it needs the closing price of 10 bars ago, and that value is not available for bars before the 11th bar. And so in this case, this indicator needs to reference 10 historical price bars before it can start plotting.

The amount of bars that the script ‘waits’ before beginning its operations depends on how many historical data the script references: the more historical price bars we use in our script, the longer the script ‘waits’ before it starts plotting.

For example, let’s change the previous example so that it plots the close of 15 bars ago:

study(title="Example of Max bars back", overlay=true)

plot(series=close[15], color=teal, linewidth=2)

The only change here is that we’ve set the series argument of the plot() function to close[15]. After saving the script, we see that the indicator now ‘waits’ an additional 5 bars:

Referencing historical price bars in a TradingView indicator

And so the further away we reference a historical price bar, the more historical data an indicator needs before it starts with its operations. And the higher the max_bars_back argument needs to be so that the script can access all of that price data.

Setting a TradingView indicator’s max bars back ourselves

Luckily, TradingView automatically computes how many bars an indicator needs for its calculations (TradingView, n.d.). But in rare circumstances, TradingView has trouble determining this value automatically (Vitvlkv, 2016) – we’ll see an example of that further down below. In those situations we need to set the max_bars_back argument ourselves.

While we can also set max_bars_back in other situations, TradingView only uses this value when it cannot determine the indicator’s maximum bars back itself. And when the manually set value is too low for the indicator’s calculations, then TradingView also discards the value of the max_bars_back argument (TradingView, n.d.).

Choosing a value for the max_bars_back argument is a trade off. On the one hand, we need to set this argument high enough so that when the indicator’s input options change, the indicator can still calculate successfully. But a very high max_bars_back value on the other hand means the script ‘waits’ a long time before computing, and then we’ll ‘waste’ a lot of historical data.

Tip: As a rule of thumb, an approximate max_bars_back value for short-term indicators is 50. A value of 100 is more suitable for medium-term indicators, while a long-term indicator can require 200 bars back or more.

When the max_bars_back argument of the study() function is set to a too high value (like, higher than the number of bars on the chart), then the ‘Too large lookback’ error message appears when we add the script to the chart. For instance, here the max_bars_back argument is set to 20,000:

Setting the max bars back of a TradingView indicator too high

By the way, there is no manual option to set the maximum number of bars that an indicator references, meaning that we can only set this value with max_bars_back. We also cannot access the current max_bars_back setting in the script’s code itself.

Setting the max bars back of a TradingView indicator programmatically

Let’s consider an example indicator that only works when the max_bars_back argument is set manually. In the script below, we plot recent swing highs and lows with the pivothigh() and pivotlow() functions. These functions require, depending on the type of arguments used, that max_bars_back is set manually (TradingView, n.d.). After discussing the code, we’ll add the indicator to the chart and see how we need to set the max_bars_back argument.

Note: There are a few ‘tricks’ in the example below so that TradingView cannot automatically determine the number of bars that the indicator needs for its calculations. This makes the example not the most straightforward or clear way to plot swing pivot highs and lows in TradingView.
study(title="Swing Pivot High/Low", overlay=true)

// Create inputs
rightStr    = input(title="Right Strength", type=integer, defval=2, minval=1)
leftStr     = input(title="Left Strength", type=integer, defval=2, minval=1)
strengthCor = input(title="Strength Correction", type=integer, defval=1)

// Determine pivots
left  = (close > ema(close, 20)) ? leftStr : leftStr + 1
right = (close < ema(close, 20)) ? rightStr : rightStr + 1

pivHigh = pivothigh(left[strengthCor], right[strengthCor])
pivLow  = pivotlow(left[strengthCor], right[strengthCor])

// Plot pivots
plot(series=pivHigh, style=circles, linewidth=4, color=green, offset=-rightStr)
plot(series=pivLow, style=cross, linewidth=4, color=red, offset=-rightStr)

We start our indicator, as always, with the study() function to configure the indicator. With this function’s title argument we set the script’s name and the overlay argument set to true displays the indicator on the chart’s instrument.

Then we add several input options to the script:

rightStr    = input(title="Right Strength", type=integer, defval=2, minval=1)
leftStr     = input(title="Left Strength", type=integer, defval=2, minval=1)
strengthCor = input(title="Strength Correction", type=integer, defval=1)

Inputs are added to a script with input(), and this function also returns the input’s current value (TradingView, n.d.). Here each of those values is stored in a variable with the assignment operator (=). That makes it possible to use the input’s value later on in the script by referring to the variable.

The three inputs that we make here are all numerical integer inputs. These inputs accept whole numbers only and are made by setting the type argument of the input() function to integer (Pine Script Language Tutorial, n.d.).

The first input has its name set to “Right Strength” with the title argument. That name is what’s placed before the option in the script’s settings (see image further down below). This input has a default value (defval) of 2 while its minimum value is 1. This latter requirement is coded with the minval argument of the input() function (TradingView, n.d.). We store this input’s value in the rightStr variable to access it later on.

The second input is named “Left Strength” and has a standard value of 2 with a minimum of 1 (minval=1). This input’s value is stored in the leftStr variable. Both the “Right Strength” and “Left Strength” inputs are used when determining the recent pivot swing high and low. This ‘strength’ value sets the number of bars on either side of the swing bar; with their standard values, 2 bars need to be on either side before TradingView can identify a possible swing high or low.

We name the third input “Strength Correction” and this one begins with a value of 1 (defval=1). This input’s value is stored in the strengthCor variable. We only use that variable later on to ensure that TradingView cannot automatically determine the number of historical bars that are needed for the indicator’s calculations.

After making the inputs, we create two variables for use with the pivot functions later on:

left  = (close > ema(close, 20)) ? leftStr : leftStr + 1
right = (close < ema(close, 20)) ? rightStr : rightStr + 1

The left and right variables both set the number of bars that need to happen prior and after a possible recent high or low before that high or low is identified as a swing high or low by the pivot functions. In a sense, these variables makes the code needlessly difficult to understand. But in our case, they’re only added here so that we calculate the pivots with values that potentially differ on each bar. That, in turn, makes it impossible for TradingView to automatically compute the number of historical bars that the script needs.

Both the left and right variables have their value set with the conditional (ternary) operator (?:). This operator works on three values, with the first being a true/false condition. When that condition is true, the conditional operator returns its second value; when the condition is false, this operator returns its third value (Pine Script Language Tutorial, n.d.). In other words, the conditional operator returns different values based on a condition.

The condition evaluated by the first conditional operator is whether the close of the current bar (close) is greater than (>) the 20-bar EMA. That Exponential Moving Average is computed with ema(), a function that works on two arguments: a series of values to calculate with and an integer that sets the EMA length in number of bars (TradingView, n.d.).

Here those arguments are set to the bar’s closing prices (close) and 20. Now whenever the current bar’s close is greater than the 20-bar EMA, the conditional operator returns the leftStr input variable. The value of that variable (which defaults to 2) is then stored in the left variable. When the bar didn’t close above the 20-bar EMA, then the value of leftStr plus 1 is assigned to the left variable. This way the left variable conditionally switches between leftStr and leftStr + 1. This has no particular meaning and is only added so that TradingView cannot automatically determine the number of historical bars needed for the indicator’s calculations.

We give the right variable a value in the same manner. Here we check whether the close of the current bar (close) is less than (<) the 20-bar EMA of closing prices (ema(close, 20)). When that’s the case, the conditional operator (?:) returns the value of the rightStr variable; when this condition evaluates to false, then the conditional operator returns the value of rightStr + 1. The returned value is then assigned to the right variable.

Now that the values for the pivot functions are determined, we can use those values when retrieving the swing pivot highs and lows:

pivHigh = pivothigh(left[strengthCor], right[strengthCor])
pivLow  = pivotlow(left[strengthCor], right[strengthCor])

The swing pivot high and low are calculated with pivothigh() and pivotlow(). These functions either return the swing high or low price, or a NaN (“not a number”) value when the current bar isn’t a swing high or low (TradingView, n.d.).

We use these functions with two arguments: the first specifies the number of bars to the left while the second defines the amount of bars to the right of the pivot (TradingView, n.d.). This way, these arguments specify the ‘strength’ of the swing pivots: the higher their values, the more a pivot high or low should stand out from the bars around it.

The pivothigh() and pivotlow() functions both use the left and right variables to set the pivots ‘strength’. To make it harder for TradingView to automatically determine how many historical bars the indicator needs, we offset both variables with the history referencing operator ([]). By placing the strengthCor input variable (which has a standard value of 1) between those square brackets, we use the previous (instead of the current) bar value of the left and right variables.

The values returned by the pivothigh() and pivotlow() functions are stored in the pivHigh and pivLow variables, which we subsequently use when we plot the pivots on the chart:

plot(series=pivHigh, style=circles, linewidth=4, color=green, offset=-rightStr)
plot(series=pivLow, style=cross, linewidth=4, color=red, offset=-rightStr)

The plot() function plots the data of its series argument on the chart (TradingView, n.d.). We use that function twice here. The first plot() statement displays the pivot highs (series=pivHigh). We set this plot’s style to circles, and those dots are coloured with the green basic TradingView colour. The second plot() statement plots the pivot lows (series=pivLow), and these values are shown as crosses (style=cross) that are coloured red.

We set the linewidth argument of both plot() statements to 4. This argument defines the plot’s size, starting with 1 for the standard size (TradingView, n.d.).

The offset argument of both plot() statements is set to -rightStr, and that negative value shifts the plots to the left (Pine Script Language Tutorial, n.d.). We need to do that here because both the pivothigh() and pivotlow() functions are inherently lagging. After all, their ‘strength’ argument defines how many bars there should be around a pivot before that point is a recent swing high or low.

Example: setting the max bars back of a TradingView indicator

Our above example indicator has the following input options:

Input options of our TradingView example indicator

When we add this script to the chart, it doesn’t plot the pivots but instead generates the ‘out of depth at index’ error message:

'Out of depth at index' error message in TradingView

Saving and compiling the script, however, went okay:

Successfully compiling a script in TradingView

We can solve that ‘out of depth at index’ error message by setting the max_bars_back argument of the study() function. This does require that we set that argument to a value that’s high enough so that the script can access enough price bars to perform its computations on.

Given how we’ve coded the script with the pivot ‘strength’, a value of 20 would give the script a sufficient number of price bars to compute on. And so we change the first statement of the example to the following:

study(title="Swing Pivot High/Low", overlay=true, max_bars_back=20)

We don’t make other changes but instead just save and compile the script. Now instead of generating an error message, the script looks like:

Sucessfully plotting a TradingView script with max_bars_back

As we can see, the indicator plots the pivot highs and lows without problems. When we change the input options so that the left and right ‘strength’ become 3 (instead of 2), then the indicator looks like:

Changing the inputs of our TradingView example script

For other ways to set indicator properties with code, see configuring an indicator’s overlaid settings and specifying an indicator’s price scale. The study() function is discussed extensively in setting indicator properties programmatically in TradingView.

Summary

Every TradingView indicator needs to use the study() function. This function specifies the indicator’s properties with several arguments, like the required title argument for setting the script’s name. max_bars_back is another argument, and this one sets the maximum amount of historical bars that the indicator uses with its calculations. By default, TradingView computes this number of bars automatically. But in rare cases TradingView cannot determine this value correctly, and that causes an error when the indicator is added to a chart. Manually setting the max_bars_back argument then ensures that the script has enough price data to calculate on. Typical values for this argument range from 50 for short-term indicators to over 200 for long-term indicators.


References

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

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

Vitvlkv (2016, February 25). Pine script documentation issue - forum discussion. Retrieved on March 11, 2016, from https://getsatisfaction.com/tradingview/topics/pine-script-documentation-issue#reply_16650071