EMA Levels, Multi-Timeframe
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © jmosullivan

// The exponential moving average (EMA) tracks price over time, giving more importance to recent price data than simple 
// moving average (SMA). MAs for larger timeframes are generally considered to be stronger supports/resistances for 
// price to move through than smaller timeframes. This indicator allows you to specify two different MA lengths that 
// you want to track. Additionally, this indicator allows you to display not just the EMA levels of your currently 
// viewed timeframe on the chart, but also shows the MA levels of up to 4 different timeframes on the same chart. This 
// allows you to quickly see if multiple MA levels are aligning across different timeframes, which is an even stronger 
// indication that price is going to meet support or resistance when it meets those levels on the chart. There are a lot 
// of nice configuration options, like:
// 
// * Ability to choose Exponential MA or Simple MA
// * Ability to customize the MA lengths you want to track
// * Style customization (color, thickness, size)
// * Hide any timeframes/levels you aren't interested in
// * Labels on the chart so you can tell which plots are the EMA levels
// * Optionally display the plot as a horizontal line if all you care about is the EMA level right now

//@version=5
indicator("MA Lvls MTF", overlay = true)

// Functions
tf_tostring(tf) =>
    string rtf = switch tf
    	"1" => "1m"
    	"2" => "2m"
    	"3" => "3m"
    	"5" => "5m"
    	"13" => "13m"
    	"15" => "15m"
    	"30" => "30m"
    	"45" => "45m"
    	"60" => "1h"
    	"120" => "2h"
    	"180" => "3h"
    	"240" => "4h"
    	"360" => "6h"
    	"480" => "8h"
    	"720" => "12h"
    	"D" => "1D"
    	"W" => "1W"
    	"M" => "1M"
    	=> tf // default
    rtf

tf_str(tf, suffix, type) =>
    ma_str = type == "Simple MA" ? "sma" : "ema"
    tf_tostring(tf) + " " + str.tostring(suffix) + " " + ma_str

do_label(do_lbl, ix_loc, src, txt, txtsize, clr) =>
    if (do_lbl)
        var label lbl = na
        label.delete(lbl)
        lbl := label.new(x=ix_loc, y=src, text=txt, style=label.style_none, textcolor=clr, size=txtsize, textalign=text.align_left)

// Define some inputs to control style & visbility
grp_mn = "MA Settings"
ma_type             = input.string  (group=grp_mn, defval="Exponential MA", title="MA Type", options=["Simple MA", "Exponential MA"])
show_labels         = input.bool    (group=grp_mn, defval=true,  title="Show Labels")
lbl_txtsize         = input.string  (group=grp_mn, defval=size.normal, title="Label Text Size", options=[size.auto, size.tiny, size.small, size.normal, size.large, size.huge])
lbl_offset          = input.int     (group=grp_mn, defval=4,     title="Label Offset",         minval=0, maxval=100)
lbl_stagger_offset  = input.int     (group=grp_mn, defval=0,     title="Label Offset Stagger", minval=0, maxval=20)
do_line             = input.bool    (group=grp_mn, defval=false, title="Do Horizontal Lines")
linewidth           = input.int     (group=grp_mn, defval=1,     title="Line Weight",          options=[1,2,3,4])
def_label_offset = 4
transparency = 50
ma1 = "MA1"
ma2 = "MA2"

grp_emas = "MA Lengths"
ma1length = input.int(group=grp_emas, defval=12, title="MA1", inline="malength")
ma2length = input.int(group=grp_emas, defval=26, title="MA2", inline="malength")

grp_tfs = "Timeframe Settings"
il_1 = "inline_1"
def_clr_1 = color.new(color.aqua, transparency)
tf_1         = input.timeframe  (group=grp_tfs, inline=il_1, defval="60",      title="")
color_ma1_1  = input.color      (group=grp_tfs, inline=il_1, defval=def_clr_1, title="")
show_ma1_1   = input.bool       (group=grp_tfs, inline=il_1, defval=true,      title=ma1)
color_ma2_1  = input.color      (group=grp_tfs, inline=il_1, defval=def_clr_1, title="")
show_ma2_1   = input.bool       (group=grp_tfs, inline=il_1, defval=true,      title=ma2)

il_2 = "inline_2"
def_clr_2 = color.new(color.blue, transparency)
tf_2          = input.timeframe (group=grp_tfs, inline=il_2, defval="240",     title="")
color_ma1_2   = input.color     (group=grp_tfs, inline=il_2, defval=def_clr_2, title="")
show_ma1_2    = input.bool      (group=grp_tfs, inline=il_2, defval=true,      title=ma1)
color_ma2_2   = input.color     (group=grp_tfs, inline=il_2, defval=def_clr_2, title="")
show_ma2_2    = input.bool      (group=grp_tfs, inline=il_2, defval=true,      title=ma2)

il_3 = "inline_3"
def_clr_3 = color.new(color.orange, transparency)
tf_3          = input.timeframe (group=grp_tfs, inline=il_3, defval="720",     title="")
color_ma1_3   = input.color     (group=grp_tfs, inline=il_3, defval=def_clr_3, title="")
show_ma1_3    = input.bool      (group=grp_tfs, inline=il_3, defval=true,      title=ma1)
color_ma2_3   = input.color     (group=grp_tfs, inline=il_3, defval=def_clr_3, title="")
show_ma2_3    = input.bool      (group=grp_tfs, inline=il_3, defval=true,      title=ma2)

