Guppy Waves
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//@version=5
indicator(title='Guppy Waves', shorttitle='Guppy Waves', overlay=true, timeframe="", timeframe_gaps=true)

//COLOR INPUTS
Color_type = input.string('User Colors', '', inline='0', 
     options=['User Colors', 
     'RSI Rainbow'])

rainbowon = if Color_type == 'RSI Rainbow'
    true
else 
    false

color bullma = input.color(color.new(color.lime, 100), '', inline='0')
color bearma = input.color(color.new(color.fuchsia, 100), '', inline='0')
filloffset = input.int(0, 'Fill Transparency Offset', inline='0', minval=-100, maxval=100)

//SPECIAL MA SETTINGS
lsmaoffset = input.int(title='LEAST SQUARES (LSMA) ONLY - LS Offset', defval=0, inline='00', group='Special MA Settings')
almaoffset = input.float(title='ALMA Offset', defval=0.85, step=0.01, inline='01', group='Special MA Settings')
almasigma = input.float(title='ALMA Sigma', defval=6, inline='01', group='Special MA Settings')
a1 = input.float(title='Tillson T3 Volume Factor', defval=0.7, step=0.001, inline='02', group='Special MA Settings')

//FUNCTIONS BLOCK
f_ehma(_source, _length) =>
    _return = ta.ema(2 * ta.ema(_source, _length / 2) - ta.ema(_source, _length), math.round(math.sqrt(_length)))
    _return

f_tema(_source, _length) =>
    _out = 3 * (ta.ema(_source, _length) - ta.ema(ta.ema(_source, _length), _length)) + ta.ema(ta.ema(ta.ema(_source, _length), _length), _length)
    _out

f_t3(_source, _length, _a1) =>
    _output = (-_a1 * _a1 * _a1) * (ta.ema(ta.ema(ta.ema(ta.ema(ta.ema(ta.ema(_source, _length), _length), _length), _length), _length), _length)) + (3 * _a1 * _a1 + 3 * _a1 * _a1 * _a1) * (ta.ema(ta.ema(ta.ema(ta.ema(ta.ema(_source, _length), _length), _length), _length), _length)) + (-6 * _a1 * _a1 - 3 * _a1 - 3 * _a1 * _a1 * _a1) * (ta.ema(ta.ema(ta.ema(ta.ema(_source, _length), _length), _length), _length)) + (1 + 3 * _a1 + _a1 * _a1 * _a1 + 3 * _a1 * _a1) * (ta.ema(ta.ema(ta.ema(_source, _length), _length), _length))
    _output

f_donchian(_length) =>
    math.avg(ta.lowest(_length), ta.highest(_length))

MA(source, length, type) =>
     type == 'SMA' ? ta.sma(source, length) : 
     type == 'EMA' ? ta.ema(source, length) : 
     type == 'SMMA (RMA)' ? ta.rma(source, length) : 
     type == 'WMA' ? ta.wma(source, length) : 
     type == 'VWMA' ? ta.vwma(source, length) : 
     type == 'HMA' ? ta.hma(source, length) : 
     type == 'EHMA' ? f_ehma(source, length) : 
     type == 'TEMA' ? f_tema(source, length) : 
     type == 'Donchian' ? f_donchian(length) : 
     type == 'ALMA' ? ta.alma(source, length, almaoffset, almasigma) : 
     type == 'Tillson T3' ? f_t3(source, length, a1) : 
     type == 'LSMA' ? ta.linreg(source, length, lsmaoffset) : na

//MA RIBBON BLOCK
show_MA1 = input.bool(true, 'MA №1', inline='MA #1', group='Moving Average Ribbon')
MA1_type = input.string('Tillson T3', '', inline='MA #1', options=['SMA', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'HMA', 'EHMA', 'TEMA', 'ALMA', 'Tillson T3', 'LSMA', 'Donchian'], group='Moving Average Ribbon')
MA1_length = input.int(5, '', inline='MA #1', minval=1, group='Moving Average Ribbon')
MA1_source = input.source(close, '', inline='MA #1', group='Moving Average Ribbon')
MA1 = MA(MA1_source, MA1_length, MA1_type)

