Multi-Timeframe Trend Indicator
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Ox_kali
// ________________________________________________________________________________________________________________________________       
                                  
//  ██████╗ ██╗  ██╗        ██╗  ██╗ █████╗ ██╗     ██╗     █████╗ ██╗      ██████╗  ██████╗ ██████╗ ██╗████████╗██╗  ██╗███╗   ███╗
// ██╔═══██╗╚██╗██╔╝        ██║ ██╔╝██╔══██╗██║     ██║    ██╔══██╗██║     ██╔════╝ ██╔═══██╗██╔══██╗██║╚══██╔══╝██║  ██║████╗ ████║
// ██║   ██║ ╚███╔╝         █████╔╝ ███████║██║     ██║    ███████║██║     ██║  ███╗██║   ██║██████╔╝██║   ██║   ███████║██╔████╔██║
// ██║   ██║ ██╔██╗         ██╔═██╗ ██╔══██║██║     ██║    ██╔══██║██║     ██║   ██║██║   ██║██╔══██╗██║   ██║   ██╔══██║██║╚██╔╝██║
// ╚██████╔╝██╔╝ ██╗███████╗██║  ██╗██║  ██║███████╗██║    ██║  ██║███████╗╚██████╔╝╚██████╔╝██║  ██║██║   ██║   ██║  ██║██║ ╚═╝ ██║
//  ╚═════╝ ╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝╚═╝    ╚═╝  ╚═╝╚══════╝ ╚═════╝  ╚═════╝ ╚═╝  ╚═╝╚═╝   ╚═╝   ╚═╝  ╚═╝╚═╝     ╚═╝
// ________________________________________________________________________________________________________________________________       

//@version=5
// Indicator title and short title
// ________________________________________________________________________________________________________________________________                      

indicator("Multi-Timeframe Trend Indicator", shorttitle="MTFTI", overlay=true)

// Table position input
// ________________________________________________________________________________________________________________________________                      

tablePosition = input.string(title="Table Position", defval="bottom_right", options=["top_left", "top_right", "middle_left", "middle_right", "bottom_left", "bottom_right"])

showTf1 = input(true, title="Show 5min")
showTf2 = input(true, title="Show 15min")
showTf3 = input(true, title="Show 30min")
showTf4 = input(true, title="Show 1H")
showTf5 = input(true, title="Show 2H")
showTf6 = input(true, title="Show 4H")
showTf7 = input(true, title="Show 6H")
showTf8 = input(true, title="Show 12H")
showTf9 = input(true, title="Show 1 Day")
showTf10 = input(true, title="Show 1 week")
showTf11 = input(true, title="Show AVG")

// Function to convert user input to position type
// ________________________________________________________________________________________________________________________________                      

get_position(value) =>
    pos = position.middle_right
    if value == "top_left"
        pos := position.top_left
    else if value == "top_right"
        pos := position.top_right
    else if value == "middle_left"
        pos := position.middle_left
    else if value == "middle_right"
        pos := position.middle_right
    else if value == "bottom_left"
        pos := position.bottom_left
    else if value == "bottom_right"
        pos := position.bottom_right
    pos

// Input for timeframes
// ________________________________________________________________________________________________________________________________                      

tf1 = "5"
tf2 = "15"
tf3 = "30"
tf4 = "60"
tf5 = "120"
tf6 = "240"
tf7 = "360"
tf8 = "720"
tf9 = "1440"
tf10 = "1W"

// Input for EMA lengths
// ________________________________________________________________________________________________________________________________                      

shortTerm = input(50, title="Short Term EMA Length")
longTerm = input(200, title="Long Term EMA Length")
showShortTerm = input(true, title="Show Short Term EMA")
showLongTerm = input(true, title="Show Long Term EMA")

emaShort = ta.ema(close, shortTerm)
emaLong = ta.ema(close, longTerm)

// Trend calculation function
// ________________________________________________________________________________________________________________________________                      

trendCalc(timeframe) =>
    emaShort = request.security(syminfo.tickerid, timeframe, ta.ema(close, shortTerm))
    emaLong = request.security(syminfo.tickerid, timeframe, ta.ema(close, longTerm))
    trend = emaShort > emaLong ? 1 : -1
    trend

// Calculate trends for each timeframe
// ________________________________________________________________________________________________________________________________                      

trend1 = trendCalc(tf1)
trend2 = trendCalc(tf2)
trend3 = trendCalc(tf3)
trend4 = trendCalc(tf4)
trend5 = trendCalc(tf5)
trend6 = trendCalc(tf6)
trend7 = trendCalc(tf7)
trend8 = trendCalc(tf8)
trend9 = trendCalc(tf9)
trend10 = trendCalc(tf10)

// Initialize trendSum and activeTfs
// ________________________________________________________________________________________________________________________________                      

trendSum = 0.0
activeTfs = 0

if showTf1
    trendSum := trendSum + trend1
    activeTfs := activeTfs + 1

if showTf2
    trendSum := trendSum + trend2
    activeTfs := activeTfs + 1

if showTf3
    trendSum := trendSum + trend3
    activeTfs := activeTfs + 1

if showTf4
    trendSum := trendSum + trend4
    activeTfs := activeTfs + 1

if showTf5
    trendSum := trendSum + trend5
    activeTfs := activeTfs + 1

if showTf6
    trendSum := trendSum + trend6
    activeTfs := activeTfs + 1

if showTf7
    trendSum := trendSum + trend7
    activeTfs := activeTfs + 1

