In TradingView we can colour the chart’s background programmatically, and that feature also allows colouring the background conditionally as well as overlapping coloured backgrounds. But how do we use coloured backgrounds to create a heat map-like effect in TradingView?

In this article:

Colouring the background and creating a heat map effect

TradingView’s bgcolor() function colours the bar’s full background from top to bottom (Pine Script Language Tutorial, n.d.), and does this in a subchart or the main price chart (depending on where the script itself displays). This function can colour the chart’s background with a basic TradingView colour or hexadecimal colour value.

We can use bgcolor() once or repeatedly within the same script. When we code our script so that bgcolor() is executed more than once on the same price bar, then its coloured backgrounds are placed on top of each other: the first bgcolor() function call makes the first background layer while the last bgcolor() statement makes the uppermost coloured backgrounds. See colouring a TradingView background repeatedly for more on this, including how it looks visually.

This bgcolor() feature can also create a heat map effect, which for instance can signal uptrends with a green-shaded background and downtrends with a reddish background. That effect is achieved by combining overlaying coloured backgrounds with colouring the background conditionally.

Let’s say we have 5 bgcolor() statements that conditionally colour the background red or green. The chart’s background is then fully green when all of them colour the bar’s background green (and likewise for a red background). But when three bgcolor() statements set the background to green and the other two to red, we’ll end up with a green-like background with a shade of red. Now by doing this on every bar we’ll create a heat map effect with some bars being fully green, others fully red, and other bars green-like and reddish.

Creating a heat map-like background in TradingView with the MACD

One approach (shared by ChartArt, a TradingView user) is to create a heat map-like background with the MACD (Moving Average Convergence Divergence) indicator, a trend-deviation indicator that uses a fast and slow moving average (Pring, 2002). After calculating the difference between these two moving averages, that difference (often plotted as a histogram) is then smoothed again with an additional moving average and plotted as a signal line (Pring, 2002).

In the example below we use different values from the MACD indicator to create a heat map effect. After discussing the example we’ll look at several charts, but let’s first discuss the script’s code:

study(title="MACD background heatmap", overlay=true)

// Inputs
srcData   = input(title="Price data", type=source, defval=close)
firstMA   = input(title="Fast MA", type=integer, defval=12)
secondMA  = input(title="Slow MA", type=integer, defval=26)
signalLen = input(title="Signal length", type=integer, defval=9)

// Calculate values
fastMA     = ema(srcData, firstMA)
slowMA     = ema(srcData, secondMA)
macdDiff   = fastMA - slowMA
macdSignal = ema(macdDiff, signalLen)
macdHist   = macdDiff - macdSignal

emaColour = (fastMA > slowMA) ? green : red

// Plot lines
plot(series=fastMA, color=emaColour, linewidth=2)
plot(series=slowMA, color=emaColour, linewidth=2)

// Colour the background
// .. based on the MAs
bgcolor(color=fastMA > slowMA ? green : red, transp=97)
bgcolor(color=change(fastMA) > 0 ? green : red, transp=97)
bgcolor(color=change(slowMA) > 0 ? green : red, transp=97)
bgcolor(color=change(macdDiff) > 0 ? green : red, transp=97)

// .. based on the histogram values
bgcolor(color=macdDiff > macdHist ? green : red, transp=97)
bgcolor(color=macdHist > 0 ? green : red, transp=97)
bgcolor(color=change(macdHist) > 0 ? green : red, transp=97)

// .. based on the MACD signal line
bgcolor(color=macdDiff > macdSignal ? green : red, transp=97)
bgcolor(color=macdSignal > 0 ? green : red, transp=97)
bgcolor(color=change(macdSignal) > 0 ? green : red, transp=97)

We start with the study() function that every indicator needs to have (TradingView, n.d.). By setting its overlay argument to true, the indicator displays on the instrument’s price chart and not in a separate chart panel.

Next we create several input options:

srcData   = input(title="Price data", type=source, defval=close)
firstMA   = input(title="Fast MA", type=integer, defval=12)
secondMA  = input(title="Slow MA", type=integer, defval=26)
signalLen = input(title="Signal length", type=integer, defval=9)

These inputs are made with input(). That function creates an input option in the script’s settings (see image further down below), and also returns the setting’s current value (TradingView, n.d.). By storing that value in a variable with the assignment operator (=), we can conveniently change one of the values used in a script without having to edit the script’s source code (Pine Script Language Tutorial, n.d.).

We first make a ‘source’ input type (type=source) that has its current value stored in the srcData input variable. This kind of input creates a pull-down menu in the script’s settings that’s used to select different kinds of price data from the instrument that the script is added to (Pine Script Language Tutorial, n.d.). That menu, for instance, contains options for ‘high’, ‘low’, and ‘close’. Here we set the input’s default value (defval) to close, meaning that the srcData variable holds the instrument’s closing prices by default. With the title argument we set the input option’s name to “Price data”, and this text is what’s placed before the input option in the script’s settings (TradingView, n.d.).

