Mad_MATH
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © djmad

// included and modified code from HPotter
// included code from peacefulLizard50262
// Mathematics from Pafnuti Lwowitsch Tschebyschow (1821–1894)
// Mathematics from John F. Ehlers
// Mathematics from alexgrover (arma/a2rma)

//@version=5
// @description this is a mathematics library where i store useful kernels, filters and selectors
library("MAD_MATH")

// Ehlers Army Knife {

//SWISS ARMY KNIFE INDICATOR by John F. Ehlers
//exported to single functions, digged for hours to find most of them, still missing the fourier :-(

// @function Calculates the Ehlers Exponential Moving Average (Ehlers_EMA)
// @param _src The source series for calculation
// @param _length The length for the Ehlers EMA
// @returns The Ehlers EMA value
export Ehlers_EMA(float _src = close, simple int _length = 20) =>
    c0 = 1.0, b0 = 1.0, a1 = 0.0, alpha = 0.0
    pi = 2 * math.asin(1)
    cycle = 2 * math.pi / _length

    alpha   := (math.cos(cycle) + math.sin(cycle) - 1) / math.cos(cycle)
    b0      := alpha
    a1      := 1 - alpha

    _Input       = _src
    _Output      = 0.0
    _Output     := (c0 * (b0 * _Input)) + (a1 * nz(_Output[1]))


// @function Calculates the Ehlers Gaussian Filter
// @param _src The source series for calculation
// @param _length The length for the Ehlers Gaussian Filter
// @returns The Ehlers Gaussian Filter value
export Ehlers_Gaussian(float _src = close, simple int _length = 20) =>
    c0 = 1.0, b0 = 1.0, a1 = 0.0, a2 = 0.0, alpha = 0.0, beta = 0.0
    pi = 2 * math.asin(1)
    cycle = 2 * math.pi / _length
    
    beta    := 2.415 * (1 - math.cos(cycle))
    alpha   := -beta + math.sqrt((beta * beta) + (2 * beta))
    c0      := alpha * alpha
    a1      := 2 * (1 - alpha)
    a2      := -(1 - alpha) * (1 - alpha)
    
    _Input       = _src
    _Output      = 0.0
    _Output     := (c0 * (b0 * _Input)) + (a1 * nz(_Output[1])) + (a2 * nz(_Output[2]))


// @function Calculates the Ehlers Supersmoother
// @param _src The source series for calculation
// @param _length The length for the Ehlers Supersmoother
// @returns The Ehlers Supersmoother value
export Ehlers_Supersmoother(float _src = close, simple int _length = 20) =>
    float _Output = na
    a1    = math.exp(-math.sqrt(2) * math.pi / _length)
    b1    = 2 * a1 * math.cos(math.sqrt(2) * math.pi / _length)
    c3    = -math.pow(a1, 2)
    c2    = b1
    c1    = 1 - c2 - c3

    _Output := c1 * _src + c2 * nz(_Output[1], _src[1]) + c3 * nz(_Output[2], _src[2])


// @function Calculates the Ehlers Simple Moving Average (SMA) Fast
// @param _src The source series for calculation
// @param _length The length for the Ehlers SMA Fast
// @returns The Ehlers SMA Fast value
export Ehlers_SMA_fast(float _src = close, simple int _length = 20) =>
    c0 = 1.0, c1 = 0.0, b0 = 1.0, a1 = 0.0 

    c1      := 1 / _length
    b0      := 1 / _length
    a1      := 1

    _Input       = _src
    _Output      = 0.0
    _Output     := (c0 * ((b0 * _Input))) + (a1 * nz(_Output[1])) - (c1 * nz(_Input[_length]))


// @function Calculates the Ehlers Exponential Moving Average (EMA) Fast
// @param _src The source series for calculation
// @param _length The length for the Ehlers EMA Fast
// @returns The Ehlers EMA Fast value
export Ehlers_EMA_fast(float _src = close, simple int _length = 20) =>
    c0 = 1.0, b0 = 1.0, a1 = 0.0, alpha = 0.0

    alpha       := 2/(_length+1)
    b0          := alpha
    a1          := 1 - alpha
    
    _Input       = _src
    _Output      = 0.0
    _Output     := (c0 * (b0 * _Input)) + (a1 * nz(_Output[1]))


