QQE of Parabolic-Weighted Velocity [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('QQE of Parabolic-Weighted Velocity [Loxx]',
     shorttitle = "QQEPWV [Loxx]", 
     overlay = false, 
     timeframe="", 
     timeframe_gaps = true)
     
import loxx/loxxexpandedsourcetypes/4

greencolor = #2DD204
redcolor = #D2042D 

darkGreenColor =  #1B7E02 
darkRedColor = #93021F

SM02 = 'Zero Cross'
SM03 = 'Fast Trend Cross'
SM04 = 'Slow Trend Cross'

_ivelocity(src, period, power)=>
    suma = 0., sumwa=0.
    sumb = 0., sumwb=0.
    velWork = src
    for k = 0 to period - 1
        weight = math.pow((period-k), power)
        suma  += nz(velWork[k]) * weight
        sumb  += nz(velWork[k]) * weight * weight
        sumwa += weight
        sumwb += math.pow(weight, 2) 
    out = sumb/sumwb-suma/sumwa
    out

    
smthtype = input.string("Kaufman", "Heikin-Ashi Better Caculation Type", options = ["AMA", "T3", "Kaufman"], group = "Source Settings")
srcin = input.string("Close", "Source", group= "Source Settings", 
     options = 
     ["Close", "Open", "High", "Low", "Median", "Typical", "Weighted", "Average", "Average Median Body", "Trend Biased", "Trend Biased (Extreme)", 
     "HA Close", "HA Open", "HA High", "HA Low", "HA Median", "HA Typical", "HA Weighted", "HA Average", "HA Average Median Body", "HA Trend Biased", "HA Trend Biased (Extreme)",
     "HAB Close", "HAB Open", "HAB High", "HAB Low", "HAB Median", "HAB Typical", "HAB Weighted", "HAB Average", "HAB Average Median Body", "HAB Trend Biased", "HAB Trend Biased (Extreme)"])

type = input.string("EMA", "QQE/DSS Smoothing Type", options = ["EMA", "WMA", "RMA", "SMA"], group = "Basic Settings")
velper = input.int(50, "Velocity Period", group = "Basic Settings")
velpow = input.float(2, "Velocity Power", group = "Basic Settings")
MAPeriod = input.int(5, "Velocity Smoothing Factor", group = "Basic Settings")
wpFast = input.float(2.618, "WP Fast Coeffient", group = "Basic Settings")
wpSlow = input.float(4.236, "WP Slow Coeffient", group = "Basic Settings")

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

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

kfl=input.float(0.666, title="* Kaufman's Adaptive MA (KAMA) Only - Fast End", group = "Moving Average Inputs")
ksl=input.float(0.0645, title="* Kaufman's Adaptive MA (KAMA) Only - Slow End", group = "Moving Average Inputs")
amafl = input.int(2, title="* Adaptive Moving Average (AMA) Only - Fast", group = "Moving Average Inputs")
amasl = input.int(30, title="* Adaptive Moving Average (AMA) Only - Slow", group = "Moving Average Inputs")

haclose = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close)
haopen = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, open)
hahigh = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, high)
halow = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, low)
hamedian = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hl2)
hatypical = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hlc3)
haweighted = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hlcc4)
haaverage = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, ohlc4)

