Jurik RSX on JMA [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("Jurik RSX on JMA [Loxx]", overlay = false, shorttitle="JRSXJMA [Loxx]", timeframe="", timeframe_gaps=true)

greencolor = #2DD204  
redcolor = #D2042D 

_a_jurik_filt(src, len, phase) =>
    //static variales
    volty = 0.0, avolty = 0.0, vsum = 0.0, bsmax = src, bsmin = src
    len1 = math.max(math.log(math.sqrt(0.5 * (len-1))) / math.log(2.0) + 2.0, 0)
    len2 = math.sqrt(0.5 * (len - 1)) * len1
    pow1 = math.max(len1 - 2.0, 0.5)
    beta = 0.45 * (len - 1) / (0.45 * (len - 1) + 2)
    div = 1.0 / (10.0 + 10.0 * (math.min(math.max(len-10, 0), 100)) / 100)
    phaseRatio = phase < -100 ? 0.5 : phase > 100 ? 2.5 : 1.5 + phase * 0.01
    bet = len2 / (len2 + 1)

    //Price volatility
    del1 = src - nz(bsmax[1])
    del2 = src - nz(bsmin[1])
    volty := math.abs(del1) > math.abs(del2) ? math.abs(del1) : math.abs(del2)

    //Relative price volatility factor
    vsum := nz(vsum[1]) + div * (volty - nz(volty[10]))
    avolty := nz(avolty[1]) + (2.0 / (math.max(4.0 * len, 30) + 1.0)) * (vsum - nz(avolty[1]))
    dVolty = avolty > 0 ? volty / avolty : 0
    dVolty := math.max(1, math.min(math.pow(len1, 1.0/pow1), dVolty))
    
    //Jurik volatility bands
    pow2 = math.pow(dVolty, pow1)
    Kv = math.pow(bet, math.sqrt(pow2))
    bsmax := del1 > 0 ? src : src - Kv * del1
    bsmin := del2 < 0 ? src : src - Kv * del2
    
    //Jurik Dynamic Factor
    alpha = math.pow(beta, pow2)

    //1st stage - prelimimary smoothing by adaptive EMA
    jma = 0.0, ma1 = 0.0, det0 = 0.0, e2 = 0.0
    ma1 := (1 - alpha) * src + alpha * nz(ma1[1])
    
    //2nd stage - one more prelimimary smoothing by Kalman filter
    det0 := (src - ma1) * (1 - beta) + beta * nz(det0[1])
    ma2 = ma1 + phaseRatio * det0

    //3rd stage - final smoothing by unique Jurik adaptive filter
    e2 := (ma2 - nz(jma[1])) * math.pow(1 - alpha, 2) + math.pow(alpha, 2) * nz(e2[1])
    jma := e2 + nz(jma[1])
    jma
    
    
_rsx_rsi(src, len)=>
    src_out = 100 * src
    mom0 = ta.change(src_out)
    moa0 = math.abs(mom0)
    Kg = 3 / (len + 2)
    Hg = 1 - Kg
 
    //mom
    f28 = 0.0, f30 = 0.0
    f28 := Kg * mom0 + Hg * nz(f28[1])
    f30 := Hg * nz(f30[1]) + Kg * f28
    mom1 = f28 * 1.5 - f30 * 0.5
 
    f38 = 0.0, f40 = 0.0
    f38 := Hg * nz(f38[1]) + Kg * mom1
    f40 := Kg * f38 + Hg * nz(f40[1])
    mom2 = f38 * 1.5 - f40 * 0.5
 
    f48 = 0.0, f50 = 0.0
    f48 := Hg * nz(f48[1]) + Kg * mom2
    f50 := Kg * f48 + Hg * nz(f50[1])
    mom_out = f48 * 1.5 - f50 * 0.5
 
    //moa
    f58 = 0.0, f60 = 0.0
    f58 := Hg * nz(f58[1]) + Kg * moa0
    f60 := Kg * f58 + Hg * nz(f60[1])
    moa1 = f58 * 1.5 - f60 * 0.5
 
    f68 = 0.0, f70 = 0.0
    f68 := Hg * nz(f68[1]) + Kg * moa1
    f70 := Kg * f68 + Hg * nz(f70[1])
    moa2 = f68 * 1.5 - f70 * 0.5
 
    f78 = 0.0, f80 = 0.0
    f78 := Hg * nz(f78[1]) + Kg * moa2
    f80 := Kg * f78 + Hg * nz(f80[1])
    moa_out = f78 * 1.5 - f80 * 0.5
 
    asdf = math.max(math.min((mom_out / moa_out + 1.0) * 50.0, 100.00), 0.00)
    asdf
    
src = input.source(close, "Source", group =  "Basic Settings")
len = input.int(8, "RSX Period", group =  "Basic Settings")
jma_phase = input.int(defval=8, title="Jurik Phase", group =  "Basic Settings")

colorbars = input.bool(true, "Color bars?", group = "UI Options")
rsx = _rsx_rsi(_a_jurik_filt(src, len, jma_phase), len)
rsx := rsx - 50

real = plot(rsx, color = rsx >=0 ? color.new(greencolor, 0) : color.new(redcolor, 0), linewidth = 2, style = plot.style_histogram)
zero = plot(0, color=color.new(color.gray, 30), linewidth=1, style=plot.style_circles, title = "Zero line")

plot(rsx, color = rsx >=0 ? color.new(greencolor, 0) : color.new(redcolor, 0), linewidth = 2)

barcolor(colorbars ? rsx >=0 ? color.new(greencolor, 0) : color.new(redcolor, 0) : na)


















