Moving Average Filters Add-on w/ Expanded Source Types [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("Moving Average Filters Add-on w/ Expanded Source Types [Loxx]", 
     shorttitle = "MAFAEST [Loxx]", 
     overlay = true, 
     timeframe="", 
     timeframe_gaps = true,
     max_bars_back = 2000)

greencolor = #2DD204
redcolor = #D2042D 

_kama(src, len, kama_fastend, kama_slowend) =>
    xvnoise = math.abs(src - src[1])
    nfastend = kama_fastend
    nslowend = kama_slowend
    nsignal = math.abs(src - src[len])
    nnoise = math.sum(xvnoise, len)
    nefratio = nnoise != 0 ? nsignal / nnoise : 0
    nsmooth = math.pow(nefratio * (nfastend - nslowend) + nslowend, 2)
    nAMA = 0.0
    nAMA := nz(nAMA[1]) + nsmooth * (src - nz(nAMA[1]))
    nAMA

_ama(src, len, fl, sl)=>
    flout = 2/(fl + 1)
    slout = 2/(sl + 1)
    hh = ta.highest(len + 1)
    ll = ta.lowest(len + 1)
    mltp = hh - ll != 0 ? math.abs(2 * src - ll - hh) / (hh - ll) : 0
    ssc = mltp * (flout - slout) + slout
    ama = 0.
    ama := nz(ama[1]) + math.pow(ssc, 2) * (src - nz(ama[1]))
    ama
    
_t3(src, len) =>
    xe1_1 = ta.ema(src, len)
    xe2_1 = ta.ema(xe1_1, len)
    xe3_1 = ta.ema(xe2_1, len)
    xe4_1 = ta.ema(xe3_1, len)
    xe5_1 = ta.ema(xe4_1, len)
    xe6_1 = ta.ema(xe5_1, len)
    b_1 = 0.7
    c1_1 = -b_1 * b_1 * b_1
    c2_1 = 3 * b_1 * b_1 + 3 * b_1 * b_1 * b_1
    c3_1 = -6 * b_1 * b_1 - 3 * b_1 - 3 * b_1 * b_1 * b_1
    c4_1 = 1 + 3 * b_1 + b_1 * b_1 * b_1 + 3 * b_1 * b_1
    nT3Average = c1_1 * xe6_1 + c2_1 * xe5_1 + c3_1 * xe4_1 + c4_1 * xe3_1
    nT3Average
    
_trendreg(o, h, l, c)=>
    compute = 0.
    if (c > o)
        compute := ((h + c)/2.0)
    else  
        compute := ((l + c)/2.0)
    compute

_trendext(o, h, l, c) =>
    compute = 0.
    if (c > o) 
        compute := h
    else if (c < o) 
        compute := l
    else 
        compute := c
    compute  
    
//ADXvma - Average Directional Volatility Moving Average
_adxvma(src, len)=>
    tpdm = 0., tmdm = 0.
    pdm = 0., mdm = 0., pdi = 0., mdi = 0., out = 0., val = 0.
    tpdi = 0., tmdi = 0., thi = 0., tlo = 0., tout = 0., vi = 0.

    diff = src - nz(src[1])
    tpdm := diff > 0 ? diff : tpdm
    tmdm := diff > 0 ? tmdm : -diff
    pdm := ((len- 1.0) * nz(pdm[1]) + tpdm) / len
    mdm := ((len- 1.0) * nz(mdm[1]) + tmdm) / len
    
    trueRange = pdm + mdm
    tpdi := nz(pdm / trueRange)
    tmdi := nz(mdm / trueRange)
    pdi := ((len- 1.0) * nz(pdi[1]) + tpdi) / len
    mdi := ((len- 1.0) * nz(mdi[1]) + tmdi) / len
    
    tout := (pdi + mdi) > 0 ?  math.abs(pdi - mdi) / (pdi + mdi) : tout
    out := ((len- 1.0) * nz(out[1]) + tout) / len
    thi := math.max(out, nz(out[1]))
    tlo := math.min(out, nz(out[1]))
    for j = 2 to len 
        thi := math.max(nz(out[j]), thi)
        tlo := math.min(nz(out[j]), tlo)
    vi := (thi - tlo) > 0 ? (out - tlo) / (thi - tlo) : vi
    val := ((len- vi) * nz(val[1]) + vi * src) / len
    [val, val[1], false]
 
//Ahrens Moving Average
_ahrma(src, len)=>
    ahrma = 0.
    medMA = (nz(ahrma[1]) + nz(ahrma[len])) / 2.0
    ahrma := nz(ahrma[1]) + ((src - medMA) / len)
    [ahrma, ahrma[1], false]

//Alexander Moving Average - ALXMA
_alxma(src, len)=>
    sumw = len - 2
    sum  = sumw * src
    for k = 1 to len 
        weight = len - k - 2 
        sumw += weight
        sum += weight * nz(src[k])
    out = len < 4 ? src : sum/sumw 
    [out, out[1], false]

//Double Exponential Moving Average - DEMA
_dema(src, len)=>
    e1 = ta.ema(src, len)
    e2 = ta.ema(e1, len)
    dema = 2 * e1 - e2
    [dema, dema[1], false]
    
//Double Smoothed Exponential Moving Average - DSEMA
_dsema(src, len)=>
    alpha = 2.0 / (1.0 + math.sqrt(len))
    _ema1 = 0., _ema2 = 0.
    _ema1 := nz(_ema1[1]) + alpha * (src - nz(_ema1[1]))
    _ema2 := nz(_ema2[1]) + alpha * (_ema1 - nz(_ema2[1]))
    [_ema2, _ema2[1], false]

//Exponential Moving Average - EMA
_ema(src, len)=>
    out = ta.ema(src, len)
    [out, out[1], false]

//Fast Exponential Moving Average - FEMA
_fema(src, len)=>
    alpha = (2.0 / (2.0 + (len - 1.0) / 2.0))
    out = 0.
    out := nz(out[1]) + alpha * (src - nz(out[1])) 
    [out, out[1], false]

//hull moving averge
_hma(src, len)=>
    out = ta.hma(src, len)
    [out, out[1], false]
    
//IE/2 - Early T3 by Tim Tilson
_ie2(src, len)=>
    sumx=0., sumxx=0., sumxy=0., sumy=0.
    for k = 0 to len - 1   
        price = nz(src[k]) 
        sumx  += k
        sumxx += k * k
        sumxy += k * price
        sumy  += price
    slope = (len * sumxy - sumx * sumy) / (sumx * sumx - len * sumxx)
    average = sumy/len
    out = (((average + slope) + (sumy + slope * sumx) / len) / 2.0)
    [out, out[1], false]

//Fractal Adaptive Moving Average - FRAMA
_frama(src, len, FC, SC) =>
    len1 = len / 2
    e = math.e
    w = math.log(2 / (SC + 1)) / math.log(e)  // Natural logarithm (ln(2/(SC+1))) workaround
    H1 = ta.highest(high, len1)
    L1 = ta.lowest(low, len1)
    N1 = (H1 - L1) / len1
    H2 = ta.highest(high, len1)[len1]
    L2 = ta.lowest(low, len1)[len1]
    N2 = (H2 - L2) / len1
    H3 = ta.highest(high, len)
    L3 = ta.lowest(low, len)
    N3 = (H3 - L3) / len
    dimen1 = (math.log(N1 + N2) - math.log(N3)) / math.log(2)
    dimen = N1 > 0 and N2 > 0 and N3 > 0 ? dimen1 : nz(dimen1[1])
    alpha1 = math.exp(w * (dimen - 1))
    oldalpha = alpha1 > 1 ? 1 : alpha1 < 0.01 ? 0.01 : alpha1
    oldN = (2 - oldalpha) / oldalpha
    N = (SC - FC) * (oldN - 1) / (SC - 1) + FC
    alpha_ = 2 / (N + 1)
    alpha = alpha_ < 2 / (SC + 1) ? 2 / (SC + 1) : alpha_ > 1 ? 1 : alpha_
    out = 0.0
    out := (1 - alpha) * nz(out[1]) + alpha * src
    [out, out[1], false]

//Instantaneous Trendline
_instant(src, alpha) =>
    itrend = 0.0
    itrend := bar_index < 7 ? (src + 2 * nz(src[1]) + nz(src[2])) / 4 : 
         (alpha - math.pow(alpha, 2) / 4) * src + 0.5 * math.pow(alpha, 2) * nz(src[1]) - (alpha - 0.75 * math.pow(alpha, 2)) * nz(src[2]) +  2 * (1 - alpha) * nz(itrend[1]) - math.pow(1 - alpha, 2) * nz(itrend[2])
    trigger = 2 * itrend - nz(itrend[2])
    [trigger, itrend, false]

//Integral of Linear Regression Slope - ILRS
_ilrs(src, len)=> // Integral of linear regression slope
    sum = len * (len -1) * 0.5
    sum2 = (len - 1) * len * (2 * len - 1) / 6.0
    sum1 = 0., sumy = 0., slope = 0.
    for i = 0 to len - 1 
        sum1 += i * nz(src[i])
        sumy += nz(src[i])
    num1 = len * sum1 - sum * sumy
    num2 = sum * sum - len * sum2
    slope := num2 != 0. ? num1/num2 : 0.
    ilrs = slope + ta.sma(src, len)
    [ilrs, ilrs[1], false]

//Laguerre Filter
_laguerre(src, alpha)=>
    L0 = 0.0, L1 = 0.0, L2 = 0.0, L3 = 0.0
    L0 := alpha * src + (1 - alpha) * nz(L0[1])
    L1 := -(1 - alpha) * L0 + nz(L0[1]) + (1 - alpha) * nz(L1[1])
    L2 := -(1 - alpha) * L1 + nz(L1[1]) + (1 - alpha) * nz(L2[1])
    L3 := -(1 - alpha) * L2 + nz(L2[1]) + (1 - alpha) * nz(L3[1])
    lf = (L0 + 2 * L1 + 2 * L2 + L3) / 6
    [lf, lf[1], false]

//Leader Exponential Moving Average
_leader(src, len)=>
    alpha = 2.0/(len + 1.0)
    ldr = 0.,ldr2 = 0.
    ldr := nz(ldr[1]) + alpha * (src - nz(ldr[1]))
    ldr2 := nz(ldr2[1]) + alpha * (src - ldr - nz(ldr2[1]))
    out = ldr + ldr2
    [out, out[1], false]
    
//Linear Regression Value - LSMA (Least Squares Moving Average)
_lsma(src, len, offset)=>
    out = ta.linreg(src, len, offset)
    [out, out[1], false]


//Linear Weighted Moving Average - LWMA
_lwma(src, len)=>
    out = ta.wma(src, len)
    [out, out[1], false]

//McGinley Dynamic
_mcginley(src, len)=>
    mg = 0.0
    t = ta.ema(src, len)
    mg := na(mg[1]) ? t : mg[1] + (src - mg[1]) / (len * math.pow(src / mg[1], 4))
    [mg, mg[1], false]

//McNicholl EMA
_mcNicholl(src, len)=>
    alpha = 2 / (len + 1)
    ema1 = ta.ema(src, len)
    ema2 = ta.ema(ema1, len)
    out = ((2 - alpha) * ema1 - ema2) / (1 - alpha)
    [out, out[1], false]

//Non lag moving average
_nonlagma(src, len)=>
    cycle = 4.0
    coeff = 3.0 * math.pi
    phase = len - 1.0
    _len = int(len * cycle + phase)
    weight = 0., alfa = 0., out = 0.
    alphas = array.new_float(_len, 0)
    for k = 0 to _len - 1
        t = 0.
        t := k <= phase - 1 ?  1.0 * k / (phase - 1) : 1.0 + (k - phase + 1) * (2.0 * cycle - 1.0) / (cycle * len -1.0)
        beta = math.cos(math.pi * t)
        g = 1.0/(coeff * t + 1)
        g := t <= 0.5  ? 1 : g
        array.set(alphas, k, g * beta)
        weight += array.get(alphas, k)
    if (weight > 0)  
        sum = 0.
        for k = 0 to _len - 1
            sum += array.get(alphas, k) * nz(src[k])
        out := (sum / weight)
    [out, out[1], false]

//Parabolic Weighted Moving Average
_pwma(src, len, pwr)=>
    sum = 0.0, weightSum = 0.0
    for i = 0 to len - 1 by 1
        weight = math.pow(len - i, pwr)
        sum += nz(src[i]) * weight
        weightSum += weight
        weightSum
    out = sum / weightSum
    [out, out[1], false]

//Recursive Moving Trendline
_rmta(src, len)=>
    alpha = 2 / (len + 1)
    b = 0.0
    b := (1 - alpha) * nz(b[1], src) + src
    rmta = 0.0
    rmta := (1 - alpha) * nz(rmta[1], src) + alpha * (src + b - nz(b[1]))
    [rmta, rmta[1], false]
    
//Simple decycler - SDEC
_decycler(src, len)=>
    alphaArg = 2 * math.pi / (len * math.sqrt(2))
    alpha = 0.0
    alpha := math.cos(alphaArg) != 0 ? (math.cos(alphaArg) + math.sin(alphaArg) - 1) / math.cos(alphaArg) : nz(alpha[1])
    hp = 0.0
    hp := math.pow(1 - alpha / 2, 2) * (src - 2 * nz(src[1]) + nz(src[2])) + 2 * (1 - alpha) * nz(hp[1]) - math.pow(1 - alpha, 2) * nz(hp[2])
    decycler = src - hp
    [decycler, decycler[1], false]

//Simple Moving Average
_sma(src, len)=>
    out = ta.sma(src, len)
    [out, out[1], false]

//Sine Weighted Moving Average
_swma(src, len)=>
    sum = 0.0, weightSum = 0.0
    for i = 0 to len - 1 by 1
        weight = math.sin((i + 1) * math.pi / (len + 1))
        sum += nz(src[i]) * weight
        weightSum += weight
        weightSum
    swma = sum / weightSum
    [swma, swma[1], false]

//Smoothed linear weighted moving average
_slwma(src, len)=>
    out = ta.wma(ta.wma(src, len), math.floor(math.sqrt(len)))
    [out, out[1], false]

//Smoothed Moving Average - SMMA
_smma(src, len)=>
    out = ta.rma(src, len)
    [out, out[1], false]

//Ehlers super smoother
_super(src, len) =>
    f = (1.414 * math.pi)/len
    a = math.exp(-f)
    c2 = 2 * a * math.cos(f)
    c3 = -a*a
    c1 = 1-c2-c3
    smooth = 0.0
    smooth := c1*(src+src[1])*0.5+c2*nz(smooth[1])+c3*nz(smooth[2])
    [smooth, smooth[1], false]

//Smoother filter
_smoother(src, len)=>
    wrk = src, wrk2 = src, wrk4 = src
    wrk0 = 0., wrk1 = 0., wrk3 = 0.
    alpha = 0.45 * (len - 1.0) / (0.45 * (len - 1.0) + 2.0)
    wrk0 := src + alpha * (nz(wrk[1]) - src)
    wrk1 := (src - wrk) * (1 - alpha) + alpha * nz(wrk1[1])
    wrk2 := wrk0 + wrk1
    wrk3 := (wrk2 - nz(wrk4[1])) * math.pow(1.0 - alpha, 2) + math.pow(alpha, 2) * nz(wrk3[1])
    wrk4 := wrk3 + nz(wrk4[1])
    [wrk4, wrk4[1], false]

//Triangular moving average - TMA
_tma(src, len)=>
    filt = 0.0, coef = 0.0, l2 = len / 2.0
    for i = 1 to len
        c = i < l2 ? i : i > l2 ? len + 1 - i : l2
        filt := filt + (c * nz(src[i - 1]))
        coef := coef + c
    filt := coef != 0 ? filt / coef : 0
    [filt, filt[1], false]
    
//Tripple exponential moving average - TEMA
_tema(src, len)=>
    ema1 = ta.ema(src, len)
    ema2 = ta.ema(ema1, len)
    ema3 = ta.ema(ema2, len)
    out = 3 * (ema1 - ema2) + ema3
    [out, out[1], false]

//Volume weighted ema - VEMA
_vwema(src, len) =>
    p = ta.ema(volume * src, len)
    v = ta.ema(volume, len)
    vwema = p / v
    [vwema, vwema[1], false]

//Volume weighted moving average - VWMA
_vwma(src, len)=>
    ma = ta.vwma(src, len)
    [ma, ma[1], false]

//Zero-lag dema
_zlagdema(src, len)=>
    _zdema1 = ta.ema(src, len) 
    _zdema2 = ta.ema(_zdema1, len)
    dema1 = 2 * _zdema1 - _zdema2
    _zdema12 = ta.ema(dema1, len)
    _zdema22 = ta.ema(_zdema12, len)
    demaout = 2 * _zdema12 - _zdema22
    [demaout, demaout[1], false]

//Zero lag moving average
_zlagma(src, len)=>
    alpha = 2.0/(1.0 + len)
    per = math.ceil((len - 1.0) / 2.0 )
    zlagma = 0.
    zlagma := nz(zlagma[1]) + alpha * (2.0 * src - nz(zlagma[per]) - nz(zlagma[1]))
    [zlagma, zlagma[1], false]

//Zero-lag tema
_zlagtema(src, len)=>
    ema1 = ta.ema(src, len)
    ema2 = ta.ema(ema1, len)
    ema3 = ta.ema(ema2, len)
    out = 3 * (ema1 - ema2) + ema3
    ema1a = ta.ema(out, len)
    ema2a = ta.ema(ema1a, len)
    ema3a = ta.ema(ema2a, len)
    outf = 3 * (ema1a - ema2a) + ema3a
    [outf, outf[1], false]

//Three pole Ehlers Butterworth
_3polebuttfilt(src, len)=>
    a1 = 0., b1 = 0., c1 = 0.
    coef1 = 0., coef2 = 0., coef3 = 0., coef4 = 0.
    bttr = 0., trig = 0.
    a1 := math.exp(-math.pi / len)
    b1 := 2 * a1 * math.cos(1.738 * math.pi / len)
    c1 := a1 * a1
    coef2 := b1 + c1
    coef3 := -(c1 + b1 * c1)
    coef4 := c1 * c1
    coef1 := (1 - b1 + c1) * (1 - c1) / 8
    bttr := coef1 * (src + 3 * nz(src[1]) + 3 * nz(src[2]) + nz(src[3])) + coef2 * nz(bttr[1]) + coef3 * nz(bttr[2]) + coef4 * nz(bttr[3])
    bttr := bar_index < 4 ? src : bttr
    trig := nz(bttr[1])
    [bttr, trig, true]

//Three pole Ehlers smoother
_3polesss(src, len)=>
    a1 = 0., b1 = 0., c1 = 0.
    coef1 = 0., coef2 = 0., coef3 = 0., coef4 = 0.
    filt = 0., trig = 0.
    a1 := math.exp(-math.pi / len)
    b1 := 2 * a1 * math.cos(1.738 * math.pi / len)
    c1 := a1 * a1
    coef2 := b1 + c1
    coef3 := -(c1 + b1 * c1)
    coef4 := c1 * c1
    coef1 := 1 - coef2 - coef3 - coef4
    filt := coef1 * src + coef2 * nz(filt[1]) + coef3 * nz(filt[2]) + coef4 * nz(filt[3])
    filt := bar_index < 4 ? src : filt
    trig := nz(filt[1])
    [filt, trig, true]

//Two pole Ehlers Butterworth
_2polebutter(src, len)=>
    a1 = 0., b1 = 0.
    coef1 = 0., coef2 = 0., coef3 = 0.
    bttr = 0., trig = 0.
    a1 := math.exp(-1.414 * math.pi / len)
    b1 := 2 * a1 * math.cos(1.414 * math.pi / len)
    coef2 := b1
    coef3 := -a1 * a1
    coef1 := (1 - b1 + a1 * a1) / 4
    bttr := coef1 * (src + 2 * nz(src[1]) + nz(src[2])) + coef2 * nz(bttr[1]) + coef3 * nz(bttr[2])
    bttr := bar_index < 3 ? src : bttr
    trig := nz(bttr[1])
    [bttr, trig, true]

//Two pole Ehlers smoother
_2poless(src, len)=>
    a1 = 0., b1 = 0.
    coef1 = 0., coef2 = 0., coef3 = 0.
    filt = 0., trig = 0.
    a1 := math.exp(-1.414 * math.pi / len)
    b1 := 2 * a1 * math.cos(1.414 * math.pi / len)
    coef2 := b1
    coef3 := -a1 * a1
    coef1 := 1 - coef2 - coef3
    filt := coef1 * src + coef2 * nz(filt[1]) + coef3 * nz(filt[2])
    filt := bar_index < 3 ? src : filt
    trig := nz(filt[1])
    [filt, trig, true]


srcoption = input.string("Close", "SMA Source Options", group= "Basic 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)"])