// @function Calculates the Ehlers Relative Strength Index (RSI) Fast
// @param _src The source series for calculation
// @param _length The length for the Ehlers RSI Fast
// @returns The Ehlers RSI Fast value
export Ehlers_RSI_fast(float _src = close, simple int _length = 20) =>
    c0 = 1.0, b0 = 1.0, a1 = 0.0, alpha = 0.0

    alpha   := 1 / _length
    b0      := alpha
    a1      := 1 - alpha
    
    _Input       = _src
    _Output      = 0.0
    _Output     := (c0 * (b0 * _Input)) + (a1 * nz(_Output[1]))


// @function Calculates the Ehlers BandPass Filter
// @param _src The source series for calculation
// @param _length The length for the Ehlers BandPass Filter
// @returns The Ehlers BandPass Filter value
export Ehlers_Band_Pass_Filter(float _src = close, simple int _length = 20) =>
    c0 = 1.0, b0 = 1.0, b2 = 0.0, a1 = 0.0, a2 = 0.0
    alpha = 0.0, beta = 0.0, gamma = 0.0, delta = 0.1  
    // delta default to 0.1. Acceptable delta -- 0.05<d<0.5

    pi          = 2 * math.asin(1)
    cycle       = 2 * math.pi / _length

    beta := math.cos(2*pi / _length)
    gamma := 1 / math.cos(4*pi*delta / _length)  // delta ^^
    alpha := gamma - math.sqrt(gamma*gamma - 1)
    c0 := (1 - alpha) / 2
    b2 := -1
    a1 := beta*(1 + alpha)
    a2 := -alpha

    _Input       = _src
    _Output      = 0.0
    _Output     := (c0 * ((b0 * _Input) + (b2 * nz(_Input[2])))) + (a1 * nz(_Output[1])) + (a2 * nz(_Output[2]))


// @function Calculates the Ehlers Butterworth Filter
// @param _src The source series for calculation
// @param _length The length for the Ehlers Butterworth Filter
// @returns The Ehlers Butterworth Filter value
export Ehlers_Butterworth(float _src = close, simple int _length = 20) =>
    c0 = 1.0, b0 = 1.0, b1 = 0.0, b2 = 0.0
    a1 = 0.0, a2 = 0.0, alpha = 0.0, beta = 0.0 

    pi          = 2 * math.asin(1)
    cycle       = 2 * math.pi / _length

    beta    := 2.415 * (1 - math.cos(cycle))
    alpha   := -beta + math.sqrt((beta * beta) + (2 * beta))
    c0      := alpha * alpha / 4
    b1      := 2
    b2      := 1
    a1      := 2 * (1 - alpha)
    a2      := -(1 - alpha) * (1 - alpha)

    _Input       = _src
    _Output      = 0.0
    _Output     := (c0 * ((b0 * _Input) + (b1 * nz(_Input[1])) + (b2 * nz(_Input[2])))) + (a1 * nz(_Output[1])) + (a2 * nz(_Output[2]))


// @function Calculates the Ehlers Two-Pole Gaussian Filter
// @param _src The source series for calculation
// @param _length The length for the Ehlers Two-Pole Gaussian Filter
// @returns The Ehlers Two-Pole Gaussian Filter value
export Ehlers_Two_Pole_Gaussian_Filter(float _src = close, simple int _length = 20) =>
    c0 = 1.0, b0 = 1.0, a1 = 0.0, a2 = 0.0
    alpha = 0.0, beta = 0.0 

    pi          = 2 * math.asin(1)
    cycle       = 2 * math.pi / _length

    beta    := 2.415 * (1 - math.cos(cycle))
    alpha   := -beta + math.sqrt((beta * beta) + (2 * beta))
    c0      := alpha * alpha
    a1      := 2 * (1 - alpha)
    a2      := -(1 - alpha) * (1 - alpha)

    _Input       = _src
    _Output      = 0.0
    _Output     := (c0 * ((b0 * _Input) )) + (a1 * nz(_Output[1])) + (a2 * nz(_Output[2]))


