Typical Price Difference - TPD © with reversal zones and signals
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//   MyFire_Yiannis 2023
//
// v1.0 NOTE: This script has been tested ONLY for BTC in a weekly time frame
//@version=5
indicator(title = 'Typical Price Difference with reversal zones and signals', shorttitle = 'TPD v1.0', overlay=false)

catTPD = '--------- Typical Price Difference ----------'
cat_HV = '----------- Historical Volatility -----------'
catCMW = '------------ CM_Williams_Vix_Fix ------------'
catZaS = '--------- Zones and Signals visuals ---------'

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TPD START
////
cumulativePeriod = input(14, 'VWAP Period', group = catTPD)
difference = input.float(30.0, 'VWAP Difference', step = 1, group = catTPD)

typicalPrice = (high + low + close) / 3
typicalPriceVolume = typicalPrice * volume
cumulativeTypicalPriceVolume = ta.sma(typicalPriceVolume, cumulativePeriod)
cumulativeVolume = ta.sma(volume, cumulativePeriod)
vwapValue = cumulativeTypicalPriceVolume / cumulativeVolume

diff = ((close - vwapValue) / close ) * 100

plot_color = diff >= difference ? color.red : (diff <= -difference ? color.green : color.yellow)
pTPD = plot(diff, color=plot_color)
////
// TPD STOP
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Historical Volatility START
// © TradingView
////
show_hv = input.bool(defval = false, title = 'Show Historical Volatility', group = cat_HV)
length = input.int(14, minval=1, group = cat_HV)
annual = 365
per = timeframe.isintraday or timeframe.isdaily and timeframe.multiplier == 1 ? 1 : 7
hv = 100 * ta.stdev(math.log(close / close[1]), length) * math.sqrt(annual / per)
plot(show_hv and hv ? hv : na, "HV", color=#2962FF)
////
// Historical Volatility STOP
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CM_Williams_Vix_Fix Finds Market Bottoms START
// © ChrisMoody
////
period = input(22, title='LookBack Period for Williams VixFix', group = catCMW)
bbl = input(20, title='Bolinger Band Length', group = catCMW)
mult = input.float(2.0, minval=1, maxval=5, title='Bollinger Band Standard Devaition Up', group = catCMW)
lb = input(50, title='Look Back Period Percentile High', group = catCMW)
ph = input(.90, title='Highest Percentile - 0.90=90%, 0.95=95%, 0.99=99%', group = catCMW)
pl = input(1.01, title='Lowest Percentile - 1.10=90%, 1.05=95%, 1.01=99%', group = catCMW)
hp = input(false, title='Show High Range - Based on Percentile and LookBack Period?', group = catCMW)
sd = input(false, title='Show Standard Deviation Line?', group = catCMW)

wvf = ((ta.highest(close, period) - low) / ta.highest(close, period)) * 100
sDev = mult * ta.stdev(wvf, bbl)
midLine = ta.sma(wvf, bbl)
lowerBand = midLine - sDev
upperBand = midLine + sDev

rangeHigh = ta.highest(wvf, lb) * ph
rangeLow = ta.lowest(wvf, lb) * pl

col = wvf >= upperBand or wvf >= rangeHigh ? color.lime : color.gray
wvfCond = wvf >= upperBand or wvf >= rangeHigh

plot(hp and rangeHigh ? rangeHigh : na, title='Range High Percentile', style=plot.style_line, linewidth=4, color=color.new(color.orange, 0))
plot(hp and rangeLow ? rangeLow : na, title='Range High Percentile', style=plot.style_line, linewidth=4, color=color.new(color.orange, 0))
plot(wvf, title='Williams Vix Fix', style=plot.style_histogram, linewidth=4, color=col)
plot(sd and upperBand ? upperBand : na, title='Upper Band', style=plot.style_line, linewidth=3, color=color.new(color.aqua, 0))
////
// CM_Williams_Vix_Fix Finds Market Bottoms STOP
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Zones and signals calculations START
////
show_signal = input.bool(defval = true, title = 'Show Signals', group = catZaS)
show_zones = input.bool(defval = true, title = 'Show Zones', group = catZaS)
bgcolor(show_zones and diff >= difference ? color.new(color.red, 80) : (show_zones and diff <= -difference ? color.new(color.green, 70) : na))

src = (diff + hv) / 2
cci = ta.cci(src, period)
pCCI = plot(cci, title = "WMA", style = plot.style_line, linewidth = 1, color=color.white)

greencolor = #2af70b
redcolor = #f70606 
fill(pTPD, pCCI, color = cci > diff ? greencolor : na)
fill(pTPD, pCCI, color = cci < diff ? redcolor : na)

reverseLong = ta.roc(cci, 1) > ta.roc(close, 1)
reverseShort = ta.roc(cci, 1) < ta.roc(close, 1)

plotshape(show_signal and diff <= -difference and reverseLong and wvfCond, title = 'Long', color = greencolor, textcolor = greencolor, text = "rL", style = shape.triangleup, location = location.bottom, size = size.auto)
plotshape(show_signal and diff >= difference and reverseShort and wvfCond, title = 'Short', color = redcolor, textcolor = redcolor, text = "rS", style = shape.triangledown, location = location.top, size = size.auto)
////
// Zones and signals calculations STOP
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////