MaxAl - Multiple MTF Moving Averages, ATR Trend & More (v0.1)
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Maximus_Algorithmus

//@version=5
indicator(title="MaxAl - MTF Multiple Moving Averages & More Indicators (v0.1)", shorttitle="MaxAl-MultMTFMA", overlay=true)

group_00 = "🟢 Hide / Display "
bool      display_01    = input.bool(true,      "Hide/Display MA #1",                   group = group_00)
bool      display_02    = input.bool(false,     "Hide/Display MA #2",                   group = group_00)
bool      display_03    = input.bool(false,     "Hide/Display MA #3",                   group = group_00)
bool      display_04    = input.bool(true,      "Hide/Display MA #4",                   group = group_00)
bool      display_05    = input.bool(true,      "Hide/Display MA #5",                   group = group_00)
bool      display_06    = input.bool(true,      "Hide/Display MA #6",                   group = group_00)
bool      display_bb    = input.bool(true,      "Hide/Display Bollinger Bands",         group = group_00)
bool      display_atr   = input.bool(false,     "Hide/Display ATR Trailing Stop",       group = group_00)
bool      display_tbl   = input.bool(true,      "Hide/Display MTF RSI & Z-Score Table", group = group_00)

group_01 = "🟢 Moving Average #1"
// Assigning Inputs
var float htf_ma_01     = na
string    res_01        = input.timeframe("",   "Timeframe",                      group = group_01)
string    avg_type_01   = input.string("EMA",   "Average Type",                   group = group_01 , options = ["SMA", "EMA", "WMA", "VWMA", "HMA"])
int       len_01        = input.int(5,          "Length",                         group = group_01)
float     src_01        = input.source(close,   "Price Source",                   group = group_01)
int       offset_01     = input.int(0,          "Offset",                         group = group_01)
int       width_01      = input.int(1,          "Line Width",                     group = group_01)
color     color_01      = input.color(color.rgb(0, 255, 0), "Color",            group = group_01)
// Defining Moving Average Calculations Based on User Selection
if avg_type_01 == "SMA"
    htf_ma_01  := ta.sma(src_01, len_01)
if avg_type_01 == "EMA"
    htf_ma_01  := ta.ema(src_01, len_01)
if avg_type_01 == "WMA"
    htf_ma_01  := ta.wma(src_01, len_01)
if avg_type_01 == "VWMA"
    htf_ma_01  := ta.vwma(src_01, len_01)
if avg_type_01 == "HMA"
    htf_ma_01  := ta.hma(src_01, len_01)
// Calculate Timeframe Based Moving Average
output_01   = request.security(syminfo.tickerid, res_01, htf_ma_01[2], lookahead = barmerge.lookahead_on)
plot_01     = display_01 ? display.all : display.none
plot(output_01, "Moving Average #1", color = color_01, display = plot_01)


group_02 = "🟢 Moving Average #2"
// Assigning Inputs
var float htf_ma_02     = na
string    res_02        = input.timeframe("",   "Timeframe",                      group = group_02)
string    avg_type_02   = input.string("EMA",   "Average Type",                   group = group_02 , options = ["SMA", "EMA", "WMA", "VWMA", "HMA"])
int       len_02        = input.int(10,         "Length",                         group = group_02)
float     src_02        = input.source(close,   "Price Source",                   group = group_02)
int       offset_02     = input.int(0,          "Offset",                         group = group_02)
int       width_02      = input.int(1,          "Line Width",                     group = group_02)
color     color_02      = input.color(color.rgb(255, 145, 0), "Color",          group = group_02)
// Defining Moving Average Calculations Based on User Selection
if avg_type_02 == "SMA"
    htf_ma_02  := ta.sma(src_02, len_02)
if avg_type_02 == "EMA"
    htf_ma_02  := ta.ema(src_02, len_02)
if avg_type_02 == "WMA"
    htf_ma_02  := ta.wma(src_02, len_02)
if avg_type_02 == "VWMA"
    htf_ma_02  := ta.vwma(src_02, len_02)
if avg_type_02 == "HMA"
    htf_ma_02  := ta.hma(src_02, len_02)
