There are different ways to work with colours in TradingView Pine, like programmatically colouring price bars for instance. How do we do that?

In this article:

Using colours in TradingView: changing a bar’s colour

When we work with colours in TradingView Pine programmatically, we can use one of the basic TradingView colours or a hexadecimal colour value that allows for millions of different colour values. After we’ve used a colour in our script, we can configure the colours by hand too in the script’s ‘Style’ window.

Several TradingView functions have a color argument that we can set to a certain colour value. One of those functions is barcolor(), which not only set the colour of price bars but can also do that based on certain conditions (Pine Script Language Tutorial, n.d.; TradingView, n.d.).

The barcolor() function doesn’t return anything and has the following default syntax (TradingView, n.d.):

barcolor(color, offset, title, editable)

These four arguments stand for the following (Pine Script Language Tutorial, n.d.; TradingView, n.d.):

Argument Description
color Required argument that sets the colour of the price bar to either a basic TradingView colour or a hexadecimal colour value. Setting this argument to a conditional expression (like close > ema(close, 20) ? green : red) allows colouring the bar with one of several colours while setting color to na will ‘turn off’ the coloured price bar.
offset Optional integer argument that shifts the coloured bars a certain number of bars to the left or right. This argument defaults to 0 (no shift) while positive values relocate the coloured bars to the right (that is, to future price bars) and negative values shift them to the left (the previous, historical bars). See offsetting colours price bars in TradingView for more.
editable Optional Boolean argument that defines whether the coloured bars may be edited manually in the script’s ‘Style’ window. This argument defaults to true (meaning manually changing the bar’s colours is allowed) while setting it to false disallows changing the bar’s colours manually.
title Optional string argument that sets the name of the coloured bar style. With a descriptive name it’s easier to identify the coloured bar style in the script’s ‘Style’ window when manually changing a script’s colours.

The barcolor() function has two additional features. First, this function always colours the price bars of the chart’s instrument, even when the script that executes barcolor() displays in a separate chart pane. Second, how the coloured bars look depends on the chart’s settings; on a ‘Candles’ chart, for example, all bars have their body coloured while on a ‘Hollow Candles’ chart only the bars closing lower are filled. Luckily, we can also colour candles in TradingView with plotcandle() and create coloured price bars with plotbar(). Both of those functions allow plotting bars in a separate chart panel and they work regardless of the chart’s visual bar style.

Example: colouring inside and outside bars in TradingView

In the example below we colour inside and outside bars with the barcolor() function. An inside bar is a bar whose range falls completely in the trading range of the previous bar while an outside bar has a range outside that of the previous bar (Pring, 2002). We’ll also use an EMA (Exponential Moving Average) to take the trend into consideration. After discussing the code, we’ll look at charts showing the script in action. But first the code:

study(title="barcolor() example", overlay=true)

// Input
emaLength = input(title="EMA Length", type=integer, defval=20)

// Compute and plot EMA
emaValue = ema(close, emaLength)

