T3 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 = 'T3 PPO [Loxx]', 
     shorttitle = "T3PPO [Loxx]", 
     timeframe="",
     overlay = false, 
     timeframe_gaps=true, 
     max_bars_back = 5000)

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

lightgreencolor = #96E881 
lightredcolor =  #DF4F6C

_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(title='Source', defval=hl2, group = "Basic Settings")
lookBack = input.int(200, "Period", group = "Basic Settings")

FastT3 = input.int(20, "Fast T3", group = "T3 Settings")
SlowT3 = input.int(50, "Slow T3", group = "T3 Settings")
HotT3 = input.float(.5, "T3 Hot", group = "T3 Settings")
t3swt = input.string("T3 New", "T3 Type", options = ["T3 New", "T3 Original"], group = "T3 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 = _iT3(src, FastT3, HotT3, t3swt)
lmal = _iT3(src, SlowT3, HotT3, t3swt)

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