// Calculate Timeframe Based Moving Average
output_02   = request.security(syminfo.tickerid, res_02, htf_ma_02[2], lookahead = barmerge.lookahead_on)
plot_02     = display_02 ? display.all : display.none
plot(output_02, "Moving Average #2", color = color_02, display = plot_02)


group_03 = "🟢 Moving Average #3"
// Assigning Inputs
var float htf_ma_03     = na
string    res_03        = input.timeframe("",   "Timeframe",                      group = group_03)
string    avg_type_03   = input.string("EMA",   "Average Type",                   group = group_03 , options = ["SMA", "EMA", "WMA", "VWMA", "HMA"])
int       len_03        = input.int(20,         "Length",                         group = group_03)
float     src_03        = input.source(close,   "Price Source",                   group = group_03)
int       offset_03     = input.int(0,          "Offset",                         group = group_03)
int       width_03      = input.int(1,          "Line Width",                     group = group_03)
color     color_03      = input.color(color.rgb(256, 256, 256), "Color",        group = group_03)
// Defining Moving Average Calculations Based on User Selection
if avg_type_03 == "SMA"
    htf_ma_03  := ta.sma(src_03, len_03)
if avg_type_03 == "EMA"
    htf_ma_03  := ta.ema(src_03, len_03)
if avg_type_03 == "WMA"
    htf_ma_03  := ta.wma(src_03, len_03)
if avg_type_03 == "VWMA"
    htf_ma_03  := ta.vwma(src_03, len_03)
if avg_type_03 == "HMA"
    htf_ma_03  := ta.hma(src_03, len_03)
// Calculate Timeframe Based Moving Average
output_03   = request.security(syminfo.tickerid, res_03, htf_ma_03[2], lookahead = barmerge.lookahead_on)
plot_03     = display_03 ? display.all : display.none
plot(output_03, "Moving Average #3", color = color_03, display = plot_03)


group_04 = "🟢 Moving Average #4"
// Assigning Inputs
var float htf_ma_04     = na
string    res_04        = input.timeframe("",   "Timeframe",                      group = group_04)
string    avg_type_04   = input.string("EMA",   "Average Type",                   group = group_04 , options = ["SMA", "EMA", "WMA", "VWMA", "HMA"])
int       len_04        = input.int(50,         "Length",                         group = group_04)
float     src_04        = input.source(close,   "Price Source",                   group = group_04)
int       offset_04     = input.int(0,          "Offset",                         group = group_04)
int       width_04      = input.int(1,          "Line Width",                     group = group_04)
color     color_04      = input.color(color.rgb(256, 0, 0), "Color",            group = group_04)
// Defining Moving Average Calculations Based on User Selection
if avg_type_04 == "SMA"
    htf_ma_04  := ta.sma(src_04, len_04)
if avg_type_04 == "EMA"
    htf_ma_04  := ta.ema(src_04, len_04)
if avg_type_04 == "WMA"
    htf_ma_04  := ta.wma(src_04, len_04)
if avg_type_04 == "VWMA"
    htf_ma_04  := ta.vwma(src_04, len_04)
if avg_type_04 == "HMA"
    htf_ma_04  := ta.hma(src_04, len_04)
// Calculate Timeframe Based Moving Average
output_04   = request.security(syminfo.tickerid, res_04, htf_ma_04[2], lookahead = barmerge.lookahead_on)
plot_04     = display_04 ? display.all : display.none
plot(output_04, "Moving Average #4", color = color_04, display = plot_04)


group_05 = "🟢 Moving Average #5"
// Assigning Inputs
var float htf_ma_05     = na
string    res_05        = input.timeframe("",   "Timeframe",                      group = group_05)
string    avg_type_05   = input.string("EMA",   "Average Type",                   group = group_05 , options = ["SMA", "EMA", "WMA", "VWMA", "HMA"])
int       len_05        = input.int(100,        "Length",                         group = group_05)
float     src_05        = input.source(close,   "Price Source",                   group = group_05)
int       offset_05     = input.int(0,          "Offset",                         group = group_05)
int       width_05      = input.int(1,          "Line Width",                     group = group_05)
color     color_05      = input.color(color.rgb(161, 1, 167), "Color",          group = group_05)
// Defining Moving Average Calculations Based on User Selection
if avg_type_05 == "SMA"
    htf_ma_05  := ta.sma(src_05, len_05)