smthtype = input.string("AMA", "Filter Options", options = ["AMA", "T3", "Kaufman"], group=  "Basic Settings")

len = input.int(55, "Period", minval = 1, group = "Basic Settings")

type = input.string("Simple Moving Average - SMA", "Moving Average Type", options = ["ADXvma - Average Directional Volatility Moving Average",  "Ahrens Moving Average"
     , "Alexander Moving Average - ALXMA", "Double Exponential Moving Average - DEMA", "Double Smoothed Exponential Moving Average - DSEMA"
     , "Exponential Moving Average - EMA", "Fast Exponential Moving Average - FEMA", "Fractal Adaptive Moving Average - FRAMA"
     , "Hull Moving Average - HMA", "IE/2 - Early T3 by Tim Tilson", "Integral of Linear Regression Slope - ILRS"
     , "Instantaneous Trendline", "Laguerre Filter", "Leader Exponential Moving Average", "Linear Regression Value - LSMA (Least Squares Moving Average)"
     , "Linear Weighted Moving Average - LWMA", "McGinley Dynamic", "McNicholl EMA", "Non-Lag Moving Average", "Parabolic Weighted Moving Average"
     , "Recursive Moving Trendline", "Simple Moving Average - SMA", "Sine Weighted Moving Average", "Smoothed Moving Average - SMMA"
     , "Smoother", "Super Smoother", "Three-pole Ehlers Butterworth", "Three-pole Ehlers Smoother"
     , "Triangular Moving Average - TMA", "Triple Exponential Moving Average - TEMA", "Two-pole Ehlers Butterworth", "Two-pole Ehlers smoother"
     , "Volume Weighted EMA - VEMA", "Zero-Lag DEMA - Zero Lag Double Exponential Moving Average", "Zero-Lag Moving Average"
     , "Zero Lag TEMA - Zero Lag Triple Exponential Moving Average"],
     group = "Basic Settings")
  
