Trend

MACD Buy Sell Signals: Crossovers and Pivot Divergence

Compare MACD line, signal, zero-cross and confirmed-pivot divergence rules. Read a 12/26/9 Pine Script example and its timing limitations.

MACD Signal Interpretation

Quick-reference guide to 7 signal types you will see on the chart.

Signal TypeIndicator ConditionMarket MeaningInterpretation limits
MACD crosses above signalPrevious MACD <= previous signal; current MACD > current signal.Histogram moves from nonpositive to positive.No prediction of price follow-through.
MACD crosses below signalPrevious MACD >= previous signal; current MACD < current signal.Histogram moves from nonnegative to negative.Can recur during sideways price action.
MACD crosses above zeroFast EMA crosses above slow EMA.Their price-unit difference becomes positive.Not the same event as a signal-line crossover.
MACD crosses below zeroFast EMA crosses below slow EMA.Their price-unit difference becomes negative.Does not establish a complete downtrend.
Hidden bullish divergenceTwo confirmed price pivot lows: the newer price low is higher, but sampled histogram is lower.Price and sampled oscillator lows disagree.Detected two bars after the newer pivot; no guaranteed continuation.
Hidden bearish divergenceTwo confirmed price pivot highs: the newer price high is lower, but sampled histogram is higher.Price and sampled oscillator highs disagree.Not an independently matched histogram pivot.
Histogram slope turnHistogram changes from non-rising to rising, or non-falling to falling.The MACD-signal difference changed slope.A slope turn need not reach zero or reverse price.

MACD Pine Script Signal Code

Educational indicator example. Review its exact rules and compare its plots with your intended calculation in TradingView. It does not place orders or establish profitability.

Pine Script v6
//@version=6
indicator("MACD Signal Conditions", overlay=false)
fastLength = input.int(12, "Fast Length", minval=1)
slowLength = input.int(26, "Slow Length", minval=2)
signalSmoothing = input.int(9, "Signal Smoothing", minval=1)
src = input.source(close, "Source")
[macdLine, signalLine, histLine] = ta.macd(src, fastLength, slowLength, signalSmoothing)
bullCrossRaw = ta.crossover(macdLine, signalLine)
bearCrossRaw = ta.crossunder(macdLine, signalLine)
bullZeroRaw = ta.crossover(macdLine, 0)
bearZeroRaw = ta.crossunder(macdLine, 0)
bullishCross = barstate.isconfirmed and bullCrossRaw
bearishCross = barstate.isconfirmed and bearCrossRaw
bullishZero = barstate.isconfirmed and bullZeroRaw
bearishZero = barstate.isconfirmed and bearZeroRaw

// Price pivots are known only after two right-side bars.
pivotLow = ta.pivotlow(low, 2, 2)
pivotHigh = ta.pivothigh(high, 2, 2)
lowConfirmed = not na(pivotLow)
highConfirmed = not na(pivotHigh)
previousLow = ta.valuewhen(lowConfirmed, pivotLow, 1)
previousLowHist = ta.valuewhen(lowConfirmed, histLine[2], 1)
previousHigh = ta.valuewhen(highConfirmed, pivotHigh, 1)
previousHighHist = ta.valuewhen(highConfirmed, histLine[2], 1)
hiddenBull = barstate.isconfirmed and lowConfirmed and not na(previousLowHist) and pivotLow > previousLow and histLine[2] < previousLowHist
hiddenBear = barstate.isconfirmed and highConfirmed and not na(previousHighHist) and pivotHigh < previousHigh and histLine[2] > previousHighHist
histTurnUp = barstate.isconfirmed and histLine > histLine[1] and histLine[1] <= histLine[2]
histTurnDown = barstate.isconfirmed and histLine < histLine[1] and histLine[1] >= histLine[2]