if avg_type_05 == "EMA"
    htf_ma_05  := ta.ema(src_05, len_05)
if avg_type_05 == "WMA"
    htf_ma_05  := ta.wma(src_05, len_05)
if avg_type_05 == "VWMA"
    htf_ma_05  := ta.vwma(src_05, len_05)
if avg_type_05 == "HMA"
    htf_ma_05  := ta.hma(src_05, len_05)
// Calculate Timeframe Based Moving Average
output_05   = request.security(syminfo.tickerid, res_05, htf_ma_05[2], lookahead = barmerge.lookahead_on)
plot_05     = display_05 ? display.all : display.none
plot(output_05, "Moving Average #5", color = color_05, display = plot_05)


group_06 = "🟢 Moving Average #6"
// Assigning Inputs
var float htf_ma_06     = na
string    res_06        = input.timeframe("",   "Timeframe",                      group = group_06)
string    avg_type_06   = input.string("EMA",   "Average Type",                   group = group_06 , options = ["SMA", "EMA", "WMA", "VWMA", "HMA"])
int       len_06        = input.int(200,        "Length",                         group = group_06)
float     src_06        = input.source(close,   "Price Source",                   group = group_06)
int       offset_06     = input.int(0,          "Offset",                         group = group_06)
int       width_06      = input.int(1,          "Line Width",                     group = group_06)
color     color_06      = input.color(color.rgb(232, 56, 147), "Color",         group = group_06)
// Defining Moving Average Calculations Based on User Selection
if avg_type_06 == "SMA"
    htf_ma_06  := ta.sma(src_06, len_06)
if avg_type_06 == "EMA"
    htf_ma_06  := ta.ema(src_06, len_06)
if avg_type_06 == "WMA"
    htf_ma_06  := ta.wma(src_06, len_06)
if avg_type_06 == "VWMA"
    htf_ma_06  := ta.vwma(src_06, len_06)
if avg_type_06 == "HMA"
    htf_ma_06  := ta.hma(src_06, len_06)
// Calculate Timeframe Based Moving Average
output_06   = request.security(syminfo.tickerid, res_06, htf_ma_06[2], lookahead = barmerge.lookahead_on)
plot_06     = display_06 ? display.all : display.none
plot(output_06, "Moving Average #6", color = color_06, display = plot_06)



group_bb = "🟢 Bollinger Band Settings"
var float htf_ma_bb      = na
string    res_bb         = input.timeframe("",   "Timeframe",                      group = group_bb)
string    avg_type_bb    = input.string("SMA",   "Basis MA Type",                  group = group_bb, options = ["SMA", "EMA", "WMA", "VWMA", "HMA", "SMMA (RMA)"])
int       len_bb         = input.int(20,         "Basis MA Length",                group = group_bb)
float     src_bb         = input.source(close,   "Basis MA Source",                group = group_bb)
float     mult_bb        = input.float(2.0,      "Bands Standard Deviation",       group = group_bb, minval=0.001, maxval=50)
int       width_basis_bb = input.int(1,          "Basis Line Width",               group = group_bb)
color     color_basis_bb = input.color(color.rgb(125, 125, 125), "Basis Color",  group = group_bb)
int       width_stdev_bb = input.int(1,          "Bands Line Width",               group = group_bb)
color     color_stdev_bb = input.color(color.rgb(0, 0, 256),     "Bands Color",  group = group_bb)
color     color_fill_bb  = input.color(color.rgb(0, 0, 256, 95), "Fill Color",   group = group_bb)

// Defining Moving Average Calculations Based on User Selection
if avg_type_bb == "SMA"
    htf_ma_bb  := ta.sma(src_bb, len_bb)
if avg_type_bb == "EMA"
    htf_ma_bb  := ta.ema(src_bb, len_bb)
if avg_type_bb == "WMA"
    htf_ma_bb  := ta.wma(src_bb, len_bb)
if avg_type_bb == "VWMA"
    htf_ma_bb  := ta.vwma(src_bb, len_bb)
