In TradingView we can colour the chart’s background from top to bottom and colour a background area as well. How do these features compare and how do we combine them?

In this article:

Colouring chart areas and the full background in TradingView

A TradingView background can be coloured with a basic TradingView colour or a hexadecimal colour value. Those backgrounds are displayed in the area of the chart’s main instrument or in the script’s subchart, depending on whether the overlay argument of the study() or strategy() function is set to true or false, respectively (TradingView, n.d.).

There are two types of coloured backgrounds in TradingView. The first is created by the bgcolor() function, and gives the bar’s full background from top to bottom a certain colour (Pine Script Language Tutorial, n.d.). We take a closer look at this function in colouring a chart’s background in TradingView.

The fill() function also colours the background. But instead of the full background, it colours the background area that’s between two plots or two horizontal lines (Pine Script Language Tutorial, n.d.). To know between which plots or horizontal lines the background area should be coloured, the function either requires two plot objects (that are returned by the plot() function) or two horizontal line objects, which the hline() function returns (TradingView, n.d.). While objects sound abstract, they represent a plot or line just like a numerical variable represents a certain number. For more on the fill() function and its arguments, see colouring part of the chart’s background.

The bgcolor() and fill() functions have similarities and differences. Their sameness includes a color argument to set the background colour and a transp argument for defining the background’s transparency with a value from 0 (no transparency) to 100 for full transparency (TradingView, n.d.). A remarkable difference is that bgcolor() can colour the background conditionally while fill() cannot. This means that the background made by fill() is the same on every bar, while bgcolor() can use different colours and even ‘turn off’ the coloured background.

For a better understanding of the differences and similarities between bgcolor() and fill(), let’s look at an example indicator that combines both.

Colouring a TradingView background or chart area programmatically

In the example below we plot an EMA (Exponential Moving Average) together with four price bands. Those price bands are computed with a certain number of standard deviations, and two of them are placed above the EMA while the other two are below this moving average.

That is like the Bollinger Bands, an indicator that generates trend following signals whenever the price exceeds its bands (Pring, 2002). When prices move outside the bands in our example indicator, we’ll colour the bar’s full background while we use fill() to colour the area between the bands. Afterwards we’ll look at charts with the indicator on it, but let’s first discuss the code:

study(title="Overlaying coloured background areas", overlay=true)

// Input options
priceData  = input(title="Price data", type=source, defval=hl2)
maLength   = input(title="MA length", type=integer, defval=20)
sdLength   = input(title="StDev length", type=integer, defval=12)
offset1    = input(title="1st StDev offset", type=float, 
     defval=1.25, minval=0.1)
offset2    = input(title="2nd StDev offset", type=float, 
     defval=2.25, minval=0.1)
colourBg   = input(title="Colour background?", type=bool, defval=true)
highLowLen = input(title="High/low lookback", type=integer, defval=20)

// Compute values
maValue = ema(priceData, maLength)
sdValue = stdev(priceData, sdLength)

maPlus2 = maValue + (offset2 * sdValue)
maPlus1 = maValue + (offset1 * sdValue)
maMin1  = maValue - (offset1 * sdValue)
maMin2  = maValue - (offset2 * sdValue)

// Plot values
plotPlus2 = plot(series=maPlus2, color=green, linewidth=2)
plotPlus1 = plot(series=maPlus1, color=green, linewidth=2)

maPlot = plot(series=maValue, color=gray, style=circles, linewidth=2)

plotMin1 = plot(series=maMin1, color=red, linewidth=2)
plotMin2 = plot(series=maMin2, color=red, linewidth=2)

// Colour background sections between plots
fill(plot1=plotPlus2, plot2=plotPlus1, color=green, transp=87)
fill(plot1=plotPlus1, plot2=maPlot, color=green, transp=92)

fill(plot1=maPlot, plot2=plotMin1, color=red, transp=92)
fill(plot1=plotMin1, plot2=plotMin2, color=red, transp=87)

// Colour full background from top to bottom
colourOfBg = (colourBg and priceData > maPlus2) ? green :
    (colourBg and priceData < maMin2) ? red :
    na

bgcolor(color=colourOfBg, transp=90)

newHigh = (high == highest(high, highLowLen))
newLow  = (low == lowest(low, highLowLen))

bgcolor(transp=85, color=
    (colourBg and newHigh and priceData > maPlus2) ? lime :
    (colourBg and newLow and priceData < maMin2) ? fuchsia :
    na)