plot(series=emaValue, linewidth=2,
     color=close > emaValue ? #228B22 : #B22222

// Determine conditions for bar colouring
insideBar  = (high < high[1]) and (low > low[1])
outsideBar = (high > high[1]) and (low < low[1])

upTrend   = (close > emaValue) and (close[1] > emaValue[1])
downTrend = (close < emaValue) and (close[1] < emaValue[1])

// Colour price bars
barColour = (upTrend and insideBar) ? green :
    (upTrend and outsideBar) ? lime :
    (downTrend and insideBar) ? maroon :
    (downTrend and outsideBar) ? purple :
    na

barcolor(color=barColour)

First we use the study() function that’s mandatory for every indicator (TradingView, n.d.). With this function’s overlay argument set to true, the script displays on the price chart and not in a separate chart pane.

Then we add an input option to the script:

emaLength = input(title="EMA Length", type=integer, defval=20)

The input() function creates inputs but also returns the input’s current value (TradingView, n.d.). Here we use that function to create a numerical integer input by setting its type argument to integer (Pine Script Language Tutorial, n.d.). We name this input “EMA Length” and the defval argument, which sets the input’s default value, makes the input starts off with a value of 20. The input’s value is stored in the emaLength variable with the assignment operator (=).

Next is the calculation and plotting of the moving average:

emaValue = ema(close, emaLength)

plot(series=emaValue, linewidth=2,
     color=close > emaValue ? #228B22 : #B22222

Here the emaValue variable is set to the value returned by ema(). That function computes an EMA with two arguments: the values to calculate the moving average on and the average’s length in number of bars (TradingView, n.d.). Here we set those arguments to close (the bar’s closing prices) and emaLength, the input variable that we gave a default value of 20 earlier.

Then we display that moving average on the chart by setting the plot() function’s series argument to the emaValue variable. These values are plotted as a line, which is the default plot type that plot() makes (TradingView, n.d.). With the function’s linewidth argument set to 2 the line is made one step larger than default.

The color argument of the plot() function is set conditionally to one of two values with the conditional (ternary) operator (?:). That operator requires three values: first a true/false condition and then two values, of which the first is returned when the condition is true while the operator returns the second should the condition be false (Pine Script Language Tutorial, n.d.).

Our condition is whether the current bar’s close (close) is greater than (>) the EMA (emaValue). If the bar indeed close above the moving average, the conditional operator returns #228B22; which is the hexadecimal colour value of forest green. Should the bar close at or below the EMA, then #B22222 (the hexadecimal colour value of firebrick) is returned. And so the color argument of our plot() function call is set conditionally to either one of these two colours.

With the EMA displayed on the chart, we determine the conditions for colouring the price bars:

insideBar  = (high < high[1]) and (low > low[1])
outsideBar = (high > high[1]) and (low < low[1])

upTrend   = (close > emaValue) and (close[1] > emaValue[1])
downTrend = (close < emaValue) and (close[1] < emaValue[1])

Each of these four variables is assigned (=) a true/false value based on combining two true/false expressions with and. That logical operator returns true when both expressions that it combines are true, and returns false when one or both of them are false too (Pine Script Language Tutorial, n.d.).

This means the insideBar variable only holds true when two things happen. First, the high of the current bar needs to be less than (<) the previous bar high. We retrieve that latter with a value of 1 placed in the history referencing operator ([]) that’s just behind the high built-in variable (so high[1]). Second, the current bar low needs to be greater than (>) the previous bar’s low (low[1]). Only when the first and second of these conditions are satisfied will the insideBar variable hold a value of true. For all other price bars that aren’t an inside bar, the insideBar variable will hold a value of false.

Likewise, the second variable (outsideBar) is also assigned a true/false value based on two conditions: whether the current bar’s high is above the previous bar high (high > high[1]) and if the low of the current bar is below the previous bar’s low (low < low[1]). When both of these conditions satisfy an outside price bar occurred and that’s when outsideBar is set to a value of true. When one or both of these conditions aren’t the case, this variable is given a false value.

The next two true/false variables compare the current and previous price bar against the EMA. The first of these, upTrend, is set to true when the current bar closes above the EMA (close > emaValue) and when the previous bar closed above the then-current EMA value (close[1] > emaValue[1]). We see such consecutive close above the moving average as an uptrend and so the upTrend variable is set to true in that case (and holds false in all other cases).

The value for the downTrend variable is set in the same way, except that here we check if the current bar closed below the EMA (close < emaValue) and whether that also happened on the previous bar (close[1] < emaValue[1]). Only when that’s the case, our downTrend variable is assigned a value of true.

Now with the different bar colouring conditions determined, let’s figure out which colour to give our bars:

barColour = (upTrend and insideBar) ? green :
    (upTrend and outsideBar) ? lime :
    (downTrend and insideBar) ? maroon :
    (downTrend and outsideBar) ? purple :
    na

The barColour variable is given one of five different values with the assignment operator (=). Which of those is stored in that variable is determined by several conditional (ternary) operators (?:) that all evaluate two true/false variables joined with the and logical operator.

The first conditional operator figures out whether both the upTrend and insideBar variables are true. When there’s indeed an uptrend with the current bar being an inside bar, then the conditional operator returns the green basic TradingView colour which is then stored in the barColour variable. Should one or both of these variables are false, then the second conditional operator is processed.

That one checks if there’s an outside bar during an uptrend (upTrend and outsideBar). It that’s the case, this conditional operator returns the lime colour which is then put into the barColour variable. But without an outside bar happening during an uptrend, the next conditional operator executes.

That third conditional operator evaluates whether the current bar is an inside bar happening during a downtrend (downTrend and insideBar). If that condition evaluates to true, this conditional operator returns maroon and that colour is then assigned to barColour. But when the condition of this conditional operator is also false, then our script evaluates the fourth conditional operator.

That last one checks whether there’s a downtrend while the current bar has a range that’s beyond the previous bar (downTrend and outsideBar). When that’s the case, this conditional operator returns the purple colour which is then stored in the barColour variable.

However, when the condition of this last conditional operator is false (which also means that the conditions of the previous conditional operators were false too), then the last conditional operator returns na. That built-in variable represents a “not a number” value (TradingView, n.d.) which, when used during colouring, keeps the colour to the default chart colour (Pine Script Language Tutorial, n.d.). This means that, whenever a colour is set to na, that we in effect use a transparent colour that doesn’t has an effect on the chart.

After conditionally setting the barColour variable to green, lime, maroon, purple, or na we use this variable as follows:

barcolor(color=barColour)

Here we colour the bar that’s currently being processed by the script by setting the color argument of the barcolor() function to our barColour variable. The other, optional arguments that aren’t specified (offset, editable, and title) all revert to their default values.

Colouring inside and outside bars in TradingView conditionally

When we add the above example to a S&P 500 Index CFD chart, it looks like:

Example of colouring inside and outside bars in TradingView

Here we see that the EMA line is coloured green or red when price bars close above or below it. The inside and outside bars are, depending on whether they close above or below the moving average, coloured with maroon, purple, green, or lime.

On a different time period and with slightly smaller bars our script looks as follows:

Colouring prie bars in TradingView

The example indicator has one input option, “EMA Length”:

Example of the TradingView script's input options

See offsetting coloured price bars in TradingView to learn more about working with coloured price bars. The colours that we can use when coding in TradingView Pine are the basic TradingView colours as well as the hexadecimal colour values that allow for literally millions of different colours.

Summary

We colour price bars programmatically with barcolor(). This function has one required argument: color, which needs to be set to either a basic TradingView colour or a hexadecimal colour value. This color argument also accepts a conditional expression so that we can use one of several colours conditionally while setting this argument to na is possible too. In that latter case the price bar is given the same colour as the bar already had, which in effect ‘turns off’ the effect of barcolor(). The optional arguments of this function are offset (relocates the coloured price bar to the left or right), editable (allows changing the coloured bars’ style by hand), and title (sets the name for the coloured price bars, which is shown 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/

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

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