MACD_base_and_reference_TF
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © vpirinski

//@version=5

//#region *********** DESCRIPTION ***********

// The "MACD_with_reference" indicator aims to illustrate the MACD (Moving Average Convergence Divergence) on two distinct timeframes: 
// the base timeframe (typically the chart's timeframe, e.g., 1D) and the reference timeframe (defaulted to 1W). 
// This tool provides a means to determine momentum shifts within the stock, potentially guiding traders in adjusting or trimming positions.

// ================================================== INFO ==================================================

// Key Features of the Indicator:
// - Dual Timeframe MACD: Displays MACD on both the primary (base) and higher (reference) timeframes - transparent.
// - Momentum Analysis: indication of MACD crossdown of the signal line on the refenence TF to indicate momentum loss on the higher timeframe, guiding decisions to manage positions.
// - MACD Line Status: Beneath the chart, a red/green bar line signifies the MACD line's position relative to the signal line on the higher timeframe.
// - Alert Creation: Allows for alerts on the MACD and signal line crossdown on the higher timeframe, aiding in planning stop-loss settings for owned stocks.

// ================================================== NOTES ==================================================

// The "MACD_with_reference" indicator finds optimal usage in several scenarios:
// - Chart Analysis: Replacing the MACD indicator during chart reviews.
// Alert Setup: Setting alerts for owned stocks to plan ahead for stop-loss placements or position closures.

// ================================================== TODO ==================================================
//#endregion ========================================================================================================
//#endregion ========================================================================================================

//#region *********** STRATEGY_SETUP *********** 
indicator(
     title      = "MACD_base_and_reference_TF",
     shorttitle = "MACD_base_and_reference_TF",
     overlay    = false
     )
//#endregion ========================================================================================================

//#region *********** LIBRARIES *********** 
import HeWhoMustNotBeNamed/enhanced_ta/14 as eta
//#endregion ========================================================================================================
     
//#region *********** USER_INPUT *********** 
var string MACD_GROUP_STR     = "MACD"
i_macd_base_timeframe         = input.timeframe(title = "Base timeframe",                 defval = "",    group = MACD_GROUP_STR)
i_macd_reference_timeframe    = input.timeframe(title = "Reference timeframe",            defval = "W",   group = MACD_GROUP_STR)
i_macd_ma_source              = input.source   (title = "Source",                         defval = close, group = MACD_GROUP_STR)
i_macd_osc_ma_type            = input.string   (title = "Osc MA type",                    defval = "ema", group = MACD_GROUP_STR, options = ["ema", "sma", "rma", "hma", "wma", "vwma", "swma"])
i_macd_signal_line_ma_type    = input.string   (title = "Signal MA type",                 defval = "ema", group = MACD_GROUP_STR, options = ["ema", "sma", "rma", "hma", "wma", "vwma", "swma"])
i_macd_fast_ma_length         = input.int      (title = "Fast MA Length",                 defval = 12,    group = MACD_GROUP_STR)
i_macd_slow_ma_length         = input.int      (title = "Slow MA Length",                 defval = 26,    group = MACD_GROUP_STR)
i_macd_signal_length          = input.int      (title = "Low MACD Hist",                  defval = 9,     group = MACD_GROUP_STR)
i_macd_repaint_en             = input.bool     (title = "MACD Repainting On/Off",         defval = true,  group = MACD_GROUP_STR, tooltip="Off for use as an Indicator to avoid repainting. On for use in Strategies so that trades can respond to realtime data.")
i_ref_macd_transplant_perc    = input.int      (title = "Reference MACD transparency %",  defval = 70,    group = MACD_GROUP_STR)

var string GENERAL_GROUP_STR  = "GENERAL"
i_general_gaps_on             = false // input.bool     (title = "Gaps On/Off",                    defval = true,  group = GENERAL_GROUP_STR, tooltip = "Flatten out the lines or stair/steps like line")
i_general_lookahead_on        = false // input.bool     (title = "Looakahead On/Off",              defval = false, group = GENERAL_GROUP_STR)

