Indicator · Pine Script v6 · Own pane

MACD Divergence

by chaise-cogent

This indicator calculates the Moving Average Convergence Divergence (MACD) and signal line in a separate pane to detect regular bullish and bearish divergences.

View on GitHub

GitHub stars5on the repository
Pine versionv6current
Lines of code115
Settings5inputs
LicenceMIT
Last update7 months ago19 Mar 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

115 lines of Pine Script v6 from src/macd-divergence.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

macd-divergence.pine
// License MIT
// This script is still educational and in WORK IN PROGRESS (WIP) mode
// @version=6
// @author chaise_cogent

indicator("MACD Divergence ", shorttitle="MACD-Div")

short_length = input.int(5, title = 'Fast length', minval = 1)
long_length = input.int(34, title = 'Slow length', minval = 1)
signal_length = input.int(5, title = 'Signal length')
div_pivot_point_length = input.int(5, title='Pivot Point Length', minval = 1)
is_check_cut_through = input.bool(true, title = 'Check cut-through?')
src = close

// cut-through above higher straigt line
is_below_upper_cut(float indicator, int len) =>
    _result = true
    trend = indicator - (indicator - nz(indicator[len])) / len
    for x = 1 to len -1
        if nz(indicator[x]) > trend[x]
            _result := false
            break
    _result

// cut-through below lower straight line
is_above_lower_cut(float indicator, int len) =>
    _result = true
    trend = indicator - (indicator - nz(indicator[len])) / len
    for x = 1 to len -1
        if nz(indicator[x]) < trend[x]
            _result := false
            break
    _result

peak = ta.pivothigh(high, div_pivot_point_length, 1) // look-forward 1 bar
trough = ta.pivotlow(low, div_pivot_point_length, 1) // look-forward 1 bar

bars_since_peak = 0
bars_since_peak := na(peak) ? nz(bars_since_peak[1]) + 1 : div_pivot_point_length
bars_since_trough = 0
bars_since_trough := na(trough) ? nz(bars_since_trough[1]) + 1 : div_pivot_point_length

// Negative Divergence - possible higher highs
local_top = ta.pivothigh(high, div_pivot_point_length, 1) // look-forward 1 bar
empty_high = true
if not na(local_top) and local_top > high[bars_since_peak] // close price must not be higher than the line between last pivot high and current high
    trend_line = local_top - (local_top - high[bars_since_peak]) / bars_since_peak
    for x = 1 to bars_since_peak - 1
        if close[x] > trend_line[x]
            empty_high := false
            break
else
    empty_high := false

// Positive Divergence - possible lower lows
local_bottom = ta.pivotlow(low, div_pivot_point_length, 1) // look-forward 1 bar
empty_low = true
if not na(local_bottom) and local_bottom < low[bars_since_trough] // close low price must not be lower than the line between last pivot low and current low
    trend_line = (local_bottom - low[bars_since_trough]) / bars_since_trough
    for x = 1 to bars_since_trough - 1
        if close[x] < trend_line[x]
            empty_low := false
            break
else
    empty_low := false


calc_divergence(indicator, isok) =>
    // Returns -1 for negative, 1 for positive and 0 if no divergence
    _result = 0

    // Check for positive
    if
      empty_low and
      not na(local_bottom)
      and indicator[bars_since_trough] < indicator
      and (not is_check_cut_through or isok)
        _result := 1
    // Check for negative
    else if
      empty_high and
      not na(local_top) and
      indicator[bars_since_peak] > indicator
      and (not is_check_cut_through or isok)
        _result := -1

    _result

[macd, macd_signal, _] = ta.macd(src, short_length, long_length, signal_length)
macd_ok_below = is_below_upper_cut(macd, bars_since_peak)
macd_ok_above = is_above_lower_cut(macd, bars_since_trough)

macd_manual_short = ta.ema(src, short_length)
macd_manual_long = ta.ema(src, long_length)
leader_i1 = macd_manual_short + ta.ema(src - macd_manual_short, short_length)
leader_i2 = macd_manual_long + ta.ema(src - macd_manual_long, long_length)
macd_leader = leader_i1 - leader_i2

