Greedy MA & Greedy Bollinger Bands 
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © peacefulLizard50262

//ema/1/700/325/1/2/1/325(700)/175/dstd/gdstd
//ema/1/14/28/1/2/14/28/20/gdstd/gdstd
//ema/-10/20/2/2/2/14/10/20/rstd/rstd
//color themes for each preset

//@version=5
indicator("All Your Averaged r Belong to Us", "Moving Average Mod", overlay = true) //, max_bars_back = 700)

donchian(src, int len) => 
    math.avg(ta.lowest(src, len), ta.highest(src, len)) 
    
stdev(float src, float avg, float dev = 2, int len = 20, bool pol = true) =>
    stdev = dev * ta.stdev(src, len)
    out = pol == true ? avg + stdev : avg - stdev
    
gstdv(float src, float avg, float dev = 2, int len = 20, bool pol = false) =>
    float result = na
    lsrc = math.log(src)
    stdev = dev * ta.stdev(lsrc, len)
    lavg = math.log(avg)
    out = pol == true ? lavg + stdev : lavg - stdev
    result := math.exp(out)
    result

rstdv(float avg, int len = 10, float dev = 2, bool pol = true) =>
    out = pol == true ? avg + ta.atr(len) * dev : avg - ta.atr(len) * dev
    
dstdv(float src, float avg, float dev = 2, int len = 20, int don_len, int min, int max, bool pol = true) =>
    deviation = array.new_float(na)
    stdev = 0.0
    for i = min to max by 1
        array.push(deviation, donchian(dev * ta.stdev(src, i), don_len))
    stdev := array.sum(deviation)/((max-min)+1)
    result = pol == true ? avg + stdev : avg - stdev
    
gstdd(float src, float avg, float dev = 2, int len = 20, int don_len, int min, int max, bool pol = true) =>
    float result = na
    deviation = array.new_float(na)
    stdev = 0.0
    lsrc = math.log(src)
    for i = min to max by 1
        array.push(deviation, donchian(dev * ta.stdev(lsrc, i), don_len))
    stdev := array.sum(deviation)/((max-min)+1)
    lavg = math.log(avg)
    out = pol == true ? lavg + stdev : lavg - stdev
    result := math.exp(out)
    result
    
std(string sel = "std", float src, float avg, float dev = 2, len, int don_len, int min = 1, bool pol = true) =>
    result = switch sel
        "std" => stdev(src, avg, dev, len, pol)
        "gstd" => gstdv(src, avg, dev, len, pol)
        "rstd" => rstdv(avg, len, dev, pol)
        "dstd" => dstdv(src, avg, dev, len, don_len, min, len, pol)
        "gdstd" => gstdd(src, avg, dev, len, don_len, min, len, pol)
        =>stdev(src, avg, dev, len, pol)
    result
    
ema(src, int len) => 
    alpha = 2 / (len + 1)
    sum = 0.0
    sum := na(sum[1]) ? src : alpha * src + (1 - alpha) * nz(sum[1])
    
tma(src, int len) => 
    ema1 = ema(src, len)
    ema2 = ema(ema1, len)
    ema3 = ema(ema2, len)
    tma = 3 * (ema1 - ema2) + ema3
    
average(src, int len = 10, string sel = 'sma') =>
    sel == "ema" ? ema(src, len) : sel == "sma" ? ta.sma(src, len) : sel == "tma" ? tma(src, len) : na

deep(source, int min, int max, int length, string select) =>
    result = array.new_float(na)
    for i = min to max by 1
        array.push(result, donchian(average(source, i, select), length))
    array.sum(result)/((max-min)+1)

band_enable = input.bool(true)
source = input.source(close)
select = input.string("tma", "select ma", ["sma","ema","tma"])
min_length = input.int(1)
max_length = input.int(700)
donchain_length = input.int(325)
smooth = input.int(1)
deviation = input.float(2)
deviation_min_lookback = input.int(1)
deviation_lookback = input.int(325)
deviation_doncian = input.int(175)
band_top = input.string("dstd", "top type", ["std","gstd","rstd","dstd","gdstd"])
band_bot = input.string("gdstd", "bot type", ["std","gstd","rstd","dstd","gdstd"])
 
deep = deep(source, min_length, max_length, donchain_length, select)
out = ta.sma(deep, smooth)
deviation_src = ta.sma(source, smooth)

top = std(band_top, deviation_src, out, deviation, deviation_lookback, deviation_doncian, deviation_min_lookback, true)
bot = std(band_bot, deviation_src, out, deviation, deviation_lookback, deviation_doncian, deviation_min_lookback, false)

topnew = top > 0 ? top : na
botnew = bot > 0 ? bot : na
outnew = out > 0 ? out : na

topen = band_enable == true ? topnew : na
boten = band_enable == true ? botnew : na

center = plot(outnew, color = color.new(color.orange, 0))
High   = plot(topen, linewidth = 2)
Low    = plot(boten, linewidth = 2)