CFB-Adaptive CCI w/ T3 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("CFB-Adaptive CCI w/ T3 Smoothing [Loxx]", 
     overlay = false, 
     shorttitle='CFBACCIT3 [Loxx]',
     timeframe="",
     timeframe_gaps=true)

import loxx/loxxjuriktools/1

greencolor = #2DD204
redcolor = #D2042D 

SM03 = 'Middle Crossover'
SM04 = 'Levels Crossover'

_iT3(src, per, hot, clean)=>
    a = hot
    _c1 = -a * a * a
    _c2 = 3 * a * a + 3 * a * a * a
    _c3 = -6 * a * a - 3 * a - 3 * a * a * a
    _c4 = 1 + 3 * a + a * a * a + 3 * a * a
    
    alpha = 0.
    
    if (clean == "T3 New")
        alpha := 2.0 / (2.0 + (per - 1.0) / 2.0)
    else 
        alpha := 2.0 / (1.0 + per)

    _t30 = src, _t31 = src
    _t32 = src, _t33 = src
    _t34 = src, _t35 = src
    
    _t30 := nz(_t30[1]) + alpha * (src -  nz(_t30[1]))
    _t31 := nz(_t31[1]) + alpha * (_t30 - nz(_t31[1]))
    _t32 := nz(_t32[1]) + alpha * (_t31 - nz(_t32[1]))
    _t33 := nz(_t33[1]) + alpha * (_t32 - nz(_t33[1]))
    _t34 := nz(_t34[1]) + alpha * (_t33 - nz(_t34[1]))
    _t35 := nz(_t35[1]) + alpha * (_t34 - nz(_t35[1]))
    out =
         _c1 * _t35 + _c2 * _t34 +
         _c3 * _t33 +  _c4 * _t32
    out

src = input.source(hlc3, "Source", group = "Basic Settings")
T3Hot = input.float(1.0, "T3 Factor", group = "Basic Settings")
T3Clean = input.string("T3 New", "Swiss Army it?", options = ["T3 New", "T3 Original"], group = "Basic Settings")

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")

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

levelOs = input.int(-100, "Oversold Level", group = "Levels Settings")
levelOb = input.int(100, "Oversold Level", group = "Levels Settings")

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

cfb_draft = loxxjuriktools.jcfb(src, cfb_len, smth)
cfb_pre = loxxjuriktools.jurik_filt(loxxjuriktools.jurik_filt(cfb_draft, jcfbsmlen, jcfbsmph), 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))

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

tempcci = _iT3((src - avg) / (0.015 * dev), len_out_cfb, T3Hot, T3Clean)
cci = dev != 0 ?  tempcci : 0.
sig = nz(cci[1])

mid = 0.
state = 0.

if sigtype == SM03
    if (cci < mid) 
        state :=-1
    if (cci > mid) 
        state := 1
else if sigtype == SM04
    if (cci > levelOb) 
        state := 1
    if (cci < levelOs)
        state := -1
    if (cci > levelOs and cci < levelOb) 
        state := 0

colorout = state == 1 ? greencolor : state == -1 ? redcolor : color.gray

plot(cci, "CFB-Adaptive T3 CCI", color = colorout, linewidth = 3, style = plot.style_histogram)
plot(levelOs, "Oversold", color =  bar_index % 2 ? color.gray : na)
plot(levelOb, "Overbought", color =  bar_index % 2 ? color.gray : na)
plot(mid, "Middle", color =  bar_index % 2 ? color.white : na)

barcolor(colorbars ? colorout : na)

goLong = sigtype == SM03 ? ta.crossover(cci, mid) : ta.crossover(cci, levelOb) 
goShort = sigtype == SM03 ? ta.crossunder(cci, mid) : ta.crossunder(cci, levelOs) 

plotshape(goLong and showsignals, title = "Long", color = color.yellow, textcolor = color.yellow, text = "L", style = shape.triangleup, location = location.bottom, size = size.auto)
plotshape(goShort and showsignals, 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 CCI w/ T3 Smoothing [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="CFB-Adaptive CCI w/ T3 Smoothing [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")


