Tradingview Pine script - how can I make custom volume indicator behave like a built-in Vol

user3675185 picture user3675185 · Feb 21, 2020 · Viewed 7.5k times · Source

I made a custom volume indicator, but when applied to the chart, it doesn't autoscale like the built-in one, doesn't auto stick to the bottom of the chart panel, nor can it go without its own explicit extra scale on the side.

Is there a way for it to do all these things?

I found no help in the original indicator code neither. E.g. when I tried to apply format.volume, it just refused to compile at all.

Below is my code, the original is further below that:

//This inddicator will show volume inversely. So if you are looking at an Altcoin, it will show volume in BTC, if you are looking at for example BTC/USD it will show volume in USD and so on. Works with all altcoins and fiat pairs.
//I find this most useful when shopping for alts to quickly get an idea of their liquidity.

//title the indicator and dont use decimals. (Otherwise when viewing fiat volume you get unreadably large numbers) you can change this in the settings dialog tho if you want.
study("Vol in Base asset 20MA", precision=0)

//Make the moving average user configurable
showMA = input(true)

//Get volume for current bar and multiply with vwap
vInverse = volume * vwap

//Plot fiat volume.
plot(vInverse, color = orange, title="VolumeBTC", style=columns, transp=65)

//Plot 20 candle moving average (changable in settings)
plot(showMA ? sma(vInverse,20) : na, color = white, title="Volume MA", style=area, transp=65)

the original code:

//@version=4
study(title="Volume", shorttitle="Vol", format=format.volume)
showMA = input(true)
barColorsOnPrevClose = input(title="Color bars based on previous close", type=input.bool, defval=false)

palette = barColorsOnPrevClose ? close[1] > close ? color.red : color.green : open > close ? color.red : color.green

plot(volume, color = palette, style=plot.style_columns, title="Volume", transp=65)
plot(showMA ? sma(volume,20) : na, style=plot.style_area, color=color.blue, title="Volume MA", transp=65)

Answer

PineCoders-LucF picture PineCoders-LucF · Feb 25, 2020

The short answer to your question is no, it's currently not possible to do everything you want. To do what the built-in volume indie does we would need 2 things we don't have:

  1. Pine visibility on which bars are displayed on the chart (so we can dynamically scale the height of the volume columns).
  2. A way to anchor indies at the chart's bottom while still allowing the indicator's scale to auto-scale.

This code also uses Michel's scale.none idea, but it adds an invisible plot on top that allows you to determine the maximum height of columns in the vertical space, without scaling the values of the columns themselves, so you still obtain correct readings. Using the *Settings/Inputs" you can:

  • Specify the maximum percentage of the vertical space you want the highest columns to occupy.
  • Specify how the maximum past value used to scale columns is determined, i.e., using:
    • The all-time high, or
    • The highest column in the last n bars (it's the default with n=400). This second method adjusts better to the recent chart context.

enter image description here

//This indicator will show volume inversely. So if you are looking at an Altcoin, it will show volume in BTC, if you are looking at for example BTC/USD it will show volume in USD and so on. Works with all altcoins and fiat pairs.
//I find this most useful when shopping for alts to quickly get an idea of their liquidity.

//title the indicator and dont use decimals. (Otherwise when viewing fiat volume you get unreadably large numbers) you can change this in the settings dialog tho if you want.
//@version=4
study("Vol in Base asset 20MA", "", true, format.volume, 0, scale.none)

//Make the moving average user configurable
HIM1 = "1. Historical High"
HIM2 = "2. Highest in last..."
showMA = input(true)
scaleFactor = 100 / input(30, "% of vertical space used", step = 10, maxval = 100)
hiMethod = input(HIM2, "High point method", options = [HIM1, HIM2])
hiMethod2Len = input(400, "  2. Length", minval = 2, step = 100)

//Get volume for current bar and multiply with vwap
vInverse = volume * vwap

//Plot fiat volume.
plot(vInverse, color = color.orange, title="VolumeBTC", style=plot.style_columns, transp=0) //Originally: transp=65

//Plot 20 candle moving average (changable in settings)
plot(showMA ? sma(vInverse,20) : na, color = color.white, title="Volume MA", style=plot.style_area, transp=65)

//Plot high line to scale down the columns.
var histHi = 0.
histHi := max(histHi, nz(vInverse, histHi))
limit = hiMethod == HIM1 ? histHi : highest(vInverse, hiMethod2Len)
plot(limit * scaleFactor, "Historical High", #00000000)

This will give something like this: enter image description here

There are 2 ways to bring the base of the columns to the bottom of the chart, but none is ideal:

  1. Set bottom margin of chart to 0% using the chart's Settings/Appearance/Bottom margin, but then chart bars continue to overlap columns.
  2. Compress the indie's scale a bit by dragging its scale up/down (red arrow). Then grab the columns on the chart (green arrow) and bring them down, but this freezes the indie's scale then, so it won't resize when you change symbols and the volume increases/decreases.

enter image description here

The ability to align indicators with the bottom of the vertical space has been identified by TV as a potential improvement—but with no ETA yet.