CFB-Adaptive, Williams %R w/ Dynamic Zones [Loxx]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © loxx

//@version=5
indicator("CFB-Adaptive, Williams %R w/ Dynamic Zones [Loxx]", 
     shorttitle='CFBAWPRDZ [Loxx]', 
     overlay = false, 
     timeframe="", 
     timeframe_gaps = true)
     
import loxx/loxxdynamiczone/3
import loxx/loxxexpandedsourcetypes/4
import loxx/loxxjuriktools/1

greencolor = #2DD204
redcolor = #D2042D

lightgreencolor = #96E881 
lightredcolor =  #DF4F6C

darkGreenColor =  #1B7E02 
darkRedColor = #93021F

SM02 = 'Slope'
SM03 = 'Middle Crossover'
SM04 = 'Levels Crossover'

WprSmoothPhase = input.float(0., "WPR Jurik Phase", group = "WPR Settings")
WprSmoothDouble = input.bool(true, "WPR Double Juirk Smoothing?", group = "WPR Settings")

smthtype = input.string("Kaufman", "Heikin-Ashi Better Caculation Type", options = ["AMA", "T3", "Kaufman"], group = "CFB Ingest Settings")
srcin = input.string("Close", "Source", group= "CFB Ingest Settings", 
     options = 
     ["Close", "Open", "High", "Low", "Median", "Typical", "Weighted", "Average", "Average Median Body", "Trend Biased", "Trend Biased (Extreme)", 
     "HA Close", "HA Open", "HA High", "HA Low", "HA Median", "HA Typical", "HA Weighted", "HA Average", "HA Average Median Body", "HA Trend Biased", "HA Trend Biased (Extreme)",
     "HAB Close", "HAB Open", "HAB High", "HAB Low", "HAB Median", "HAB Typical", "HAB Weighted", "HAB Average", "HAB Average Median Body", "HAB Trend Biased", "HAB Trend Biased (Extreme)"])

nlen = input.int(50, "CFB Normal Period", minval = 1, group = "CFB Ingest Settings")
cfb_len = input.int(4, "CFB Depth", maxval = 10, group = "CFB Ingest Settings")
smth = input.int(8, "CFB Smooth Period", minval = 1, group = "CFB Ingest Settings")
slim = input.int(5, "CFB Short Limit", minval = 1, group = "CFB Ingest Settings")
llim = input.int(50, "CFB Long Limit", minval = 1, group = "CFB Ingest Settings")
jcfbsmlen = input.int(10, "CFB Jurik Smooth Period", minval = 1, group = "CFB Ingest Settings")
jcfbsmph = input.float(0, "CFB Jurik Smooth Phase", group = "CFB Ingest Settings")
CfbSmoothDouble = input.bool(true, "CFB Double Juirk Smoothing?", group = "CFB Ingest Settings")


dzper = input.int(70, "Dynamic Zone Period", group = "Levels Settings") 
buy1  = input.float(0.1 , "Dynamic Zone Buy Probability Level 1", group = "Levels Settings", maxval = 0.5)
sell1 = input.float(0.1 , "Dynamic Zone Sell Probability Level 1", group = "Levels Settings", maxval = 0.5)

lbR = input(title="Pivot Lookback Right", defval=5, group = "Divergences Settings")
lbL = input(title="Pivot Lookback Left", defval=5, group = "Divergences Settings")
rangeUpper = input(title="Max of Lookback Range", defval=60, group = "Divergences Settings")
rangeLower = input(title="Min of Lookback Range", defval=5, group = "Divergences Settings")
plotBull = input(title="Plot Bullish", defval=true, group = "Divergences Settings")
plotHiddenBull = input(title="Plot Hidden Bullish", defval=false, group = "Divergences Settings")
plotBear = input(title="Plot Bearish", defval=true, group = "Divergences Settings")
plotHiddenBear = input(title="Plot Hidden Bearish", defval=false, group = "Divergences Settings")
bearColor = darkRedColor
bullColor = darkGreenColor
hiddenBullColor = color.new(darkGreenColor, 80)
hiddenBearColor = color.new(darkRedColor, 80)
textColor = color.white
noneColor = color.new(color.white, 100)