frama_FC = input.int(defval=1, title="* Fractal Adjusted (FRAMA) Only - FC", group = "Moving Average Inputs")
frama_SC = input.int(defval=200, title="* Fractal Adjusted (FRAMA) Only - SC", group = "Moving Average Inputs")
instantaneous_alpha = input.float(defval=0.07, minval = 0, title="* Instantaneous Trendline (INSTANT) Only - Alpha", group = "Moving Average Inputs")
_laguerre_alpha = input.float(title='* Laguerre Filter (LF) Only - Alpha', minval=0, maxval=1, step=0.1, defval=0.7, group = "Moving Average Inputs")
lsma_offset = input.int(defval=0, title="* Least Squares Moving Average (LSMA) Only - Offset", group = "Moving Average Inputs")
_pwma_pwr = input.int(2, '* Parabolic Weighted Moving Average (PWMA) Only - Power', minval=0, group = "Moving Average Inputs")
kama_fastend=input.float(0.666, title="* Kaufman's Adaptive MA (KAMA) Only - Fast End", group = "Moving Average Inputs")
kama_slowend=input.float(0.0645, title="* Kaufman's Adaptive MA (KAMA) Only - Slow End", group = "Moving Average Inputs")
fastLength = input.int(2, title="* Adaptive Moving Average (AMA) Only - Fast", group = "Moving Average Inputs")
slowLength = input.int(30, title="* Adaptive Moving Average (AMA) Only - Slow", group = "Moving Average Inputs")
colorbars = input.bool(false, "Color bars?", group = "UI Options")
showsignal = input.bool(false, "Show Signal Line??", group = "UI Options")

