What it does
MACD Divergence shows the standard MACD (line, signal line and a four-shade histogram) in a separate pane and automatically marks divergences between price and the oscillator. It finds both regular divergences, which point to a fading move, and hidden divergences, which point to a pullback inside an existing trend.
Each divergence is drawn as a line between the two oscillator pivots plus a label, and each type has its own alert.
How it works
MACD line = EMA(fast) − EMA(slow) of the source. Signal = EMA(MACD, signal length). Histogram = MACD − signal. You choose whether divergences are measured on the MACD line or the histogram.
Pivots are found on the chosen oscillator: a pivot low is lower than the "bars left" values before it and the "bars right" values after it (pivot highs mirror this). When a new pivot is confirmed, it is compared with the previous pivot of the same kind, provided the two are between the minimum and maximum distance apart.
| Type | Price | Oscillator |
|---|---|---|
| Regular bullish | lower low | higher low |
| Hidden bullish | higher low | lower low |
| Regular bearish | higher high | lower high |
| Hidden bearish | lower high | higher high |
Price is read from the bar's low (for lows) or high (for highs) at each pivot. Regular divergences use solid lines; hidden ones use dashed lines.
How to use it
- Regular divergence suggests momentum is weakening against price. It is a warning, not a reversal signal: many traders wait for a structure break, a MACD/signal cross or a reaction at a resistance or support level before acting.
- Hidden divergence fits trend-continuation ideas: in an uptrend, a hidden bullish divergence at a higher low suggests the pullback may be ending.
- Histogram divergences react faster but are noisier; MACD-line divergences are fewer and slower.
- Combine with the broader trend and check the MACD lesson if you are new to the oscillator. Works on most markets from M30 to D1.
Settings
| Input | Default | What it changes |
|---|---|---|
| Source | close | Price used for the MACD. |
| Fast / Slow / Signal length | 12 / 26 / 9 | MACD speed and smoothing. |
| Detect divergence on | MACD line | MACD line or histogram. |
| Pivot bars left / right | 5 / 5 | Pivot strictness and confirmation delay. |
| Min / Max bars between pivots | 5 / 60 | Ignores pivots that are too close or too far apart. |
| Show regular / hidden divergence | On / On | Toggle each type (also affects alerts). |
| Draw divergence lines | On | Lines between the two pivots. |
Limitations
- A pivot is only confirmed "bars right" bars after it forms. Divergences are drawn back at the pivot but appear, and alert, five bars later with the defaults. They do not repaint once shown, but they are never early.
- Divergence can persist through a strong trend: several regular divergences in a row are common before any reversal, if one happens at all.
- Results depend heavily on the pivot settings; tighter settings find more, weaker divergences.
- MACD is unbounded and scale-dependent, so divergences across a large price move can be misleading.
Pine Script source
In TradingView open Pine Editor, paste the code, click Save and then Add to chart.
FXP_MacdDivergence.pine
93 lines
// © FXPIPS ONLINE — https://fxpips.online/tradingview-indicators/macd-divergence/
// License: MIT. Educational tool — not financial advice. Trading involves substantial risk.
//@version=6
// MACD with regular and hidden divergence detection on confirmed oscillator pivots.
// A pivot is only known "Pivot bars right" bars after it forms, so divergences are drawn back
// at the pivot bar but appear (and alert) that many bars later. Nothing is redrawn afterwards.
indicator("FXP MACD Divergence", shorttitle = "FXP MACD Div", overlay = false, max_lines_count = 200, max_labels_count = 200)
// ── Inputs ─────────────────────────────────────────────────────────────
grpM = "MACD"
src = input.source(close, "Source", group = grpM)
fastLen = input.int(12, "Fast length", minval = 1, group = grpM)
slowLen = input.int(26, "Slow length", minval = 2, group = grpM)
sigLen = input.int(9, "Signal length", minval = 1, group = grpM)
oscChoice = input.string("MACD line", "Detect divergence on", options = ["MACD line", "Histogram"], group = grpM)
grpD = "Divergence"
lbL = input.int(5, "Pivot bars left", minval = 1, group = grpD)
lbR = input.int(5, "Pivot bars right", minval = 1, group = grpD)
minGap = input.int(5, "Min bars between pivots", minval = 1, group = grpD)
maxGap = input.int(60, "Max bars between pivots", minval = 2, group = grpD)
showRegular = input.bool(true, "Show regular divergence", group = grpD)
showHidden = input.bool(true, "Show hidden divergence", group = grpD)
showLines = input.bool(true, "Draw divergence lines", group = grpD)
grpV = "Display"
colBull = input.color(#26a69a, "Bullish color", group = grpV)
colBear = input.color(#ef5350, "Bearish color", group = grpV)
colMacd = input.color(#2962ff, "MACD line", group = grpV)
colSig = input.color(#ff6d00, "Signal line", group = grpV)
// ── MACD ───────────────────────────────────────────────────────────────
[macdLine, signalLine, hist] = ta.macd(src, fastLen, slowLen, sigLen)
osc = oscChoice == "Histogram" ? hist : macdLine
// ── Pivots on the oscillator ───────────────────────────────────────────
plFound = not na(ta.pivotlow(osc, lbL, lbR))
phFound = not na(ta.pivothigh(osc, lbL, lbR))
oscPivot = osc[lbR]
lowPivot = low[lbR]
highPivot = high[lbR]
pivotBar = bar_index - lbR
prevOscPl = ta.valuewhen(plFound, oscPivot, 1)
prevLowPl = ta.valuewhen(plFound, lowPivot, 1)
prevPlBar = ta.valuewhen(plFound, pivotBar, 1)
prevOscPh = ta.valuewhen(phFound, oscPivot, 1)
prevHiPh = ta.valuewhen(phFound, highPivot, 1)
prevPhBar = ta.valuewhen(phFound, pivotBar, 1)
plGap = pivotBar - prevPlBar
phGap = pivotBar - prevPhBar
plOk = plFound and plGap >= minGap and plGap <= maxGap and barstate.isconfirmed
phOk = phFound and phGap >= minGap and phGap <= maxGap and barstate.isconfirmed
// Regular: price and oscillator disagree on the extreme. Hidden: continuation pattern.
regBull = showRegular and plOk and oscPivot > prevOscPl and lowPivot < prevLowPl
hidBull = showHidden and plOk and oscPivot < prevOscPl and lowPivot > prevLowPl
regBear = showRegular and phOk and oscPivot < prevOscPh and highPivot > prevHiPh
hidBear = showHidden and phOk and oscPivot > prevOscPh and highPivot < prevHiPh
// ── Drawings ───────────────────────────────────────────────────────────
if regBull
label.new(pivotBar, oscPivot, "Bull", style = label.style_label_up, color = colBull, textcolor = color.white, size = size.small)
if showLines
line.new(prevPlBar, prevOscPl, pivotBar, oscPivot, color = colBull, width = 2)
if hidBull
label.new(pivotBar, oscPivot, "H Bull", style = label.style_label_up, color = color.new(colBull, 35), textcolor = color.white, size = size.small)
if showLines
line.new(prevPlBar, prevOscPl, pivotBar, oscPivot, color = colBull, width = 1, style = line.style_dashed)
if regBear
label.new(pivotBar, oscPivot, "Bear", style = label.style_label_down, color = colBear, textcolor = color.white, size = size.small)
if showLines
line.new(prevPhBar, prevOscPh, pivotBar, oscPivot, color = colBear, width = 2)
if hidBear
label.new(pivotBar, oscPivot, "H Bear", style = label.style_label_down, color = color.new(colBear, 35), textcolor = color.white, size = size.small)
if showLines
line.new(prevPhBar, prevOscPh, pivotBar, oscPivot, color = colBear, width = 1, style = line.style_dashed)
// ── Plots ──────────────────────────────────────────────────────────────
histColor = hist >= 0 ? (hist > hist[1] ? colBull : color.new(colBull, 50)) : (hist < hist[1] ? colBear : color.new(colBear, 50))
plot(hist, "Histogram", color = histColor, style = plot.style_columns)
plot(macdLine, "MACD", color = colMacd)
plot(signalLine, "Signal", color = colSig)
hline(0, "Zero line", color = color.new(color.gray, 50))
// ── Alerts ─────────────────────────────────────────────────────────────
alertcondition(regBull, "Regular bullish divergence", "MACD regular bullish divergence confirmed on {{ticker}} ({{interval}})")
alertcondition(hidBull, "Hidden bullish divergence", "MACD hidden bullish divergence confirmed on {{ticker}} ({{interval}})")
alertcondition(regBear, "Regular bearish divergence", "MACD regular bearish divergence confirmed on {{ticker}} ({{interval}})")
alertcondition(hidBear, "Hidden bearish divergence", "MACD hidden bearish divergence confirmed on {{ticker}} ({{interval}})")

