3x MTF MACD v3.0
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// Idea by © thebearfib - Made By @kioseffTrading
//
//MACD on 3time frames
//@version=5
//
indicator("3x MTF MACD v5.150", overlay = true, max_labels_count = 500)

import RicardoSantos/MathOperator/2
import HeWhoMustNotBeNamed/arraymethods/1


color _Bullish = input.color(color.rgb(34, 255, 0), 'Bullish', inline = '1x', group = '390 min in a Trading Day')
color _Bearish = input.color(color.rgb(255, 0, 0),  'Bearish', inline = '1x', group = '390 min in a Trading Day')

_time          = input.timeframe("D","TimeFrame" ,    group   = 'Simple Moving Avg Line', inline='1x'                         )
showSMA        = input.bool (true, '',                group   = 'Simple Moving Avg Line', inline='3x'                         )
_smaLen        = input.int  (defval = 13, title=' ',  group   = 'Simple Moving Avg Line', inline='3x'                         )
_smaWt         = input.int  (defval = 2,  title=' ',  group   = 'Simple Moving Avg Line', inline='3x', minval = 1, maxval = 20)

showMin        = input.bool(defval = true, title = "sʜᴏᴡ ᴍᴀᴄᴅ ᴛɪᴍᴇ ғʀᴀᴍᴇ ɪɴ ᴍɪɴᴜᴛᴇs [ɪɴ ᴛᴀʙʟᴇ]",         group = "MACD Input Settings", inline = "0")
one            = input.float(defval = 30,           title = "ᴛɪᴍᴇ", minval = 1, maxval = 1444,           group = "MACD Input Settings", inline = "1")
fast1          = input.int(defval = 12, minval = 2, title = "ғᴀsᴛ",                                      group = "MACD Input Settings", inline = "2")
slow1          = input.int(defval = 26, minval = 2, title = "sʟᴏᴡ",                                      group = "MACD Input Settings", inline = "3")
smooth1        = input.int(defval = 9 , minval = 2, title = "sᴍᴏᴏ",                                      group = "MACD Input Settings", inline = "4")

two            = input.float(defval = 45,           title = " ", minval = 1, maxval = 1444,              group = "MACD Input Settings", inline = "1")
fast2          = input.int(defval = 18, minval = 2, title = " ",                                         group = "MACD Input Settings", inline = "2")
slow2          = input.int(defval = 32, minval = 2, title = " ",                                         group = "MACD Input Settings", inline = "3")
smooth2        = input.int(defval = 15, minval = 2, title = " ",                                         group = "MACD Input Settings", inline = "4")

three          = input.float(defval = 60,           title = " ", minval = 1, maxval = 1444,              group = "MACD Input Settings", inline = "1")
fast3          = input.int(defval = 24, minval = 2, title = " ",                                         group = "MACD Input Settings", inline = "2")
slow3          = input.int(defval = 38, minval = 2, title = " ",                                         group = "MACD Input Settings", inline = "3")
smooth3        = input.int(defval = 21, minval = 2, title = " ",                                         group = "MACD Input Settings", inline = "4")

method Float(int id) => float(id)

type lowerTFvals 

    array<label> upLabels 
    array<label> dnLabels 
    int          counterUp 
    int          counterDn

[dayOpen, dayHigh, dayLow, dayClose] = request.security(syminfo.tickerid, _time,

  [open, high, low, close], 

  lookahead = barmerge.lookahead_off, 
  gaps      = barmerge.gaps_on

  )

_sma13  = ta.sma(dayClose, _smaLen)

_trend = switch 

    _sma13 > _sma13[3]  =>   color.rgb(0, 255, 8) 
    _sma13 < _sma13[3]  =>   color.rgb(255, 0, 0) 
    _sma13 > _sma13[1]  =>   color.rgb(109, 111, 120,50) 
    _sma13 < _sma13[1]  =>   color.rgb(108, 110, 117,50) 
    =>                       color.rgb(113, 116, 125,50)


rs(fast, slow, smooth) => 
    
    _rs1     = ta.ema(close, fast), 
    _rs2     = ta.ema(close, slow)
    rs       = _rs1.subtract(_rs2)
    rsMA     = ta.sma(rs, smooth)
  
    crossUp = ta.crossover (rs, rsMA) 
    crossDn = ta.crossunder(rs, rsMA)

    [n, tim] = switch 

        crossUp => [1 , time]
        crossDn => [-1, time]
        =>         [0 ,  0  ]

    [n, tim]


