Percentile Rank of Bollinger Bands
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © TheSaltyAustin
//@version=5
indicator(shorttitle="BB ranked", title="Bollinger Bands", overlay=false, timeframe="", timeframe_gaps=true)
length = input.int(20, minval=1, group='Bollinger')
src = input(close, title="Source", group='Bollinger')
mult = input.float(2.0, minval=0.001, maxval=50, title="StdDev", group='Bollinger')

lookback = input.int(750, title='Stdev Rank Lookback', group='Ranking')

showStdev    = input.bool(true, title='Show Boll Stdev %', group='Display')
showPosition = input.bool(true, title='Show Current Price\'s Relative Height in Band', group='Display')

var stdevArray = array.new_float(lookback,0.0)


basis = ta.sma(src, length)
dev = mult * ta.stdev(src, length)
upper = basis + dev
lower = basis - dev
positionBetweenBands = 100 * (src - lower)/(upper - lower)

array.push(stdevArray, dev/close)
if array.size(stdevArray)>=lookback
    array.remove(stdevArray, 0)

rank = array.percentrank(stdevArray, lookback-1)
rankColor = rank[0]>rank[1] ? color.green : color.red
positionColor = positionBetweenBands[0]>positionBetweenBands[1] ? color.aqua : color.blue

hist = 100*dev/close
plot(showStdev ? hist : na, style=plot.style_columns, color=(hist[1] < hist ? #26A69A : #B2DFDB) , title='Stdev %' )
plot(rank, color=rankColor, linewidth=2, title='Boll Percentile')
plot(showPosition ? positionBetweenBands : na, color=positionColor, title='Relative Height')
hline(95, title='High Percentile', color=color.new(color.white,50), linestyle=hline.style_dashed )
hline( 5, title='Low Percentile' , color=color.new(color.white,50), linestyle=hline.style_dashed )
