VIDYA DMI Oscillator w/ DSL Levels [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("VIDYA DMI Oscillator w/ DSL Levels [Loxx]",
     shorttitle='VDMIODSLL [Loxx]', 
     overlay = false, 
     timeframe="", 
     timeframe_gaps = true)

greencolor = #2DD204
redcolor = #D2042D 

SM02 = 'Slope'
SM03 = 'Middle Crossover'
SM04 = 'Levels Crossover'

variant(type, src, len) =>
    sig = 0.0
    if type == "SMA"
        sig := ta.sma(src, len) 
    else if type == "EMA"
        sig := ta.ema(src, len) 
    else if type == "WMA"
        sig := ta.wma(src, len)   
    else if type == "RMA"
        sig := ta.rma(src, len)  
    sig
    
_vidya(price, priceForCmo, cmoPeriod, smoothPeriod)=>
    vidya_price = price
    vidya_pricc = priceForCmo
    sumUp = 0., sumDo = 0.
    for k = 1 to cmoPeriod 
        diff = nz(vidya_pricc[k]) -  nz(vidya_pricc[k-1])
        if (diff > 0)
            sumUp += diff
        else  
            sumDo -= diff
    vidya_value = 0.
    vidya_value := nz(vidya_value[1]) +   
         ((((sumUp + sumDo) != 0) ? math.abs((sumUp-sumDo)/(sumUp+sumDo)) : 1) *  
         2.00 / (1.00 + math.max(smoothPeriod, 1))) *  
         (vidya_price - nz(vidya_value[1]))
    vidya_value

DmiPeriod= input.int(32, "DMI Period", minval = 1, group = "DMI Settings")
SignalPeriod  = input.int(9, "DMI Signal Period", minval = 1, group = "DMI Settings")
type = input.string("SMA", "DMI Smoothing Type", options = ["EMA", "WMA", "RMA", "SMA"], group = "DMI Settings")

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


Smooth = input.int(2, "VIDYA CMO Period", minval = 1, group = "VIDYA Settings")
SmoothPeriod = input.int(5, "VIDYA Smoothing Period", minval = 1, group = "VIDYA Settings")

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

dhh = high - nz(high[1])
dll = nz(low[1]) - low   
tr  = math.max(high, nz(close[1])) - math.min(low, nz(close[1]))  
atr = ta.ema(tr, DmiPeriod)

plusDM = (dhh > dll and dhh>0) ? dhh : 0
minusDM = (dll > dhh and dll>0) ? dll : 0
plusDI = 100 * variant(type, plusDM, DmiPeriod) / atr
minusDI = 100 * variant(type, minusDM, DmiPeriod) / atr
stoch  = _vidya(plusDI - minusDI, close, Smooth, SmoothPeriod)

levelu = 0.
leveld = 0.
alpha = 2.0 / (1.0 + SignalPeriod)
levelu := (stoch > 0) ? nz(levelu[1]) + alpha * (stoch - nz(levelu[1])) : nz(levelu[1])  
leveld := (stoch < 0) ? nz(leveld[1]) + alpha * (stoch - nz(leveld[1])) : nz(leveld[1])
sig = stoch[1]
mid = 0.

state = 0.
if sigtype == SM02
    if (stoch < sig) 
        state :=-1
    if (stoch > sig) 
        state := 1
else if sigtype == SM03
    if (stoch < mid) 
        state :=-1
    if (stoch > mid)
        state := 1
else if sigtype == SM04
    if (stoch < leveld) 
        state :=-1
    if (stoch > levelu)
        state := 1

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

plot(stoch, "DMI", color = colorout, linewidth = 3)
plot(levelu, "Level Up", color = bar_index % 2 ? color.gray : na)
plot(leveld, "Level Down", color = bar_index % 2 ? color.gray : na)

barcolor(colorbars ? colorout : na)

goLong = sigtype == SM02 ? ta.crossover(stoch, sig) : sigtype == SM03 ? ta.crossover(stoch, mid) : ta.crossover(stoch, levelu)
goShort = sigtype == SM02 ? ta.crossunder(stoch, sig) : sigtype == SM03 ? ta.crossunder(stoch, mid) :  ta.crossunder(stoch, leveld)

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="VIDYA DMI Oscillator w/ DSL Levels [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="VIDYA DMI Oscillator w/ DSL Levels [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")