req(timeframe, fast, slow, smooth) => 

    [higher, highert] = request.security         (syminfo.tickerid, timeframe = str.tostring(timeframe), expression = rs(fast, slow, smooth))
    [lower , lowert ] = request.security_lower_tf(syminfo.tickerid, timeframe = str.tostring(timeframe), expression = rs(fast, slow, smooth), ignore_invalid_timeframe = true)

    [higher, highert, lower, lowert]


[rs1, t1, rs1ltf, tltf1] = req(one, fast1, slow1, smooth1), [rs2, t2, rs2ltf, tltf2] = req(two, fast2, slow2, smooth2),
                     [rs3, t3, rs3ltf, tltf3] = req(three, fast3, slow3, smooth3)


determine(rs) =>

    switch rs 

        1  => _Bullish 
        -1 => _Bearish
        =>   color.black


atrFunction( float ) => 

    atr = ta.atr(30)
    x   = float *  atr + close
    y   = float * -atr + close

    [x, y]

[_atrH1, _atrL1] = atrFunction(2), [_atrH2, _atrL2] = atrFunction(8),
                   [_atrH3, _atrL3] = atrFunction(12)

method appendLabel(array<label> id, cond, txtu, txtd) => 

    [upText, col, location, styl] = switch cond 

        true => ["▲" + txtu, _Bullish, yloc.belowbar, label.style_label_up  ]
        =>      [txtd + "▼", _Bearish, yloc.abovebar, label.style_label_down]

    id.push(label.new(time, close, upText, size = size.tiny, 
                         color     = #00000000, 
                         textcolor = col,
                         xloc      = xloc.bar_time, 
                         yloc      = location, 
                         style     = styl
                         ))     