if avg_type_bb == "HMA"
    htf_ma_bb  := ta.hma(src_bb, len_bb)
if avg_type_bb == "SMMA (RMA)"
    htf_ma_bb  := ta.rma(src_bb, len_bb)

deviation = ta.stdev(src_bb, len_bb)
basis     = request.security(syminfo.tickerid, res_bb, htf_ma_bb, lookahead = barmerge.lookahead_on)
dev       = request.security(syminfo.tickerid, res_bb, deviation, lookahead = barmerge.lookahead_on)
upper     = basis + mult_bb * dev
lower     = basis - mult_bb * dev
plot_bb   = display_bb ? display.all : display.none
p1 = plot(upper,     "Upper",      color = color_stdev_bb, display = plot_bb)
plot(basis,          "Basis",      color = color_basis_bb, display = plot_bb)
p2 = plot(lower,     "Lower",      color = color_stdev_bb, display = plot_bb)
fill(p1, p2, title = "Background", color = color_fill_bb,  display = plot_bb)



// Begin - ATR Stop
group_ATR   = "🟢 ATR Trailing Stop Settings"
// Begin - ATR Stop
var float atr_trailing_stop = na
var float pos               = na
var bool  atr_entry_signal  = false
atr_tooltip          = "ATR Trailing Stop indicator is specific to timeframe and ticker.  Must set parameters to specific ticker and timeframe."
atr_period_bull      = input.int(6,     "Bull Trend - ATR Period",       minval = 1, step = 1,   group = group_ATR, tooltip = atr_tooltip)
atr_multi_bull       = input.float(2,   "Bull Trend - ATR Multiplier",   minval = 0, step = 0.1, group = group_ATR, tooltip = atr_tooltip)
color_bull_atr       = input.color(color.rgb(0, 256, 0), "ATR Trail Stop Color",               group = group_ATR)
atr_period_bear      = input.int(17,    "Bear Trend - ATR Period",       minval = 1, step = 1,   group = group_ATR, tooltip = atr_tooltip)
atr_multi_bear       = input.float(2.7, "Bear Trend - ATR Multiplier",   minval = 0, step = 0.1, group = group_ATR, tooltip = atr_tooltip)
color_bear_atr       = input.color(color.rgb(256, 0, 0), "ATR Trail Stop Color",               group = group_ATR)
atr_bull             = ta.atr(atr_period_bull)
loss_bull            = atr_multi_bull * atr_bull
atr_bear             = ta.atr(atr_period_bear)
loss_bear            = atr_multi_bear * atr_bear
atr_trailing_stop   := close > nz(atr_trailing_stop[1], 0) and close[1] > nz(atr_trailing_stop[1], 0) ? math.max(nz(atr_trailing_stop[1]), close - loss_bull) : close < nz(atr_trailing_stop[1], 0) and close[1] < nz(atr_trailing_stop[1], 0) ? math.min(nz(atr_trailing_stop[1]), close + loss_bear) : close > nz(atr_trailing_stop[1], 0) ? close - loss_bull : close + loss_bear
pos                 := close[1] < nz(atr_trailing_stop[1], 0) and close > nz(atr_trailing_stop[1], 0) ? 1 : close[1] > nz(atr_trailing_stop[1], 0) and close < nz(atr_trailing_stop[1], 0) ? -1 : nz(pos[1], 0)
color_atr            = pos > 0 ? color_bull_atr : color_bear_atr
plot_atr             = display_atr ? display.all : display.none
plot(display_atr ? atr_trailing_stop : na, color = color_atr, title="ATR Trailing Stop", display = plot_atr)



// Position 
group_tbl_01 = "🟢 MTF RSI & Z-Score Settings"
tablePos = input.string("Bottom Right", "Location", 
             ["Top Right" , "Middle Right"  , "Bottom Right" , 
              "Top Center", "Middle Center" , "Bottom Center", 
              "Top Left"  , "Middle Left"   , "Bottom Left" ],      group = group_tbl_01, inline = "1")
    
// Size
tableSiz = input.string("Small", " Size", 
             ["Auto",  "Huge",  "Large", "Normal", "Small", "Tiny"], group = group_tbl_01, inline = "1")

