// @version=5indicator("MTFL", overlay=true)
// ==========================================// 1. GENERAL SETTINGS// ==========================================var string GRP_GEN = "General Display"var show_labels = input.bool(true, "Show Labels", group=GRP_GEN)var show_lines = input.bool(true, "Show Lines", group=GRP_GEN)// Hierarchy toggle: Prevents "straight down" lines by hiding levels smaller than the current chartvar enforce_hierarchy = input.bool(true, "Hide Lower Timeframe Levels", tooltip="Automatically hides levels that are lower than your current chart timeframe (e.g., hides Daily levels when viewing a Monthly chart).", group=GRP_GEN)
// ==========================================// 2. MACRO LEGACY LEVELS (MINT)// ==========================================var string GRP_MACRO = "Macro Legacy Levels (Yearly Lows)"var show_macro_levels = input.bool(true, "Show Macro Levels", group=GRP_MACRO)var color_macro = input.color(color.rgb(152, 255, 152), "Macro Color (Mint)", group=GRP_MACRO)
var show_2002 = input.bool(true, "2002 (Dot Com Low)", group=GRP_MACRO)var show_2009 = input.bool(true, "2009 (GFC Low)", group=GRP_MACRO)var show_2020 = input.bool(true, "2020 (Covid Low)", group=GRP_MACRO)var show_2022 = input.bool(true, "2022 (Inflation Low)", group=GRP_MACRO)var show_2025 = input.bool(true, "2025 (Tariff/Shock Low)", group=GRP_MACRO)
// ==========================================// 3. OVERNIGHT/PRE-MARKET (ORANGE)// ==========================================var string GRP_ON = "Overnight / Pre-Market"var show_on_levels = input.bool(true, "Show Overnight H/L", tooltip="Visible on Intraday charts only.", group=GRP_ON)var time_on = input.session("1600-0930", "Session Time", group=GRP_ON)var color_on = input.color(color.orange, "Overnight Color", group=GRP_ON)
// ==========================================// 4. EXISTING LEVEL INPUTS// ==========================================// Previous Candle (Pink)var string GRP_CANDLE = "Previous Candle Levels"var show_candle_levels = input.bool(true, "Show Previous Candle", group=GRP_CANDLE)var color_candle_high = input.color(color.rgb(255, 0, 128), "High Color", group=GRP_CANDLE)var color_candle_low = input.color(color.rgb(255, 0, 128), "Low Color", group=GRP_CANDLE)var color_candle_mid = input.color(color.rgb(255, 0, 128), "Mid Color", group=GRP_CANDLE)
// Daily (Gray)var string GRP_DAY = "Daily Levels"var show_daily_levels = input.bool(true, "Show Daily", group=GRP_DAY)var label_color_day_high = input.color(color.gray, "High Color", group=GRP_DAY)var label_color_day_low = input.color(color.gray, "Low Color", group=GRP_DAY)var label_color_day_mid = input.color(color.gray, "Mid Color", group=GRP_DAY)
// Weekly (White)var string GRP_WEEK = "Weekly Levels"var show_weekly_levels = input.bool(true, "Show Weekly", group=GRP_WEEK)var label_color_high = input.color(color.white, "High Color", group=GRP_WEEK)var label_color_low = input.color(color.white, "Low Color", group=GRP_WEEK)var label_color_mid = input.color(color.white, "Mid Color", group=GRP_WEEK)
// Monthly (Maroon)var string GRP_MONTH = "Monthly Levels"var show_monthly_levels = input.bool(true, "Show Monthly", group=GRP_MONTH)var label_color_month_high = input.color(color.maroon, "High Color", group=GRP_MONTH)var label_color_month_low = input.color(color.maroon, "Low Color", group=GRP_MONTH)var label_color_month_mid = input.color(color.maroon, "Mid Color", group=GRP_MONTH)
// Quarterly (Quartz)var string GRP_QUARTER = "Quarterly Levels"var show_quarterly_levels = input.bool(true, "Show Quarterly", group=GRP_QUARTER)var label_color_quarter_high = input.color(color.new(#AA98A9, 0), "High Color", group=GRP_QUARTER)var label_color_quarter_low = input.color(color.new(#AA98A9, 0), "Low Color", group=GRP_QUARTER)var label_color_quarter_mid = input.color(color.new(#AA98A9, 0), "Mid Color", group=GRP_QUARTER)
// Yearly (Yellow)var string GRP_YEAR = "Yearly Levels"var show_yearly_levels = input.bool(true, "Show Yearly", group=GRP_YEAR)var label_color_year_high = input.color(color.yellow, "High Color", group=GRP_YEAR)var label_color_year_low = input.color(color.yellow, "Low Color", group=GRP_YEAR)var label_color_year_mid = input.color(color.yellow, "Mid Color", group=GRP_YEAR)
// All-Time (Cyan)var string GRP_ATH = "All-Time Levels"var show_alltime_levels = input.bool(true, "Show All-Time", group=GRP_ATH)var label_color_alltime_high = input.color(color.rgb(0, 255, 255), "High Color", group=GRP_ATH)var label_color_alltime_low = input.color(color.rgb(0, 255, 255), "Low Color", group=GRP_ATH)var label_color_alltime_mid = input.color(color.rgb(0, 255, 255), "Mid Color", group=GRP_ATH)
// ==========================================// 5. CALCULATIONS & LOGIC// ==========================================
// --- A. Hierarchy & Redundancy Logic ---// 1. Hierarchy: We use "max possible" seconds to account for 31-day months or leap yearscur_sec = timeframe.in_seconds(timeframe.period)check_tf(level_sec) => not enforce_hierarchy or cur_sec <= level_sec
allow_on = timeframe.isintraday // Restricted to Intraday onlyallow_daily = check_tf(86400) // Exact dayallow_weekly = check_tf(604800) // Exact weekallow_monthly = check_tf(2700000) // ~31.25 Daysallow_quarterly = check_tf(8100000) // ~93.75 Daysallow_yearly = check_tf(32000000) // ~370 Days
// 2. Redundancy: Hide "Previous Candle" if it matches an active levelis_dup_d = timeframe.isdaily and show_daily_levelsis_dup_w = timeframe.isweekly and show_weekly_levelsis_dup_m = timeframe.ismonthly and show_monthly_levelsis_dup_q = timeframe.in_seconds(timeframe.period) >= 7000000 and timeframe.in_seconds(timeframe.period) <= 8100000 and show_quarterly_levelsis_dup_y = timeframe.in_seconds(timeframe.period) >= 30000000 and show_yearly_levels
// Final logic for PC: Show if toggled ON AND NOT redundantshow_final_pc = show_candle_levels and not (is_dup_d or is_dup_w or is_dup_m or is_dup_q or is_dup_y)
// --- B. Standard Levels (Optimized Tuples) ---pch = high[1]pcl = low[1]pcm = (pch + pcl) / 2pct = time[1]
[p_day_h, p_day_l, p_day_t] = request.security(syminfo.tickerid, "D", [high[1], low[1], time[1]], lookahead=barmerge.lookahead_on)p_day_m = (p_day_h + p_day_l) / 2
[p_wk_h, p_wk_l, p_wk_t] = request.security(syminfo.tickerid, "W", [high[1], low[1], time[1]], lookahead=barmerge.lookahead_on)p_wk_m = (p_wk_h + p_wk_l) / 2
[p_mn_h, p_mn_l, p_mn_t] = request.security(syminfo.tickerid, "M", [high[1], low[1], time[1]], lookahead=barmerge.lookahead_on)p_mn_m = (p_mn_h + p_mn_l) / 2
[p_qt_h, p_qt_l, p_qt_t] = request.security(syminfo.tickerid, "3M", [high[1], low[1], time[1]], lookahead=barmerge.lookahead_on)p_qt_m = (p_qt_h + p_qt_l) / 2
[p_yr_h, p_yr_l, p_yr_t] = request.security(syminfo.tickerid, "12M", [high[1], low[1], time[1]], lookahead=barmerge.lookahead_on)p_yr_m = (p_yr_h + p_yr_l) / 2
// --- C. All-Time Levels ---var float fixed_ath = navar float fixed_atl = naif barstate.isfirst fixed_ath := high fixed_atl := lowelse fixed_ath := math.max(fixed_ath, high) fixed_atl := math.min(fixed_atl, low)fixed_atm = (fixed_ath + fixed_atl) / 2
// --- D. Macro Legacy Levels ---current_year = year(timenow)off_02 = current_year - 2002off_09 = current_year - 2009off_20 = current_year - 2020off_22 = current_year - 2022off_25 = current_year - 2025
[raw_l_02, raw_t_02] = request.security(syminfo.tickerid, "12M", [low[off_02], time[off_02]], lookahead=barmerge.lookahead_on)[raw_l_09, raw_t_09] = request.security(syminfo.tickerid, "12M", [low[off_09], time[off_09]], lookahead=barmerge.lookahead_on)[raw_l_20, raw_t_20] = request.security(syminfo.tickerid, "12M", [low[off_20], time[off_20]], lookahead=barmerge.lookahead_on)[raw_l_22, raw_t_22] = request.security(syminfo.tickerid, "12M", [low[off_22], time[off_22]], lookahead=barmerge.lookahead_on)[raw_l_25, raw_t_25] = request.security(syminfo.tickerid, "12M", [low[off_25], time[off_25]], lookahead=barmerge.lookahead_on)
l_2002 = show_2002 and off_02 >= 0 ? raw_l_02 : nat_2002 = show_2002 and off_02 >= 0 ? raw_t_02 : nal_2009 = show_2009 and off_09 >= 0 ? raw_l_09 : nat_2009 = show_2009 and off_09 >= 0 ? raw_t_09 : nal_2020 = show_2020 and off_20 >= 0 ? raw_l_20 : nat_2020 = show_2020 and off_20 >= 0 ? raw_t_20 : nal_2022 = show_2022 and off_22 >= 0 ? raw_l_22 : nat_2022 = show_2022 and off_22 >= 0 ? raw_t_22 : nal_2025 = show_2025 and off_25 >= 0 ? raw_l_25 : nat_2025 = show_2025 and off_25 >= 0 ? raw_t_25 : na
// --- E. Overnight/Pre-Market High/Low ---var float on_high = navar float on_low = nain_session = not na(time(timeframe.period, time_on))
if in_session if not in_session[1] on_high := high on_low := low else on_high := math.max(on_high, high) on_low := math.min(on_low, low)
var float final_on_high = navar float final_on_low = navar int final_on_time = na
if not in_session and in_session[1] final_on_high := on_high final_on_low := on_low final_on_time := time
// ==========================================// 6. DRAWING FUNCTIONS// ==========================================
draw_mtfl_group(bool is_active, bool show_lines_in, bool show_labels_in, int start_tm, float h, float l, float m, color ch, color cl, color cm, string txt) => if is_active and barstate.islast if show_lines_in lh = line.new(start_tm, h, time, h, xloc.bar_time, extend.right, ch) ll = line.new(start_tm, l, time, l, xloc.bar_time, extend.right, cl) lm = line.new(start_tm, m, time, m, xloc.bar_time, extend.right, cm) line.delete(lh[1]) line.delete(ll[1]) line.delete(lm[1]) if show_labels_in posX = time + (24 * 60 * 60 * 1000) lbh = label.new(posX, h, txt + "H (" + str.tostring(h, format.mintick) + ")", xloc.bar_time, yloc.price, color.new(color.white, 100), label.style_label_left, ch, size.normal, text.align_left) lbl = label.new(posX, l, txt + "L (" + str.tostring(l, format.mintick) + ")", xloc.bar_time, yloc.price, color.new(color.white, 100), label.style_label_left, cl, size.normal, text.align_left) lbm = label.new(posX, m, txt + "M (" + str.tostring(m, format.mintick) + ")", xloc.bar_time, yloc.price, color.new(color.white, 100), label.style_label_left, cm, size.normal, text.align_left) label.delete(lbh[1]) label.delete(lbl[1]) label.delete(lbm[1])
draw_single_level(bool is_active, float lvl, int start_tm, color c, string txt) => if is_active and not na(lvl) and barstate.islast if show_lines l = line.new(start_tm, lvl, time, lvl, xloc.bar_time, extend.right, c, style=line.style_solid, width=2) line.delete(l[1]) if show_labels posX = time + (24 * 60 * 60 * 1000) lb = label.new(posX, lvl, txt + " (" + str.tostring(lvl, format.mintick) + ")", xloc.bar_time, yloc.price, color.new(color.white, 100), label.style_label_left, c, size.normal, text.align_left) label.delete(lb[1])
draw_ath(bool is_active, float h, float l, float m, color ch, color cl, color cm) => if is_active and not na(h) and not na(l) and barstate.islast if show_lines var int offset = timeframe.isintraday ? 10000 : 25 lh = line.new(bar_index - offset, h, bar_index, h, xloc.bar_index, extend.right, ch) ll = line.new(bar_index - offset, l, bar_index, l, xloc.bar_index, extend.right, cl) lm = line.new(bar_index - offset, m, bar_index, m, xloc.bar_index, extend.right, cm) line.delete(lh[1]) line.delete(ll[1]) line.delete(lm[1]) if show_labels posX = time + (24 * 60 * 60 * 1000) lbh = label.new(posX, h, "ATH (" + str.tostring(h, format.mintick) + ")", xloc.bar_time, yloc.price, color.new(color.white, 100), label.style_label_left, ch, size.normal, text.align_left) lbl = label.new(posX, l, "ATL (" + str.tostring(l, format.mintick) + ")", xloc.bar_time, yloc.price, color.new(color.white, 100), label.style_label_left, cl, size.normal, text.align_left) lbm = label.new(posX, m, "ATM (" + str.tostring(m, format.mintick) + ")", xloc.bar_time, yloc.price, color.new(color.white, 100), label.style_label_left, cm, size.normal, text.align_left) label.delete(lbh[1]) label.delete(lbl[1]) label.delete(lbm[1])
// ==========================================// 7. EXECUTIONS// ==========================================
draw_mtfl_group(show_final_pc, show_lines, show_labels, pct, pch, pcl, pcm, color_candle_high, color_candle_low, color_candle_mid, "PC")draw_mtfl_group(show_daily_levels and allow_daily, show_lines, show_labels, p_day_t, p_day_h, p_day_l, p_day_m, label_color_day_high, label_color_day_low, label_color_day_mid, "PD")draw_mtfl_group(show_weekly_levels and allow_weekly, show_lines, show_labels, p_wk_t, p_wk_h, p_wk_l, p_wk_m, label_color_high, label_color_low, label_color_mid, "PW")draw_mtfl_group(show_monthly_levels and allow_monthly, show_lines, show_labels, p_mn_t, p_mn_h, p_mn_l, p_mn_m, label_color_month_high, label_color_month_low, label_color_month_mid, "PM")draw_mtfl_group(show_quarterly_levels and allow_quarterly, show_lines, show_labels, p_qt_t, p_qt_h, p_qt_l, p_qt_m, label_color_quarter_high, label_color_quarter_low, label_color_quarter_mid, "PQ")draw_mtfl_group(show_yearly_levels and allow_yearly, show_lines, show_labels, p_yr_t, p_yr_h, p_yr_l, p_yr_m, label_color_year_high, label_color_year_low, label_color_year_mid, "PY")draw_ath(show_alltime_levels, fixed_ath, fixed_atl, fixed_atm, label_color_alltime_high, label_color_alltime_low, label_color_alltime_mid)
if show_macro_levels draw_single_level(show_2002, l_2002, t_2002, color_macro, "DotCom Low") draw_single_level(show_2009, l_2009, t_2009, color_macro, "GFC Low") draw_single_level(show_2020, l_2020, t_2020, color_macro, "Covid Low") draw_single_level(show_2022, l_2022, t_2022, color_macro, "Inflation Low") draw_single_level(show_2025, l_2025, t_2025, color_macro, "Tariff Low")
if show_on_levels and allow_on and not na(final_on_high) if show_lines l_on_h = line.new(final_on_time, final_on_high, time, final_on_high, xloc.bar_time, extend.right, color_on, style=line.style_solid) l_on_l = line.new(final_on_time, final_on_low, time, final_on_low, xloc.bar_time, extend.right, color_on, style=line.style_solid) line.delete(l_on_h[1]) line.delete(l_on_l[1]) if show_labels posX = time + (24 * 60 * 60 * 1000) lb_on_h = label.new(posX, final_on_high, "ON High (" + str.tostring(final_on_high, format.mintick) + ")", xloc.bar_time, yloc.price, color.new(color.white, 100), label.style_label_left, color_on, size.normal, text.align_left) lb_on_l = label.new(posX, final_on_low, "ON Low (" + str.tostring(final_on_low, format.mintick) + ")", xloc.bar_time, yloc.price, color.new(color.white, 100), label.style_label_left, color_on, size.normal, text.align_left) label.delete(lb_on_h[1]) label.delete(lb_on_l[1])
// ==========================================// 8. PLOTS// ==========================================plot(show_final_pc ? pch : na, "PCH", color.new(color_candle_high, 100))plot(show_final_pc ? pcl : na, "PCL", color.new(color_candle_low, 100))plot(show_final_pc ? pcm : na, "PCM", color.new(color_candle_mid, 100))
plot(show_daily_levels and allow_daily ? p_day_h : na, "PDH", color.new(label_color_day_high, 100))plot(show_daily_levels and allow_daily ? p_day_l : na, "PDL", color.new(label_color_day_low, 100))plot(show_daily_levels and allow_daily ? p_day_m : na, "PDM", color.new(label_color_day_mid, 100))
plot(show_weekly_levels and allow_weekly ? p_wk_h : na, "PWH", color.new(label_color_high, 100))plot(show_weekly_levels and allow_weekly ? p_wk_l : na, "PWL", color.new(label_color_low, 100))plot(show_weekly_levels and allow_weekly ? p_wk_m : na, "PWM", color.new(label_color_mid, 100))
plot(show_monthly_levels and allow_monthly ? p_mn_h : na, "PMH", color.new(label_color_month_high, 100))plot(show_monthly_levels and allow_monthly ? p_mn_l : na, "PML", color.new(label_color_month_low, 100))plot(show_monthly_levels and allow_monthly ? p_mn_m : na, "PMM", color.new(label_color_month_mid, 100))
plot(show_quarterly_levels and allow_quarterly ? p_qt_h : na, "PQH", color.new(label_color_quarter_high, 100))plot(show_quarterly_levels and allow_quarterly ? p_qt_l : na, "PQL", color.new(label_color_quarter_low, 100))plot(show_quarterly_levels and allow_quarterly ? p_qt_m : na, "PQM", color.new(label_color_quarter_mid, 100))
plot(show_yearly_levels and allow_yearly ? p_yr_h : na, "PYH", color.new(label_color_year_high, 100))plot(show_yearly_levels and allow_yearly ? p_yr_l : na, "PYL", color.new(label_color_year_low, 100))plot(show_yearly_levels and allow_yearly ? p_yr_m : na, "PYM", color.new(label_color_year_mid, 100))
plot(show_alltime_levels ? fixed_ath : na, "ATH", color.new(label_color_alltime_high, 100))plot(show_alltime_levels ? fixed_atl : na, "ATL", color.new(label_color_alltime_low, 100))plot(show_alltime_levels ? fixed_atm : na, "ATM", color.new(label_color_alltime_mid, 100))
plot(show_macro_levels and show_2002 ? l_2002 : na, "DotCom Low", color.new(color_macro, 100))plot(show_macro_levels and show_2009 ? l_2009 : na, "GFC Low", color.new(color_macro, 100))plot(show_macro_levels and show_2020 ? l_2020 : na, "Covid Low", color.new(color_macro, 100))plot(show_macro_levels and show_2022 ? l_2022 : na, "Inflation Low", color.new(color_macro, 100))plot(show_macro_levels and show_2025 ? l_2025 : na, "Tariff Low", color.new(color_macro, 100))
plot(show_on_levels and allow_on ? final_on_high : na, "ON High", color.new(color_on, 100))plot(show_on_levels and allow_on ? final_on_low : na, "ON Low", color.new(color_on, 100))
// ==========================================// 9. SMART ALERTS// ==========================================check_lvl(bool show, bool allow, float lvl, string name) => string msg = "" if show and allow and ta.cross(close, lvl) msg := "Price crossed " + name + "\n" msg
string alert_msg = ""alert_msg := alert_msg + check_lvl(show_final_pc, true, pch, "PC High") + check_lvl(show_final_pc, true, pcl, "PC Low") + check_lvl(show_final_pc, true, pcm, "PC Mid")alert_msg := alert_msg + check_lvl(show_daily_levels, allow_daily, p_day_h, "Daily High") + check_lvl(show_daily_levels, allow_daily, p_day_l, "Daily Low") + check_lvl(show_daily_levels, allow_daily, p_day_m, "Daily Mid")alert_msg := alert_msg + check_lvl(show_weekly_levels, allow_weekly, p_wk_h, "Weekly High") + check_lvl(show_weekly_levels, allow_weekly, p_wk_l, "Weekly Low") + check_lvl(show_weekly_levels, allow_weekly, p_wk_m, "Weekly Mid")alert_msg := alert_msg + check_lvl(show_monthly_levels, allow_monthly, p_mn_h, "Monthly High") + check_lvl(show_monthly_levels, allow_monthly, p_mn_l, "Monthly Low") + check_lvl(show_monthly_levels, allow_monthly, p_mn_m, "Monthly Mid")alert_msg := alert_msg + check_lvl(show_quarterly_levels, allow_quarterly, p_qt_h, "Quarterly High") + check_lvl(show_quarterly_levels, allow_quarterly, p_qt_l, "Quarterly Low") + check_lvl(show_quarterly_levels, allow_quarterly, p_qt_m, "Quarterly Mid")alert_msg := alert_msg + check_lvl(show_yearly_levels, allow_yearly, p_yr_h, "Yearly High") + check_lvl(show_yearly_levels, allow_yearly, p_yr_l, "Yearly Low") + check_lvl(show_yearly_levels, allow_yearly, p_yr_m, "Yearly Mid")alert_msg := alert_msg + check_lvl(show_alltime_levels, true, fixed_ath, "ATH") + check_lvl(show_alltime_levels, true, fixed_atl, "ATL") + check_lvl(show_alltime_levels, true, fixed_atm, "ATM")// Macro Alertsalert_msg := alert_msg + check_lvl(show_macro_levels and show_2002, true, l_2002, "DotCom Low") + check_lvl(show_macro_levels and show_2009, true, l_2009, "GFC Low") + check_lvl(show_macro_levels and show_2020, true, l_2020, "Covid Low") + check_lvl(show_macro_levels and show_2022, true, l_2022, "Inflation Low") + check_lvl(show_macro_levels and show_2025, true, l_2025, "Tariff Low")// Overnight Alertsalert_msg := alert_msg + check_lvl(show_on_levels and allow_on, true, final_on_high, "ON High") + check_lvl(show_on_levels and allow_on, true, final_on_low, "ON Low")
if alert_msg != "" alert("MTFL Alert:\n" + alert_msg, alert.freq_once_per_bar_close)