The three other inputs are all numerical integer input options, and we make these by setting the type argument of the input() function to integer (Pine Script Language Tutorial, n.d.). The first of these, which has a default value (defval) of 12, is named “Fast MA” and has its current value stored in the firstMA variable. The next input is named “Slow MA”, and defaults to 26 with its current value put into the secondMA variable. “Signal length” is the title of the last input and we store its standard value of 9 (as well as any other value that this input is set to) in the signalLen input variable.

Then we calculate some of the values needed in our script:

fastMA     = ema(srcData, firstMA)
slowMA     = ema(srcData, secondMA)
macdDiff   = fastMA - slowMA
macdSignal = ema(macdDiff, signalLen)
macdHist   = macdDiff - macdSignal

The moving averages for the MACD are computed with ema(). That function returns an Exponential Moving Average (EMA) and requires two arguments: a series of values to process and an integer that sets the EMA length in number of bars (TradingView, n.d.).

To get the value of the quick moving average we use ema() and pass in the srcData and firstMA input variables. The first of these holds the instrument’s closing prices by default while 12 is the standard value of the second input variable. We store this 12-bar EMA of closing prices in the fastMA variable. The slower moving average (whose value we assign to the slowMA variable) is determined similarly, except that here we set the EMA length to the secondMA input variable that defaults to 26.

Then we subtract the current value of the slow moving average from the faster moving average and store that difference in the macdDiff variable. The macdSignal variable that’s created next is set to the EMA of the difference between the fast and slow moving average (macdDiff) and computed on the signalLen number of bars. That latter variable holds the current setting of the “Signal length” input that we’ve set to a default value of 9 earlier. We end this part of our example by calculating the MACD histogram (macdHist) value, for which we subtract the macdSignal variable from the macdDiff variable.

Before plotting the moving averages, we first figure out their colour:

emaColour = (fastMA > slowMA) ? green : red

The plot colour (which we store in the emaColour variable) is determined here with the conditional ternary operator (?:). This operator requires a true/false condition as its first value. When that condition is true, it returns its second value; when the condition is false, this operator returns its third value (Pine Script Language Tutorial, n.d.).

Our condition here is whether the value of the fastMA variable is greater than (>) the slowMA variable. When the indicator’s input options are set to their default values, this condition evaluates if the 12-bar EMA of closing prices is above the 26-bar EMA of closing prices. When that’s the case on the current bar, the conditional operator returns the green basic TradingView colour which is then stored in the emaColour variable. Should the quicker moving average be less than or equal to the slow one (meaning the condition isn’t true), then the red colour is returned by the conditional operator and assigned to the emaColour variable. This also means that this variable either holds the green or red colour.

We use the emaColour variable when plotting the EMA values:

plot(series=fastMA, color=emaColour, linewidth=2)
plot(series=slowMA, color=emaColour, linewidth=2)

The plot() function creates, by default, a line plot that’s set to the values specified by its series argument (TradingView, n.d.). In the first plot() statement here we set that argument to the fastMA variable. Those quick EMA values are painted with the emaColour variable and so shown in red or green depending on how both EMAs are positioned. With the linewidth argument set to 2 we create a line that’s one step bigger than the default size (TradingView, n.d.). The second plot() statement is nearly identical, except that here we display the slowMA values on the chart.

After plotting the moving averages we colour the chart’s background. Those overlaid coloured backgrounds are made in three steps: first we colour the chart’s background based on the moving averages, then we use the histogram values, and the last bgcolor() statements use the MACD signal line.

So we begin with colouring the chart’s background from top to bottom with moving average values:

bgcolor(color=fastMA > slowMA ? green : red, transp=97)
bgcolor(color=change(fastMA) > 0 ? green : red, transp=97)
bgcolor(color=change(slowMA) > 0 ? green : red, transp=97)
bgcolor(color=change(macdDiff) > 0 ? green : red, transp=97)

Before discussing the specifics of these bgcolor() statements, let’s discuss what all four have in common. Each has its color argument is set to green or red with the conditional ternary operator (?:). That operator, as we saw above, evaluates a condition and returns its second value when the condition is true and its third value when it’s false (Pine Script Language Tutorial, n.d.).

Another similarity is the transp argument with a value of 97. That argument sets the background’s transparency with values ranging from 0 (fully solid) to 100 (fully invisible) (TradingView, n.d.). This argument set to 97 creates a highly transparent background. That, in turns, helps when combining colours backgrounds: with a high transparency, we can still see colours of several backgrounds ‘shine through’ which wouldn’t be possible when each background was fully solid.

