Customizable Moving Average Ribbon
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © LeafAlgo

//@version=5
indicator('Customizable Moving Average Ribbon', shorttitle=' Custom MA ribbon', overlay=true)
//Inputs//
src= input.string('Renko Close', title='Source', options=['Classic Close', 'Classic Open', 'OHLC4', 'Renko Open', 'Renko Close'])
type = input.string('EMA', title='Moving Average Type Selection', options=['EMA', 'DEMA', 'TEMA','SMA', 'RMA', 'VWMA', 'WMA', 'SMMA', 'HULL'])
Color= input.string('Green/Red', title='Color Selection', options=['Green/Red','Purple/White','White/Blue','Silver/Orange','Teal/Orange'])
mode =input.string(title = 'Input Method', defval ='ATR', options=['Traditional', 'ATR'])
modevalue = input.int(title ='ATR Brick Size', defval = 14, minval = 1)
boxsize = input.float(title ='Traditional Brick Size', defval = 1, step= 0.001, minval = 0.0000001)
//Calculations//
conv_atr(value)=>
    a = 0
    num = syminfo.mintick
    s = value
    if na(s)
        s := syminfo.mintick
    if num < 1
        for i = 1 to 20
            num := num * 10
            if num > 1
                break
            a := a +1
    for x = 1 to a 
        s := s * 10
    s := math.round(s)
    for x = 1 to a
        s := s / 10
    s := s < syminfo.mintick  ? syminfo.mintick : s
    s


atrboxsize = conv_atr(ta.atr(modevalue))

float box = na
box := na(box[1]) ? mode == 'ATR' ? atrboxsize : boxsize : box[1] 

reversal = 2
top = 0.0, bottom = 0.0
trend = 0
trend := barstate.isfirst ? 0 : nz(trend[1])
currentprice = 0.0
currentprice := close 
float beginprice = na
beginprice := barstate.isfirst ? math.floor(open / box) * box : nz(beginprice[1])
openprice = 0.0
closeprice = 0.0

if trend == 0 and box * reversal <= math.abs(beginprice - currentprice)
    if beginprice > currentprice
        numcell = math.floor(math.abs(beginprice - currentprice) / box)
        openprice := beginprice
        closeprice := beginprice - numcell * box
        trend := -1
    if beginprice < currentprice
        numcell = math.floor(math.abs(beginprice - currentprice) / box)
        openprice := beginprice
        closeprice := beginprice + numcell * box
        trend := 1

if trend == -1
    nok = true
    if beginprice > currentprice and box <= math.abs(beginprice - currentprice)
        numcell = math.floor(math.abs(beginprice - currentprice) / box)
        closeprice := beginprice - numcell * box
        trend := -1
        beginprice := closeprice
        nok := false
    else
        openprice := openprice == 0 ? nz(openprice[1]) : openprice
        closeprice := closeprice == 0 ? nz(closeprice[1]) : closeprice
    
    tempcurrentprice = close
    if beginprice < tempcurrentprice and box * reversal <= math.abs(beginprice - tempcurrentprice) and nok //new column
        numcell = math.floor(math.abs(beginprice - tempcurrentprice) / box)
        openprice := beginprice + box
        closeprice := beginprice + numcell * box
        trend := 1
        beginprice := closeprice
    else
        openprice := openprice == 0 ? nz(openprice[1]) : openprice
        closeprice := closeprice == 0 ? nz(closeprice[1]) : closeprice
else        
    if trend == 1
        nok = true
        if beginprice < currentprice and box <= math.abs(beginprice - currentprice)
            numcell = math.floor(math.abs(beginprice - currentprice) / box)
            closeprice := beginprice + numcell * box
            trend := 1
            beginprice := closeprice
            nok := false
        else
            openprice := openprice == 0 ? nz(openprice[1]) : openprice
            closeprice := closeprice == 0 ? nz(closeprice[1]) : closeprice
    
        tempcurrentprice = close
        if beginprice > tempcurrentprice and box * reversal <= math.abs(beginprice - tempcurrentprice) and nok //new column
            numcell = math.floor(math.abs(beginprice - tempcurrentprice) / box)
            openprice := beginprice - box
            closeprice := beginprice - numcell * box
            trend := -1
            beginprice := closeprice
        else
            openprice := openprice == 0 ? nz(openprice[1]) : openprice
            closeprice := closeprice == 0 ? nz(closeprice[1]) : closeprice    


box := ta.change(closeprice) ?  mode == 'ATR' ? atrboxsize :  boxsize : box

oprice =
   trend == 1 ? nz(trend[1]) == 1 ? nz(closeprice[1]) - nz(box[1]) : nz(closeprice[1]) + nz(box[1]) : 
   trend == -1 ? nz(trend[1]) == -1 ? nz(closeprice[1]) + nz(box[1]) : nz(closeprice[1]) - nz(box[1]) :
   nz(closeprice[1]) 