sigtype = input.string(SM03, "Signal type", options = [SM02, SM03, SM04], group = "Signal Settings")

colorbars = input.bool(true, "Color bars?", group= "UI Options")
showsignals = input.bool(true, "Show signals?", group = "UI Options")

kfl=input.float(0.666, title="* Kaufman's Adaptive MA (KAMA) Only - Fast End", group = "Moving Average Inputs")
ksl=input.float(0.0645, title="* Kaufman's Adaptive MA (KAMA) Only - Slow End", group = "Moving Average Inputs")
amafl = input.int(2, title="* Adaptive Moving Average (AMA) Only - Fast", group = "Moving Average Inputs")
amasl = input.int(30, title="* Adaptive Moving Average (AMA) Only - Slow", group = "Moving Average Inputs")

haclose = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close)
haopen = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, open)
hahigh = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, high)
halow = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, low)
hamedian = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hl2)
hatypical = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hlc3)
haweighted = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hlcc4)
haaverage = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, ohlc4)

src = switch srcin
	"Close" => loxxexpandedsourcetypes.rclose()
	"Open" => loxxexpandedsourcetypes.ropen()
	"High" => loxxexpandedsourcetypes.rhigh()
	"Low" => loxxexpandedsourcetypes.rlow()
	"Median" => loxxexpandedsourcetypes.rmedian()
	"Typical" => loxxexpandedsourcetypes.rtypical()
	"Weighted" => loxxexpandedsourcetypes.rweighted()
	"Average" => loxxexpandedsourcetypes.raverage()
    "Average Median Body" => loxxexpandedsourcetypes.ravemedbody()
	"Trend Biased" => loxxexpandedsourcetypes.rtrendb()
	"Trend Biased (Extreme)" => loxxexpandedsourcetypes.rtrendbext()
	"HA Close" => loxxexpandedsourcetypes.haclose(haclose)
	"HA Open" => loxxexpandedsourcetypes.haopen(haopen)
	"HA High" => loxxexpandedsourcetypes.hahigh(hahigh)
	"HA Low" => loxxexpandedsourcetypes.halow(halow)
	"HA Median" => loxxexpandedsourcetypes.hamedian(hamedian)
	"HA Typical" => loxxexpandedsourcetypes.hatypical(hatypical)
	"HA Weighted" => loxxexpandedsourcetypes.haweighted(haweighted)
	"HA Average" => loxxexpandedsourcetypes.haaverage(haaverage)
    "HA Average Median Body" => loxxexpandedsourcetypes.haavemedbody(haclose, haopen)
	"HA Trend Biased" => loxxexpandedsourcetypes.hatrendb(haclose, haopen, hahigh, halow)
	"HA Trend Biased (Extreme)" => loxxexpandedsourcetypes.hatrendbext(haclose, haopen, hahigh, halow)
	"HAB Close" => loxxexpandedsourcetypes.habclose(smthtype, amafl, amasl, kfl, ksl)
	"HAB Open" => loxxexpandedsourcetypes.habopen(smthtype, amafl, amasl, kfl, ksl)
	"HAB High" => loxxexpandedsourcetypes.habhigh(smthtype, amafl, amasl, kfl, ksl)
	"HAB Low" => loxxexpandedsourcetypes.hablow(smthtype, amafl, amasl, kfl, ksl)
	"HAB Median" => loxxexpandedsourcetypes.habmedian(smthtype, amafl, amasl, kfl, ksl)
	"HAB Typical" => loxxexpandedsourcetypes.habtypical(smthtype, amafl, amasl, kfl, ksl)
	"HAB Weighted" => loxxexpandedsourcetypes.habweighted(smthtype, amafl, amasl, kfl, ksl)
	"HAB Average" => loxxexpandedsourcetypes.habaverage(smthtype, amafl, amasl, kfl, ksl)
    "HAB Average Median Body" => loxxexpandedsourcetypes.habavemedbody(smthtype, amafl, amasl, kfl, ksl)
	"HAB Trend Biased" => loxxexpandedsourcetypes.habtrendb(smthtype, amafl, amasl, kfl, ksl)
	"HAB Trend Biased (Extreme)" => loxxexpandedsourcetypes.habtrendbext(smthtype, amafl, amasl, kfl, ksl)
	=> haclose