//tabColr = input.color(color.new(color.white, 50), "",  group = "Table Location & Size", inline = "1")
tabColr = color.new(color.white, 50)

//  RSI in Different Timeframes
d_rsi_1  = input.bool(true,    "Display RSI 1",    group = "RSI 1 Settings")
rsiSrc1  = input.source(close, "RSI 1 Source",     group = "RSI 1 Settings")
rsiLen1  = input.int(2,        "RSI 1 Length", 1,  group = "RSI 1 Settings")
rsi_os_1 = input.int(5,        "Oversold Level",   group = "RSI 1 Settings")
rsi_ob_1 = input.int(95,       "Overbought Level", group = "RSI 1 Settings")
d_rsi_2  = input.bool(false,   "Display RSI 2",    group = "RSI 2 Settings")
rsiSrc2  = input.source(close, "RSI 2 Source",     group = "RSI 2 Settings")
rsiLen2  = input.int(3,        "RSI 2 Length", 1,  group = "RSI 2 Settings")
rsi_os_2 = input.int(5,        "Oversold Level",   group = "RSI 2 Settings")
rsi_ob_2 = input.int(95,       "Overbought Level", group = "RSI 2 Settings")
d_rsi_3  = input.bool(true,    "Display RSI 3",    group = "RSI 3 Settings")
rsiSrc3  = input.source(close, "RSI 3 Source",     group = "RSI 3 Settings")
rsiLen3  = input.int(14,       "RSI 3 Length", 1,  group = "RSI 3 Settings")
rsi_os_3 = input.int(30,       "Oversold Level",   group = "RSI 3 Settings")
rsi_ob_3 = input.int(70,       "Overbought Level", group = "RSI 3 Settings")

d_z_1    = input.bool(true,    "Display Z-Score 1",    group = "Z-Score 1 Settings")
zLen1    = input.int(20,       "Z-Score 1 Length", 1,  group = "Z-Score 1 Settings")
zSrc1    = input.source(close, "Z-Score 1 Source",     group = "Z-Score 1 Settings")
z_os_1   = input.float(-2.0,   "Oversold Level",       group = "Z-Score 1 Settings")
z_ob_1   = input.float(2.0,    "Overbought Level",     group = "Z-Score 1 Settings")
d_z_2    = input.bool(true,    "Display Z-Score 2",    group = "Z-Score 2 Settings")
zLen2    = input.int(100,      "Z-Score 2 Length", 1,  group = "Z-Score 2 Settings")
zSrc2    = input.source(close, "Z-Score 2 Source",     group = "Z-Score 2 Settings")
z_os_2   = input.float(-2.0,   "Oversold Level",       group = "Z-Score 2 Settings")
z_ob_2   = input.float(2.0,    "Overbought Level",     group = "Z-Score 2 Settings")
d_z_3    = input.bool(true,    "Display Z-Score 3",    group = "Z-Score 3 Settings")
zLen3    = input.int(200,      "Z-Score 3 Length", 1,  group = "Z-Score 3 Settings")
zSrc3    = input.source(close, "Z-Score 3 Source",     group = "Z-Score 3 Settings")
z_os_3   = input.float(-2.0,   "Oversold Level",       group = "Z-Score 3 Settings")
z_ob_3   = input.float(2.0,    "Overbought Level",     group = "Z-Score 3 Settings")

// Timeframes
flg01 = input.bool(true, "TF[01]",  inline = "01")
tim01 = input.timeframe("5", "",    inline = "01")

flg02 = input.bool(true, "TF[02]",  inline = "02")
tim02 = input.timeframe("30", "",    inline = "02")

flg03 = input.bool(true, "TF[03]",  inline = "03")
tim03 = input.timeframe("60", "",   inline = "03")

flg04 = input.bool(true, "TF[04]",  inline = "04")
tim04 = input.timeframe("240", "",   inline = "04")

flg05 = input.bool(true, "TF[05]",  inline = "05")
tim05 = input.timeframe("1D", "",  inline = "05")

flg06 = input.bool(true, "TF[06]",  inline = "06")
tim06 = input.timeframe("1W", "",   inline = "06")

flg07 = input.bool(true, "TF[07]", inline = "07")
tim07 = input.timeframe("1M", "",   inline = "07")

