When plotting an indicator in TradingView we often read the indicator’s values from the chart. How do we programmatically specify the number of decimals of those indicator values?

In this article:

Setting the precision of an indicator programmatically

The settings of a TradingView indicator, like its name and how to display its values, are set programmatically with the study() function (Pine Script Language Tutorial, n.d.). That function needs to be added to every indicator, and its title argument (which specifies the indicator’s name) always needs to be set too (TradingView, n.d.).

Another argument of that function is precision. This optional argument accepts a non-negative integer that specifies the number of digits after the floating point of the indicator’s values (TradingView, n.d.). For example:

study(title="My example script", precision=3)

Furthermore, precision set to 0 gives special formatting for large numbers (Pine Script Language Tutorial, n.d.; TradingView, n.d.). In that case, thousands are displayed with the ‘K’ and millions with the ’M’ suffix, which prevents large numbers from needing a lot of chart space. When precision isn’t defined, the script’s values show with 4 digits after the floating point by default.

The precision argument has a few features to be aware of:

  • The precision argument can only be set to a literal integer (like precision=3). It doesn’t accept built-in and user-defined variables nor does precision accept a numerical input variable.
  • precision affects all values from the indicator – it’s not possible to specify that, for instance, one moving average should display with 2 decimals while another one should plot with 4. While rounding is possible (like to 120.53), those values would still display with 4 decimals (120.5300) when precision is set to 4.
  • When an indicator is overlaid on the chart’s instrument, the precision of the instrument’s price scale affects the precision of the indicator. This means the value set to the precision argument is not always respected by TradingView. For more on this and the possible workarounds, see why does my indicator display with another precision than specified?.

Setting the precision of a TradingView indicator manually

Besides the precision argument of the study() function, it’s also possible to manually set the number of decimals used by the indicator. While it’s convenient to configure an indicator’s precision in the script’s code, it’s also helpful to have a manual option. That way we can give multiple instances of the same indicator a different number of digits after the floating point.

To set the precision of a TradingView indicator manually, we click on the ‘Format’ icon ( ) that’s to the right of the indicator’s name:

Formatting the settings of a TradingView indicator

This opens the indicator’s settings and there we select the ‘Style’ tab. Then we can set the indicator’s settings to any of the values in the ‘Precision’ pull-down menu:

Setting the precision of a TradingView indicator manually

After changing the precision, we press ‘OK’ to have the updated setting apply to the chart.

Setting precision programmatically: the CCI TradingView indicator

For a better understanding of the study() function’s precision argument, let’s look at two examples. The first plots an indicator with several numbers after the floating point, while the second plots large values without any decimals.

Let’s begin with the CCI (Commodity Channel Index). This indicator compares the current price to an average price over a period of time, and the majority of its values fall between -100 and +100 and indicate respectively weakness and strength in price movement (Mitchell, n.d.). After discussing the code, we look at the indicator and how its precision affects the plotted values.

study(title="CCI (Commodity Channel Index)", precision=5)

// Inputs
cciLen  = input(title="CCI Length", type=integer, defval=20)
emaLen  = input(title="EMA Length", type=integer, defval=10)
obLevel = input(title="Overbought Level", type=integer, defval=100)
osLevel = input(title="Oversold Level", type=integer, defval=-100)

// Compute values
cciVal = cci(close, cciLen)
emaVal = ema(cciVal, emaLen)

