Moving Average Convergence Divergence (MACD)

Haiyue
9min

I. What is MACD

The Moving Average Convergence Divergence (MACD) is one of the most popular trend-following momentum indicators in technical analysis. It measures changes in price momentum through the difference between two Exponential Moving Averages (EMAs) of different periods, helping traders identify trend direction, strength, and potential reversal points.

Historical Background

MACD was invented by Gerald Appel in 1979, and later enhanced by Thomas Aspray in 1986 with the addition of the Histogram component, forming the classic three-element structure we know today. Due to its dual functionality of trend following and momentum analysis, MACD has been called the “Swiss Army knife of technical analysis” and is one of the most frequently used indicators by traders worldwide.

Indicator Classification

  • Type: Oscillator, displayed in a separate panel
  • Category: Trend + Momentum composite indicator
  • Default Parameters: Fast EMA period =12= 12, Slow EMA period =26= 26, Signal EMA period =9= 9
  • Value Range: Unbounded, oscillates around the zero line
Three Components
  1. MACD Line (fast line): Difference between EMA(12) and EMA(26)
  2. Signal Line (slow line): EMA(9) of the MACD Line
  3. Histogram: MACD Line minus Signal Line

II. Mathematical Principles and Calculation

Core Formulas

Step 1: Calculate fast and slow EMAs

The EMA recursive formula:

EMAt=αPt+(1α)EMAt1,α=2n+1EMA_t = \alpha \cdot P_t + (1 - \alpha) \cdot EMA_{t-1}, \quad \alpha = \frac{2}{n + 1}

  • Fast EMA: EMA12EMA_{12} (α=2/130.1538\alpha = 2/13 \approx 0.1538)
  • Slow EMA: EMA26EMA_{26} (α=2/270.0741\alpha = 2/27 \approx 0.0741)

Step 2: Calculate the MACD Line

MACDt=EMA12,tEMA26,tMACD_t = EMA_{12,t} - EMA_{26,t}

Step 3: Calculate the Signal Line

Signalt=EMA(MACD,9)tSignal_t = EMA(MACD, 9)_t

That is, apply a 9-period EMA smoothing to the MACD Line.

Step 4: Calculate the Histogram

Histogramt=MACDtSignaltHistogram_t = MACD_t - Signal_t

Step-by-Step Calculation Logic

  1. Calculate 12-period EMA using close prices as input
  2. Calculate 26-period EMA using close prices as input
  3. MACD Line = Fast EMA - Slow EMA
  4. Signal Line = 9-period EMA of the MACD Line
  5. Histogram = MACD Line - Signal Line

Intuitive Understanding

  • When the short-term average rises faster than the long-term average, MACD is positive — upward momentum is increasing
  • When the MACD Line is far from the Signal Line, the Histogram grows — current trend momentum is strong
  • When the Histogram begins to shrink — momentum is weakening, a crossover may be imminent
On Parameter Selection

Appel’s originally recommended parameters (12, 26, 9) were derived from empirical analysis of the U.S. stock market. 26 days is approximately one month of trading days, and 12 days is about half a month. Different markets and timeframes may require parameter adjustments.


III. Python Implementation

import numpy as np
import pandas as pd


def macd(close: pd.Series,
         fast: int = 12,
         slow: int = 26,
         signal: int = 9) -> pd.DataFrame:
    """
    Calculate the MACD indicator

    Parameters
    ----------
    close : pd.Series
        Close price series
    fast : int
        Fast EMA period, default 12
    slow : int
        Slow EMA period, default 26
    signal : int
        Signal line EMA period, default 9

    Returns
    -------
    pd.DataFrame
        DataFrame with MACD, Signal, and Histogram columns
    """
    ema_fast = close.ewm(span=fast, adjust=False).mean()
    ema_slow = close.ewm(span=slow, adjust=False).mean()

    macd_line = ema_fast - ema_slow
    signal_line = macd_line.ewm(span=signal, adjust=False).mean()
    histogram = macd_line - signal_line

    return pd.DataFrame({
        "MACD": macd_line,
        "Signal": signal_line,
        "Histogram": histogram
    }, index=close.index)