// Complete Calculations
symbol = ticker.modify(syminfo.tickerid, syminfo.session)
// RSI & MA
timArr  = array.new<string>(na)
rsi1Arr = array.new<float>(na)
rsi2Arr = array.new<float>(na)
rsi3Arr = array.new<float>(na)
z1Arr   = array.new<float>(na)
z2Arr   = array.new<float>(na)
z3Arr   = array.new<float>(na)

// Functions
zscore(source, length) =>
	mean  = ta.sma(source,length)
	stdev = ta.stdev(source,length)
	z     = (source - mean) / stdev

// RSI & MA Function
rsiNmaFun(tf, flg) =>
    [rsi1, rsi2, rsi3, z1, z2, z3] =  request.security(symbol, tf, [ta.rsi(rsiSrc1, rsiLen1), ta.rsi(rsiSrc2, rsiLen2), ta.rsi(rsiSrc3, rsiLen3), zscore(zSrc1, zLen1), zscore(zSrc2, zLen2), zscore(zSrc3, zLen3)])

    if flg and (barstate.isrealtime ? true : timeframe.in_seconds(timeframe.period) <= timeframe.in_seconds(tf))
        array.push(timArr,  na(tf) ? timeframe.period : tf)
        array.push(rsi1Arr,                           rsi1)
        array.push(rsi2Arr,                           rsi2)
        array.push(rsi3Arr,                           rsi3)
        array.push(z1Arr ,                              z1)
        array.push(z2Arr ,                              z2)
        array.push(z3Arr ,                              z3)

rsiNmaFun(tim01, flg01), rsiNmaFun(tim02, flg02), rsiNmaFun(tim03, flg03), rsiNmaFun(tim04, flg04), 
rsiNmaFun(tim05, flg05), rsiNmaFun(tim06, flg06), rsiNmaFun(tim07, flg07) 

// Build The Table
// Get Table Location & Size
locNsze(x) => 
    y   = str.split(str.lower(x), " ")
    out = ""
    for i = 0 to array.size(y) - 1
        out := out + array.get(y, i)
        if i != array.size(y) - 1
            out := out + "_"
    out

// Define Table
var tbl = table.new(locNsze(tablePos), 9, 10,
      frame_width  = 3, frame_color  = tabColr, 
      border_width = 1, border_color = tabColr)

// Cell Function
cell(col, row, txt, color, x, y, z) =>    
    th = z == -1 ? text.align_left : z == 1 ? text.align_right : text.align_center
    table.cell(tbl, col, row, txt, text_color = color.new(color, x), text_halign  = th, 
     bgcolor = color.new(color, y), text_size = locNsze(tableSiz))

// Post Timeframe in format 
tfTxt(x)=>
    out = x
    if not str.contains(x, "S") and not str.contains(x, "M") and 
       not str.contains(x, "W") and not str.contains(x, "D")
        if str.tonumber(x)%60 == 0
            out := str.tostring(str.tonumber(x)/60)+"H"
        else 
            out := x + "m"
    out

// Coloring Cell Function 
cellColor(x, o_b, o_s) =>
    BL3	= o_b                                                      //BULL Red
    BL2	= (o_b + o_s) * 0.5 + (o_b - (o_b + o_s) * 0.5) * 0.9      //BULL Orange to Red
    BL1	= (o_b + o_s) * 0.5 + (o_b - (o_b + o_s) * 0.5) * 0.85     //BULL Green to Orange
    NL0	= (o_b + o_s) * 0.5                                        //NEUTRAL
    BR1	= (o_b + o_s) * 0.5 - (o_b - (o_b + o_s) * 0.5) * 0.85     //BEAR Red to Orange
    BR2	= (o_b + o_s) * 0.5 - (o_b - (o_b + o_s) * 0.5) * 0.9      //BEAR Orange to Green
    BR3	= o_s                                                      //BEAR Green

    x >= BL3 ? color.red :
     x <= BL3 and x >= BL2 ? color.from_gradient(x, BL2, BL3, color.orange, color.red   ) :
     x <= BL2 and x >= BL1 ? color.from_gradient(x, BL1, BL2, color.green,  color.orange) :
     x <= BL1 and x >= NL0 ? color.from_gradient(x, NL0, BL1, color.white,  color.green ) :
     x <= BR3 ? color.green :
     x >= BR3 and x <= BR2 ? color.from_gradient(x, BR3, BR2, color.green,  color.orange) :
     x >= BR2 and x <= BR1 ? color.from_gradient(x, BR2, BR1, color.orange, color.red   ) :
     x >= BR1 and x <= NL0 ? color.from_gradient(x, BR1, NL0, color.red,    color.white ) :
     color.white