// @function Calculates the Ehlers Two-Pole Butterworth Filter
// @param _src The source series for calculation
// @param _length The length for the Ehlers Two-Pole Butterworth Filter
// @returns The Ehlers Two-Pole Butterworth Filter value
export Ehlers_Two_Pole_Butterworth_Filter(float _src = close, simple int _length = 20) =>
    c0 = 1.0,b0 = 1.0,b1 = 0.0,b2 = 0.0,a1 = 0.0,a2 = 0.0
    alpha = 0.0, beta = 0.0, gamma = 0.0 

    pi          = 2 * math.asin(1)
    cycle       = 2 * math.pi / _length

    beta    := 2.415 * (1 - math.cos(cycle))
    alpha   := -beta + math.sqrt((beta * beta) + (2 * beta))
    c0      := alpha * alpha / 4
    b1      := 2
    b2      := 1
    a1      := 2 * (1 - alpha)
    a2      := -(1 - alpha) * (1 - alpha)

    _Input       = _src
    _Output      = 0.0
    _Output     := (c0 * ((b0 * _Input) + (b1 * nz(_Input[1])) + (b2 * nz(_Input[2])))) + (a1 * nz(_Output[1])) + (a2 * nz(_Output[2]))


// @function Calculates the Ehlers Band Stop Filter
// @param _src The source series for calculation
// @param _length The length for the Ehlers Band Stop Filter
// @returns The Ehlers Band Stop Filter value
export Ehlers_Band_Stop_Filter(float _src = close, simple int _length = 20) =>
    c0 = 1.0, b0 = 1.0, b1 = 0.0, b2 = 0.0, 
    a1 = 0.0, a2 = 0.0, alpha = 0.0, beta = 0.0, gamma = 0.0, 
    delta = 0.1  // delta default to 0.1. Acceptable delta -- 0.05<d<0.5

    pi          = 2 * math.asin(1)
    cycle       = 2 * math.pi / _length

    beta    := math.cos(cycle)
    gamma   := 1 / math.cos(cycle*2*delta) // delta ^^
    alpha   := gamma - math.sqrt((gamma * gamma) - 1)
    c0      := (1 + alpha) / 2
    b1      := -2 * beta
    b2      := 1
    a1      := beta * (1 + alpha)
    a2      := -alpha
    _Input       = _src
    _Output      = 0.0
    _Output     := (c0 * ((b0 * _Input) + (b1 * nz(_Input[1])) + (b2 * nz(_Input[2])))) + (a1 * nz(_Output[1])) + (a2 * nz(_Output[2]))


// @function Calculates the Ehlers Smoother
// @param _src The source series for calculation
// @returns The Ehlers Smoother value
export Ehlers_Smoother(float _src = close) => 
    c0 = 0.25, b0 = 1.0, b1 = 2, b2 = 1

    _Input       = _src
    _Output      = 0.0
    _Output     := (c0 * ((b0 * _Input) + (b1 * nz(_Input[1])) + (b2 * nz(_Input[2]))))


// @function Calculates the Ehlers High Pass Filter
// @param _src The source series for calculation
// @param _length The length for the Ehlers High Pass Filter
// @returns The Ehlers High Pass Filter value
export Ehlers_High_Pass_Filter(float _src = close, simple int _length = 20) => 
    c0 = 1.0, c1 = 0.0, b0 = 1.0, b1 = 0.0, b2 = 0.0
    a1 = 0.0, a2 = 0.0, alpha = 0.0 
    
    pi          = 2 * math.asin(1)
    cycle       = 2 * math.pi / _length

    alpha := (math.cos(2*pi/_length) + math.sin(2*pi/_length) - 1) / math.cos(2*pi/_length)
    c0 := 1 - alpha / 2
    b1 := -1
    a1 := 1 - alpha

    _Input       = _src
    _Output      = 0.0
    _Output     := (c0 * ((b0 * _Input) + (b1 * nz(_Input[1])) )) + (a1 * nz(_Output[1]))


// @function Calculates the Ehlers Two-Pole High Pass Filter
// @param _src The source series for calculation
// @param _length The length for the Ehlers Two-Pole High Pass Filter
// @returns The Ehlers Two-Pole High Pass Filter value
export Ehlers_Two_Pole_High_Pass_Filter(float _src = close, simple int _length = 20) =>  
    c0 = 1.0, b0 = 1.0, b1 = 0.0, b2 = 0.0
    a1 = 0.0, a2 = 0.0, alpha = 0.0, beta = 0.0

    pi          = 2 * math.asin(1)
    cycle       = 2 * math.pi / _length

    beta := 2.415*(1 - math.cos(2*pi / _length))
    alpha := -beta + math.sqrt(beta*beta + 2*beta)
    c0 := (1 - alpha / 2)*(1 - alpha / 2)
    b1 := -2
    b2 := 1
    a1 := 2*(1 - alpha)
    a2 := -(1 - alpha)*(1 - alpha)

    _Input       = _src
    _Output      = 0.0
    _Output     := (c0 * ((b0 * _Input) + (b1 * nz(_Input[1])) + (b2 * nz(_Input[2])))) + (a1 * nz(_Output[1])) + (a2 * nz(_Output[2]))


//SWISS ARMY KNIFE INDICATOR by John F. Ehlers
//exported to single functions }

// Moving Averages {

// @function PR Calculates the percentage rank (PR) of a value within a range.
// @param _src The source value for which the percentage rank is calculated. It rePResents the value to be ranked within the range.
// @param _length The _length of the range over which the percentage rank is calculated. It determines the number of bars considered for the calculation.
// @returns The percentage rank (PR) of the source value within the range, adjusted by adding 50 to the result.
export PR(float _src = close, simple int _length = 20) =>
    float _max = na
    float _min = na
    float _PR = na
    _max := ta.highest(_src, _length)
    _min := ta.lowest(_src, _length)
    _PR := (100 * (_src - _max) / (_max - _min)) + 50
    _PR


// @function Calculates the SMMA (Smoothed Moving Average)
// @param _src The source series for calculation
// @param len The _length of the SMMA
// @returns The SMMA value
export SMMA(float _src = close, simple int _length = 20) =>
    SMMA = 0.0
    temp_sma = ta.sma(_src, _length)
    SMMA := na(SMMA[1]) ? temp_sma : (SMMA[1] * (_length - 1) + _src) / _length
    SMMA


// @function Calculates the Hull Moving Average (HULLMA)
// @param _src The source series for calculation
// @param _length The _length of the HULLMA
// @returns The HULLMA value
export HULLMA(float _src = close, simple int _length = 20) =>
    ta.wma(2 * ta.wma(_src, _length / 2) - ta.wma(_src, _length), math.round(math.sqrt(_length)))


// @function Calculates the Triple Moving Average (TMA)
// @param _src The source series for calculation
// @param _length The _length of the TMA
// @returns The TMA value
export TMA(float _src = close, simple int _length = 20) =>
    ta.sma(ta.sma(_src, _length), _length)


// @function Calculates the Double Exponential Moving Average (DEMA)
// @param _src The source series for calculation
// @param _length The _length of the DEMA
// @returns The DEMA value
export DEMA(float _src = close, simple int _length = 20) =>
    emaValue = ta.ema(_src, _length)
    2 * emaValue - ta.ema(emaValue, _length)

// @function Calculates the Triple Exponential Moving Average (TEMA)
// @param _src The source series for calculation
// @param _length The _length of the TEMA
// @returns The TEMA value
export TEMA(float _src = close, simple int _length = 20) =>
    ema1 = ta.ema(_src, _length)
    ema2 = ta.ema(ema1, _length)
    ema3 = ta.ema(ema2, _length)
    3 * ema1 - 3 * ema2 + ema3


// @function Calculates the Normalized Double Moving Average (N2MA)
// @param _src The source series for calculation
// @param _length The _length of the N2MA
// @returns The N2MA value
export W2MA(float _src = close, simple int _length = 20) =>
    2 * ta.wma(_src, math.round(_length / 2))

// @function Calculates the Normalized Moving Average (NMA)
// @param _src The source series for calculation
// @param _length The _length of the NMA
// @returns The NMA value
export wma(float _src = close, simple int _length = 20) =>
    ta.wma(_src, _length)


// @function Calculates the Normalized Moving Average (NMA)
// @param _open The open PRice series
// @param _close The close PRice series
// @param _length The _length for finding the highest and lowest values
// @returns The NMA value
export nma(float _open = open, float _close = close, simple int _length = 20) => 
    highestValue = ta.highest(math.max(_open, _close), _length)
    lowestValue = ta.lowest(math.min(_open, _close), _length)
    nmaValue = math.avg(highestValue, lowestValue)
    nmaValue

export lma(float _src = close, simple int _length = 20) =>
    norm = 0.0, sum = 0.0, alpha = 0.0, d1 = 0.0 

    for i = 0 to _length - 1
        alpha   := math.log(_length + 1 - i)
        norm    += alpha
        sum     += _src[i] * alpha
        d1      := sum/norm
    d1    

