CFB-Adaptive, Jurik DMX Histogram [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(title="CFB-Adaptive, Jurik DMX Histogram [Loxx]", 
     shorttitle="CFBAJDMXH [Loxx]",
     timeframe="", 
     timeframe_gaps=true, 
     overlay = false)

import loxx/loxxjuriktools/1 as jf
import loxx/loxxexpandedsourcetypes/4

greencolor = #2DD204
redcolor = #D2042D 
 
lightgreencolor = #96E881 
lightredcolor =  #DF4F6C
 
darkGreenColor =  #1B7E02 
darkRedColor = #93021F
 
smthtype = input.string("Kaufman", "Heiken-Ashi Better Smoothing", options = ["AMA", "T3", "Kaufman"], group=  "Source Settings")
srcoption = input.string("Close", "Source", group= "Source 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)"])

adapt = input.string("CFB Adaptive", "Calculation type", options = ["Fixed", "CFB Adaptive"], group = "Basic Settings")
len = input.int(32, minval=1, title="Length", group = "Basic Settings")
phs = input.int(0, title= "Jurik Phase", group = "Basic Settings")
siglen = input.int(5, minval=1, title="Signal Smoothing Length", group = "Basic Settings")

nlen = input.int(50, "CFB Normal Period", minval = 1, group = "CFB Ingest Settings")
cfb_len = input.int(8, "CFB Depth", maxval = 10, group = "CFB Ingest Settings")
smth = input.int(8, "CFB Smooth Period", minval = 1, group = "CFB Ingest Settings")
slim = input.int(10, "CFB Short Limit", minval = 1, group = "CFB Ingest Settings")
llim = input.int(60, "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")

colorbars = input.bool(true, "Color bars?", group = "UI Options")
showSigs = 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)

float src = switch srcoption
	"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
	
	
cfb_draft = jf.jcfb(src, cfb_len, smth)
cfb_pre = 
     CfbSmoothDouble ? jf.jurik_filt(jf.jurik_filt(cfb_draft, jcfbsmlen, jcfbsmph), jcfbsmlen, jcfbsmph) :
     jf.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))

out = adapt == "Fixed" ? len : len_out_cfb

up = ta.change(high)
down = -ta.change(low)

plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)

trur = jf.jurik_filt(ta.tr, out, phs)

plus = fixnan(100 * jf.jurik_filt(plusDM, out, phs) / trur)
minus = fixnan(100 * jf.jurik_filt(minusDM, out, phs) / trur)

trigger = plus-minus
signal = jf.jurik_filt(trigger, siglen, phs)

colorout = 
     trigger >= 0 and trigger >= signal ? greencolor  : 
     trigger >= 0 and trigger < signal ? lightgreencolor  : 
     trigger < 0 and trigger < signal ? redcolor : 
     lightredcolor 

mid = 0
plot(trigger, color=colorout, title = "DMX", style = plot.style_histogram)
plot(trigger, "DMX", color = trigger >= 0 ? darkGreenColor : darkRedColor, linewidth = 1)
plot(signal, color = color.white, title = "Signal", linewidth = 1)
plot(mid, "Middle", color = bar_index % 2 ? color.gray : na)

barcolor(colorbars ? colorout : na)

goLong = ta.crossover(trigger, mid)  
goShort =  ta.crossunder(trigger, mid)  

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

alertcondition(goLong, title = "Long", message = "CFB-Adaptive, Jurik DMX Histogram [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title = "Short", message = "CFB-Adaptive, Jurik DMX Histogram [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")
