Jurik-Filtered, Adaptive Laguerre PPO [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 = 'Jurik-Filtered, Adaptive Laguerre PPO [Loxx]', 
     shorttitle = "JFALPPO [Loxx]", 
     timeframe="",
     overlay = false, 
     timeframe_gaps=true, 
     max_bars_back = 5000)

import loxx/loxxjuriktools/1 as jt

greencolor = #2DD204
redcolor = #D2042D 
bluecolor = #042dd2

lightgreencolor = #96E881 
lightredcolor =  #DF4F6C

_lagfilt(src, gam) =>
    L0 = 0.0, L1 = 0.0, L2 = 0.0, L3 = 0.0
    L0 := (1 - gam) * src + gam * nz(L0[1])
    L1 := -gam * L0 + nz(L0[1]) + gam * nz(L1[1])
    L2 := -gam * L1 + nz(L1[1]) + gam * nz(L2[1])
    L3 := -gam * L2 + nz(L2[1]) + gam * nz(L3[1])
    out = (L0 + 2 * L1 + 2 * L2 + L3) / 6
    out

src = input.source(title='Source', defval=hl2, group = "Basic Settings")

lookBack = input.int(200, "Period", group = "Basic Settings")
gamFast = input.float(0.4, "Gamma Fast", step = 0.01, group = "Basic Settings")
gamSlow = input.float(0.8, "Gamm Slow", step = 0.01, group = "Basic Settings")

fphs = input.int(-100, title= "Fast Jurik Phase", group = "Jurik Settings")
sphs = input.int(0, title= "Slow Jurik Phase", group = "Jurik Settings")
fast = input.int(7, "Fast Jurik Period", group = "Jurik Settings")
slow = input.int(40, "Slow Jurik Period", group = "Jurik Settings")

percent1 = input.float(80, "Percent 1", group = "Levels Settings")
percent2 = input.float(90, "Percent 2", group = "Levels Settings")

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


lmas = _lagfilt(src, gamFast)
lmal = _lagfilt(src, gamSlow)

lmas := jt.jurik_filt(lmas, fast, fphs)
lmal := jt.jurik_filt(lmal, slow, sphs)

topvalueMinus    = 0
topvaluePlus     = 0
bottomvalueMinus = 0
bottomvaluePlus  = 0

ppoT = (lmas - lmal) / lmal * 100.0
ppoB = (lmal - lmas) / lmal * 100.0

pctRankT = 0.0
pctRankB = 0.0

stateu = 0
stated = 0

for k = 1 to lookBack by 1
    if (ppoT[k] < ppoT) 
        topvalueMinus := topvalueMinus + 1
    else 
        topvaluePlus := topvaluePlus + 1
    if (ppoB[k] < ppoB) 
        bottomvalueMinus := bottomvalueMinus + 1
    else 
        bottomvaluePlus := bottomvaluePlus + 1 

if (topvalueMinus + topvaluePlus != 0)       
    pctRankT := topvalueMinus / (topvalueMinus + topvaluePlus)
   
if (bottomvalueMinus + bottomvaluePlus != 0)
    pctRankB := (bottomvalueMinus / (bottomvalueMinus + bottomvaluePlus)) * -1

if (pctRankT > math.max(percent1, percent2) / 100) 
    stateu := 2
   
if (pctRankT> math.min(percent1, percent2) / 100 and stateu == 0) 
    stateu := 1
   
if (pctRankB < -math.max(percent1, percent2) / 100) 
    stated :=-2
   
if (pctRankB < -math.min(percent1, percent2) / 100 and stated == 0) 
    stated :=-1
 
colorout = 
     stateu == 1 ? lightredcolor : 
     stateu == 2 ? redcolor : 
     stated == -1 ? lightgreencolor : 
     stated == -2 ? greencolor : 
     color.gray
     
plot(pctRankB, "8", color = colorout, style = plot.style_columns)
plot(pctRankT, "7", color = colorout, style = plot.style_columns)

barcolor(colorbars ? colorout : na)

plot(percent1/100, color=color.new(redcolor, 30), linewidth=1, style=plot.style_circles, title = "Overbought level 2")
plot(percent2/100, color=color.new(redcolor, 30), linewidth=1, style=plot.style_circles, title = "Overbought level 1")

plot(-percent1/100, color=color.new(greencolor, 30), linewidth=1, style=plot.style_circles, title = "Oversold level 1")
plot(-percent2/100, color=color.new(greencolor, 30), linewidth=1, style=plot.style_circles, title = "Oversold level 2")







