Trend Angle
// 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("Trend Angle")

length = input.int(8, "Length", 1)
scale  = input.int(2, "Scale", 1)
smooth = input.float(2, "Smooting", 1)
factor = input.float(1, "Smoothing Factor", 0.125, 100, 0.125)


ema(source)=>
    var float ema = 0.0
    var int count = 0
    count := nz(count[1]) + 1
    ema := (1.0 - 2.0 / (count + 1.0)) * nz(ema[1]) + 2.0 / (count + 1.0) * source
    ema

atan2(y, x) =>
    var float angle = 0.0
    if x > 0
        angle := math.atan(y / x)
    else
        if x < 0 and y >= 0
            angle := math.atan(y / x) + math.pi
        else
            if x < 0 and y < 0
                angle := math.atan(y / x) - math.pi
            else
                if x == 0 and y > 0
                    angle := math.pi / 2
                else
                    if x == 0 and y < 0
                        angle := -math.pi / 2
    angle

degrees(float source) =>
    source * 180 / math.pi

// Epanechnikov kernel function
epanechnikov_kernel(_src, _size, _h, _r) =>
    _currentWeight = 0.0
    _cumulativeWeight = 0.0
    for i = 0 to _size
        y = _src[i]
        u = math.pow(i, 2) / (math.pow(_h, 2) * _r)
        w = (u >= 1) ? 0 : (3. / 4) * (1 - math.pow(u, 2))
        _currentWeight := _currentWeight + y * w
        _cumulativeWeight := _cumulativeWeight + w
    _currentWeight / _cumulativeWeight

atr = ema(ta.tr)
slope = (close - close[length]) / (atr/(length/scale) * length)
angle_rad = atan2(slope, 1)
degrees = epanechnikov_kernel(degrees(angle_rad), length, smooth, factor)

plot(degrees, "Trend Angle", color.orange)
hline(0)
hline(90, linestyle = hline.style_solid)
hline(-90, linestyle = hline.style_solid)