method levelDetection (array<float> id, timefram, rsint, t1, upstr, dnstr) => 

    if timeframe.in_seconds(timeframe.period).Float().under_equal(timeframe.in_seconds(str.tostring(timefram)))
        if rsint.Float().not_equal(0)

            [str, col, location, styl] = switch

                rsint.Float().equal(1) => [upstr, _Bullish, yloc.belowbar, label.style_label_up  ]
                =>                        [dnstr, _Bearish, yloc.abovebar, label.style_label_down]

            label.new(t1, close, str, size=size.large, color = #00000000, textcolor = col,xloc = xloc.bar_time, yloc = location, style = styl)                                                                                                              

    else 
        
        if id.size().Float().over(0) 

            labsu    = array.new_label(), labsd    = array.new_label(), 
            counteru = 0                , counterd = 0

            for i = 0 to id.size().Float().subtract(1)

                cond = id.get(i).equal(1) 

                if id.get(i).not_equal(0)

                    switch 

                        id.get(i).equal(1) => counteru += 1
                        =>                    counterd += 1

                    extraCondition = counteru.Float().over(1)

                    [txtu, txtd] = switch extraCondition

                        true => ["\n" + str.tostring(counteru), str.tostring(counterd) + "\n"]
                        =>      ["",""]

                    if id.get(i).equal(1)
                        if labsu.size().Float().over(0) 

                            labsu.flush()

                        labsu.appendLabel(cond, txtu, txtd)

                    if id.get(i).equal(-1)
                        if labsd.size().Float().over(0)

                            labsd.flush()

                        labsd.appendLabel(cond, txtu, txtd)

    id

rs1ltf.levelDetection(one  , rs1, t1, "\n▲\n①"             , "\n①\n▼"      )
rs2ltf.levelDetection(two  , rs2, t2, "\n\n\n▲\n②"         ,"\n\n②\n▼"     )
rs3ltf.levelDetection(three, rs3, t3, "\n \n \n \n \n▲\n③" , "\n\n\n\n③\n▼")

if barstate.islastconfirmedhistory

    _xo1            = determine(rs1), _xo2   = determine(rs2), _xo3   = determine(rs3)
    showTable       = input.bool(defval = true, title = "Show Table", inline = '1', group = 'Table')

    positionGo      = input.string("Top Right", " ", 
      options       = ["Top Right", "Top Center", "Top Left", "Middle Right", "Middle Center", "Middle Left", "Bottom Right", "Bottom Center", "Bottom Left"], 
      inline        = '1', group = 'Table')

    tableposGo = switch positionGo

        "Top Right"     => position.top_right
        "Top Center"    => position.top_center
        "Top Left"      => position.top_left
        "Middle Right"  => position.middle_right
        "Middle Center" => position.middle_center
        "Middle Left"   => position.middle_left
        "Bottom Right"  => position.bottom_right
        "Bottom Center" => position.bottom_center
        "Bottom Left"   => position.bottom_left


    var table Display3 = table.new(tableposGo, 99, 99,
      bgcolor          = color.rgb(54, 58, 69, 100), 
      frame_width      = 1, 
      frame_color      = color.rgb(255, 255, 255, 100))

    if showTable

        table.cell(Display3, 1, 1,"①",   bgcolor= color.rgb(0, 187, 212, 100),   text_halign=text.align_center, text_color=_xo1, text_size=size.huge, text_font_family = font.family_monospace)
        table.cell(Display3, 2, 1,"②",   bgcolor= color.rgb(0, 187, 212, 100),   text_halign=text.align_center, text_color=_xo2, text_size=size.huge, text_font_family = font.family_monospace)
        table.cell(Display3, 3, 1,"③",   bgcolor= color.rgb(0, 187, 212, 100),   text_halign=text.align_center, text_color=_xo3, text_size=size.huge, text_font_family = font.family_monospace)

    if showMin

        table.cell(Display3, 1, 2,str.tostring(one)+" min",   bgcolor= color.rgb(0, 187, 212, 100),   text_halign=text.align_center, text_color=_xo1, text_size=size.normal, text_font_family = font.family_monospace)
        table.cell(Display3, 2, 2,str.tostring(two)+" min",   bgcolor= color.rgb(0, 187, 212, 100),   text_halign=text.align_center, text_color=_xo2, text_size=size.normal, text_font_family = font.family_monospace)
        table.cell(Display3, 3, 2,str.tostring(three)+" min", bgcolor= color.rgb(0, 187, 212, 100),   text_halign=text.align_center, text_color=_xo3, text_size=size.normal, text_font_family = font.family_monospace)

    if showSMA
        table.cell(Display3, 1, 3,"══════════",bgcolor= color.rgb(0, 187, 212, 100),text_halign=text.align_center, text_color=_xo1, text_size=size.normal, text_font_family = font.family_monospace)
        table.cell(Display3, 2, 3,"══════════",bgcolor= color.rgb(0, 187, 212, 100),text_halign=text.align_center, text_color=_xo1, text_size=size.normal, text_font_family = font.family_monospace)
        table.cell(Display3, 3, 3,"══════════",bgcolor= color.rgb(0, 187, 212, 100),text_halign=text.align_center, text_color=_xo1, text_size=size.normal, text_font_family = font.family_monospace)

        table.cell(Display3, 1, 4,"SMA ",bgcolor= color.rgb(0, 187, 212, 100),text_halign=text.align_center, text_color=_trend, text_size=size.normal, text_font_family = font.family_monospace)
        table.cell(Display3, 2, 4,str.tostring(_smaLen),bgcolor= color.rgb(0, 187, 212, 100),text_halign=text.align_center, text_color=_trend, text_size=size.normal, text_font_family = font.family_monospace)
        table.cell(Display3, 3, 4, _time,bgcolor= color.rgb(0, 187, 212, 100),text_halign=text.align_center, text_color=_trend, text_size=size.normal, text_font_family = font.family_monospace)


plot(showSMA ? _sma13 : na, 'SMA 13',  color= _trend,  linewidth = _smaWt, display = display.all)
plot(_atrL1,'ATR Low', color=color.rgb(255, 0, 0), style = plot.style_line, linewidth = 2, display = display.all, show_last = 1)
plot(_atrH1,'ATR Low', color=color.rgb(255, 0, 0), style = plot.style_line, linewidth = 2, display = display.all, show_last = 1)

plot(_atrL2,'ATR Low', color=color.rgb(166, 0, 0), style = plot.style_line, linewidth = 2, display = display.all, show_last = 1)
plot(_atrH2,'ATR Low', color=color.rgb(166, 0, 0), style = plot.style_line, linewidth = 2, display = display.all, show_last = 1)

plot(_atrL3,'ATR Low', color=color.rgb(79, 1, 1), style = plot.style_line, linewidth = 2, display = display.all, show_last = 1)
plot(_atrH3,'ATR Low', color=color.rgb(79, 1, 1), style = plot.style_line, linewidth = 2, display = display.all, show_last = 1)