oprice := oprice < 0 ? 0 : oprice

//Color Options//
colorbull = 
 Color == 'Green/Red' ? color.green  : 
 Color == 'Purple/White' ? color.white : 
 Color == 'White/Blue' ? color.white : 
 Color == 'Silver/Orange' ? color.silver : 
 Color == 'Teal/Orange' ? color.teal :
  na
colorbear = 
 Color == 'Green/Red' ? color.red : 
 Color == 'Purple/White' ? color.purple : 
 Color == 'White/Blue' ? color.blue : 
 Color == 'Silver/Orange' ? color.orange : 
 Color == 'Teal/Orange' ? color.orange :
   na
Source() => 
    switch src
        "Classic Close" => close 
        "Classic Open" => open
        "OHLC4" => ohlc4
        "Renko Open" => openprice
        "Renko Close" => closeprice

//Moving Average Selection//
Multi_ma(type, src, len) =>
    float result = 0
    if type == 'EMA'
        result := ta.ema(Source(), len)
    if type == 'DEMA'
        ema1 = ta.ema(Source(), len)
        ema2 = ta.ema(ema1, len)
        result := 2 * ema1 - ema2
    if type == 'TEMA'
        ema1 = ta.ema(Source(), len)
        ema2 = ta.ema(ema1, len)
        ema3 = ta.ema(ema2, len)
        result := 3 * (ema1 - ema2) + ema3
    if type == 'SMA'
        result := ta.sma(Source(), len)
    if type == 'RMA'
        result := ta.rma(Source(), len)
    if type == 'VWMA'  
        result := ta.vwma(Source(), len)
    if type == 'WMA'  
        result := ta.wma(Source(), len)
    if type == 'SMMA'
        wma= ta.wma(Source(),len)
        sma= ta.sma(Source(),len)
        result := na(wma[1]) ? sma : (wma[1 ] * (len -1) + Source()) / len
    if type == 'HULL' 
        result := ta.hma(Source(),len)
    result

//MA Lengths//
MALen1=input.int(5, title='MA 1 Length')
MALen2=input.int(7, title='MA 2 Length')
MALen3=input.int(10, title='MA 3 Length')
MALen4=input.int(14, title='MA 4 Length')
MALen5=input.int(21, title='MA 5 Length')
MALen6=input.int(26, title='MA 6 Length')
MALen7=input.int(50, title='MA 7 Length')
MALen8=input.int(75, title='MA 8 Length')
MALen9=input.int(100, title='MA 9 Length')
MALen10=input.int(150, title='MA 10 Length')
MALen200=input.int(200, title='MA 200 Length')

//MA's//
MA1= Multi_ma(type, src, MALen1)
MA2= Multi_ma(type, src, MALen2)
MA3= Multi_ma(type, src, MALen3)
MA4= Multi_ma(type, src, MALen4)
MA5= Multi_ma(type, src, MALen5)
MA6= Multi_ma(type, src, MALen6)
MA7= Multi_ma(type, src, MALen7)
MA8= Multi_ma(type, src, MALen8)
MA9= Multi_ma(type, src, MALen9)
MA10= Multi_ma(type, src, MALen10)
MA200= Multi_ma(type, src, MALen200)

//MA Plots and Color Change//
maColor(MA, RefMA) =>
    changeMA = ta.change(MA)
    macolor = changeMA >= 0 and MA > RefMA ? colorbull : changeMA < 0 and MA > RefMA ? colorbear : changeMA <= 0 and MA < RefMA ? colorbear : changeMA >= 0 and MA < RefMA ? colorbull : color.gray

plot(MA1, color=maColor(MA1,MA200), linewidth =1, title='MA 1')
plot(MA2, color=maColor(MA2,MA200), linewidth =1, title='MA 2')
plot(MA3, color=maColor(MA3,MA200), linewidth =1, title='MA 3')
plot(MA4, color=maColor(MA4,MA200), linewidth =1, title='MA 4')
plot(MA5, color=maColor(MA5,MA200), linewidth =1, title='MA 5')
plot(MA6, color=maColor(MA6,MA200), linewidth =1, title='MA 6')
plot(MA7, color=maColor(MA7,MA200), linewidth =1, title='MA 7')
plot(MA8, color=maColor(MA8,MA200), linewidth =1, title='MA 8')
plot(MA9, color=maColor(MA9,MA200), linewidth =1, title='MA 9')
plot(MA10, color=maColor(MA10,MA200), linewidth =1, title='MA 10')
plot(MA200, color= MA200 <= closeprice ? colorbull : colorbear, linewidth=2, title='MA 200')
