OMA-Filtered Kase Permission Stochastic [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("OMA-Filtered Kase Permission Stochastic [Loxx]",
     shorttitle="OMAFKPS [Loxx]",
     overlay = false, 
     timeframe="", 
     timeframe_gaps = true)

greencolor = #2DD204
redcolor = #D2042D 

_oma(src, len, sped, adapt) =>
    e1 = nz(src[1]), e2 = nz(src[1]), e3 = nz(src[1])
    e4 = nz(src[1]), e5 = nz(src[1]), e6 = nz(src[1])
    
    averagePeriod = 0.
    noise = 0.00000000001
    minPeriod = len/2.0
    maxPeriod = minPeriod*5.0
    endPeriod = math.ceil(maxPeriod)
    signal = math.abs(src - nz(src[endPeriod]))
    
    if adapt
        for k = 1 to endPeriod
            noise += math.abs(src - nz(src[k]))
        averagePeriod := ((signal / noise) * (maxPeriod - minPeriod)) + minPeriod
    
    //calc jurik momentum
    alpha = (2.0 + sped) / (1.0 + sped + averagePeriod)
    
    e1 := nz(e1[1] + alpha * (src - e1[1]), src)
    e2 := nz(e2[1] + alpha * (e1 - e2[1]), e1)
    v1 = 1.5 * e1 - 0.5 * e2
    
    e3 := nz(e3[1] + alpha * (v1 - e3[1]), v1)
    e4 := nz(e4[1] + alpha * (e3 - e4[1]), e3)
    v2 = 1.5 * e3 - 0.5 * e4
    
    e5 := nz(e5[1] + alpha * (v2 - e5[1]), v2) 
    e6 := nz(e6[1] + alpha * (e5 - e6[1]), e5) 
    v3 = 1.5 * e5 - 0.5 * e6
    v3
    
pstLength = input.int(9, "Period", group = "Basic Settings")
pstX = input.int(5, "Synthetic Multiplier", group = "Basic Settings")
pstSmooth = input.int(3, "Stochasitc Smoothing Period", group = "Basic Settings")
smoothPeriod = input.int(10, "OMA Smoothing Period", group = "Basic Settings")
smoothSpeed = input.float(3., "OMA Speed", group = "Basic Settings")
smoothAdaptive = input.bool(true, "Make OMA adaptive?", group = "Basic Settings")

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

lookBackPeriod = pstLength * pstX
alpha = 2.0 / (1.0 + pstSmooth)

TripleK = 0., TripleDF = 0., TripleDS = 0., TripleDSs = 0., TripleDFs = 0.

fmin = ta.lowest(low, lookBackPeriod)  
fmax = ta.highest(high, lookBackPeriod) - fmin

if (fmax > 0)
    TripleK := 100.0 * (close - fmin) / fmax
else 
    TripleK := 0.0

TripleDF := nz(TripleDF[pstX]) + alpha * (TripleK - nz(TripleDF[pstX]))
TripleDS := (nz(TripleDS[pstX]) * 2.0 + TripleDF) / 3.0

TripleDSs := ta.sma(TripleDS, 3)
pssBuffer = _oma(TripleDSs, smoothPeriod, smoothSpeed, smoothAdaptive) 

TripleDFs := ta.sma(TripleDF, 3)
pstBuffer = _oma(TripleDFs, smoothPeriod, smoothSpeed, smoothAdaptive)

trend = 0
trend := nz(trend[1])

if (pstBuffer > pssBuffer) 
    trend := 1
if (pstBuffer < pssBuffer) 
    trend := -1

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

plot(pssBuffer, color = color.white, linewidth = 1)
plot(pstBuffer, color = colorout, linewidth = 3)

barcolor(colorbars ? colorout : na)

goLong = ta.crossover(pstBuffer, pssBuffer)  
goShort =  ta.crossunder(pstBuffer, pssBuffer)  

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 = "OMA-Filtered Kase Permission Stochastic [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title = "Short", message = "OMA-Filtered Kase Permission Stochastic [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")