show_MA2 = input.bool(true, 'MA №2', inline='MA #2', group='Moving Average Ribbon')
MA2_type = input.string('SMA', '', inline='MA #2', options=['SMA', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'HMA', 'EHMA', 'TEMA', 'ALMA', 'Tillson T3', 'LSMA', 'Donchian'], group='Moving Average Ribbon')
MA2_length = input.int(9, '', inline='MA #2', minval=1, group='Moving Average Ribbon')
MA2_source = input.source(close, '', inline='MA #2', group='Moving Average Ribbon')
MA2 = MA(MA2_source, MA2_length, MA2_type)

show_MA3 = input.bool(true, 'MA №3', inline='MA #3', group='Moving Average Ribbon')
MA3_type = input.string('EMA', '', inline='MA #3', options=['SMA', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'HMA', 'EHMA', 'TEMA', 'ALMA', 'Tillson T3', 'LSMA', 'Donchian'], group='Moving Average Ribbon')
MA3_length = input.int(12, '', inline='MA #3', minval=1, group='Moving Average Ribbon')
MA3_source = input.source(close, '', inline='MA #3', group='Moving Average Ribbon')
MA3 = MA(MA3_source, MA3_length, MA3_type)

show_MA4 = input.bool(true, 'MA №4', inline='MA #4', group='Moving Average Ribbon')
MA4_type = input.string('WMA', '', inline='MA #4', options=['SMA', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'HMA', 'EHMA', 'TEMA', 'ALMA', 'Tillson T3', 'LSMA', 'Donchian'], group='Moving Average Ribbon')
MA4_length = input.int(26, '', inline='MA #4', minval=1, group='Moving Average Ribbon')
MA4_source = input.source(close, '', inline='MA #4', group='Moving Average Ribbon')
MA4 = MA(MA4_source, MA4_length, MA4_type)

show_MA5 = input.bool(true, 'MA №5', inline='MA #5', group='Moving Average Ribbon')
MA5_type = input.string('ALMA', '', inline='MA #5', options=['SMA', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'HMA', 'EHMA', 'TEMA', 'ALMA', 'Tillson T3', 'LSMA', 'Donchian'], group='Moving Average Ribbon')
MA5_length = input.int(50, '', inline='MA #5', minval=1, group='Moving Average Ribbon')
MA5_source = input.source(close, '', inline='MA #5', group='Moving Average Ribbon')
MA5 = MA(MA5_source, MA5_length, MA5_type)

show_MA6 = input.bool(true, 'MA №6', inline='MA #6', group='Moving Average Ribbon')
MA6_type = input.string('EHMA', '', inline='MA #6', options=['SMA', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'HMA', 'EHMA', 'TEMA', 'ALMA', 'Tillson T3', 'LSMA', 'Donchian'], group='Moving Average Ribbon')
MA6_length = input.int(100, '', inline='MA #6', minval=1, group='Moving Average Ribbon')
MA6_source = input.source(close, '', inline='MA #6', group='Moving Average Ribbon')
MA6 = MA(MA6_source, MA6_length, MA6_type)

show_MA7 = input.bool(true, 'MA №7', inline='MA #7', group='Moving Average Ribbon')
MA7_type = input.string('HMA', '', inline='MA #7', options=['SMA', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'HMA', 'EHMA', 'TEMA', 'ALMA', 'Tillson T3', 'LSMA', 'Donchian'], group='Moving Average Ribbon')
MA7_length = input.int(200, '', inline='MA #7', minval=1, group='Moving Average Ribbon')
MA7_source = input.source(close, '', inline='MA #7', group='Moving Average Ribbon')
MA7 = MA(MA7_source, MA7_length, MA7_type)