src = switch srcin
	"Close" => loxxexpandedsourcetypes.rclose()
	"Open" => loxxexpandedsourcetypes.ropen()
	"High" => loxxexpandedsourcetypes.rhigh()
	"Low" => loxxexpandedsourcetypes.rlow()
	"Median" => loxxexpandedsourcetypes.rmedian()
	"Typical" => loxxexpandedsourcetypes.rtypical()
	"Weighted" => loxxexpandedsourcetypes.rweighted()
	"Average" => loxxexpandedsourcetypes.raverage()
    "Average Median Body" => loxxexpandedsourcetypes.ravemedbody()
	"Trend Biased" => loxxexpandedsourcetypes.rtrendb()
	"Trend Biased (Extreme)" => loxxexpandedsourcetypes.rtrendbext()
	"HA Close" => loxxexpandedsourcetypes.haclose(haclose)
	"HA Open" => loxxexpandedsourcetypes.haopen(haopen)
	"HA High" => loxxexpandedsourcetypes.hahigh(hahigh)
	"HA Low" => loxxexpandedsourcetypes.halow(halow)
	"HA Median" => loxxexpandedsourcetypes.hamedian(hamedian)
	"HA Typical" => loxxexpandedsourcetypes.hatypical(hatypical)
	"HA Weighted" => loxxexpandedsourcetypes.haweighted(haweighted)
	"HA Average" => loxxexpandedsourcetypes.haaverage(haaverage)
    "HA Average Median Body" => loxxexpandedsourcetypes.haavemedbody(haclose, haopen)
	"HA Trend Biased" => loxxexpandedsourcetypes.hatrendb(haclose, haopen, hahigh, halow)
	"HA Trend Biased (Extreme)" => loxxexpandedsourcetypes.hatrendbext(haclose, haopen, hahigh, halow)
	"HAB Close" => loxxexpandedsourcetypes.habclose(smthtype, amafl, amasl, kfl, ksl)
	"HAB Open" => loxxexpandedsourcetypes.habopen(smthtype, amafl, amasl, kfl, ksl)
	"HAB High" => loxxexpandedsourcetypes.habhigh(smthtype, amafl, amasl, kfl, ksl)
	"HAB Low" => loxxexpandedsourcetypes.hablow(smthtype, amafl, amasl, kfl, ksl)
	"HAB Median" => loxxexpandedsourcetypes.habmedian(smthtype, amafl, amasl, kfl, ksl)
	"HAB Typical" => loxxexpandedsourcetypes.habtypical(smthtype, amafl, amasl, kfl, ksl)
	"HAB Weighted" => loxxexpandedsourcetypes.habweighted(smthtype, amafl, amasl, kfl, ksl)
	"HAB Average" => loxxexpandedsourcetypes.habaverage(smthtype, amafl, amasl, kfl, ksl)
    "HAB Average Median Body" => loxxexpandedsourcetypes.habavemedbody(smthtype, amafl, amasl, kfl, ksl)
	"HAB Trend Biased" => loxxexpandedsourcetypes.habtrendb(smthtype, amafl, amasl, kfl, ksl)
	"HAB Trend Biased (Extreme)" => loxxexpandedsourcetypes.habtrendbext(smthtype, amafl, amasl, kfl, ksl)
	=> haclose

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
    
qqe = 0.
trend1 = 0.
trend2 = 0.

velout = _ivelocity(src, velper, velpow)

velma = variant(type, velout, MAPeriod)
mavel = variant(type, math.abs(nz(velma[1]) - velma), velper)
outer = variant(type, mavel, velper)

emas = outer * wpSlow
emaf = outer * wpFast

TrendSlow = 0.0
tr = nz(TrendSlow[1])
dv = tr

if (velma < tr) 
    tr := velma + emas
    if ((nz(velma[1]) < dv and tr > dv)) 
        tr := dv
       
if (velma > tr) 
    tr := velma - emas
    if ((nz(velma[1]) > dv) and (tr < dv))
        tr := dv

TrendSlow := tr

TrendFast = 0.0
tr := nz(TrendFast[1])
dv := tr

if (velma < tr) 
    tr := velma + emaf
    if ((nz(velma[1]) < dv and tr > dv)) 
        tr := dv
       
if (velma > tr) 
    tr := velma - emaf
    if ((nz(velma[1]) > dv) and (tr < dv))
        tr := dv

TrendFast := tr
mid = 0

colorout = 
     sigtype == SM02 ? 
     velma > mid ? greencolor :  
     velma < mid ? redcolor : color.gray : 
     
     sigtype == SM03 ? 
     velma > TrendFast ? greencolor :  
     velma < TrendFast ? redcolor : color.gray :
    
     velma > TrendSlow ? greencolor :  
     velma < TrendSlow ? redcolor : color.gray 

plot(velma,"Parabolic-Weighted Velocity MA", color = colorout, linewidth = 3)
plot(mid, color=color.new(color.gray, 30), linewidth=1, style=plot.style_circles, title = "Zero line")

plot(TrendFast, "Fast Trend", color=color.new(color.white, 0), linewidth = 1)
plot(TrendSlow, "Slow Trend", color=color.new(color.yellow, 0), linewidth = 1)

barcolor(colorbars ? colorout : na)

goLong  = sigtype == SM02 ? ta.crossover(velma, mid) : sigtype == SM03 ? ta.crossover(velma, TrendFast) : ta.crossover(velma, TrendSlow) 
goShort = sigtype == SM02 ? ta.crossunder(velma, mid) : sigtype == SM03 ? ta.crossunder(velma, TrendFast) : ta.crossunder(velma, TrendSlow) 

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}}")