Now let’s discuss what these four bgcolor() statements do. The first colours the chart’s background red or green depending on the fastMA > slowMA condition. When the faster moving average is indeed greater than (>) the slower moving average on the current bar, bgcolor() colours the background green and red otherwise. Since this statement is the very first bgcolor() function call in our script, it creates the coloured background that all subsequent coloured backgrounds are placed on.

The color argument of the next three bgcolor() function calls is set with the conditional operator and the value returned by the change() function. That function returns the difference between the current and previous bar value (TradingView, n.d.), and so it returns a positive number when the value between its parentheses has increased (risen) and a negative number when that value has decreased (dropped).

So in the second bgcolor() statement, where the condition that affects the color argument is change(fastMA) > 0, we check if the faster moving average has increased on this bar compared to the previous bar. When it has, we see that as bullish and the conditional operator returns green (and red otherwise).

The next bgcolor() statement also uses the change() function, but here it’s used to evaluate if the slower moving average has increased (change(slowMA) > 0). When that happened, the current bar’s background is made green. The fourth and final bgcolor() statement in this part sets the background colour based on the change of the distance between both moving averages (change(macdDiff) > 0`).

The next group of bgcolor() statements use the MACD histogram to colour the background red or green:

bgcolor(color=macdDiff > macdHist ? green : red, transp=97)
bgcolor(color=macdHist > 0 ? green : red, transp=97)
bgcolor(color=change(macdHist) > 0 ? green : red, transp=97)

These three bgcolor() statements are similar to the previous ones: they also create a highly transparent (transp=97) red or green background. The first of them uses the conditional operator to see if the macdDiff variable (which holds the value of the slow moving average subtracted from the fast one) is greater than (>) macdHist. That latter variable holds the difference between the macdDiff variable and its 9-bar moving average.

In the next bgcolor() statement there’s a condition that checks if the MACD histogram (macdHist) is above 0. That happens when the difference between the fast and slow moving averages is greater the 9-bar EMA of this difference, which can be seen as positive and so we colour the background green when that happens.

In this section’s last bgcolor() statement we use the change() function to see if the MACD histogram has increased on the current bar (change(macdHist) > 0). Since that also can be considered bullish, that situation also leads to a green background.

We conclude the example with three additional bgcolor() statements that colour the chart’s background based on the MACD signal line values:

bgcolor(color=macdDiff > macdSignal ? green : red, transp=97)
bgcolor(color=macdSignal > 0 ? green : red, transp=97)
bgcolor(color=change(macdSignal) > 0 ? green : red, transp=97)

The color argument of the first bgcolor() function call is set to green or red here depending on the macdDiff > macdSignal condition. That condition evaluates to true whenever the difference between the fast and slow moving averages is greater than the EMA of that difference.

The macdSignal variable is also used with this part’s second bgcolor() statement, but this time the EMA of the slow moving average subtracted from the fast one needs to be positive (macdSignal > 0) before the background is made green. The last line of our example also uses that EMA, this time with a bgcolor() function call that colours the background depending on how that EMA differs compared to the previous bar (change(macdSignal) > 0).

Creating a heat map-like background in TradingView programmatically

When we add our example indicator to a EUR/USD chart, it looks like:

Example of a heat map background in TradingView

And the overlaid backgrounds look like this on a S&P 500 Index CFD chart:

A heat map TradingView background on the S&P 500 index

Before changing the indicator’s settings, its backgrounds look like this on a Crude Oil CFD chart:

Colouring the background of a TradingView chart

The input options of the indicator are the following:

Input options of the TradingView example script

When we change the ‘Fast MA’ and ‘Slow MA’ inputs to values of 25 and 57, then the previous Crude Oil chart becomes:

Colouring the background of a TradingView chart like a heat map

Things that are also possible with the bgcolor() function are offsetting a coloured background and colouring a background conditionally. For more on this function and its arguments, see colouring a TradingView background. Whereas bgcolor() colours the bar’s full background from top to bottom, the fill() function only colours a background section. Both functions, however, work with the basic TradingView colours and hexadecimal colour values.

Summary

The bgcolor() function colours a bar’s background (from top to bottom) with the colour set by its color argument. This function affects the background of the chart’s main instrument (when the script displays in that area) or the background of the script’s subchart. When bgcolor() is used several times in one script, the function call order matters: the first bgcolor() statement colours the main background and any subsequent bgcolor() function calls create coloured backgrounds placed on top of the previous. This allows for creating a heat map-like background, provided that the transp argument (which sets the background’s transparency) is set to a high-enough value so that the colour of underlying backgrounds ‘shines through’.


References

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

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

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