We start the indicator with the study() function. With this function’s overlay argument set to true the script displays in the main price chart area and not in a separate subchart. This also means our coloured backgrounds will be applied to the chart’s instrument.

Next we add several inputs to the script:

priceData  = input(title="Price data", type=source, defval=hl2)
maLength   = input(title="MA length", type=integer, defval=20)
sdLength   = input(title="StDev length", type=integer, defval=12)
offset1    = input(title="1st StDev offset", type=float, 
     defval=1.25, minval=0.1)
offset2    = input(title="2nd StDev offset", type=float, 
     defval=2.25, minval=0.1)
colourBg   = input(title="Colour background?", type=bool, defval=true)
highLowLen = input(title="High/low lookback", type=integer, defval=20)

With input options it’s easy to manually change values that are used in the script. That’s because inputs are made with input() and that function also returns the input’s current value (Pine Script Language Tutorial, n.d.). Here we use the assignment operator (=) to store those returned values in variables. And so whenever we change an input’s value by hand, the input variable changes with it. And that affects the calculations in our script wherever that input variable is used.

The first input that we make is a so-called ‘source’ input option, made by setting the input() function’s type argument to source (TradingView, n.d.). This input has a pull-down menu for selecting different kinds of price data from the instrument that the script is added to (Pine Script Language Tutorial, n.d.), such as its high, low, or close prices. Here its default value (defval) is hl2, a value that resembles the bar’s midpoint (that is, [high + low] / 2) (TradingView, n.d.). The title argument specifies the name to place before the input in the script’s settings (Pine Script Language Tutorial, n.d.), and we set that to “Price data” here. This input’s value is assigned to the priceData variable, and we’ll use this to compute the EMA and standard deviation on.

We then add two numerical integer inputs by setting the type argument of the input() function to integer. The first of these is named “MA length” with a default value of 20, and has its current setting stored in the maLength variable. The other integer input is named “StDev length” and has a default value of 12. This input, whose value is stored in the sdLength variable, is used later on to set the standard deviation length.

The next two inputs are floating-point inputs which can hold decimal values and are made by setting the type argument of the input() function to float (Pine Script Language Tutorial, n.d.). We name them “1st StDev offset” and “2nd StDev offset” and use these later on when multiplying the standard deviation values. With the minval argument, which sets a numerical input’s minimum value (TradingView, n.d.), we ensure that the minimum standard deviation offset is one-tenth. Their current values are stored in the offset1 and offset2 variables.

In the next input() function call we set the type argument to bool. That makes a Boolean true/false input that displays as a checkbox in the script’s settings (Pine Script Language Tutorial, n.d.). We store this input’s current value in the colourBg variable that we’ll use later on to colour the background conditionally. This input is titled “Colour background?” and enabled by default (defval=true).

The last input option that we make is again a numerical integer input. We name this one “High/low lookback” and give it a default value of 20 with its current value put into the highLowLen variable. That variable is used to set the period of the highest high and lowest low when we check if there’s a strong breakout.

After creating the input options we calculate several values:

maValue = ema(priceData, maLength)
sdValue = stdev(priceData, sdLength)

maPlus2 = maValue + (offset2 * sdValue)
maPlus1 = maValue + (offset1 * sdValue)
maMin1  = maValue - (offset1 * sdValue)
maMin2  = maValue - (offset2 * sdValue)

The value that we assign to the maValue variable here is returned by ema(), a function that calculates the EMA based on a series of values alongside an integer that sets the amount of bars to compute the moving average on (TradingView, n.d.). We base the EMA on priceData, our input variable that we set to the bar’s midpoint (hl2) value earlier while the moving average length is set with the maLength input variable.

We calculate the standard deviation with stdev(). That function, just like ema(), works on a series of values and an integer that sets the standard deviation length (TradingView, n.d.). We set the first argument to the priceData input here, and set the number of bars to calculate the standard deviation on with sdLength. The value returned by stdev() is stored in the sdValue variable for use later on in the script.

After computing the EMA and the standard deviation we determine the price bands. The two price bands above the EMA are stored in the maPlus2 and maPlus1 variables, while the maMin1 and maMin2 variables hold the price bands values below the moving average. We get these price bands by taking the EMA value (maValue) and adding or subtracting an offset value times the standard deviation (sdValue). That multiplication is performed with the offset1 and offset2 variables that have standard values of 1.25 and 2.25.

Next those values are plotted on the chart:

plotPlus2 = plot(series=maPlus2, color=green, linewidth=2)
plotPlus1 = plot(series=maPlus1, color=green, linewidth=2)

maPlot = plot(series=maValue, color=gray, style=circles, linewidth=2)

plotMin1 = plot(series=maMin1, color=red, linewidth=2)
plotMin2 = plot(series=maMin2, color=red, linewidth=2)

We plot the values on the chart with plot(), a function that displays whichever data its series argument is set to (TradingView, n.d.). Other plot() arguments that we use here are color (which sets the plot colour) and linewidth. That latter argument sets the plot size with values ranging from 1 (default) to 4 for the thickest plot possible (TradingView, n.d.). The plot() function always returns a plot object, but we often have no use for it. But that’s not the case in our current example: since we’re going to fill the background area between two plots, we store each plot object in a variable for use later.

The first plot() function call displays the maPlus2 variable on the chart, which is the top price band that’s furthest away from the EMA. We set this line to the green basic TradingView colour and give it a linewidth that’s one step above the default size. The second plot() function call is highly similar, except that now we plot the maPlus1 values that are one standard deviation offset above the EMA.

The plot object that’s stored in the maPlot variable are the EMA values (maValue) plotted in grey (color=gray), with a plot slightly greater than typically (linewidth=2). This plot has its style argument set to circles to have it plot small, non-connecting dots instead of the standard line plot (TradingView, n.d.).

The last two plot() function calls display the maMin1 and maMin2 variables on the chart, which are the price bands placed below the EMA based on some multiple of the standard deviation value. These lines plotted in red have their plot objects stored in the plotMin1 and plotMin2 variables with the assignment operator (=).

Now, let’s use those plot objects to colour several chart areas:

fill(plot1=plotPlus2, plot2=plotPlus1, color=green, transp=87)
fill(plot1=plotPlus1, plot2=maPlot, color=green, transp=92)

fill(plot1=maPlot, plot2=plotMin1, color=red, transp=92)
fill(plot1=plotMin1, plot2=plotMin2, color=red, transp=87)

With the fill() function we colour the chart’s background that’s between two plots or two horizontal lines (TradingView, n.d.). Here we use that function four times, each time to colour a background area between two plots. With this function’s plot1 and plot2 arguments we specify between which plots the background should be filled (TradingView, n.d.).

The first fill() function call fills the area between the plotPlus2 and plotPlus1 plots, which are the price bands plotted above the EMA value. We set this background’s colour to the green basic TradingView colour and its transparency (transp) to 87%. The next fill() statement colours the background section between the plotPlus1 plot (the first price band above the EMA) and the EMA value itself (maPlot). This filled background is green, but only very lightly so due to its high transparency (transp=92).

The third fill() function call fills the area between the maPlot and plotMin1 plots, which is the chart background between the EMA and the first price band plotted below this moving average. This area is coloured red (color=red) in a very light shade (transp=92). The fourth and last fill() statement fills the chart area between the two price bands that are below the EMA (the plotMin1 and plotMin2 plots), and also makes this background section red but a bit more pronounced due to a lower transparency (transp=87).

After colouring the area between the plots, we highlight price bars that moved outside the price bands:

colourOfBg = (colourBg and priceData > maPlus2) ? green :
    (colourBg and priceData < maMin2) ? red :
    na

bgcolor(color=colourOfBg, transp=90)

We assign the colourOfBg variable a value here with the help of two conditional (ternary) operators (?:). That kind of operator evaluates a true/false condition as its first value and, when that condition is true, returns its second value. Should the condition be false, then the conditional operator returns its third and last value (Pine Script Language Tutorial, n.d.). By using multiple conditional operators, as we do here, we can evaluate multiple conditions.

The condition of the first conditional operator has two expressions joined together with the and logical operator. This operator only returns true when the value on its left and the one on its right are both true, and returns false when one or both of them are false (Pine Script Language Tutorial, n.d.).

In that first condition we begin with evaluating colourBg, which is our true/false input variable of the “Colour background?” setting. This variable holds true when that input is enabled and false when disabled. The other part of our condition is whether the value of priceData (which holds the bar’s midpoint by default) is greater than (>) the topmost price band (maPlus2). When both of these expressions are true, the first conditional operator returns the green basic TradingView colour which is then stored in the colourOfBg variable.