if barstate.islast and display_tbl
    table.clear(tbl, 0, 0, 8, 9)
    // Build Table
    // Table Header
    cell(0, 0, "TF", color.white, 10, 70, 0)
    if d_rsi_1
        cell(1, 0, "RSI(" + str.tostring(rsiLen1) +")", color.white, 10, 70, 0)
    if d_rsi_2
        cell(2, 0, "RSI(" + str.tostring(rsiLen2) +")", color.white, 10, 70, 0)
    if d_rsi_3
        cell(3, 0, "RSI(" + str.tostring(rsiLen3) +")", color.white, 10, 70, 0)
    if d_z_1
        cell(4, 0, "Z("+ str.tostring(zLen1) + ")", color.white, 10, 70, 0)
    if d_z_2
        cell(5, 0, "Z("+ str.tostring(zLen2) + ")", color.white, 10, 70, 0)
    if d_z_3
        cell(6, 0, "Z("+ str.tostring(zLen3) + ")", color.white, 10, 70, 0)

    // Create Info Table Cells
    j = 1
    if array.size(rsi1Arr) > 0
        for i = 0 to array.size(rsi1Arr) - 1
            if not na(array.get(rsi1Arr, i))
                cell(0, j, tfTxt(array.get(timArr, i)), color.white, 0, 70,  0)
                if d_rsi_1
                    cell(1, j, str.tostring(array.get(rsi1Arr, i), "#.##") + (array.get(rsi1Arr, i) >= 50 ? " ▲" : array.get(rsi1Arr, i) < 50 ? " ▼" : ""), cellColor(array.get(rsi1Arr, i), rsi_ob_1, rsi_os_1),  0, 60, 1)
                if d_rsi_2
                    cell(2, j, str.tostring(array.get(rsi2Arr, i), "#.##") + (array.get(rsi2Arr, i) >= 50 ? " ▲" : array.get(rsi2Arr, i) < 50 ? " ▼" : ""), cellColor(array.get(rsi2Arr, i), rsi_ob_2, rsi_os_2),  0, 60, 1)
                if d_rsi_3
                    cell(3, j, str.tostring(array.get(rsi3Arr, i), "#.##") + (array.get(rsi3Arr, i) >= 50 ? " ▲" : array.get(rsi3Arr, i) < 50 ? " ▼" : ""), cellColor(array.get(rsi3Arr, i), rsi_ob_3, rsi_os_3),  0, 60, 1)
                if d_z_1
                    cell(4, j, str.tostring(array.get(z1Arr, i), "#.##") + (array.get(z1Arr, i) > 0 ? " ▲" : array.get(z1Arr, i) < 0 ? " ▼" : ""), cellColor(array.get(z1Arr, i), z_ob_1, z_os_1), 0, 60, na(array.get(z1Arr, i)) ? 0 : 1)
                if d_z_2
                    cell(5, j, str.tostring(array.get(z2Arr, i), "#.##") + (array.get(z2Arr, i) > 0 ? " ▲" : array.get(z2Arr, i) < 0 ? " ▼" : ""), cellColor(array.get(z2Arr, i), z_ob_2, z_os_2), 0, 60, na(array.get(z2Arr, i)) ? 0 : 1)
                if d_z_3
                    cell(6, j, str.tostring(array.get(z3Arr, i), "#.##") + (array.get(z3Arr, i) > 0 ? " ▲" : array.get(z3Arr, i) < 0 ? " ▼" : ""), cellColor(array.get(z3Arr, i), z_ob_3, z_os_3), 0, 60, na(array.get(z3Arr, i)) ? 0 : 1)
                j += 1
