A common feature of TradingView indicators is to plot values in the same chart area as where the instrument displays, like we do with Bollinger Bands and moving averages for example. But how can a TradingView strategy also plot its values on the chart’s instrument?

In this article:

Programmatically placing a TradingView strategy on the price chart

In TradingView the properties of a trading strategy, like its initial capital and pyramiding settings, can be set with the strategy() function (TradingView, n.d.). This function is something that every strategy needs to use (Pine Script Language Tutorial, n.d.) and the function’s title argument (which sets the strategy’s name) always needs to be used as well (TradingView, n.d.).

Another argument of strategy() is overlay. This optional argument, when set to true, overlays the strategy on the chart’s instrument (that is, it makes the strategy display in the chart area where the instrument’s price bars are). When we set overlay to false, the strategy displays in a separate chart panel (TradingView, n.d.).

The visual difference between overlay set to true or false is:

TradingView strategy: difference between overlay enabled vs disabled

We use the overlay argument like this:

strategy(title="My example strategy", overlay=true)

The default value of the overlay argument is false (TradingView, n.d.). And so the strategy displays in a separate chart panel whenever we don’t specify the overlay argument in the strategy() function.

Note: The overlay argument of the strategy() function only accepts literal true/false values (like overlay=false). We cannot set this argument to a built-in or user-defined bool variable (like overlay=myVariable) nor can the overlay argument work with a Boolean input variable (such as overlay=myInputVariable).
Tip: When we add a strategy to the chart before the overlay argument was set or changed, the strategy needs to be removed from the chart and re-added to see the effect of the updated code.

A couple of insights when working with overlay are:

  • It’s not possible to specify in which subchart the strategy displays – when overlay is set to false, the script just shows up in a new chart panel below the instrument’s price chart. If we want to move that chart panel up or down, we need to use the ‘Move Up’ ( ) and ‘Move Down’ ( ) icons that are displayed in the chart panel’s top right.
  • Every strategy can be overlaid on the chart’s instrument, even when the strategy plots values that are much higher or lower than the instrument’s prices. In that case, we can set the strategy’s price scale to prevent skewing the instrument’s price axis.
  • Most TradingView functions are affected by the overlay argument. For instance, plot() will either plot in the instrument’s chart area or in a separate chart panel depending on the value of overlay. But functions like barcolor() always colour the instrument’s price bars regardless of the overlay argument’s value.

To see how the overlay argument works in practice, let’s look at a programming example.

Plotting a TradingView stochastic strategy on the price chart

In the example below we plot the stochastic indicator on the instrument’s price chart. We trade this oscillator as follows: when the %K line moves into the overbought area (which we set at 80 and higher), the strategy goes short. And we enter a long position when that line drops below 20 (the oversold area).

The image below gives a quick peek at the finished strategy script; after discussing the code, we’ll look at how the strategy displays on the chart more closely. Then we’ll change the overlay argument so that the strategy doesn’t plot on the instrument but in a separate chart panel instead.

Example of the TradingView strategy overlaid on the price chart
//@version=2
strategy(title="Stochastics strategy", overlay=true, scale=scale.left)

// Inputs
length  = input(title="Length", type=integer, defval=14)
dLength = input(title="D Length", type=integer, defval=3)
obLevel = input(title="Overbought", type=integer, defval=80)
osLevel = input(title="Oversold", type=integer, defval=20)

// Compute values
stochK = stoch(close, high, low, length)
stochD = sma(stochK, dLength)

