In TradingView we can colour plots and horizontal lines, and also fill the background section that’s between these. But how do we colour the complete background of a TradingView chart, from top to bottom?

In this article:

Colouring the full background of a TradingView chart

We can set a script’s colours by hand but also with code, and this latter makes things like using colours conditionally possible. The available colours in TradingView are the basic colour variables and hexadecimal colour values that literally allow for millions of colours.

Several functions have a color argument that accepts a colour value. One of those is bgcolor(). That function colours the script’s background (Pine Script Language Tutorial, n.d.) and this can either be the background of the price chart or a subchart (depending on where the script displays). Things that we can do with bgcolor() including colouring the chart’s background conditionally and highlight the background of trading sessions.

The bgcolor() function has the following default syntax (TradingView, n.d.):

bgcolor(color, transp, offset, editable, title)

These arguments work as follows (Pine Script Language Tutorial, n.d.; TradingView, n.d.):

Argument Description
color Required argument that sets the colour of the filled background to a basic TradingView colour or a hexadecimal colour value. This argument can also be set to an expression (like close > open ? green : red) in order to colour the chart’s background conditionally.
transp Optional argument that sets the filled background’s transparency. It defaults to 90 (highly transparent) and its possible values range from 0 (not transparent) to 100 (fully invisible).
offset Optional argument that shifts the coloured background with a certain number of bars. When omitted, offset defaults to 0 (meaning no offset). Setting this argument to negative values shifts the background to the left (that is, to the past) while positive values relocate it to the future bars on the chart’s right. Also see offsetting a coloured background.
editable Optional argument that, with its default value of true, allows us to manually change the filled background’s settings in the script’s ‘Style’ window. The background settings cannot be manually changed when editable is set to false.
title Optional argument that specifies the title of the filled background, and this name shows up in the ‘Style’ window when manually changing a script’s colours. A descriptive name makes it easier to distinguish between different backgrounds.
Note: The bgcolor() and fill() functions both colour the chart’s background. But where fill() colours the background section that’s between two plots or two horizontal lines, bgcolor() colours the chart’s background from top to bottom.

Colouring the chart’s background with a TradingView trading strategy

An example of the bgcolor() function is given below. In this strategy we enter a long position when three EMAs (Exponential Moving Averages) are aligned above each other and go short when they’re positioned below each other. The script’s background is given a colour depending on the strategy’s market position: when long, the background is made green; when short, it’s red. After discussing the code we’ll look at several charts with the script on it. But first the code:

//@version=2
strategy(title="EMA crosses", overlay=true)

// Inputs
priceData  = input(title="Price data", type=source, defval=hl2)
ema1Length = input(title="EMA 1", type=integer, defval=12)
ema2Length = input(title="EMA 2", type=integer, defval=24)
ema3Length = input(title="EMA 3", type=integer, defval=36)

// Compute values
ema1 = ema(priceData, ema1Length)
ema2 = ema(priceData, ema2Length)
ema3 = ema(priceData, ema3Length)

enterLong  = ema1 > ema2 and ema2 > ema3 and not nz(enterLong[1], 0)
enterShort = ema1 < ema2 and ema2 < ema3 and not nz(enterShort[1], 0)

// Plot values
plot(series=ema1, color=orange, linewidth=2)
plot(series=ema2, color=maroon, linewidth=2)
plot(series=ema3, color=blue, linewidth=2)

// Submit orders
if (enterLong)
    strategy.entry(id="Enter Long", long=strategy.long)

if (enterShort)
    strategy.entry(id="Enter Short", long=strategy.short)

// Colour background
backgroundColour = (strategy.position_size > 0) ? green : red

bgcolor(color=backgroundColour, transp=85)

We start with the strategy() function that’s required for every trading strategy (TradingView, n.d.). We set this function’s overlay argument to true to display the strategy overlaid on the chart’s instrument. Since we’re going to use if statements later on, we need to set the Pine Script version to 2 (Pine Script Language Tutorial, n.d.). We do that with the //@version=2 statement in the top of the script.

Next we add three inputs to the strategy:

priceData  = input(title="Price data", type=source, defval=hl2)
ema1Length = input(title="EMA 1", type=integer, defval=12)
ema2Length = input(title="EMA 2", type=integer, defval=24)
ema3Length = input(title="EMA 3", type=integer, defval=36)

We make these manual input options with input(), a function which also returns the input’s current value (TradingView, n.d.).