rclose = close 
ropen = open
rhigh = high
rlow = low
rmedian =  hl2
rtypical =  hlc3
rweighted =  hlcc4
raverage =  ohlc4
ravemedbody = (open + close)/2
rtrendb = _trendreg(ropen, rhigh, rlow, rclose)
rtrendbext = _trendext(ropen, rhigh, rlow, rclose)

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)
haavemedbody = (haopen + haclose)/2
hatrendb = _trendreg(haopen, hahigh, halow, haclose)
hatrendbext = _trendext(haopen, hahigh, halow, haclose)

habingest = (ropen + rclose)/2 + (((rclose - ropen)/(rhigh - rlow)) * math.abs((rclose - ropen)/2))
habclose = smthtype == "AMA" ? _ama(habingest, 2, fastLength, slowLength) : smthtype == "T3" ? _t3(habingest, 3) : _kama(habingest, 2, kama_fastend, kama_slowend)
habopen = 0.
habopen := (nz(habopen[1]) + nz(habclose[1]))/2
habhigh = math.max(rhigh, habopen, habclose)
hablow = math.min(rlow, habopen, habclose)
habmedian = (habhigh + hablow)/2
habtypical = (habhigh + hablow + habclose)/3
habweighted = (habhigh + hablow + habclose + habclose)/4
habaverage = (habopen + habhigh + hablow + habclose)/4
habavemedbody = (habopen + habclose)/2
habtrendb = _trendreg(habopen, habhigh, hablow, habclose)
habtrendbext = _trendext(habopen, habhigh, hablow, habclose)


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