divergence =
  calc_divergence(macd, macd_ok_above) + calc_divergence(macd, macd_ok_below) // possibly to sum up other indicatorcators

hline(0, color = color.gray, linestyle = hline.style_dotted)
plot(macd_leader, title='MACD Leader', color=color.maroon, style=plot.style_histogram, linewidth = 2)
plot(macd, title='MACD', color=color.new(color.green, 20), style=plot.style_areabr)
plot(macd_signal, title='Signal', color=color.orange, linewidth = 2)

plotchar(divergence > 0 ? high * 1.12 : na, char='↑', color=color.new(color.green, 20), title="Positive Divergence", location=location.absolute, size=size.small, force_overlay=true)
plotchar(divergence < 0 ? low * 0.95 : na, char='↓', color=color.new(color.red, 20), title="Negative Divergence", location=location.absolute, size=size.small, force_overlay=true)

// plotshape(empty_high, color=color.lime, location=location.top, title='empty high')
// plotshape(empty_low, color=color.maroon, location=location.bottom, title='empty low')
// plotshape(peak, color=color.blue, style=shape.triangleup, title='Peak', location=location.abovebar, force_overlay = true)
// plotshape(trough, color=color.orange, style=shape.triangledown, title='Trough', location=location.belowbar, force_overlay = true)
// plotshape(local_top, color=color.navy, location=location.top, title='loc.top', force_overlay = true)
// plotshape(local_bottom, color=color.maroon, location=location.bottom, title='loc.bott', force_overlay = true)

Overview

MACD Divergence identifies price pivot highs and lows using a configurable lookback length and compares them against corresponding MACD values. An optional cut-through validation checks whether price or indicator values cross the trend line between pivots, filtering invalid setups. The script also computes an EMA-based leader line. Divergence signals depend on pivot confirmation and appear with a one-bar lag after the pivot resolves.

Details

Published by

chaise-cogent on GitHub

Type

Indicator, Pine Script v6

Draws

Separate pane below the chart

Category

Oscillators & momentum, Divergence, Moving averages

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Fast lengthint5short_length
Slow lengthint34long_length
Signal lengthint5signal_length
Pivot Point Lengthint5div_pivot_point_length
Check cut-through?booltrueis_check_cut_through
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

330 stars

This separate-pane indicator plots a MACD line, a signal line, and a histogram whose colors show whether the histogram is rising or falling above or below zero. The oscillator and signal can each use an SMA or an EMA, and an optional marker highlights MACD and

Indicator v5 Oscillators & momentumDivergence
Updated 2 months ago · None stated GitHub repository of MTF + MACD [Alorse]

Benso RSI + PMARP

by benso87
24 stars

This indicator plots an RSI and a PMARP line in a separate pane. It calculates RSI from a chosen source and length, then overlays an SMA or EMA signal. Horizontal bull and bear control and critical levels scale the oscillator. Optional arrows mark regular and

Indicator v5 Oscillators & momentumDivergence
Updated 4 years ago · MPL-2.0 GitHub repository of Benso RSI + PMARP

Relative Strength Index

by deepentropy
13 stars

The Relative Strength Index indicator calculates momentum based on price changes over a specified length and plots the curve in a separate pane. It includes adjustable upper and lower bands, background color fills, and an optional smoothing moving average or B

Indicator v6 Oscillators & momentumMoving averages
Updated 6 months ago · MIT GitHub repository of Relative Strength Index

This indicator evaluates how price relates to one selected moving-average family rather than treating a crossover as a signal. It scores trend quality, historical respect of the average, extension, compression, acceleration, and exhaustion, then plots a relati

Indicator v6 TrendMoving averages
Updated yesterday · MIT GitHub repository of Market–Average Relationship Engine [WavesUnchained]

This indicator combines RSI and MFI into a hybrid oscillator scaled to 0-1. It detects divergences by comparing price and MFI slopes from linear regression. The MFI receives extra weight during divergence to amplify the effect. A TMA smooths the hybrid result

Indicator v6 Oscillators & momentumDivergence
Updated 5 months ago · None stated GitHub repository of Hybrid RSI+MFI - Gold Divergence

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers