ATR Adaptive EMA (AEMA)
// 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("AEMA", overlay = true)
import lastguru/DominantCycle/2
ema(float source = close, float length = 9)=>
    alpha = 2 / (length + 1)
    var float smoothed = na
    smoothed := alpha * source + (1 - alpha) * nz(smoothed[1])

average_true_range(source, length)=>
    true_range = high - low
    _range = math.abs(open - close)
    a_range = (true_range * 2 + _range) / 3
    average_true_range = ema(a_range, length)

max(source, outlier_level, dev_lookback)=>
    var float max = na
    src = array.new<float>()
    stdev = math.abs((source - ta.ema(source, dev_lookback))/ta.stdev(source, dev_lookback))
    array.push(src, stdev < outlier_level ? source : -1.7976931348623157e+308)
    max := math.max(nz(max[1]), array.get(src, 0))

min(source) =>
    var float min = na
    src = array.new<float>()
    array.push(src, source)
    min := math.min(nz(min[1]), array.get(src, 0))

min(source, outlier_level, dev_lookback) =>
    var float min = na
    src = array.new<float>()
    stdev = math.abs((source - ta.ema(source, dev_lookback))/ta.stdev(source, dev_lookback))
    array.push(src, stdev < outlier_level ? source : 1.7976931348623157e+308)
    min := math.min(nz(min[1]), array.get(src, 0))

min_max(src, min_length, outlier_level, dev_lookback, max_length) =>
    out = min_length + (max_length - (src - min(src, outlier_level, dev_lookback))/(max(src, outlier_level, dev_lookback) - min(src, outlier_level, dev_lookback)) * max_length)
    math.max(math.min(max_length + min_length, out), min_length)

scaled_atr(src, min_length, max_length, atr_length, outlier_level, dev_lookback)=>
    min_max(nz(average_true_range(src, atr_length), math.avg(min_length, max_length)), min_length, outlier_level, dev_lookback, max_length)

source      = input.source(close, 'Input')
min_length      = input.int(16, "Min Length", 3)
max_length  = input.int(1000, "Max Length")
vol_length  = input.int(10, "ATR Length", 1)
outlier_len = input.int(10, "Outlier Length", 5)
outlier_dev = input.float(1, "Outlier Level", 0, 10, 0.01)

length = scaled_atr(source,  min_length, max_length, vol_length, outlier_dev, outlier_len)

ma = ema(source, length)

plot(ma, "AEMA")