// © 2026 Enhanced for Munger Engine Strategy // This script combines MACD and RSI with multi-timeframe analysis, // divergence detection, and momentum confirmation to complement // the Munger Engine weekly value investing strategy. //@version=6 indicator("Enhanced RSI & MACD", "RSI/MACD+", false) // ===================== // 1. INPUTS // ===================== // --- Display Mode --- display_group = "0. Display Mode" indicator_mode = input.string("MACD", "Show Indicator", options=["MACD", "RSI"], group = display_group) // --- MACD Inputs --- macd_group = "1. MACD Settings" fast_len = input.int(12, "Fast Length", group = macd_group) slow_len = input.int(26, "Slow Length", group = macd_group) signal_len = input.int(9, "Signal Length", group = macd_group) source = input.source(close, "Source", group = macd_group) // --- RSI Inputs --- rsi_group = "2. RSI Settings" rsi_len = input.int(14, "RSI Length", group = rsi_group) rsi_ob = input.int(70, "Overbought Level", group = rsi_group) rsi_os = input.int(30, "Oversold Level", group = rsi_group) // --- Multi-Timeframe --- mtf_group = "3. Multi-Timeframe" show_weekly = input.bool(true, "Show Weekly Indicators", group = mtf_group) weekly_opacity = input.int(50, "Weekly Line Opacity", minval=0, maxval=100, group = mtf_group) // --- Divergence Detection --- div_group = "4. Divergence Detection" enable_div = input.bool(true, "Enable Divergence Detection", group = div_group) div_lookback = input.int(5, "Lookback Period", minval=2, maxval=20, group = div_group) // --- Momentum Confirmation --- mom_group = "5. Momentum Signals" show_momentum = input.bool(true, "Show Momentum Background", group = mom_group) show_info_panel = input.bool(true, "Show Info Panel", group = mom_group) // ===================== // 2. CALCULATIONS // ===================== // --- Daily MACD & RSI --- [macdLine, signalLine, histLine] = ta.macd(source, fast_len, slow_len, signal_len) rsi_val = ta.rsi(source, rsi_len) // --- Weekly MACD & RSI --- calc_weekly_indicators() => [w_macd, w_signal, w_hist] = ta.macd(close, fast_len, slow_len, signal_len) w_rsi = ta.rsi(close, rsi_len) [w_macd, w_signal, w_hist, w_rsi] [w_macdLine, w_signalLine, w_histLine, w_rsi_val] = request.security(syminfo.tickerid, "W", calc_weekly_indicators()) // --- Momentum State --- // Bullish: RSI > 50 AND MACD hist rising // Bearish: RSI < 50 OR MACD hist falling macd_rising = histLine > histLine[1] macd_falling = histLine < histLine[1] momentum_bullish = rsi_val > 50 and macd_rising momentum_bearish = rsi_val < 50 or macd_falling momentum_neutral = not momentum_bullish and not momentum_bearish // Weekly momentum w_macd_rising = w_histLine > w_histLine[1] w_momentum_bullish = w_rsi_val > 50 and w_macd_rising // --- Divergence Detection --- // Bullish Divergence: Price lower low, RSI higher low // Bearish Divergence: Price higher high, RSI lower high find_pivot_low(src, left, right) => pivot = true for i = 1 to left if src[i] < src pivot := false for i = 0 to right - 1 if src[i] < src pivot := false pivot find_pivot_high(src, left, right) => pivot = true for i = 1 to left if src[i] > src pivot := false for i = 0 to right - 1 if src[i] > src pivot := false pivot // Detect divergences and store reason text var float last_pivot_low_price = na var float last_pivot_low_rsi = na var int last_pivot_low_bar = na var float last_pivot_high_price = na var float last_pivot_high_rsi = na var int last_pivot_high_bar = na bullish_div = false bearish_div = false var string bullish_reason = "" var string bearish_reason = "" if enable_div // Check for pivot lows if find_pivot_low(low, div_lookback, div_lookback) if not na(last_pivot_low_price) // Price made lower low, RSI made higher low if low < last_pivot_low_price and rsi_val > last_pivot_low_rsi bullish_div := true bullish_reason := "BULLISH DIVERGENCE\n" + "------------------------\n" + "Price: Lower Low\n" + " Prev: " + str.tostring(last_pivot_low_price, format.mintick) + "\n" + " Now: " + str.tostring(low, format.mintick) + "\n" + "RSI: Higher Low\n" + " Prev: " + str.tostring(last_pivot_low_rsi, "#.2") + "\n" + " Now: " + str.tostring(rsi_val, "#.2") + "\n" + "------------------------\n" + "Signal: Potential reversal up" last_pivot_low_price := low last_pivot_low_rsi := rsi_val last_pivot_low_bar := bar_index // Check for pivot highs if find_pivot_high(high, div_lookback, div_lookback) if not na(last_pivot_high_price) // Price made higher high, RSI made lower high if high > last_pivot_high_price and rsi_val < last_pivot_high_rsi bearish_div := true bearish_reason := "BEARISH DIVERGENCE\n" + "------------------------\n" + "Price: Higher High\n" + " Prev: " + str.tostring(last_pivot_high_price, format.mintick) + "\n" + " Now: " + str.tostring(high, format.mintick) + "\n" + "RSI: Lower High\n" + " Prev: " + str.tostring(last_pivot_high_rsi, "#.2") + "\n" + " Now: " + str.tostring(rsi_val, "#.2") + "\n" + "------------------------\n" + "Signal: Potential reversal down" last_pivot_high_price := high last_pivot_high_rsi := rsi_val last_pivot_high_bar := bar_index // ===================== // 3. PLOTTING // ===================== // --- Background for Momentum Zones --- bgcolor_color = show_momentum ? (momentum_bullish ? color.new(color.green, 95) : momentum_bearish ? color.new(color.red, 95) : color.new(color.gray, 98)) : na bgcolor(bgcolor_color, title="Momentum Background") // --- Plot MACD (if selected) --- show_macd = indicator_mode == "MACD" histColor = histLine >= 0 ? color.new(color.green, 40) : color.new(color.red, 40) plot(show_macd ? histLine : na, title="Daily Histogram", style=plot.style_histogram, color=histColor, linewidth=2) plot(show_macd ? macdLine : na, title="Daily MACD", color=color.new(color.blue, 0), linewidth=2) plot(show_macd ? signalLine : na, title="Daily Signal", color=color.new(color.orange, 0), linewidth=2) hline(0, "Zero Line", color.gray, hline.style_dashed) // --- Plot Weekly MACD (if enabled and MACD mode) --- w_histColor = w_histLine >= 0 ? color.new(color.green, weekly_opacity) : color.new(color.red, weekly_opacity) plot(show_macd and show_weekly ? w_histLine : na, title="Weekly Histogram", style=plot.style_line, color=w_histColor, linewidth=1) plot(show_macd and show_weekly ? w_macdLine : na, title="Weekly MACD", color=color.new(color.blue, weekly_opacity), linewidth=1, style=plot.style_circles) plot(show_macd and show_weekly ? w_signalLine : na, title="Weekly Signal", color=color.new(color.orange, weekly_opacity), linewidth=1, style=plot.style_circles) // --- Plot RSI (if selected) --- show_rsi = indicator_mode == "RSI" plot(show_rsi ? rsi_val : na, title="Daily RSI", color=color.new(color.purple, 0), linewidth=2) plot(show_rsi and show_weekly ? w_rsi_val : na, title="Weekly RSI", color=color.new(color.purple, weekly_opacity), linewidth=1, style=plot.style_circles) // Plot RSI reference levels (only when RSI mode) ob_line = hline(show_rsi ? rsi_ob : na, "RSI Overbought", color.maroon, hline.style_dashed) os_line = hline(show_rsi ? rsi_os : na, "RSI Oversold", color.maroon, hline.style_dashed) mid_line = hline(show_rsi ? 50 : na, "RSI Midline", color.gray, hline.style_dotted) fill(ob_line, os_line, color=show_rsi ? color.new(color.purple, 90) : na, title="RSI Background Fill") // --- Divergence Markers with Tooltips --- // Position labels based on indicator mode for visibility label_y_bottom = show_rsi ? rsi_os - 5 : histLine < 0 ? histLine * 1.5 : -math.abs(histLine) * 0.5 label_y_top = show_rsi ? rsi_ob + 5 : histLine > 0 ? histLine * 1.5 : math.abs(histLine) * 0.5 if bullish_div label.new(bar_index, label_y_bottom, text="▲", color=color.lime, textcolor=color.white, style=label.style_label_up, size=size.small, tooltip=bullish_reason) if bearish_div label.new(bar_index, label_y_top, text="▼", color=color.red, textcolor=color.white, style=label.style_label_down, size=size.small, tooltip=bearish_reason) // ===================== // 4. INFO PANEL // ===================== if show_info_panel and barstate.islast var table info_panel = table.new(position.bottom_right, 2, 5, border_width=1) // Header table.cell(info_panel, 0, 0, "Timeframe", bgcolor=color.gray, text_color=color.white, text_size=size.small) table.cell(info_panel, 1, 0, "Momentum", bgcolor=color.gray, text_color=color.white, text_size=size.small) // Daily daily_state = momentum_bullish ? "BULLISH" : momentum_bearish ? "BEARISH" : "NEUTRAL" daily_color = momentum_bullish ? color.new(color.green, 70) : momentum_bearish ? color.new(color.red, 70) : color.new(color.gray, 70) table.cell(info_panel, 0, 1, "Daily", text_size=size.small) table.cell(info_panel, 1, 1, daily_state, bgcolor=daily_color, text_size=size.small) // Weekly weekly_state = w_momentum_bullish ? "BULLISH" : "BEARISH" weekly_color = w_momentum_bullish ? color.new(color.green, 70) : color.new(color.red, 70) table.cell(info_panel, 0, 2, "Weekly", text_size=size.small) table.cell(info_panel, 1, 2, weekly_state, bgcolor=weekly_color, text_size=size.small) // RSI Comparison rsi_diff = rsi_val - w_rsi_val rsi_trend = rsi_diff > 0 ? "D > W" : "D < W" table.cell(info_panel, 0, 3, "RSI", text_size=size.small) table.cell(info_panel, 1, 3, rsi_trend, text_size=size.small) // MACD Trend macd_trend = macd_rising ? "RISING" : macd_falling ? "FALLING" : "FLAT" macd_color = macd_rising ? color.new(color.green, 70) : macd_falling ? color.new(color.red, 70) : color.new(color.gray, 70) table.cell(info_panel, 0, 4, "MACD", text_size=size.small) table.cell(info_panel, 1, 4, macd_trend, bgcolor=macd_color, text_size=size.small)