variant(type, src, len) =>
    sig = 0.0
    trig = 0.0
    special = false
    if type == "ADXvma - Average Directional Volatility Moving Average"
        [t, s, b] = _adxvma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Ahrens Moving Average"
        [t, s, b] = _ahrma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Alexander Moving Average - ALXMA"
        [t, s, b] = _alxma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Double Exponential Moving Average - DEMA"
        [t, s, b] = _dema(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Double Smoothed Exponential Moving Average - DSEMA"
        [t, s, b] = _dsema(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Exponential Moving Average - EMA"
        [t, s, b] = _ema(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Fast Exponential Moving Average - FEMA"
        [t, s, b] = _fema(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Fractal Adaptive Moving Average - FRAMA"
        [t, s, b] = _frama(src, len, frama_FC, frama_SC)
        sig := s
        trig := t
        special := b
    else if type == "Hull Moving Average - HMA"
        [t, s, b] = _hma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "IE/2 - Early T3 by Tim Tilson"
        [t, s, b] = _ie2(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Integral of Linear Regression Slope - ILRS"
        [t, s, b] = _ilrs(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Instantaneous Trendline"
        [t, s, b] = _instant(src, instantaneous_alpha)
        sig := s
        trig := t
        special := b
    else if type == "Laguerre Filter"
        [t, s, b] = _laguerre(src, _laguerre_alpha)
        sig := s
        trig := t
        special := b
    else if type == "Leader Exponential Moving Average"
        [t, s, b] = _leader(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Linear Regression Value - LSMA (Least Squares Moving Average)"
        [t, s, b] = _lsma(src, len, lsma_offset)
        sig := s
        trig := t
        special := b
    else if type == "Linear Weighted Moving Average - LWMA"
        [t, s, b] = _lwma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "McGinley Dynamic"
        [t, s, b] = _mcginley(src, len)
        sig := s
        trig := t
        special := b
    else if type == "McNicholl EMA"
        [t, s, b] = _mcNicholl(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Non-Lag Moving Average"
        [t, s, b] = _nonlagma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Parabolic Weighted Moving Average"
        [t, s, b] = _pwma(src, len, _pwma_pwr)
        sig := s
        trig := t
        special := b
    else if type == "Recursive Moving Trendline"
        [t, s, b] = _rmta(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Simple Moving Average - SMA"
        [t, s, b] = _sma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Sine Weighted Moving Average"
        [t, s, b] = _swma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Smoothed Moving Average - SMMA"
        [t, s, b] = _smma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Smoother"
        [t, s, b] = _smoother(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Super Smoother"
        [t, s, b] = _super(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Three-pole Ehlers Butterworth"
        [t, s, b] = _3polebuttfilt(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Three-pole Ehlers Smoother"
        [t, s, b] = _3polesss(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Triangular Moving Average - TMA"
        [t, s, b] = _tma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Triple Exponential Moving Average - TEMA"
        [t, s, b] = _tema(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Two-pole Ehlers Butterworth"
        [t, s, b] = _2polebutter(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Two-pole Ehlers smoother"
        [t, s, b] = _2poless(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Volume Weighted EMA - VEMA"
        [t, s, b] = _vwema(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Zero-Lag DEMA - Zero Lag Double Exponential Moving Average"
        [t, s, b] = _zlagdema(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Zero-Lag Moving Average"
        [t, s, b] = _zlagma(src, len)
        sig := s
        trig := t
        special := b
    else if type == "Zero Lag TEMA - Zero Lag Triple Exponential Moving Average"
        [t, s, b] = _zlagtema(src, len)
        sig := s
        trig := t
        special := b
    [trig, sig, special]

[trig, sig, special] = variant(type, src, len)

plot(trig, "Moving Average", color = trig > sig ? greencolor : redcolor, linewidth = 3)
plot(showsignal ? sig : na, "Signal", color = color.white, linewidth = 1)
barcolor(colorbars ? trig > sig ? greencolor : redcolor : na)







































