Adaptive-Lookback CCI w/ Double Juirk Smoothing [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-Lookback CCI w/ Double Juirk Smoothing [Loxx]", 
     overlay = false, 
     shorttitle='ALBCCIDJS [Loxx]',
     timeframe="",
     timeframe_gaps=true)

import loxx/loxxjuriktools/1

greencolor = #2DD204
redcolor = #D2042D

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

_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

src = input.source(hlc3, "CCI Source", group = "Basic Settings")
jper = input.int(14, "Jurik Smoothing Period", group = "Basic Settings")
jphs = input.float(0., "Jurik Smoothing Phase", group = "Basic 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")

lvlup = input.int(100, "Upper Level", group = "Levels Settings")
lvldn = input.int(-100, "Bottom Level", group = "Levels Settings")

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

colorbars = input.bool(true, "Color bars?", group= "UI Options")
showSigs = input.bool(true, "Show signals?", group= "UI Options")
    
    
albper = _albper(swingCount, speed)

avg = 0.
for k = 0 to albper - 1  
    avg += nz(src[k])
avg /= albper
dev = 0.
for k = 0 to albper
    dev += math.abs(nz(src[k]) - avg)
dev /= albper

cci = 0.
if (dev != 0)
    cci := (src - avg) / (0.015 * dev)
else 
    cci := 0.
    
cci := loxxjuriktools.jurik_filt(loxxjuriktools.jurik_filt(cci, albper, jphs), albper, jphs)
sigval = cci[1]
mid = 0.

state = 0.
if sigtype == SM02
    if (cci < sigval) 
        state :=-1
    if (cci > sigval) 
        state := 1
else if sigtype == SM03
    if (cci < mid) 
        state :=-1
    if (cci > mid)
        state := 1
else if sigtype == SM04
    if (cci < lvldn) 
        state := -1
    if (cci > lvlup)
        state := 1
        
colorout = state == 1 ? greencolor : state == -1 ? redcolor : color.gray

plot(cci, "CCI", color = colorout, linewidth = 3)
plot(lvlup, "Overbought", color = bar_index % 2 ? color.gray : na)
plot(lvldn, "Oversold", color = bar_index % 2 ? color.gray : na)
plot(mid, "Middle", color = bar_index % 2 ? color.gray : na)

barcolor(colorbars ?  colorout: na)

goLong = sigtype == SM02 ? ta.crossover(cci, sigval) : sigtype == SM03 ? ta.crossover(cci, mid) :  ta.crossover(cci, lvlup)
goShort = sigtype == SM02 ? ta.crossunder(cci, sigval) : sigtype == SM03 ? ta.crossunder(cci, mid) : ta.crossunder(cci, lvldn)

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="Adaptive-Lookback CCI w/ Double Juirk Smoothing [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="Adaptive-Lookback CCI w/ Double Juirk Smoothing [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")