// Plot colors
var string MACD_COLOR_STR     = "Color Settings"
var string MACD_HISTOGRAM_STR = "Histogram"
i_col_macd               = input(#2962FF, "MACD Line  ",    group=MACD_COLOR_STR,           inline="MACD")
i_col_signal             = input(#FF6D00, "Signal Line  ",  group=MACD_COLOR_STR,           inline="Signal")
i_col_grow_above         = input(#26A69A, "Above   Grow",   group=MACD_HISTOGRAM_STR,       inline="Above")
i_col_fall_above         = input(#B2DFDB, "Fall",           group=MACD_HISTOGRAM_STR,       inline="Above")
i_col_grow_below         = input(#FFCDD2, "Below Grow",     group=MACD_HISTOGRAM_STR,       inline="Below")
i_col_fall_below         = input(#FF5252, "Fall",           group=MACD_HISTOGRAM_STR,       inline="Below")

//#endregion ========================================================================================================

//#region *********** COMMON_FUNCTIONS *********** 
// Function offering a repainting/no-repainting version of the HTF data (but does not work on tuples).
// It has the advantage of using only one `security()` call for both.
// The built-in MACD function behaves identically to Repainting On in the custom function below. In other words _repaint = TRUE. 
// https://www.tradingview.com/script/cyPWY96u-How-to-avoid-repainting-when-using-security-PineCoders-FAQ/
f_security(_symbol, _tf, _src, _repaint) => request.security(symbol     = _symbol,
                                                             timeframe  = _tf, 
                                                             expression = _src[_repaint          ? 0                     : barstate.isrealtime ? 1 : 0],
                                                             gaps       = i_general_gaps_on      ? barmerge.gaps_on      : barmerge.gaps_off,
                                                             lookahead  = i_general_lookahead_on ? barmerge.lookahead_on : barmerge.lookahead_off)[_repaint ? 0 : barstate.isrealtime ? 0 : 1]
//#endregion ========================================================================================================

//#region *********** LOGIC *********** 
// Get the current TF MACD lines and then interpolate them for the Base and the Reference timeframes
fast_ma              = eta.ma(source = i_macd_ma_source, maType = i_macd_osc_ma_type, length = i_macd_fast_ma_length)
slow_ma              = eta.ma(source = i_macd_ma_source, maType = i_macd_osc_ma_type, length = i_macd_slow_ma_length)
ctf_macd_line        = fast_ma - slow_ma
ctf_signal_line      = eta.ma(source = ctf_macd_line, maType = i_macd_signal_line_ma_type, length = i_macd_signal_length)
ctf_hist_line        = ctf_macd_line - ctf_signal_line

base_macd_line       = f_security(syminfo.tickerid, i_macd_base_timeframe,      ctf_macd_line,    i_macd_repaint_en)
base_signal_line     = f_security(syminfo.tickerid, i_macd_base_timeframe,      ctf_signal_line,  i_macd_repaint_en)
base_hist_line       = f_security(syminfo.tickerid, i_macd_base_timeframe,      ctf_hist_line,    i_macd_repaint_en)

ref_macd_line        = f_security(syminfo.tickerid, i_macd_reference_timeframe, ctf_macd_line,    i_macd_repaint_en)
ref_signal_line      = f_security(syminfo.tickerid, i_macd_reference_timeframe, ctf_signal_line,  i_macd_repaint_en)
ref_hist_line        = f_security(syminfo.tickerid, i_macd_reference_timeframe, ctf_hist_line,    i_macd_repaint_en)

ref_macd_crossunder  = ta.crossunder(ref_macd_line, ref_signal_line)

//#endregion ========================================================================================================

//#region *********** DEBUG_&_PLOTS *********** 
color ref_macd_line_color     = color.new(i_col_macd,   i_ref_macd_transplant_perc)
color ref_macd_signal_color   = color.new(i_col_signal, i_ref_macd_transplant_perc)

// Base MACD 
hline(price = 0, title = "Zero Line", color=color.new(#787B86, 50))
plot(base_hist_line,
      title="Histogram",  
      style=plot.style_columns, 
      color=(base_hist_line>=0 ? (base_hist_line[1] < base_hist_line ? i_col_grow_above : i_col_fall_above) : (base_hist_line[1] < base_hist_line ? i_col_grow_below : i_col_fall_below))
     )
plot(base_macd_line,     title="Base MACD",       color=i_col_macd)
plot(base_signal_line,   title="Base Signal",     color=i_col_signal)

// Reference MACD
plot(ref_macd_line,      title="Ref MACD",       color=ref_macd_line_color)     
plot(ref_signal_line,    title="Ref Signal",     color=ref_macd_signal_color)

ref_filter_color     = ref_signal_line < ref_macd_line ? color.new(color.green, 50) : color.new(color.red, 50)
plotshape(series = 1, title = "Ref TF filter", style = shape.square, location = location.bottom, color = ref_filter_color, size = size.auto)
plotshape(ref_macd_crossunder,  style=shape.triangledown, location=location.top,      size = size.tiny, color=ref_macd_crossunder  ? color.rgb(216, 129, 71) : na)
//#endregion ========================================================================================================
     
//#region *********** ALERTS *********** 
alertcondition(ref_macd_crossunder, "ReferenceMACDCrossUnder", "MACD line xUnder signal line for {{ticker}} at price {{close}}")
//#endregion ========================================================================================================