Adaptive, One More Moving Average (OMA) [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("Adaptive, One More Moving Average (OMA) [Loxx]", shorttitle="AOMA [Loxx]", timeframe="", timeframe_gaps=true, overlay = true)

greencolor = #2DD204
redcolor = #D2042D 

//speed  0.5 - T3 (0.618 Tilson)
//sspeed 2.5 - T3 (0.618 Fulks/Matulich)
//sspeed 1 - SMA, harmonic mean
//sspeed 2 - LWMA
//sspeed 7 - very similar to Hull and TEMA
//sspeed 8 - very similar to LSMA and Linear regression value

src = input.source(close, "Source")
len = input.int(26, "Average Period", minval = 1)
const = input.float(1.0, "Speed", step = .01)
adapt = input.bool(true, "Make it adapotive?")
colorbars = input.bool(false, "Color bars?")

_oma(src, len, const, adapt) =>
    e1 = nz(src[1]), e2 = nz(src[1]), e3 = nz(src[1])
    e4 = nz(src[1]), e5 = nz(src[1]), e6 = nz(src[1])
    averagePeriod = len
    noise = 0.00000000001
    minPeriod = averagePeriod/2.0
    maxPeriod = minPeriod*5.0
    endPeriod = math.ceil(maxPeriod)
    signal = math.abs(src - nz(src[endPeriod]))
    
    if adapt
        for k = 1 to endPeriod
            noise += math.abs(src - nz(src[k]))
        averagePeriod := math.ceil(((signal / noise) * (maxPeriod - minPeriod)) + minPeriod)
        
    alpha = (2.0 + const) / (1.0 + const + averagePeriod)
    
    e1 := nz(e1[1] + alpha * (src - e1[1]), src)
    e2 := nz(e2[1] + alpha * (e1 - e2[1]), e1)
    v1 = 1.5 * e1 - 0.5 * e2
    
    e3 := nz(e3[1] + alpha * (v1 - e3[1]), v1)
    e4 := nz(e4[1] + alpha * (e3 - e4[1]), e3)
    v2 = 1.5 * e3 - 0.5 * e4
    
    e5 := nz(e5[1] + alpha * (v2 - e5[1]), v2) 
    e6 := nz(e6[1] + alpha * (e5 - e6[1]), e5) 
    v3 = 1.5 * e5 - 0.5 * e6
    v3
    
out = _oma(src, len, const, adapt)
plot(out, color = src >= out ? greencolor : redcolor, linewidth = 3)

barcolor(colorbars ? src >= out ? greencolor : redcolor : na)