// Plot values and signal lines
plot(series=cciVal, color=blue)
plot(series=emaVal, color=#228B22, style=circles, linewidth=2)

hline(price=obLevel, color=gray)
hline(price=osLevel, color=gray)

We begin with the mandatory study() function. We use this function’s title argument to set the indicator name programmatically. And with the precision argument set to 5 the indicator values display with five decimals after their floating point.

Then we add several input options to the script:

cciLen  = input(title="CCI Length", type=integer, defval=20)
emaLen  = input(title="EMA Length", type=integer, defval=10)
obLevel = input(title="Overbought Level", type=integer, defval=100)
osLevel = input(title="Oversold Level", type=integer, defval=-100)

Adding configurable inputs to a script is done with input(), and this function also returns the input option’s current value (Pine Script Language Tutorial, n.d.). Here we store each of those values in a variable with the assignment operator (=). This way we can access the input’s value later on in the script.

The four inputs are all numerical integer inputs that accept whole numbers only. We make these by setting the type argument of the input() function to integer (Pine Script Language Tutorial, n.d.). The first input is named “CCI Length” with the title argument, and that name is what’s placed before the input option in the script’s settings (see image further down below). This input has a default value (defval) of 20 and has its value stored in cciLen. That variable is used later on when computing the CCI.

The next input is named “EMA Length” and starts with a value of 10 (defval=10). We assign its value to the emaLen variable and use that variable later on when computing the CCI. The last two inputs are named “Overbought Level” and “Oversold Level” and have default values of 100 and -100. These inputs, which we track with the obLevel and osLevel variables, are used later on to plot the CCI’s horizontal lines. By creating an input option for these lines we can easily change the value at which they plot.

With the inputs made, we compute the indicator’s values:

cciVal = cci(close, cciLen)
emaVal = ema(cciVal, emaLen)

The Commodity Channel Index (CCI) is calculated here with cci(), a function that requires two arguments: a series of values to compute on and an integer that sets the CCI length (TradingView, n.d.). We set those arguments to the bar’s closing price (close) and the cciLen input variable, which we gave a default value of 20 earlier. The value returned by cci() is assigned to the cciVal variable.

That variable is then used to calculate the Exponential Moving Average (EMA) of the CCI. We do that with ema(), a function that also requires two arguments: a series of values to process and an integer that specifies the EMA length in number of bars (TradingView, n.d.). Those arguments are set to cciVal (the CCI value that we’ve just calculated) and emaLen, the input variable that has a standard value of 10. We store the CCI EMA in the emaVal variable.

Then we plot the computed values on the chart:

plot(series=cciVal, color=blue)
plot(series=emaVal, color=#228B22, style=circles, linewidth=2)

The plot() function displays data on the chart that’s set by its series argument (TradingView, n.d.). In the first plot() statement we set that argument to cciVal. Those CCI values are displayed with the blue standard TradingView colour and displayed as a line given that plot() makes lines by default.

The second plot() statement displays the CCI EMA (series=emaVal) with the hexadecimal colour value of forest green (#228B22). The style argument of the plot() function specifies the kind of plot, and we set that to circles here to make a plot with unconnected dots. We make these dots a little bigger than normal by setting linewidth to 2 (TradingView, n.d.).

Then we display the overbought and oversold lines on the chart:

hline(price=obLevel, color=gray)
hline(price=osLevel, color=gray)

Both lines are made with hline(), a function that creates a horizontal line at a given fixed price level (TradingView, n.d.). This function’s price argument defines where the line is placed, and here we set that argument to the obLevel and osLevel input variable that we gave defaults of 100 and -100 earlier. Both lines are displayed in the gray basic TradingView colour.

Example: plotting the CCI indicator in TradingView Pine

When we add the above example to a chart, like the EUR/USD chart shown below, we see that the indicator’s values are displayed with 5 decimals after the floating point on the price axis:

Example of the TradingView indicator added to a price chart

The example indicator has the following input options:

Input options of the TradingView example script

The 5 decimals that we’ve set with the precision=5 argument of the study() function also show up in the ‘Data Window’:

Example of the decimals in the chart's Data Window

In addition, this amount of precision is also used in the ‘Create Alerts’ window. To open that window, we right-click on an indicator’s plot and select ‘Add Alert’ (or we press Alt - A with the indicator is selected):

Opening the Create Alert window in TradingView

Then in the ‘Create Alert’ window we can specify the alert’s price value with the amount of decimals set by the precision argument:

Example of the indicator's precision in the TradingView 'Create Alert' window

Plotting TradingView volume in thousands and millions

The next example looks at the study() function’s precision argument set to 0. With precision set to that value, large numbers are formatted in a special way (TradingView, n.d.): millions will be displayed with the ’M’ suffix while thousands are shown with ‘K’. In the example below we create a volume histogram with a moving average. After discussing the code, we look at the indicator and its values.

study(title="Precision example: volume histogram", precision=0)

// Create input
maLen = input(title="Average Length", type=integer, defval=30)

// Plot values
plot(series=volume, style=histogram, color=#D2691E, linewidth=4)
plot(series=wma(volume, maLen), style=line, color=#B22222)

hline(price=0, color=black)

With the study() function we set the indicator’s name programmatically and give the precision argument a value of 0. Then we add an input option to the script:

maLen = input(title="Average Length", type=integer, defval=30)

We create inputs with input(), and this function also returns the input’s value (TradingView, n.d.). Here we assign that returned value to the maLen variable for use later on.

The numerical integer input that we make here by setting the type argument of the input() function to integer accepts whole numbers only (Pine Script Language Tutorial, n.d.). The default value (defval) of this input is 30, and with the title argument we name our input “Average Length”.

Then we plot the volume values:

plot(series=volume, style=histogram, color=#D2691E, linewidth=4)
plot(series=wma(volume, maLen), style=line, color=#B22222)

hline(price=0, color=black)

The volume and its average are displayed on the chart with plot(). In the first plot() function call we set the series argument to the bar’s volume (volume). The style argument is given the histogram value in order to make a histogram plot (TradingView, n.d.). These histogram bars are coloured with the hexadecimal colour value of chocolate (#D2691E). And we set the linewidth argument to 4 to display these bars with a thick style.

The series argument of the second plot() statement is set to the value returned by wma(). That function computes a Weighted Moving Average (WMA) based on two arguments: a series of values to process and an integer that specifies the length of the moving average (TradingView, n.d.). We set these to volume and maLen, our input variable that we gave a standard value of 30.

That plot() statement’s style argument is set to line to display the WMA as a consecutive line. The line’s colour is set to the #222222 firebrick hexadecimal colour and is made slightly thicker than default (linewidth=2) (TradingView, n.d.).

The last line in our example is the hline() function that draws a horizontal line at a fixed price level (TradingView, n.d.). We set this function’s price argument to 0 and its color argument to the black basic TradingView colour. That black line at the zero price level makes it look like the volume histogram bars are ‘stacked on’ this line.

Using thousands and millions precision in TradingView

Now when we add the above example to a GBP/USD chart, the indicator plots volume values that are in their thousands with the ‘K’ notation:

Plotting a volume histogram in TradingView Pine

The input option of the indicator looks like:

Input option of our TradingView example indicator

When we switch to another instrument, like a daily chart of Goldman Sachs, then the indicator plots the volume in millions:

Example of changing the indicator settings in TradingView

The indicator values with the ‘K’ and ’M’ suffix also show up in the chart’s ‘Data Window’ by the way:

Example of decimal precision in TradingView's Data Window

When we set the precision argument of the study() function to 1 or higher, then TradingView doesn’t shorten our values to thousands and millions. For instance, when we change the first line of the previous programming example to:

study(title="Precision example: volume histogram", precision=1)

And when we save the script (without making other changes), the previous Goldman Sachs chart changes to:

Programmatically changing the precision of a TradingView indicator

This also shows that, while we lose some accuracy with the ‘K’ and ’M’ suffixes, they also reduce the amount of chart space that’s required.

To learn more about the study() function and its arguments, see specifying an indicator’s overlaid settings programmatically and setting the indicator’s scaling with code. In fixing the discrepancy between specified and displayed precision we look at how there can be a difference between the precision set with precision and the number of decimals shown on the chart.

Summary

The study() function needs to be added every TradingView indicator. This function defines the indicator’s properties with several arguments, including the required title argument and the optional precision argument. This latter accepts a non-negative integer that specifies how many numbers are displayed after the decimal point of the indicator’s values. When this precision argument isn’t set, the indicator uses with 4 decimals. Values of the indicator can also display with thousands (‘K’) and millions (’M’) notation by setting precision to 0.


References

Mitchell, C. (n.d.). How Traders Can Utilize CCI (Commodity Channel Index) To Trade Stock Trends. Retrieved on March 3, 2016, from http://www.investopedia.com/articles/active-trading/031914/how-traders-can-utilize-cci-commodity-channel-index-trade-stock-trends.asp

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

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