But when that condition of the first conditional operator isn’t true, the second conditional operator is processed. This one also checks the colourBg input variable besides verifying if the price is less than the lowest price band (priceData < maMin2). When the bar’s price indeed moved below the lowest price band and we’ve enabled the “Colour background?” input option, then the second conditional operator returns red and that colour is then assigned to the colourOfBg variable.

Should the condition of the second conditional operator be false also, then this operator returns na to be stored in the colourOfBg variable. That na built-in variable represents a “not a number” value (TradingView, n.d.) which, in this context, has the effect of making a coloured background fully invisible (Pine Script Language Tutorial, n.d.).

After giving the colourOfBg variable one of three values (green, red, or na), we set the chart’s background to that variable’s value with the bgcolor() function. We also set this function’s transp argument to 90 for a highly transparent background.

So what happens here? When the price moves above the upper price band and the “Colour background?” option is enabled, then we’re making the bar’s background from top to bottom green. Should the price drop below the lowest price band and “Colour background?” is enabled, then that the background is made red. When the price hasn’t moved outside the price bands and/or the “Colour background?” option is turned off, then the background is transparent (that is, ‘turned off’). This shows how we can use the “Colour background?” input option to turn the background colouring on or off.

The example ends with another code segment that conditionally colours the background:

newHigh = (high == highest(high, highLowLen))
newLow  = (low == lowest(low, highLowLen))

bgcolor(transp=85, color=
    (colourBg and newHigh and priceData > maPlus2) ? lime :
    (colourBg and newLow and priceData < maMin2) ? fuchsia :
    na)

We create two Boolean variables here: newHigh and newLow. The first is assigned true or false depending on a condition that checks if the current bar’s high equals (==) the highest high. That latter value is retrieved with the highest() function with two arguments: a series of values and an integer that sets the number of bars to get the highest price of (TradingView, n.d.). With the high and highLowLen values passed into this function, we get the 20-bar high price (assuming that the “High/low lookback” input option is still set to its standard value of 20). This way our newHigh variable holds true when the bar’s high is a new 20-bar high.

The newLow variable is set similarly, this time checking if the current bar’s low equals the lowest low of the last highLowLen number of bars, including the current bar. When that’s the case, newLow holds a value of true and false otherwise.

The very last line in our example indicator is another bgcolor() function call. This background is less transparent (transp=85) than the other, but its color argument is also set to one of three values (lime, fuchsia, or na) with the help of two conditional operators (?:). The difference is that now we don’t create a variable first, but use the conditional operators directly inside the parentheses of the bgcolor() function.

They may look cryptic, but these conditional operators works just like the previous ones. Here we colour the background lime when three expressions are true: the colourBg input variable, the newHigh variable, and priceData > maPlus2. This means the current bar’s background is lime green when the “Colour background?” input is turned on, the current bar’s high is a new highest high, and the price is above the topmost price band. Should one or several of these expressions be false, then the next conditional operator is evaluated.

That conditional operator colours the current bar’s background fuchsia when three things are the case: the “Colour background?” input is enabled, the bar’s low is a new lowest low, and the price is below the lowest price band. When one or several of these are false, then the conditional operator returns na so that bgcolor() creates a fully transparent background on the current bar.

Colouring the chart and its different chart areas programmatically

When we add the above example to a EuroStoxx 50 CFD chart, it looks this:

Colouring the background and chart areas in TradingView

And applied to a S&P 500 Index CFD chart, our example indicator displays as:

Programmatically colouring the background in TradingView

The input options that the script makes are the following:

Input options of our TradingView example script

When we change the ‘Price Data’ input to ‘close’, set the moving average and standard deviation length to 35 and 20, and disable the ‘Colour Background?’ option; then the previous S&P 500 Index CFD chart changes to:

Coloured price bands in TradingView Pine

Other things possible with the fill() function are colouring the background between a plot and line and highlighting support and resistance areas. Applications of the bgcolor() function include creating a heat map effect and colouring the background of forex market sessions. Both functions can use standard TradingView colours and hexadecimal colour values.

Summary

The background of a TradingView chart can be coloured with the bgcolor() and fill() functions. The first colours the bar’s background from top to bottom, while the second fills the background that’s between two plots or two horizontal lines. For this the fill() function requires two plot objects (which are returned by plot()) or two horizontal line objects that hline() returns. The bgcolor() function can colour the background conditionally; something that isn’t possible with fill().


References

Pring, M.J. (2002). Technical Analysis Explained (4th edition). New York, NY: McGraw-Hill.

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

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