Dynamic Zone Range on OMA [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("Dynamic Zone Range on OMA [Loxx]",
     shorttitle='DDZROMA [Loxx]', 
     overlay = false, 
     timeframe="", 
     timeframe_gaps = true)
     

import loxx/loxxdynamiczone/3

greencolor = #2DD204
redcolor = #D2042D
lightgreencolor = #96E881 
lightredcolor =  #DF4F6C

SM02 = 'Slope'
SM03 = 'Middle Crossover'
SM04 = 'Inner Crossover'
SM05 = 'Outer Crossover'

_oma(src, len, const, 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 = len
    noise = 0.00000000001
    minPeriod = averagePeriod/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 := math.ceil(((signal / noise) * (maxPeriod - minPeriod)) + minPeriod)
    
    //calc jurik momentum
    alpha = (2.0 + const) / (1.0 + const + 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
    
HLR_Range = input.int(25, "HLR Range", group = "Basic Settings")
len = input.int(15, "Average Period", minval = 1, group = "Basic Settings")
const = input.float(.5, "Speed", step = .01, group = "Basic Settings")
adapt = input.bool(true, "Make it adaptive?", group = "Basic Settings")

dzper = input.int(70, "Dynamic Zone Period", group = "Levels Settings") 
buy1  = input.float(0.2, "Dynamic Zone Buy Probability Level 1", group = "Levels Settings")
buy2  = input.float(0.06, "Dynamic Zone Buy Probability Level 2", group = "Levels Settings")
sell1 = input.float(0.2, "Dynamic Zone Sell Probability Level 1", group = "Levels Settings")
sell2 = input.float(0.06, "Dynamic Zone Sell Probability Level 2", group = "Levels Settings")

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

colorbars = input.bool(false, "Color bars?", group= "UI Options")
ShowMiddleLine  = input.bool(true, "Show middle line?", group = "UI Options")  
filllevels  = input.bool(false, "Show fill colors?", group = "UI Options")  
showsignals = input.bool(false, "Show signals?", group = "UI Options")

hhv  = _oma(ta.highest(high, HLR_Range), len, const, adapt)
llv  = _oma(ta.lowest(low, HLR_Range), len, const, adapt)
m_pr = _oma((high + low)/2, len, const, adapt)

HLR_Buffer   = 100.0 * (m_pr - llv) / (hhv - llv) 
 
bl1 = loxxdynamiczone.dZone("buy", HLR_Buffer, buy1,  dzper)
bl2 = loxxdynamiczone.dZone("buy", HLR_Buffer, buy2,  dzper)
sl1 = loxxdynamiczone.dZone("sell", HLR_Buffer, sell1, dzper)
sl2 = loxxdynamiczone.dZone("sell", HLR_Buffer, sell2, dzper)
zli = loxxdynamiczone.dZone("sell", HLR_Buffer, 0.5 , dzper)

state = 0.

if sigtype == SM02
    if (HLR_Buffer<nz(HLR_Buffer[1])) 
        state :=-1
    if (HLR_Buffer>nz(HLR_Buffer[1])) 
        state := 1
else if sigtype == SM03
    if (HLR_Buffer<zli) 
        state :=-1
    if (HLR_Buffer>zli)
        state := 1
else if sigtype == SM04
    if (HLR_Buffer<bl1) 
        state :=-1
    if (HLR_Buffer>sl1)
        state := 1
else if sigtype == SM05
    if (HLR_Buffer<bl2) 
        state :=-1
    if (HLR_Buffer>sl2)
        state := 1

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

plot(HLR_Buffer, color = colorout, linewidth = 3)
bl1pl = plot(bl1, "buy lvl 1", color = bar_index % 3 ? lightgreencolor: na)
bl2pl = plot(bl2, "buy lvl 2", color = bar_index % 2 ? greencolor: na)
sl1pl = plot(sl1, "sell lvl 1", color = bar_index % 3 ? lightredcolor: na)
sl2pl = plot(sl2, "sell lvl 1", color = bar_index % 2 ? redcolor: na)

midpl = plot(ShowMiddleLine ? zli : na, "mid lvl", color = bar_index % 4 ? color.white : na)


fill(bl1pl, bl2pl, color = filllevels ? color.new(greencolor, 85) : na)
fill(bl2pl, midpl, color = filllevels ? color.new(greencolor, 95): na)
fill(sl1pl, sl2pl, color = filllevels ? color.new(redcolor, 85): na)
fill(sl2pl, midpl, color = filllevels ? color.new(redcolor, 95): na)

barcolor(colorbars ? colorout : na)

goLong = colorout == greencolor and colorout[1] == redcolor
goShort = colorout == redcolor and colorout[1] == greencolor
plotshape(goLong and showsignals, title = "Long", color = greencolor, textcolor = greencolor, text = "L", style = shape.triangleup, location = location.bottom, size = size.auto)
plotshape(goShort and showsignals, title = "Short", color = redcolor, textcolor = redcolor, text = "S", style = shape.triangledown, location = location.top, size = size.auto)

alertcondition(goLong, title="Long", message="Dynamic Zone Range on OMA [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="Dynamic Zone Range on OMA [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")