if showTf8
    trendSum := trendSum + trend8
    activeTfs := activeTfs + 1

if showTf9
    trendSum := trendSum + trend9
    activeTfs := activeTfs + 1

if showTf10
    trendSum := trendSum + trend10
    activeTfs := activeTfs + 1

// Calculate average trend if activeTfs is not zero to avoid division by zero
// ________________________________________________________________________________________________________________________________ 

trendAvg = activeTfs != 0 ? trendSum / activeTfs : na
                    

trendAvgText = ""
trendAvgBgcolor = color.silver
if trendAvg <= -0.8
    trendAvgText := "Strong Down"
    trendAvgBgcolor := color.rgb(172, 1, 1)
else if trendAvg <= -0.2
    trendAvgText := "Down"
    trendAvgBgcolor := color.red
else if trendAvg >= 0.8
    trendAvgText := "Strong Up"
    trendAvgBgcolor := color.rgb(1, 128, 5)
else if trendAvg >= 0.2
    trendAvgText := "Up"
    trendAvgBgcolor := color.green
else
    trendAvgText := "Neutral"
    trendAvgBgcolor := color.rgb(170, 169, 169)

trendTable = table.new(position=get_position(tablePosition), columns=2, rows=12, frame_color=color.white, bgcolor=color.black)

// Add header cell with left alignment
// ________________________________________________________________________________________________________________________________                      

table.cell(trendTable, column=0, row=0, text="Trend", bgcolor=color.black, text_color=color.white)
table.cell(trendTable, column=1, row=0, text="TF", bgcolor=color.black, text_color=color.white)

// Fill table cells
// ________________________________________________________________________________________________________________________________                      

if showTf1
    table.cell(trendTable, column=1, row=1, text="5", bgcolor=color.rgb(0, 0, 0, 70), text_color=color.white)
    table.cell(trendTable, column=0, row=1, text=(trend1 > 0 ? "Up" : "Down"), bgcolor=trend1 > 0 ? color.green : color.red)

if showTf2
    table.cell(trendTable, column=1, row=2, text="15", bgcolor=color.rgb(0, 0, 0, 70), text_color=color.white)
    table.cell(trendTable, column=0, row=2, text=(trend2 > 0 ? "Up" : "Down"), bgcolor=trend2 > 0 ? color.green : color.red)

if showTf3
    table.cell(trendTable, column=1, row=3, text="30", bgcolor=color.rgb(0, 0, 0, 70), text_color=color.white)
    table.cell(trendTable, column=0, row=3, text=(trend3 > 0 ? "Up" : "Down"), bgcolor=trend3 > 0 ? color.green : color.red)

if showTf4
    table.cell(trendTable, column=1, row=4, text="1H", bgcolor=color.rgb(0, 0, 0, 70), text_color=color.white)
    table.cell(trendTable, column=0, row=4, text=(trend4 > 0 ? "Up" : "Down"), bgcolor=trend4 > 0 ? color.green : color.red)

if showTf5
    table.cell(trendTable, column=1, row=5, text="2H", bgcolor=color.rgb(0, 0, 0, 70), text_color=color.white)
    table.cell(trendTable, column=0, row=5, text=(trend5 > 0 ? "Up" : "Down"), bgcolor=trend5 > 0 ? color.green : color.red)

if showTf6
    table.cell(trendTable, column=1, row=6, text="4H", bgcolor=color.rgb(0, 0, 0, 70), text_color=color.white)
    table.cell(trendTable, column=0, row=6, text=(trend6 > 0 ? "Up" : "Down"), bgcolor=trend6 > 0 ? color.green : color.red)

if showTf7
    table.cell(trendTable, column=1, row=7, text="6H", bgcolor=color.rgb(0, 0, 0, 70), text_color=color.white)
    table.cell(trendTable, column=0, row=7, text=(trend7 > 0 ? "Up" : "Down"), bgcolor=trend7 > 0 ? color.green : color.red)

if showTf8
    table.cell(trendTable, column=1, row=8, text="12H", bgcolor=color.rgb(0, 0, 0, 70), text_color=color.white)
    table.cell(trendTable, column=0, row=8, text=(trend8 > 0 ? "Up" : "Down"), bgcolor=trend8 > 0 ? color.green : color.red)

if showTf9
    table.cell(trendTable, column=1, row=9, text="1D", bgcolor=color.rgb(0, 0, 0, 70), text_color=color.white)
    table.cell(trendTable, column=0, row=9, text=(trend9 > 0 ? "Up" : "Down"), bgcolor=trend9 > 0 ? color.green : color.red)

if showTf10
    table.cell(trendTable, column=1, row=10, text="1W", bgcolor=color.rgb(0, 0, 0, 70), text_color=color.white)
    table.cell(trendTable, column=0, row=10, text=(trend10 > 0 ? "Up" : "Down"), bgcolor=trend10 > 0 ? color.green : color.red)

if showTf11
    table.cell(trendTable, column=1, row=11, text="AVG", bgcolor=color.rgb(0, 0, 0, 70), text_color=color.white)
    table.cell(trendTable, column=0, row=11, text=(trendAvgText), bgcolor=trendAvgBgcolor)

// Plot table and ema
// ________________________________________________________________________________________________________________________________                      

plot(showShortTerm ? emaShort : na, title="Short Term EMA", color=color.blue, linewidth=2)
plot(showLongTerm ? emaLong : na, title="Long Term EMA", color=color.orange, linewidth=2)