The first input that we make here is a source data input option. For that we set the input() function’s type argument to source. Such an input creates a pull-down menu in the script’s settings that allows selecting price data from the instrument that we added the script to (Pine Script Language Tutorial, n.d.). These source input options are typically used to specify the kind of price data that a script should calculate with. In our case, we set this input’s default value (defval) to hl2. That built-in variable returns the bar’s midpoint (that is, its [high + low] / 2 value) (TradingView, n.d.). We name our input “Price data” and use the assignment operator (=) to store its current value in the priceData variable. That way we can use this variable to reference the “Price data” input’s current value.

The three other inputs are all numerical integer inputs, and we make these by setting the type argument of the input() function to integer. These inputs, named “EMA 1”, “EMA 2”, and “EMA 3”, are given default values of 12, 24, and 36. We store the current value that’s returned by input() here in the ema1Length, ema2Length, and ema3Length input variables. That way we can refer them later on when calculating the EMAs.

Then we compute the moving averages:

ema1 = ema(priceData, ema1Length)
ema2 = ema(priceData, ema2Length)
ema3 = ema(priceData, ema3Length)

The EMAs are calculated with ema(), a function that requires two arguments: a series of data alongside the number of bars to calculate the EMA on (TradingView, n.d.). These moving averages are based on the priceData values that we set to a default of hl2 just a moment ago. The EMAs’ length is set to the ema1Length, ema2Length, and ema3Length input variables. We store the computed EMA values that are returned by ema() in the ema1, ema2, and ema3 variables.

Those EMA values are then used for figuring out the value of the enterLong and enterShort variables:

enterLong  = ema1 > ema2 and ema2 > ema3 and not nz(enterLong[1], 0)
enterShort = ema1 < ema2 and ema2 < ema3 and not nz(enterShort[1], 0)

Both variables are given a true/false value based on an expression that uses the greater than (>) and less than (<) comparison operators as well as the and and not logical operators.

The enterLong variable is assigned a true/false value based on three conditions. Since we combine those conditions with the and logical operator, all of them need to be true before enterLong is given a value of true. When one or several conditions are false, then and makes the combined result false too (Pine Script Language Tutorial, n.d.). Our first condition checks if the first EMA is above the second (ema1 > ema2) while the next condition evaluates whether the second EMA is above the third (ema2 > ema3). In other words, the quickest EMA needs to be above the middle EMA and that EMA needs to be above the slowest EMA.

The third condition that’s used to set the value of the enterLong variable looks obscure: not nz(enterLong[1], 0). Three things happen in this small expression. First, we retrieve the previous bar value of enterLong with the history referencing operator ([]). But when the strategy calculates on the first bar of the data series, then there isn’t a enterLong[1] value because there isn’t a previous bar yet. In that case, the history referencing operator returns NaN ( “not a number”) (Pine Script Language Tutorial, n.d.).

The problem is that those NaN values cannot be used as a true/false value. And so we use the nz() function here to replace any NaN value returned by enterLong[1] with 0 (TradingView, n.d.). Because TradingView sees 0 as false and 1 as true (TradingView, n.d.), we’re in effect replacing any NaN value with false here.

We placed the not logical operator before nz(). This operator returns true when the value it precedes is false and returns false when placed for something that’s true (Pine Script Language Tutorial, n.d.). And so when enterLong[1] evaluates to false, then not enterLong[1] returns true. Since this not expression is joined with the two other conditions with and, it means that enterLong is only assigned true when not enterLong[1] returns true also. After all, with and all conditions need to be true before the result is true also (Pine Script Language Tutorial, n.d.).

So why use such a complex statement to give the enterLong variable its value? We do that because we want enterLong to be true just once when the three EMAs are positioned correctly, and not stay true on the bars after that. Otherwise, our strategy would continue to fire market orders and we end up with a much bigger long position than intended. And that’s why we require that enterLong[1] is false before the current value of enterLong can be true.

After giving the enterLong variable its value, we assign the enterShort variable a true/false value in much the same way. The difference is that we now check whether the first EMA is below the second (ema1 < ema2) and whether that second EMA is below the third (ema2 < ema3). For the enterShort variable we also require that its previous bar value was false (not nz(enterShort[1], 0)). And so our enterShort variable is true when the first EMA is below the second EMA and the second EMA is below the third, and both of these EMAs need to be aligned in a different way on the previous bar.

Next we plot the EMA values on the chart:

plot(series=ema1, color=orange, linewidth=2)
plot(series=ema2, color=maroon, linewidth=2)
plot(series=ema3, color=blue, linewidth=2)

We perform the plotting with plot(), a function that displays the values on the chart that are specified by its series argument (TradingView, n.d.). That argument is set to the ema1, ema2, and ema3 variables here, and these hold the 12-bar, 24-bar, and 36-bar EMAs when the input options are set to their default values. With the linewidth argument set to 2 we make these lines a bit bigger than their default size (see TradingView, n.d.), and their colours are set to the orange, maroon, and blue standard TradingView colours.

We then submit the strategy’s orders:

if (enterLong)
    strategy.entry(id="Enter Long", long=strategy.long)

if (enterShort)
    strategy.entry(id="Enter Short", long=strategy.short)

These two if statements use the enterLong and enterShort true/false variables. An if statement evaluates a condition and, when that condition is true, executes a block of code (Pine Script Language Tutorial, n.d.). The first if statement evaluates the enterLong variable and, when this variable returns true, executes the statement below it.

That indented statement calls strategy.entry(), a function that by default submits a market order to open a position (TradingView, n.d.). Two of its arguments are defined here: id (which sets the order identifier) and long. This latter argument either needs to be set to strategy.long (or true) for submitting a buy order or set to strategy.short (or false) for submitting an enter short order (TradingView, n.d.).

To open a bullish position whenever enterLong is true, we set the strategy.enter() function’s id argument to “Enter Long” and use strategy.long to specify the long argument’s value. We initiate a bearish position with the second if statement similarly, but now the enterShort variable needs to be true. When it is, we use the strategy.entry() function to send an enter short (long=strategy.short) order named “Enter Short”.

Note: We submit entry orders in this example with strategy.entry() but don’t place exit orders, which require the strategy.close() or strategy.exit() function (TradingView, n.d.). This means our strategy is always in the market, and changes its market position from short to long and vice versa.

We end the example with finally colouring the chart’s background, based on the strategy’s current position:

backgroundColour = (strategy.position_size > 0) ? green : red

bgcolor(color=backgroundColour, transp=85)

Here we colour the background conditionally. For that we first create the backgroundColour variable and assign it the value returned by the conditional ternary operator (?:). That operator evaluates a condition and returns its second value when the condition is true or its third value should the condition be false (Pine Script Language Tutorial, n.d.).

The condition that we evaluate here is whether the value of strategy.position_size is greater than (>) 0. The strategy.position_size built-in variable returns both the direction and size of the strategy’s open position: a positive value indicates the number of open long contracts, shares, or units; a negative value signals the market position to the short side (TradingView, n.d.). And so our condition here checks if the strategy is currently long. If that’s the case, the conditional operator returns the green basic TradingView colour; otherwise, the red colour is returned.

After storing one of those colours in the backgroundColour variable, we change the chart’s background colour with bgcolor(). We set this function’s color argument to the backgroundColour variable and its transp argument, which sets the coloured background’s transparency (TradingView, n.d.), is set to 85 for a reasonably transparent background. This way the chart’s background is coloured green when the strategy is long and red when it’s short.

Colouring the background of a TradingView strategy

When the above example strategy is added to a Brent Crude Oil CFD, the chart looks as follows:

Colouring the background of a TradingView chart

And added to a EUR/USD chart, the strategy looks like:

Colouring the background of a forex chart in TradingView

The input options that the example script has are:

Input options of the TradingView example strategy

When we, for example, change the ‘Price Data’ input to ‘close’ and set the EMAs length to 7, 20, and 80, then then previous EUR/USD chart looks like:

Colouring the background with a TradingView strategy

To learn more about colouring the chart background in TradingView, see colouring the background conditionally and offsetting a coloured background in TradingView. Besides colouring the background from top to bottom, we can also colour a chart’s background section. The colours that are available in TradingView are the basic colours and the hexadecimal colour values that allow for literally millions of colours.

Summary

The bgcolor() function colours the chart’s background, and this can either be the main chart area (when the script is added to the chart’s instrument) or the subchart in which the indicator or strategy displays. Setting the background colour is done with this function’s color argument while the background’s transparency is set with transp, an argument that accepts values from 0 (no transparency) to 100 (fully transparent). To shift a coloured background to the left or right we set the bgcolor() function’s offset argument to a negative or positive value, respectively. The other two arguments of bgcolor(), title and editable, define if, and with which name, the coloured background is displayed in the script’s ‘Style’ window.


References

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