// Plot values
plot(series=stochK, color=#1E90FF, title="K")
plot(series=stochD, color=orange, title="D")

hline(price=obLevel, color=#C0C0C0)
hline(price=osLevel, color=#C0C0C0)

// Submit orders
if (crossunder(stochK, osLevel))
    strategy.entry(id="Enter Long", long=true)
    
if (crossover(stochK, obLevel))
    strategy.entry(id="Enter Short", long=false)

We start with a comment saying @version=2. This way we make the script use the second version of Pine Script, which makes using if statements possible (Pine Script Language Tutorial, n.d.).

Then we add the strategy() function to our script and set three of its arguments. With title we specify the strategy’s name while overlay set to true makes the strategy display on the chart’s instrument. And with the scale argument set to scale.left, the strategy’s values are attached to the chart’s left price axis (TradingView, n.d.). This way we don’t distort the chart by plotting the instrument and oscillator values on the same price axis.

Next we add several input options to the script:

length  = input(title="Length", type=integer, defval=14)
dLength = input(title="D Length", type=integer, defval=3)
obLevel = input(title="Overbought", type=integer, defval=80)
osLevel = input(title="Oversold", type=integer, defval=20)

Inputs make it easy to change values used by the script. We make these inputs with input(), and this function not only adds the input to the script’s settings but also returns the input’s current value (TradingView, n.d.). Here we store those returned values in variables with the assignment operator (=). This way we can use the input’s value in the script by referring to the variable.

All 4 inputs that we make here are numerical integer inputs. These kind of 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 two inputs are used to calculate the stochastic %K and %D lines. We name these “Length” and “D Length” with the title argument, and this name is what’s placed before the input option in the script’s settings (see image further down below). Their default values (defval) are 14 and 3, and we track their current values with the length and dLength variables.

The other two inputs are our “Overbought” and “Oversold” settings, and these have their standard values set to 80 and 20. We store their current values in the obLevel and osLevel variables. These variables are used later on when plotting the overbought and oversold lines as well as determining the long and short conditions.

Then we calculate the stochastic’s %K and %D values:

stochK = stoch(close, high, low, length)
stochD = sma(stochK, dLength)

We calculate the %K line with stoch(). This function requires four arguments: a series of data to calculate on, the high and low prices of that data, and the length of the stochastic (TradingView, n.d.). Here the function computes on closing (close), high (high), and low (low) prices of the instrument, while the stochastic length is set to the length input variable that we gave a default value of 14. We store the calculated value in the stochK variable.

Then we calculate the stochastic %D line by smoothing the stochK variable’s value with sma(). That function computes a Simple Moving Average (SMA) with two arguments: a series of values to process and an integer that defines the SMA length (TradingView, n.d.). Here we set those arguments to the stochK variable and the dLength input variable, that starts off with a value of 3. We assign the SMA value to the stochD variable.

Next up is plotting the stochastic values on the chart:

plot(series=stochK, color=#1E90FF, title="K")
plot(series=stochD, color=orange, title="D")

hline(price=obLevel, color=#C0C0C0)
hline(price=osLevel, color=#C0C0C0)

Displaying a series of data on the chart is done with plot(), and this function plots a line by default (TradingView, n.d.). Here we use this function twice. We first use it to plot the stochK values with the #1E90FF hexadecimal colour value of dodger blue. We name this plot “K” with the title argument, and this name is what’s shown in the ‘Data Window’ and when changing a script’s colours by hand.

The second plot() function call displays the stochD values on the chart in the orange basic TradingView colour, and we aptly name this plotted line “D”.

The script displays the overbought and oversold levels on the chart with hline(). This function creates a horizontal line at a fixed price level (TradingView, n.d.), and we set its price argument of the two hline() function calls to obLevel and osLevel. This displays the values of our “Overbought” and “Oversold” inputs on the chart. The colour of these lines is set to #C0C0C0, the hexadecimal colour value of silver.

With the oscillator’s values computed, it’s time to submit the orders:

if (crossunder(stochK, osLevel))
    strategy.entry(id="Enter Long", long=true)
    
if (crossover(stochK, obLevel))
    strategy.entry(id="Enter Short", long=false)

We submit orders conditionally with two if statements. The first evaluates the value that’s returned by crossunder(). That function returns true when, on the current bar, the value of its first argument is less than the value of the second argument while, on the previous bar, the first argument’s value was below that of the second (TradingView, n.d.). Since we’re using the function here with the stochK and osLevel variables, it returns true when the stochastic %K line (stochK) drops below the oversold level (osLevel) on the current bar, while the %K line was still above oversold on the previous bar.

When such a cross under happens, we enter a market position with strategy.entry(). This function submits a market order by default and, when the strategy already has a position in the opposite direction, reverses that open position (TradingView, n.d.). We set two of the function’s arguments here: id and long.

The first argument specifies the order identifier, and this name displays on the chart and in the ‘Strategy Tester’ but is also used by other functions when referring to this order. We give our order the “Enter Long” identifier. The second argument specifies if a long position should be opened (long=true) or that strategy.entry() should open a short position (long=false) (TradingView, n.d.). Since we want to open a long position when the %K line drops below oversold, we set long to true here.

With the second if statement we submit short orders. This if statement’s condition uses the crossover() function. That function returns true when, on the current bar, the value of the first argument is greater than that of the second argument while, on the previous bar, first argument’s value was less than that of the second (TradingView, n.d.). Since we use crossover() here with the stochK and obLevel variables, the function returns true whenever the %K line crossed above the overbought level and false in all other cases.

When such a crossover happened, we use the strategy.entry() function to enter a short position (and reverse any long position). For that we set that function’s long argument to false, and set that order’s identifier to “Enter Short”. By the way, since we use the strategy.entry() function for entries and exits (by reversing the existing market position), the strategy is always in the market.

Displaying a TradingView’s strategy on the chart’s instrument

Now let’s examine how the strategy behaves. When added to a EUR/GBP chart, it looks like:

TradingView example strategy: plotting overlaid on the instrument's price chart

Since we’ve set the overlay argument of the strategy() function to true, our stochastic oscillator is overlaid on the EUR/GBP price chart. The strategy’s values, however, don’t distort the chart’s price values – even though the stochastic has considerably higher values than the EUR/GBP prices. This doesn’t happen because we’ve attached the strategy to the left price axis (with the scale argument) whereas EUR/GBP uses the right price axis.

Our strategy has these input options:

Input options of the TradingView example strategy

When we change the stochastic length to 18 and 5 with the overbought and oversold levels set to 90 and 10, the previous chart changes to:

TradingView example chart with changed input options

Now let’s see how the strategy behaves when plotted below the chart’s instrument.

Displaying a TradingView strategy in a separate chart panel

To display the strategy in a chart panel that’s below the instrument, we need to make one code change. That adjustment is replacing the strategy() function line with the following:

strategy(title="Stochastics strategy", overlay=false)

Compared to the above example, this strategy() function has two differences. First, we change the overlay argument from true to its default value of false. This way the script plots below the chart’s instrument instead of on it. The other difference is removing the scale=scale.left argument. Since the strategy displays in a separate chart panel, it has its own price axis and so can default to using the right price axis again.

We save the script without making other changes. The strategy (that’s already on the chart) reloads and looks like:

Example of the TradingView strategy visually unchanged

The strategy still displays with the old setting, though. This happens because, when we change the overlay argument when the script is on the chart, it won’t reload with the new setting. Instead, we need to remove and re-add the strategy to the chart. When we do that, the updated strategy looks like:

Plotting the strategy's values below the instrument in TradingView

Now, thanks to overlay=false, the strategy displays in a separate subchart (but still places the buy and sell arrows on the instrument’s chart).

Summary

A TradingView strategy always needs to use the strategy() function. This function sets the strategy’s properties with several arguments, including the required title and the optional overlay arguments. This latter one specifies where the strategy displays: with overlay set to true, the strategy is overlaid on the chart’s instrument. And with overlay set to false or with overlay missing from the strategy() function, the script displays in a chart panel below the chart’s instrument. When the strategy is already added to the chart before we add or change the overlay argument, we need to remove and re-add the script before the effect of the updated code becomes visible.

Learn more:


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 May 15, 2016, from https://www.tradingview.com/study-script-reference/