plot(macdLine, "MACD", color=color.blue)
plot(signalLine, "Signal", color=color.orange)
plot(histLine, "Histogram", color=histLine >= 0 ? color.teal : color.red, style=plot.style_histogram)
hline(0, "Zero", color=color.gray)
plotshape(bullishCross, "Signal cross up", shape.triangleup, location.bottom, color=color.green, size=size.tiny)
plotshape(bearishCross, "Signal cross down", shape.triangledown, location.top, color=color.red, size=size.tiny)
plotshape(bullishZero, "Zero cross up", shape.circle, location.bottom, color=color.teal, size=size.tiny)
plotshape(bearishZero, "Zero cross down", shape.circle, location.top, color=color.maroon, size=size.tiny)
// Mark the confirmation bar without a negative offset.
plotshape(hiddenBull, "Hidden bullish confirmation", shape.labelup, location.bottom, color=color.aqua, text="HB", size=size.tiny)
plotshape(hiddenBear, "Hidden bearish confirmation", shape.labeldown, location.top, color=color.orange, text="HB", size=size.tiny)
plotshape(histTurnUp, "Histogram turns up", shape.square, location.bottom, color=color.gray, size=size.tiny)
plotshape(histTurnDown, "Histogram turns down", shape.square, location.top, color=color.gray, size=size.tiny)
alertcondition(bullishCross, "MACD signal cross up", "MACD crossed above its signal at bar close")
alertcondition(bearishCross, "MACD signal cross down", "MACD crossed below its signal at bar close")
alertcondition(bullishZero, "MACD zero cross up", "MACD crossed above zero at bar close")
alertcondition(bearishZero, "MACD zero cross down", "MACD crossed below zero at bar close")
alertcondition(hiddenBull, "Hidden bullish confirmation", "Price-pivot hidden bullish divergence confirmed two bars after pivot")
alertcondition(hiddenBear, "Hidden bearish confirmation", "Price-pivot hidden bearish divergence confirmed two bars after pivot")

Example settings for MACD

Record the inputs used by the example. These settings are not an optimized trading recommendation.

Feature comparison table: Default vs Description
ParameterDefaultDescription
Fast Length12EMA length applied to Source. Keep it shorter than Slow Length for the usual interpretation.
Slow Length26Second EMA length. MACD is fast EMA minus slow EMA in the units of the source price.
Signal Smoothing9EMA length applied to MACD. It changes the histogram and signal-cross timing.
SourceCloseSource for both EMAs. Divergence uses chart high/low pivots and the histogram sampled on those pivot bars.
Pivot left/right bars2 / 2Fixed in this example. Two subsequent bars are required; markers appear on the confirmation bar.

Turn the condition into an explicit rule

Specify the calculation, confirmation time, entry and exit rules before asking Pineify to draft or revise Pine Script. Review the code and simulate realistic costs before evaluating a strategy.

Explore Pine Script coding

FAQ

MACD Signals FAQ

How does a MACD signal-line cross differ from a zero cross?
The histogram equals MACD minus its signal, so a histogram zero cross and a MACD/signal cross are the same algebraic event. A MACD zero cross instead means its fast and slow price EMAs crossed. Neither is an order or a complete trading system.
What divergence does the example detect?
It compares consecutive confirmed price pivots and samples the histogram at those same bars. A higher price low with a lower histogram value is hidden bullish divergence; a lower price high with a higher histogram value is hidden bearish divergence. It does not independently locate histogram pivots or impose a wider trend filter.
When is a divergence marker available?
With two right-side bars, a pivot at bar t is not known until bar t+2 closes. The example draws its marker at t+2 and does not backdate it. For a hypothetical pair of confirmed lows at 100 and 102 with sampled histogram values -1 and -2, the hidden bullish comparison is true at the second confirmation, not at the original low.
Does a shrinking histogram guarantee a crossover?
No. A positive histogram can shrink and then expand again without reaching zero. A slope turn only describes changes in the MACD-signal distance; it does not establish that MACD itself has reversed or that a crossover will happen within a fixed number of bars.
Does this example prevent intrabar signals from disappearing?
The event conditions require barstate.isconfirmed, while plotted MACD values still update on an open bar. Confirmed-bar logic does not prevent changes caused by different inputs, history, source data revisions or chart types. Compare standard-candle charts with the same symbol and settings.
Which settings or signals have the highest win rate?
No comparative test is supplied here. A win rate requires specified entries, exits, costs, symbol, interval and sample. This indicator places no orders. Test a separately defined strategy on held-out data and inspect drawdown, trade count and execution assumptions alongside win rate.
How do I use the alert conditions?
Create a TradingView alert for the named condition after adding the indicator and choosing its inputs. Use Once Per Bar Close. Alert servers save the script and settings at creation; recreate an alert when the intended logic or inputs change.