wpr = 0.
cfb_draft = loxxjuriktools.jcfb(src, cfb_len, smth)
cfb_pre = 
     CfbSmoothDouble ? loxxjuriktools.jurik_filt(loxxjuriktools.jurik_filt(cfb_draft, jcfbsmlen, jcfbsmph), jcfbsmlen, jcfbsmph) :
     loxxjuriktools.jurik_filt(cfb_draft, jcfbsmlen, jcfbsmph)

max = ta.highest(cfb_pre, nlen)
min = ta.lowest(cfb_pre, nlen)
denom = max - min
ratio = (denom > 0) ? (cfb_pre - min) / denom : 0.5
len_out_cfb = math.ceil(slim + ratio * (llim - slim))

hi = ta.highest(high, len_out_cfb)
lo = ta.lowest(low, len_out_cfb)

t31 = WprSmoothDouble ? loxxjuriktools.jurik_filt(loxxjuriktools.jurik_filt(-100*(hi-src)/(hi-lo), len_out_cfb, WprSmoothPhase), len_out_cfb, WprSmoothPhase) :
     loxxjuriktools.jurik_filt(-100*(hi-src)/(hi-lo), len_out_cfb, WprSmoothPhase) 
t32 = WprSmoothDouble ? loxxjuriktools.jurik_filt(loxxjuriktools.jurik_filt(0., len_out_cfb, WprSmoothPhase) , len_out_cfb, WprSmoothPhase) :
     loxxjuriktools.jurik_filt(0., len_out_cfb, WprSmoothPhase) 
    
wpr := hi!=lo ? t31 : t32
sig = wpr[1]

bl1 = loxxdynamiczone.dZone("buy", wpr, buy1,  dzper)
sl1 = loxxdynamiczone.dZone("sell", wpr, sell1, dzper)
zli = loxxdynamiczone.dZone("sell", wpr, 0.5 , dzper)

state = 0.
if sigtype == SM02
    if (wpr<sig) 
        state :=-1
    if (wpr>sig) 
        state := 1
else if sigtype == SM03
    if (wpr<zli) 
        state :=-1
    if (wpr>zli)
        state := 1
else if sigtype == SM04
    if (wpr<bl1) 
        state :=-1
    if (wpr>sl1)
        state := 1

colorwpr = state == -1 ? redcolor : state == 1 ? greencolor : color.gray
plot(wpr, color = colorwpr, linewidth = 3)
plot(bl1, color =  lightgreencolor)
plot(sl1, color =  lightredcolor)
plot(zli, color =  bar_index % 2 ? color.white : na)

barcolor(colorbars ? colorwpr : na)

osc = wpr

plFound = na(ta.pivotlow(osc, lbL, lbR)) ? false : true
phFound = na(ta.pivothigh(osc, lbL, lbR)) ? false : true
_inRange(cond) =>
	bars = ta.barssince(cond == true)
	rangeLower <= bars and bars <= rangeUpper

//------------------------------------------------------------------------------
// Regular Bullish
// Osc: Higher Low

oscHL = osc[lbR] > ta.valuewhen(plFound, osc[lbR], 1) and _inRange(plFound[1])

// Price: Lower Low

priceLL = low[lbR] < ta.valuewhen(plFound, low[lbR], 1)
bullCond = plotBull and priceLL and oscHL and plFound

plot(
     plFound ? osc[lbR] : na,
     offset=-lbR,
     title="Regular Bullish",
     linewidth=2,
     color=(bullCond ? bullColor : noneColor)
     )

plotshape(
	 bullCond ? osc[lbR] : na,
	 offset=-lbR,
	 title="Regular Bullish Label",
	 text="R",
	 style=shape.labelup,
	 location=location.absolute,
	 color=bullColor,
	 textcolor=textColor
	 )

//------------------------------------------------------------------------------
// Hidden Bullish
// Osc: Lower Low

oscLL = osc[lbR] < ta.valuewhen(plFound, osc[lbR], 1) and _inRange(plFound[1])