// Helperfunction for A2RMA - Adaptive Autonomous Recursive Moving Average
// @function ama (not Exported)
// @param _x Input value for the ama function
// @param _er Efficiency ratio to be used for calculation
// @returns a float value calculated based on the efficiency ratio and input value
ama(float _x, float _src, simple int _length) =>
    //Helper for A2RMA
    // The AMA is a type of moving average that adjusts its sensitivity based on market conditions, 
    //rePResented by the efficiency ratio. It is commonly used in technical analysis to smooth out PRice data and identify trends
    var float a = 0.0
    _er = math.abs(ta.change(_src, _length)) / math.sum(math.abs(ta.change(_src)), _length)
    a := _er * _x + (1 - _er) * nz(a[1], _x)
    a


// @function A2RMA - Adaptive Autonomous Recursive Moving Average

// @param _src Source float input used for the calculation
// @param _length Integer value rePResenting the length of the period
// @param _gamma Integer value rePResenting a factor for the calculation
// @returns the value of the adaptive moving average
export A2RMA(float _src = close, simple int _length = 14, simple float _gamma = 3) => 
    //Thanks alexgrover for the permission to add the a2rma here
    //https://www.tradingview.com/script/4bI1zjc6-Adaptive-Autonomous-Recursive-Moving-Average/
    ma = 0.0
    d = ta.cum(math.abs(_src - nz(ma[1], _src))) / bar_index * _gamma
    ma := ama(ama(_src > nz(ma[1], _src) + d ? _src + d : _src < nz(ma[1], _src) - d ? _src - d : nz(ma[1], _src),_src, _length),_src, _length)
    ma


// @function Calculates the Autonomous Recursive Moving Average (ARMA)
// @param _src The source series for calculation
// @param _length The length for the ARMA
// @param _gamma The parameter for ARMA calculation
// @param _zerolag Boolean flag indicating whether to use zero lag
// @returns An array containing the ARMA value and a flag indicating flatness
export ARMA(float _src = close, simple int _length = 14, simple float _gamma = 3, simple bool _zerolag = false) => 
    //Thanks alexgrover for the permission to add the arma here
    //https://www.tradingview.com/script/AnmTY0Q3-Autonomous-Recursive-Moving-Average/
    ma = 0.0
    mad = 0.0
    change_1 = ta.change(_src, _length / 2)
    _src_ = _zerolag ? _src + change_1 : _src
    ma := nz(mad[1], _src_)
    d = ta.cum(math.abs(_src_[_length] - ma)) / bar_index * _gamma
    mad := ta.sma(
     ta.sma(
      _src_ > nz(mad[1], _src_) + d ? _src_ + d : 
      _src_ < nz(mad[1], _src_) - d ? _src_ - d : 
      nz(mad[1], _src_),
      _length
      ), 
     _length
     )
    mad


// Trigonometrics for Chebyshev
// Pafnuti Lwowitsch Tschebyschow (1821–1894)
// Thanks peacefulLizard50262 for the find and translation
cosh(float x) =>
    (math.exp(x) + math.exp(-x)) / 2
acosh(float x) =>
    x < 1 ? na : math.log(x + math.sqrt(x * x - 1))
sinh(float x) =>
    (math.exp(x) - math.exp(-x)) / 2
asinh(float x) =>
    math.log(x + math.sqrt(x * x + 1))
atan(float x) =>
    math.pi / 2 - math.atan(1 / x)


// @function Calculates the Chebyshev Type I Filter
// @param src The source series for calculation
// @param len The length of the filter
// @param ripple The ripple factor for the filter
// @returns The output of the Chebyshev Type I Filter
// math from Pafnuti Lwowitsch Tschebyschow (1821–1894)
// Thanks peacefulLizard50262 for the find and translation
export ChebyshevI(float _src = close, int _length = 20, float _ripple = 0.05) =>
    a = 0.
    b = 0.
    g = 0.
    chebyshev = 0.
    
    a := cosh(1 / _length * acosh(1 / (1 - _ripple)))
    b := sinh(1 / _length * asinh(1 / _ripple))
    g := (a - b) / (a + b)
    chebyshev := (1 - g) * _src + g * nz(chebyshev[1])
    chebyshev