//OPTIONAL RAINBOW RSI GRADIENT
var grad2 = array.new_color(na)
if barstate.isfirst
    array.push(grad2, color.gray)
    array.push(grad2, #800080)
    array.push(grad2, #890089)
    array.push(grad2, #910091)
    array.push(grad2, #9a009a)
    array.push(grad2, #a300a3)
    array.push(grad2, #ab00ab)
    array.push(grad2, #b400b4)
    array.push(grad2, #bd00bd)
    array.push(grad2, #c700c7)
    array.push(grad2, #d000d0)
    array.push(grad2, #d900d9)
    array.push(grad2, #e200e2)
    array.push(grad2, #ec00ec)
    array.push(grad2, #f500f5)
    array.push(grad2, #ff00ff)
    array.push(grad2, #ff00f0)
    array.push(grad2, #ff00e1)
    array.push(grad2, #ff00d2)
    array.push(grad2, #ff00c4)
    array.push(grad2, #ff00b7)
    array.push(grad2, #ff00aa)
    array.push(grad2, #ff009d)
    array.push(grad2, #ff0091)
    array.push(grad2, #ff0086)
    array.push(grad2, #ff187c)
    array.push(grad2, #ff2972)
    array.push(grad2, #ff3669)
    array.push(grad2, #ff4160)
    array.push(grad2, #ff4a59)
    array.push(grad2, #ff5252)
    array.push(grad2, #ff5a4e)
    array.push(grad2, #ff624a)
    array.push(grad2, #ff6a45)
    array.push(grad2, #ff7240)
    array.push(grad2, #ff7b3b)
    array.push(grad2, #ff8336)
    array.push(grad2, #ff8c30)
    array.push(grad2, #ff942a)
    array.push(grad2, #ff9d23)
    array.push(grad2, #ffa61c)
    array.push(grad2, #ffaf12)
    array.push(grad2, #ffb805)
    array.push(grad2, #ffc100)
    array.push(grad2, #ffca00)
    array.push(grad2, #ffd300)
    array.push(grad2, #ffdc00)
    array.push(grad2, #ffe500)
    array.push(grad2, #ffed00)
    array.push(grad2, #fff600)
    array.push(grad2, #ffff00)
    array.push(grad2, #eefd1d)
    array.push(grad2, #ddfb2d)
    array.push(grad2, #ccf83a)
    array.push(grad2, #bcf546)
    array.push(grad2, #adf150)
    array.push(grad2, #9eee59)
    array.push(grad2, #8fea62)
    array.push(grad2, #81e66a)
    array.push(grad2, #74e172)
    array.push(grad2, #66dc79)
    array.push(grad2, #5ad87f)
    array.push(grad2, #4dd385)
    array.push(grad2, #41cd8a)
    array.push(grad2, #36c88f)
    array.push(grad2, #2cc393)
    array.push(grad2, #24bd96)
    array.push(grad2, #1fb798)
    array.push(grad2, #1eb299)
    array.push(grad2, #21ac9a)
    array.push(grad2, #26a69a)
    array.push(grad2, #26aca0)
    array.push(grad2, #26b1a6)
    array.push(grad2, #25b7ad)
    array.push(grad2, #24bdb3)
    array.push(grad2, #24c3ba)
    array.push(grad2, #23c9c0)
    array.push(grad2, #21cfc7)
    array.push(grad2, #20d5ce)
    array.push(grad2, #1edbd4)
    array.push(grad2, #1be1db)
    array.push(grad2, #18e7e2)
    array.push(grad2, #15ede9)
    array.push(grad2, #10f3f0)
    array.push(grad2, #09f9f8)
    array.push(grad2, #00ffff)
    array.push(grad2, #00f5ff)
    array.push(grad2, #00ebff)
    array.push(grad2, #00e1ff)
    array.push(grad2, #00d6ff)
    array.push(grad2, #00cbff)
    array.push(grad2, #00bfff)
    array.push(grad2, #00b3ff)
    array.push(grad2, #00a6ff)
    array.push(grad2, #0099ff)
    array.push(grad2, #008aff)
    array.push(grad2, #007bff)
    array.push(grad2, #0069ff)
    array.push(grad2, #0055ff)
    array.push(grad2, #003bff)
    array.push(grad2, #0000ff)

dncolor1 = array.get(grad2, math.round(math.avg(0, math.round(ta.rsi(MA1, MA1_length)))))
upcolor1 = array.get(grad2, math.round(math.avg(50, math.round(ta.rsi(MA1, MA1_length)))))
dncolor2 = array.get(grad2, math.round(math.avg(0, math.round(ta.rsi(MA2, MA2_length)))))
upcolor2 = array.get(grad2, math.round(math.avg(50, math.round(ta.rsi(MA2, MA2_length)))))
dncolor3 = array.get(grad2, math.round(math.avg(0, math.round(ta.rsi(MA3, MA3_length)))))
upcolor3 = array.get(grad2, math.round(math.avg(50, math.round(ta.rsi(MA3, MA3_length)))))
dncolor4 = array.get(grad2, math.round(math.avg(0, math.round(ta.rsi(MA4, MA4_length)))))
upcolor4 = array.get(grad2, math.round(math.avg(50, math.round(ta.rsi(MA4, MA4_length)))))
dncolor5 = array.get(grad2, math.round(math.avg(0, math.round(ta.rsi(MA5, MA5_length)))))
upcolor5 = array.get(grad2, math.round(math.avg(50, math.round(ta.rsi(MA5, MA5_length)))))
dncolor6 = array.get(grad2, math.round(math.avg(0, math.round(ta.rsi(MA6, MA6_length)))))
upcolor6 = array.get(grad2, math.round(math.avg(50, math.round(ta.rsi(MA6, MA6_length)))))
dncolor7 = array.get(grad2, math.round(math.avg(0, math.round(ta.rsi(MA7, MA7_length)))))
upcolor7 = array.get(grad2, math.round(math.avg(50, math.round(ta.rsi(MA7, MA7_length)))))

//PLOTS BLOCK
p1 = plot(show_MA1 ? MA1 : na, title='Fast MA 1', linewidth=1, color=MA1 > MA1[1] ? bullma : bearma)
p2 = plot(show_MA2 ? MA2 : na, title='Fast MA 2', linewidth=1, color=MA2 > MA2[1] ? bullma : bearma)
p3 = plot(show_MA3 ? MA3 : na, title='Fast MA 3', linewidth=1, color=MA3 > MA3[1] ? bullma : bearma)
p4 = plot(show_MA4 ? MA4 : na, title='Fast MA 4', linewidth=1, color=MA4 > MA4[1] ? bullma : bearma)
p5 = plot(show_MA5 ? MA5 : na, title='Fast MA 5', linewidth=1, color=MA5 > MA5[1] ? bullma : bearma)
p6 = plot(show_MA6 ? MA6 : na, title='Fast MA 6', linewidth=1, color=MA6 > MA6[1] ? bullma : bearma)
p7 = plot(show_MA7 ? MA7 : na, title='Fast MA 7', linewidth=1, color=MA7 > MA7[1] ? bullma : bearma)

//GUPPY WAVES
fill(p1, p2, color= MA1 > MA2 ? rainbowon == true ? color.new(upcolor1,82+filloffset) : color.new(bullma, 82+filloffset) : rainbowon == true ? color.new(dncolor1,82+filloffset) : color.new(bearma, 82+filloffset))
fill(p2, p3, color= MA2 > MA3 ? rainbowon == true ? color.new(upcolor2,85+filloffset) : color.new(bullma, 85+filloffset) : rainbowon == true ? color.new(dncolor2,85+filloffset) : color.new(bearma, 85+filloffset))
fill(p3, p4, color= MA3 > MA4 ? rainbowon == true ? color.new(upcolor3,88+filloffset) : color.new(bullma, 88+filloffset) : rainbowon == true ? color.new(dncolor3,88+filloffset) : color.new(bearma, 88+filloffset))
fill(p4, p5, color= MA4 > MA5 ? rainbowon == true ? color.new(upcolor4,91+filloffset) : color.new(bullma, 91+filloffset) : rainbowon == true ? color.new(dncolor4,91+filloffset) : color.new(bearma, 91+filloffset))
fill(p5, p6, color= MA5 > MA6 ? rainbowon == true ? color.new(upcolor5,94+filloffset) : color.new(bullma, 94+filloffset) : rainbowon == true ? color.new(dncolor5,94+filloffset) : color.new(bearma, 94+filloffset))
fill(p6, p7, color= MA6 > MA7 ? rainbowon == true ? color.new(upcolor6,97+filloffset) : color.new(bullma, 97+filloffset) : rainbowon == true ? color.new(dncolor6,97+filloffset) : color.new(bearma, 97+filloffset))