# ========== Usage Example ==========
if __name__ == "__main__":
    np.random.seed(42)
    dates = pd.date_range("2024-01-01", periods=150, freq="D")
    # Generate simulated price with trend
    trend = np.linspace(0, 10, 150)
    noise = np.cumsum(np.random.randn(150) * 0.8)
    price = 100 + trend + noise

    df = pd.DataFrame({
        "date": dates,
        "open":  price + np.random.randn(150) * 0.3,
        "high":  price + np.abs(np.random.randn(150) * 0.6),
        "low":   price - np.abs(np.random.randn(150) * 0.6),
        "close": price,
        "volume": np.random.randint(1000, 10000, size=150),
    })
    df.set_index("date", inplace=True)

    # Calculate MACD
    macd_df = macd(df["close"])
    df = pd.concat([df, macd_df], axis=1)

    # Print last 10 rows
    print("=== MACD Results ===")
    print(df[["close", "MACD", "Signal", "Histogram"]].tail(10).to_string())

    # Crossover signal detection
    df["cross"] = np.sign(df["MACD"] - df["Signal"])
    df["signal_type"] = df["cross"].diff()
    golden = df[df["signal_type"] > 0]  # MACD crosses above Signal
    death = df[df["signal_type"] < 0]   # MACD crosses below Signal

    print("\n=== Bullish Crossovers ===")
    print(golden[["close", "MACD", "Signal"]].to_string())
    print("\n=== Bearish Crossovers ===")
    print(death[["close", "MACD", "Signal"]].to_string())

IV. Problems the Indicator Solves

1. Trend Direction

  • MACD > 0: Fast line is above the slow line, short-term trend is up
  • MACD < 0: Fast line is below the slow line, short-term trend is down
  • MACD rising continuously: Uptrend is accelerating
  • MACD falling continuously: Downtrend is accelerating

2. Signal Line Crossover

Signal TypeConditionMeaning
Bullish CrossMACD Line crosses above Signal LineBullish signal, especially significant when below zero
Bearish CrossMACD Line crosses below Signal LineBearish signal, especially significant when above zero

3. Zero Line Crossover

  • MACD crosses above zero — EMA(12) exceeds EMA(26) — medium-term trend turns bullish
  • MACD crosses below zero — EMA(12) falls below EMA(26) — medium-term trend turns bearish

4. Histogram Analysis

The Histogram is the most sensitive component of the MACD system:

  • Histogram turns from negative to positive: Momentum shifts from bearish to bullish
  • Histogram turns from positive to negative: Momentum shifts from bullish to bearish
  • Histogram increasing: Trend is accelerating
  • Histogram decreasing: Trend is decelerating, crossover approaching

5. Divergence Signals

  • Bearish Divergence: Price makes a new high, MACD does not — upward momentum is fading
  • Bullish Divergence: Price makes a new low, MACD does not — downward momentum is fading
Caution

MACD divergence can persist for a long time during strong trends; entering too early can lead to losses. It is advisable to wait for an actual crossover confirmation before acting.


V. Advantages, Disadvantages, and Use Cases

Advantages

AdvantageDescription
Dual functionalityCombines trend following and momentum oscillation
Rich signalsCrossovers, zero line, histogram, and divergence provide multi-layered information
Less lagBased on EMA rather than SMA, responds faster
Widely recognizedUniversal among global traders, strong self-fulfilling effect

Disadvantages

DisadvantageDescription
False signals in ranging marketsFrequent crossovers during trendless, sideways consolidation
No fixed boundariesUnlike RSI’s 0-100 range, difficult to define absolute overbought/oversold
Still has lagBased on moving averages, inherently a lagging indicator
Parameter dependent(12,26,9) is not optimal for all markets

Use Cases

  • Medium to long-term trend trading: MACD signal line crossovers are suited for capturing multi-week trends
  • Swing trading: Histogram changes help identify short-term momentum shifts
  • Trend confirmation: Combined with price patterns, e.g., breakout + bullish MACD cross as dual confirmation
ComparisonMACDRSIStochastic
TypeTrend + MomentumPure MomentumPure Momentum
Value RangeUnbounded0-1000-100
Best ScenarioTrending marketsRanging marketsRanging markets
Signal DelayMediumLowLow
Practical Tips
  1. Zero line filter: Only go long when MACD > 0, only go short when MACD < 0 — this significantly reduces false signals.
  2. Multi-timeframe: Use MACD on the daily chart for direction, find entries on the hourly chart.
  3. Histogram leads: The Histogram’s turning point usually precedes the MACD line crossover and can serve as an early warning.
  4. Combine with RSI: Bullish MACD cross + RSI recovering from oversold = stronger buy signal.