// @function Calculates the Chebyshev Type II Filter
// @param src The source series for calculation
// @param len The length of the filter
// @param ripple The ripple factor for the filter
// @returns The output of the Chebyshev Type II Filter
// math from Pafnuti Lwowitsch Tschebyschow (1821–1894)
// Thanks peacefulLizard50262 for the find
export ChebyshevII(float _src = close, int _length = 20, float _ripple = 0.05) =>
    a = 0.
    b = 0.
    g = 0.
    chebyshev = 0.
    
    a := cosh(1 / _length * acosh(1 / _ripple))
    b := sinh(1 / _length * asinh(_ripple))
    g := (a - b) / (a + b)
    chebyshev := (1 - g) * _src + g * nz(chebyshev[1], _src)
    chebyshev
//}

// Others {

// @function Calculates the WaveTrend indicator
// @param _src The source series for calculation
// @param _n1 The period for the first EMA calculation
// @param _n2 The period for the second EMA calculation
// @returns The WaveTrend value
export wavetrend(float _src = close, simple int _n1 = 10, simple int _n2 = 21) =>
    esa = ta.ema(_src, _n1)
    d = ta.ema(math.abs(_src - esa), _n1)
    ci = (_src - esa) / (0.015 * d)
    wt = ta.ema(ci, _n2)
    wt
// }

// Selectors {

// @function Calculates various types of moving averages
// @param _type The type of indicator to calculate
// @param _src The source series for calculation
// @param _length The length for the moving average or indicator
// @returns The calculated moving average or indicator value
export f_getma(simple string _type = "OFF", float _src = close, simple int _length = 20, simple float _gamma = 3, simple float _ripple = 0.05, simple bool _zerolag = false) =>
    float ma = switch _type
        "OFF" =>                                    _src
        "ARMA" =>                                   ARMA(_src, _length, _gamma, _zerolag)
        "A2RMA" =>                                  A2RMA(_src, _length, _gamma)
        "ChebyshevI" =>                             ChebyshevI(_src, _length, _ripple)
        "ChebyshevII" =>                            ChebyshevII(_src, _length, _ripple)
        "DEMA" =>                                   DEMA(_src, _length)
        "EMA" =>                                    Ehlers_EMA_fast(_src, _length)
        "Ehlers Band Stop Filter" =>                Ehlers_Band_Stop_Filter(_src, _length)
        "Ehlers Butterworth" =>                     Ehlers_Butterworth(_src, _length)
        "Ehlers EMA" =>                             Ehlers_EMA(_src, _length)
        "Ehlers Gaussian" =>                        Ehlers_Gaussian(_src, _length)
        "Ehlers Smoother" =>                        Ehlers_Smoother(_src)
        "Ehlers Supersmoother" =>                   Ehlers_Supersmoother(_src, _length)
        "Ehlers Two Pole Butterworth Filter" =>     Ehlers_Two_Pole_Butterworth_Filter(_src, _length)
        "Ehlers Two Pole Gaussian Filter" =>        Ehlers_Two_Pole_Gaussian_Filter(_src, _length)
        "Ehlers Relative Strength Index" =>         Ehlers_RSI_fast(_src, _length)
        "HMA" =>                                    ta.hma(_src, _length)
        "LMA" =>                                    lma(_src, _length)
        "RMA" =>                                    ta.rma(_src, _length)
        "SMA" =>                                    Ehlers_SMA_fast(_src, _length)
        "SMMA" =>                                   SMMA(_src, _length)
        "TEMA" =>                                   TEMA(_src, _length)
        "TMA" =>                                    TMA(_src, _length)
        "VWMA" =>                                   ta.vwma(_src,_length)
        "WMA" =>                                    ta.wma(_src, _length)
        "W2MA" =>                                   W2MA(_src, _length)
        =>                                          _src


// @function Calculates various types of Deviations and other indicators
// @param _type The type of indicator to calculate
// @param _src The source series for calculation
// @param _length The length for the moving average or indicator
// @returns The calculated moving average or indicator value
export f_getoszillator(simple string _type = "OFF", float _src = close, simple int _length = 20) =>
    float oszii = switch _type
        "OFF" =>                                    _src
        "Average True Range" =>                     ta.atr(_length)
        "Ehlers Band Pass Filter" =>                Ehlers_Band_Pass_Filter(_src, _length)
        "Ehlers High Pass Filter" =>                Ehlers_High_Pass_Filter(_src, _length)
        "Ehlers Two Pole High Pass Filter" =>       Ehlers_Two_Pole_High_Pass_Filter(_src, _length)
        "Percent Range" =>                          PR(_src, _length)
        "Rate of Change" =>                         ta.roc(_src, _length)
        "Standard Deviation" =>                     ta.stdev(_src, _length)
        "True Range" =>                             ta.tr(false)
        =>                                          _src


