Several TradingView functions can work with colours, with applications ranging from plotting histograms to creating custom bars. But how do we use the iff() function to add conditional colours to our scripts?

In this article:

Changing the colours used in a TradingView script conditionally

In TradingView Pine we can work with the basic TradingView colours and hexadecimal colours. Once we’ve coded one of those colour values into our script, we can also change the script’s colours manually.

The basic use of TradingView colours is applying the same colour on every bar, like plotting an orange volume histogram. But applying colours conditionally gives us a whole lot of additional options, like highlighting price bars on which breakouts or crossovers occurred. We can even use conditions in TradingView Pine to ‘turn off’ colours.

Note: Conditional colours cannot be used with every function: the fill() and hline() functions don’t accept them, while the barcolor(), bgcolor(), plot(), plotarrow(), plotbar(), plotcandle(), plotchar(), and plotshape() functions do (TradingView, n.d.).

Programmatically implementing conditional colours can be done in several ways, like colouring conditionally with the conditional operator or setting colours with an if/else statement. Another approach is with the iff() function.

That standard function works like an if/else statement and requires three arguments: a true/false condition, a value that’s returned when the condition is true, and another value that’s returned whenever the condition is false (TradingView, n.d.). This makes iff() operate just like the conditional (ternary) operator (?:) but in a more functional and less abstract manner (Pine Script Language Tutorial, n.d.).

A quick example of iff() is:

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

barcolor(color=iff(close > close[1] and close[1] > close[2], 
     black, na))

Here we colour price bars with barcolor() and set the color argument of this function with iff(). The condition that we evaluate is whether the current bar closed above the previous bar (close > close[1]) and if that previous bar also closed higher (close[1] > close[2]). With two higher closes, the iff() function returns the black TradingView colour. That colour is then used by the color argument of the barcolor() function to make those price bars black. However, when the condition isn’t true iff() returns na. That value has the effect of ‘turning off’ colouring so that, in effect, the barcolor() function doesn’t affect the colour of the chart’s price bars.

Now let’s consider an example that colours histogram bars conditionally with the iff() function.

Creating a volume histogram that’s conditionally coloured with iff()

Below we make an indicator that displays the current bar’s volume with a histogram. We colour those histogram bars based on how high or low the volume is, and we use the standard deviation of the volume to determine what ‘high’ and ‘low’ volume is. After discussing the code we’ll look at how the script looks like on the chart.

study(title="Conditional colours with iff()", 
     overlay=false, precision=0)

// Inputs
volMaLength  = input(title="Volume MA Length", type=integer, defval=30)
stdevLength  = input(title="StDev Length", type=integer, defval=30)
stdevHigh    = input(title="StDev High", type=float, defval=1.10)
stdevExtreme = input(title="StDev Extreme", type=float, defval=1.75)

// Calculate values
volumeMA   = sma(volume, volMaLength)
stdevValue = stdev(volume, stdevLength)

highVol    = volumeMA + (stdevHigh * stdevValue)
lowVolume  = volumeMA - (stdevHigh * stdevValue)
extremeVol = volumeMA + (stdevExtreme * stdevValue)

