Zero-line Volatility Quality Index (VQI) [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('Zero-line Volatility Quality Index (VQI) [Loxx]',
     shorttitle = "ZLVQI [Loxx]", 
     overlay = false, 
     timeframe="", 
     timeframe_gaps = true)
     
greencolor = #2DD204
redcolor = #D2042D 

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
    
inpPriceSmoothing = input.int(10, "Source Smoothing Period", group = "Basic Settings")
inpFilter = input.float(7.5, "ATR Percentage %", group = "Basic Settings")/100
type = input.string("WMA", "Smoothing Type", options = ["EMA", "WMA", "RMA", "SMA"], group = "Basic Settings")

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

chigh = variant(type, high, inpPriceSmoothing)
clow = variant(type, low, inpPriceSmoothing)
cclose = variant(type, close, inpPriceSmoothing)
copen = variant(type, open, inpPriceSmoothing)
pclose = variant(type, nz(close[1]), inpPriceSmoothing)

trueRange = (chigh > pclose ? chigh : pclose) - (clow < pclose ? clow : pclose)
rng = chigh - clow

vqi = 0.
vqi := (rng > 0 and trueRange > 0) ? ((cclose - pclose) / trueRange + (cclose - copen) / rng) * 0.5 : (bar_index > 0) ? nz(vqi[1]) : 0
vqi := (bar_index > 0) ? (vqi > 0 ? vqi : -vqi) * (cclose - pclose + cclose - copen) * 0.5 : 0
val = vqi

atr = ta.atr(inpPriceSmoothing)
if inpFilter > 0 and bar_index > 0
    if (val > nz(val[1]) ? val - nz(val[1]) : nz(val[1]) - val) < inpFilter * atr
        val := nz(val[1])

valc = 0
valc := (val > 0) ? 1 : (val < 0) ? 2 : (bar_index > 0) ? nz(valc[1]) : 0

colorout = valc == 1 ? greencolor : valc == 2 ? redcolor : color.gray
mid = 0.
plot(vqi, "VQI", color = colorout, linewidth = 2)
plot(mid, "Middle", color = bar_index % 2 ? color.gray : na)

barcolor(colorbars ? colorout : na)

goLong  = ta.crossover(val, mid)
goShort = ta.crossunder(val, mid)

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="QQE of Parabolic-Weighted Velocity [Loxx]: Long\nSymbol: {{ticker}}\nPrice: {{close}}")
alertcondition(goShort, title="Short", message="QQE of Parabolic-Weighted Velocity [Loxx]: Short\nSymbol: {{ticker}}\nPrice: {{close}}")

