Adaptive-LB, Jurik-Filtered, Triangular MA w/ Price 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("Adaptive-LB, Jurik-Filtered, Triangular MA w/ Price Zones [Loxx]", 
     shorttitle="ALBJFTMAPZ [Loxx]", 
     overlay = true, 
     timeframe="", 
     timeframe_gaps = true)
     
import loxx/loxxjuriktools/1
import loxx/loxxexpandedsourcetypes/4

greencolor = #2DD204  
redcolor = #D2042D 

_albper(swingCount, speed)=>
    swing = 0.
    if bar_index > 3
        if (high > nz(high[1]) and 
             nz(high[1]) > nz(high[2]) and
             nz(low[2]) < nz(low[3]) and 
             nz(low[3]) < nz(low[4]))
            swing := -1
            
        if (low < nz(low[1]) and 
             nz(low[1]) < nz(low[2]) and 
             nz(high[2]) > nz(high[3]) and 
             nz(high[3]) > nz(high[4]))
            swing :=  1
    
    swingBuffer = swing
    k = 0, n = 0
    while (k < bar_index) and (n < swingCount)
        if(swingBuffer[k] != 0) 
            n += 1
        k += 1
    albPeriod = math.max(math.round((speed != 0 and swingCount != 0) ? k/swingCount/speed : k/swingCount), 1)
    albPeriod

_calcrng(per)=>
    lsum = (per + 1) * low
    hsum = (per + 1) * high
    sumw = (per + 1)
    k = per
    for j = 1 to per
        lsum += k * nz(low[j])
        hsum += k * nz(high[j])
        sumw += k
        k -= 1
    out = (hsum / sumw - lsum / sumw)
    out

src = input.source(hl2, "Source", group= "Source Settings")
swingCount = input.int(15, "ALB Swing Count", group = "Adaptive Lookback Settings")
speed = input.float(.5, "ALB Speed", minval = 0., step = 0.01, group = "Adaptive Lookback Settings")

smthper = input.int(30, "Jurik Smoothing Period", group = "Jurik Settings")
smthphs = input.float(0., "Jurik Smoothing Phase", group = "Jurik Settings")

rngper = input.int(5, "Range Period", group = "Price Zone Settings")
dev = input.float(1.8, "Deviation", group = "Price Zone Settings")
colorbars = input.bool(true, "Color bars?", group = "UI Options")
showsignals = input.bool(true, "Show signals?", group = "UI Options")

alb = _albper(swingCount, speed)

sum = (alb + 1) * src
sumw = (alb + 1)
k = alb

for j = 1 to alb 
    sum += k * nz(src[j])
    sumw += k
    k -= 1

tma = loxxjuriktools.jurik_filt(sum / sumw, smthper, smthphs)
sig = tma[1]

rng = _calcrng(rngper)

uplvl = tma + dev * rng
dnlvl = tma - dev * rng

colorout = tma > sig ? greencolor : redcolor

plot(tma, "TMA", color = colorout, linewidth = 4)
plot(uplvl, "Upper Channel", color = color.gray, linewidth = 1)
plot(dnlvl, "Lower Channel", color = color.gray, linewidth = 1)

barcolor(colorbars ? colorout : na)

goLong = ta.crossover(tma, sig) 
goShort = ta.crossunder(tma, sig)  

plotshape(goLong and showsignals, title = "Long", color = color.yellow, textcolor = color.yellow, text = "L", style = shape.triangleup, location = location.belowbar, size = size.tiny)
plotshape(goShort and showsignals, title = "Short", color = color.fuchsia, textcolor = color.fuchsia, text = "S", style = shape.triangledown, location = location.abovebar, size = size.tiny)

alertcondition(goLong, title="Long", message="Adaptive-LB, Jurik-Filtered, Triangular MA w/ Price Zones [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="Adaptive-LB, Jurik-Filtered, Triangular MA w/ Price Zones [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")





