Chebyshev type I and II Filter
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © peacefulLizard50262

//@version=5
indicator("Chebyshev type I and II", "CHBV", true)

// Custom cosh function
cosh(float x) =>
    (math.exp(x) + math.exp(-x)) / 2

// Custom acosh function
acosh(float x) =>
    x < 1 ? na : math.log(x + math.sqrt(x * x - 1))

// Custom sinh function
sinh(float x) =>
    (math.exp(x) - math.exp(-x)) / 2

// Custom asinh function
asinh(float x) =>
    math.log(x + math.sqrt(x * x + 1))

// Custom inverse tangent function
atan(float x) =>
    math.pi / 2 - math.atan(1 / x)

// Chebyshev Type I Moving Average
chebyshevI(float src, int len, float ripple) =>
    a = 0.
    b = 0.
    g = 0.
    chebyshev = 0.
    
    a := cosh(1 / len * acosh(1 / (1 - ripple)))
    b := sinh(1 / len * asinh(1 / ripple))
    g := (a - b) / (a + b)
    chebyshev := (1 - g) * src + g * nz(chebyshev[1])
    chebyshev

// Chebyshev Type II Moving Average
chebyshevII(float src, int len, float ripple) =>
    a = 0.
    b = 0.
    g = 0.
    chebyshev = 0.
    
    a := cosh(1 / len * acosh(1 / ripple))
    b := sinh(1 / len * asinh(ripple))
    g := (a - b) / (a + b)
    chebyshev := (1 - g) * src + g * nz(chebyshev[1], src)
    chebyshev

// adjust the ripple value based on your requirement (between 0 and 1)

chebyshev(float src, int length, float ripple, bool style) =>
    not style ?
     chebyshevI(src, length, ripple) :
     chebyshevII(src, length, ripple)

source = input.source(close, "Source")
length = input.int(14, 'Length', 2, 5000)
ripple = input.float(0.05, "Ripple", 0.01, 1, 0.01)
style = input.bool(false, "Use type II")

cheb = chebyshev(source, length, ripple, style)

plot(cheb, "Chebyshev Type Moving Average", color.orange, 2)


