VHF Adaptive ADXm [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("VHF Adaptive ADXm [Loxx]", 
     overlay = false, 
     shorttitle="VHFAADXM [Loxx]",
     timeframe="", 
     timeframe_gaps=true, 
     max_bars_back = 3000)

greencolor = #2DD204
redcolor = #D2042D 

_iAdxm(cls, hi, lo, period)=>
    hc = hi
    lc = lo
    cp = nz(cls[1])
    hp = nz(hi[1])
    lp = nz(lo[1])
    dh = (hc > hp) ? hc - hp : 0
    dl = (lp > lc) ? lp - lc : 0
    
    dh := dh == dl ? 0 : dh < dl ? 0 : dh
    dl := dh == dl ? 0 : dl < dh ? 0 : dl

    tr = math.max(hc, cp) - math.min(lc, cp)
    dhk = (tr != 0) ? 100.0 * dh / tr : 0
    dlk = (tr != 0) ? 100.0 * dl / tr : 0
    alpha = 2.0 / (period + 1.0)
    
    sdh = 0.
    sdl = 0.
    di = 0.
    adx = 0.

    sdh := nz(sdh[1]) + alpha * (dhk - nz(sdh[1]))  
    sdl := nz(sdl[1]) + alpha * (dlk - nz(sdl[1]))  
    di  := sdh - sdl

    div = sdh + sdl
    div := math.abs(div)
    temp = (div != 0.0) ? 100.0 * di / div : 0

    adx := nz(adx[1])  + alpha * (temp - nz(adx[1])) 
    [adx, di]

per = input.int(14, "Period", group = "Basic Settings")
level = input.int(20, "Level", group = "Basic Settings")
inpAdaptive = input.bool(true, "VHF Adaptive?", group = "Basic Settings")

sigtype = input.string("Zero-line", "Signal Type", options = ["Zero-line", "Signal", "Levels"], group = "UI Options")
showsignals = input.bool(false, "Show signals?", group = "UI Options")
colorbars = input.bool(false, "Color bars?", group = "UI Options")

vhfNoise = 0.
vhfDiff = (close > nz(close[1])) ? close - nz(close[1]) : nz(close[1]) - close
vhfNoise := nz(vhfNoise[1]) - nz(vhfDiff[per]) + vhfDiff

HCP = ta.highest(close, per) 
LCP = ta.lowest(close, per) 
vhf = (HCP - LCP) / vhfNoise  
peradapt = per * vhf * 2.0

perout = inpAdaptive ? peradapt : per

[adxm, di] = _iAdxm(close, high, low, perout)

middle = 0
adxmc = 0.

sigout = sigtype == "Zero-line" ? middle : nz(adxm[1])

adxmc := 
     sigtype == "Zero-line" ? adxm > sigout ? 1 : adxm < sigout ? 2 : 3 : 
     sigtype == "Signal" ? adxm > adxm[1] ? 1 : adxm < adxm[1] ? 2 : 3 :
     adxm > level ? 1 : adxm < -level ? 2 : 3
     
colorout = adxmc == 1 ? greencolor : adxmc == 2 ? redcolor : color.gray

plot(adxm, color = colorout, linewidth = 2)
plot(di, color = color.gray)

plot(level, color = bar_index % 2 ? color.gray : na)
plot(-level, color = bar_index % 2 ? color.gray : na)
plot(middle, color = bar_index % 2 ? color.gray : na)

goLong = colorout == greencolor and (colorout[1] == redcolor or colorout[1] == color.gray)
goShort = colorout == redcolor and (colorout[1] == greencolor or colorout[1] == color.gray)

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="VHF Adaptive ADXm [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="VHF Adaptive ADXm [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")

barcolor(colorbars ? colorout : na)