// @function Calculates various types of Deviations and other indicators
// @param _type The type of indicator to calculate
// @param _src The source series for calculation
// @param _length The length for the moving average or indicator
// @returns The calculated moving average or indicator value
export f_getall(simple string _type = "OFF", float _src = close, simple int _length = 20, simple float _gamma = 3, simple float _ripple = 0.05, simple bool _zerolag = false) =>
    float oszii = switch _type
        "OFF" =>                                    _src
        "ARMA" =>                                   ARMA(_src, _length, _gamma, _zerolag)
        "A2RMA" =>                                  A2RMA(_src, _length, _gamma)
        "Average True Range" =>                     ta.atr(_length)
        "ChebyshevI" =>                             ChebyshevI(_src, _length, _ripple)
        "ChebyshevII" =>                            ChebyshevII(_src, _length, _ripple)
        "DEMA" =>                                   DEMA(_src, _length)
        "EMA" =>                                    Ehlers_EMA_fast(_src, _length)
        "Ehlers Band Pass Filter" =>                Ehlers_Band_Pass_Filter(_src, _length)
        "Ehlers Band Stop Filter" =>                Ehlers_Band_Stop_Filter(_src, _length)
        "Ehlers Butterworth" =>                     Ehlers_Butterworth(_src, _length)
        "Ehlers EMA" =>                             Ehlers_EMA(_src, _length)
        "Ehlers Gaussian" =>                        Ehlers_Gaussian(_src, _length)
        "Ehlers High Pass Filter" =>                Ehlers_High_Pass_Filter(_src, _length)
        "Ehlers Relative Strength Index"  =>        Ehlers_RSI_fast(_src, _length)
        "Ehlers Smoother" =>                        Ehlers_Smoother(_src)
        "Ehlers Supersmoother" =>                   Ehlers_Supersmoother(_src, _length)
        "Ehlers Two Pole Butterworth Filter" =>     Ehlers_Two_Pole_Butterworth_Filter(_src, _length)
        "Ehlers Two Pole Gaussian Filter" =>        Ehlers_Two_Pole_Gaussian_Filter(_src, _length)
        "Ehlers Two Pole High Pass Filter" =>       Ehlers_Two_Pole_High_Pass_Filter(_src, _length)
        "HMA" =>                                    ta.hma(_src, _length)
        "LMA" =>                                    lma(_src, _length)
        "Percentage rank" =>                        PR(_src, _length)
        "Rate of Change" =>                         ta.roc(_src, _length)
        "RMA" =>                                    ta.rma(_src, _length)
        "SMA" =>                                    Ehlers_SMA_fast(_src, _length)
        "SMMA" =>                                   SMMA(_src, _length)
        "Standard Deviation" =>                     ta.stdev(_src, _length)
        "TEMA" =>                                   TEMA(_src, _length)
        "TMA" =>                                    TMA(_src, _length)
        "True Range" =>                             ta.tr(false)
        "VWMA" =>                                   ta.vwma(_src,_length)
        "WMA" =>                                    ta.wma(_src, _length)
        "W2MA" =>                                   W2MA(_src, _length)
        =>                                          _src

    //}



// ALL THE NAMES:
//input.string("OFF", options=["OFF","ARMA","A2RMA","Average True Range","ChebyshevI","ChebyshevII","DEMA","EMA","Ehlers Band Pass Filter","Ehlers Band Stop Filter","Ehlers Butterworth","Ehlers EMA","Ehlers Gaussian","Ehlers High Pass Filter","Ehlers Smoother","Ehlers Supersmoother","Ehlers Two Pole Butterworth Filter","Ehlers Two Pole Gaussian Filter","Ehlers Two Pole High Pass Filter","Ehlers Relative Strength Index","HMA","LMA","Percentage rank","Rate of Change","RMA","SMA","SMMA","Standard Deviation","TEMA","TMA","True Range","VWMA","WMA","W2MA",])