// Price: Higher Low

priceHL = low[lbR] > ta.valuewhen(plFound, low[lbR], 1)
hiddenBullCond = plotHiddenBull and priceHL and oscLL and plFound

plot(
	 plFound ? osc[lbR] : na,
	 offset=-lbR,
	 title="Hidden Bullish",
	 linewidth=2,
	 color=(hiddenBullCond ? hiddenBullColor : noneColor)
	 )

plotshape(
	 hiddenBullCond ? osc[lbR] : na,
	 offset=-lbR,
	 title="Hidden Bullish Label",
	 text="H",
	 style=shape.labelup,
	 location=location.absolute,
	 color=bullColor,
	 textcolor=textColor
	 )

//------------------------------------------------------------------------------
// Regular Bearish
// Osc: Lower High

oscLH = osc[lbR] < ta.valuewhen(phFound, osc[lbR], 1) and _inRange(phFound[1])

// Price: Higher High

priceHH = high[lbR] > ta.valuewhen(phFound, high[lbR], 1)

bearCond = plotBear and priceHH and oscLH and phFound

plot(
	 phFound ? osc[lbR] : na,
	 offset=-lbR,
	 title="Regular Bearish",
	 linewidth=2,
	 color=(bearCond ? bearColor : noneColor)
	 )

plotshape(
	 bearCond ? osc[lbR] : na,
	 offset=-lbR,
	 title="Regular Bearish Label",
	 text="R",
	 style=shape.labeldown,
	 location=location.absolute,
	 color=bearColor,
	 textcolor=textColor
	 )

//------------------------------------------------------------------------------
// Hidden Bearish
// Osc: Higher High

oscHH = osc[lbR] > ta.valuewhen(phFound, osc[lbR], 1) and _inRange(phFound[1])

// Price: Lower High

priceLH = high[lbR] < ta.valuewhen(phFound, high[lbR], 1)

hiddenBearCond = plotHiddenBear and priceLH and oscHH and phFound

plot(
	 phFound ? osc[lbR] : na,
	 offset=-lbR,
	 title="Hidden Bearish",
	 linewidth=2,
	 color=(hiddenBearCond ? hiddenBearColor : noneColor)
	 )

plotshape(
	 hiddenBearCond ? osc[lbR] : na,
	 offset=-lbR,
	 title="Hidden Bearish Label",
	 text="H",
	 style=shape.labeldown,
	 location=location.absolute,
	 color=bearColor,
	 textcolor=textColor
	 )


goLong = sigtype == SM02 ? ta.crossover(wpr, sig) : sigtype == SM03 ? ta.crossover(wpr, zli) : ta.crossover(wpr, sl1)
goShort = sigtype == SM02 ? ta.crossunder(wpr, sig) : sigtype == SM03 ? ta.crossunder(wpr, zli) :  ta.crossunder(wpr, bl1)

plotshape(goLong and showsignals, title = "Long", color = greencolor, textcolor = greencolor, text = "L", style = shape.triangleup, location = location.bottom, size = size.auto)
plotshape(goShort and showsignals, title = "Short", color = redcolor, textcolor = redcolor, text = "S", style = shape.triangledown, location = location.top, size = size.auto)

alertcondition(goLong, title="Long", message="CFB-Adaptive, Williams %R w/ Dynamic Zones [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="CFB-Adaptive, Williams %R w/ Dynamic Zones [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")

alertcondition(hiddenBearCond, title="Hidden Bear Divergence", message="CFB-Adaptive, Williams %R w/ Dynamic Zones [Loxx]: Hidden Bear Divergence\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(bearCond, title="Regular Bear Divergence", message="CFB-Adaptive, Williams %R w/ Dynamic Zones [Loxx]: Regular Bear Divergence\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(hiddenBullCond, title="Hidden Bull Divergence", message="CFB-Adaptive, Williams %R w/ Dynamic Zones [Loxx]: Hidden Bull Divergence\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(bullCond, title="Regular Bull Divergence", message="CFB-Adaptive, Williams %R w/ Dynamic Zones [Loxx]: Regular Bull Divergence\nSymbol: {{ticker}}\nPrice: {{close}}")