// Determine colour
histColour = iff(volume > extremeVol, #DC143C,
     iff(volume > highVol, #FF34B3,
     iff(volume < lowVolume, #E3CF57,
     #1E90FF)))

// Create histogram bars
plot(series=volume, style=histogram, linewidth=4,
     color=histColour)

We start off with the study() function and define three of its arguments. The title argument is used to name the indicator while the overlay argument, when set to false, makes the script display in a separate chart panel (TradingView, n.d.). With the precision argument we define how many digits are displayed behind the floating point of decimal values. That argument, when set to 0, displays large values with K (thousands) and M (millions) (TradingView, n.d.). That way we can plot volume values without the y-axis becoming very wide to accompany high volume values.

Then we add several input options to the script:

volMaLength  = input(title="Volume MA Length", type=integer, defval=30)
stdevLength  = input(title="StDev Length", type=integer, defval=30)
stdevHigh    = input(title="StDev High", type=float, defval=1.10)
stdevExtreme = input(title="StDev Extreme", type=float, defval=1.75)

Manual input options are added to the script’s ‘Inputs’ window with input(), and that function also returns the input’s current value (TradingView, n.d.). Here we assign each of those returned values in a variable. That way we can use the variable later on in the script to refer to the input’s value.

The first input option is a numerical integer input, which we make by setting the type argument of the input() function to integer (Pine Script Language Tutorial, n.d.). With the title argument we specify that the “Volume MA Length” text needs to be placed before the option in the script’s settings (see image further down below). The defval argument, which defines the input’s default value (TradingView, n.d.), is set to 30. We store the input’s value in the volMaLength variable that we use later on to compute the volume moving average.

The next input option is also an integer input (type=integer). We name this one “StDev Length” and give it a default value of 30. This input is used to calculate the standard deviation of the volume’s moving average, and to access it later we store the input’s value in the stdevLength variable.

The last two inputs are numerical floating-point inputs. These accept decimal values and we make them by setting the type argument of the input() function to float (Pine Script Language Tutorial, n.d.). They are set to default values of 1.10 and 1.75, and we use them as standard deviation multiples to determine what ‘high’, ‘low’, and ‘extreme’ volume values are. The current value of these inputs are tracked in the stdevHigh and stdevExtreme input variables.

After that we calculate the indicator’s values:

volumeMA   = sma(volume, volMaLength)
stdevValue = stdev(volume, stdevLength)

highVol    = volumeMA + (stdevHigh * stdevValue)
lowVolume  = volumeMA - (stdevHigh * stdevValue)
extremeVol = volumeMA + (stdevExtreme * stdevValue)

We first get the average volume with sma(), a function that calculates a Simple Moving Average (SMA) based on two arguments: a series of values to compute on and an integer that sets the SMA length in number of bars (TradingView, n.d.). Here we use sma() with the volume built-in variable (which returns the bar’s volume) and the volMaLength input variable that we set to 30 by default. We store the SMA value in the volumeMA variable.

With stdev() we calculate the standard deviation next. That function also works on two arguments: a series of values and the length of the standard deviation (TradingView, n.d.), and here we set these to volume and the stdevLength input variable. This 30-bar standard deviation value is then assigned to the stdevValue variable.

The next three variables hold values that we see as ‘high’, ‘low’, and ‘extreme’ volume in this example. The first of these, the highVol variable, is set to the volume moving average (volumeMA) plus the stdevHigh input variable times the volume standard deviation (stdevValue). And so when the script’s inputs are set to their default value, the highVol variable holds the 30-bar volume average plus 1.10 times the 30-bar standard deviation of the volume.

We assign the lowVolume variable the average volume (volumeMA) subtracted by the stdevHigh input variable multiplied with the volume’s standard deviation (stdevValue). This way the lowVolume variable holds the volume value of subtracting the 30-bar average volume with 1.10 times the 30-bar standard deviation. The last variable that we compute here is extremeVol. This one is set to the average volume (volumeMA) plus 1.75 times the 30-bar standard deviation (stdevExtreme * stdevValue).

After computing the variables we evaluate if the current bar’s volume is ‘high’, ‘low’, or ‘extreme’:

histColour = iff(volume > extremeVol, #DC143C,
     iff(volume > highVol, #FF34B3,
     iff(volume < lowVolume, #E3CF57,
     #1E90FF)))

Here we create the histColour variable which we use to colour the histogram bars. We assign this variable one of four hexadecimal colour values based on up to three conditions that are evaluated by several iff() functions.

The first iff() function checks whether the bar’s volume (volume) is greater than (>) the extremeVol variable. When the current bar’s volume is indeed above the 30-bar average volume plus 1.75 times the 30-bar standard deviation, then this iff() function returns #DC143C (the crimson red colour in hexadecimal format). That colour value is then stored in the histColour variable for use later on in the script.

When the condition of the first iff() function evaluates to false, then the second iff() function is processed. This one checks if the volume is above highVol (the 30-bar volume average plus 1.10 times the 30-bar standard deviation of volume). When it is, this second iff() function returns the hexadecimal colour value of maroon (#FF34B3).

If the condition of the second iff() function is also false, then the third iff() function is processed. This one checks whether the bar’s volume is less than (<) the lowVolume variable, which holds the 30-bar average volume minus 1.10 times the volume’s 30-bar standard deviation. When that’s the case, iff() returns #E3CF57 (the hexadecimal colour value of banana yellow) which is then assigned to the histColour variable.

When that condition isn’t true, then this last iff() function returns the hexadecimal colour of dodger blue (#1E90FF). And so that shade of blue is stored in the histColour variable when all of the previous three conditions were false. That way this colour is the standard colour, while ‘extreme volume’ is highlighted with crimson red, ‘high volume’ with maroon, and ‘low volume’ with banana yellow.

Tip: When nesting iff() functions, work from the most restrictive to the least restrictive condition. Here we first checked if the bar’s volume is ‘extreme’ before looking to see if it’s ‘high’. That’s because on any bar on which the volume > extremeVol condition is true, volume > highVol will be true too. In other words, if our first condition checked if the bar’s volume was above highVol, then the histColour variable would be given the same colour for both ‘high’ and ‘extreme’ volume bars.

After we’ve set the histColour variable to one of four colours (crimson red, maroon, banana yellow, or dodger blue) we use this variable when creating the histogram:

plot(series=volume, style=histogram, linewidth=4,
     color=histColour)

Here we use plot(), a function that displays a series of data on the chart (TradingView, n.d.). We set this function’s series argument to volume and its style argument to histogram to show those values with a histogram. With the linewidth argument set to 4 we make the thickest histogram bars that are possible. Last but not least is the color argument, which we set to the histColour variable that we’ve just assigned one of four colour values.

Colouring a volume histogram conditionally in TradingView Pine

When we add the example indicator to the German Bund (10-year bonds) CFD, the script looks like:

Example of conditional colours in TradingView

The indicator’s input options are the following:

Input options of the example indicator in TradingView

Setting the ‘StDev High’ input to 1.80 and ‘StDev Extreme’ to 2.50 changes the previous chart to:

Example of colouring with the iff function in TradingView Pine

And setting those inputs to 0.75 and 1.30 changes the volume histogram to this:

Colouring a volume histogram in TradingView

Besides the iff() function, other ways to use TradingView Pine colours conditionally are setting colours with the conditional operator and using if/else statements for conditional colours. It’s also possible to turn TradingView colours ‘off’. The kind of colours that we can use programmatically are the basic TradingView colours and the hexadecimal colour values.

Summary

TradingView colours can be applied in a straight-forward way by applying the same colour on every bar, but using colours conditionally is also possible. One ways to do so is with iff(). That function requires three arguments. The first is a true/false expression that, when true, returns the function’s second value and, when false, returns the function’s third value. This way the iff() function works like a concise if/else statement. We can place several iff() functions inside each other, and the values that the iff() function returns can be basic TradingView colours and/or hexadecimal colour values.


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