il_4 = "inline_4"
def_clr_4 = color.new(color.purple, transparency)
tf_4          = input.timeframe (group=grp_tfs, inline=il_4, defval="D",       title="")
color_ma1_4   = input.color     (group=grp_tfs, inline=il_4, defval=def_clr_4, title="")
show_ma1_4    = input.bool      (group=grp_tfs, inline=il_4, defval=true,      title=ma1)
color_ma2_4   = input.color     (group=grp_tfs, inline=il_4, defval=def_clr_4, title="")
show_ma2_4    = input.bool      (group=grp_tfs, inline=il_4, defval=true,      title=ma2)

ta_ma1 = ma_type == "Simple MA" ? ta.sma(close, ma1length) : ta.ema(close, ma1length)
ta_ma2 = ma_type == "Simple MA" ? ta.sma(close, ma2length) : ta.ema(close, ma2length)

// Define the lines to be plotted
ma_1_1 = show_ma1_1 ? request.security(syminfo.tickerid, tf_1, ta_ma1) : na
ma_2_1 = show_ma2_1 ? request.security(syminfo.tickerid, tf_1, ta_ma2) : na
ma_1_2 = show_ma1_2 ? request.security(syminfo.tickerid, tf_2, ta_ma1) : na
ma_2_2 = show_ma2_2 ? request.security(syminfo.tickerid, tf_2, ta_ma2) : na
ma_1_3 = show_ma1_3 ? request.security(syminfo.tickerid, tf_3, ta_ma1) : na
ma_2_3 = show_ma2_3 ? request.security(syminfo.tickerid, tf_3, ta_ma2) : na
ma_1_4 = show_ma1_4 ? request.security(syminfo.tickerid, tf_4, ta_ma1) : na
ma_2_4 = show_ma2_4 ? request.security(syminfo.tickerid, tf_4, ta_ma2) : na

// plot them
plot_offset = do_line ? -9999 : 0
plot(ma_1_1, color=color_ma1_1, title="TF1 MA1", trackprice=do_line, offset=plot_offset, editable=false, style=plot.style_line, linewidth=linewidth)
plot(ma_2_1, color=color_ma2_1, title="TF1 MA2", trackprice=do_line, offset=plot_offset, editable=false, style=plot.style_line, linewidth=linewidth)
plot(ma_1_2, color=color_ma1_2, title="TF2 MA1", trackprice=do_line, offset=plot_offset, editable=false, style=plot.style_line, linewidth=linewidth)
plot(ma_2_2, color=color_ma2_2, title="TF2 MA2", trackprice=do_line, offset=plot_offset, editable=false, style=plot.style_line, linewidth=linewidth)
plot(ma_1_3, color=color_ma1_3, title="TF3 MA1", trackprice=do_line, offset=plot_offset, editable=false, style=plot.style_line, linewidth=linewidth)
plot(ma_2_3, color=color_ma2_3, title="TF3 MA2", trackprice=do_line, offset=plot_offset, editable=false, style=plot.style_line, linewidth=linewidth)
plot(ma_1_4, color=color_ma1_4, title="TF4 MA1", trackprice=do_line, offset=plot_offset, editable=false, style=plot.style_line, linewidth=linewidth)
plot(ma_2_4, color=color_ma2_4, title="TF4 MA2", trackprice=do_line, offset=plot_offset, editable=false, style=plot.style_line, linewidth=linewidth)

if (show_labels)
    offset_ma1_1 = lbl_offset
    offset_ma2_1 = lbl_offset + (lbl_stagger_offset*1)
    offset_ma1_2 = lbl_offset + (lbl_stagger_offset*2)
    offset_ma2_2 = lbl_offset + (lbl_stagger_offset*3)
    offset_ma1_3 = lbl_offset + (lbl_stagger_offset*4)
    offset_ma2_3 = lbl_offset + (lbl_stagger_offset*5)
    offset_ma1_4 = lbl_offset + (lbl_stagger_offset*6)
    offset_ma2_4 = lbl_offset + (lbl_stagger_offset*7)
    do_label(show_ma1_1, bar_index[0] + offset_ma1_1, ma_1_1, tf_str(tf_1, ma1length, ma_type), lbl_txtsize, color_ma1_1)
    do_label(show_ma2_1, bar_index[0] + offset_ma2_1, ma_2_1, tf_str(tf_1, ma2length, ma_type), lbl_txtsize, color_ma2_1)
    do_label(show_ma1_2, bar_index[0] + offset_ma1_2, ma_1_2, tf_str(tf_2, ma1length, ma_type), lbl_txtsize, color_ma1_2)
    do_label(show_ma2_2, bar_index[0] + offset_ma2_2, ma_2_2, tf_str(tf_2, ma2length, ma_type), lbl_txtsize, color_ma2_2)
    do_label(show_ma1_3, bar_index[0] + offset_ma1_3, ma_1_3, tf_str(tf_3, ma1length, ma_type), lbl_txtsize, color_ma1_3)
    do_label(show_ma2_3, bar_index[0] + offset_ma2_3, ma_2_3, tf_str(tf_3, ma2length, ma_type), lbl_txtsize, color_ma2_3)
    do_label(show_ma1_4, bar_index[0] + offset_ma1_4, ma_1_4, tf_str(tf_4, ma1length, ma_type), lbl_txtsize, color_ma1_4)
    do_label(show_ma2_4, bar_index[0] + offset_ma2_4, ma_2_4, tf_str(tf_4, ma2length, ma_type), lbl_txtsize, color_ma2_4)

