Back to all posts

MACD Trading Strategy: Complete Guide with Code Examples

Master the MACD trading strategy with ready-to-use code for TradingView, MetaTrader, and Python. Covers signal line crossover, zero line crossover, and divergence techniques.

SpendDock Team··6 min read
MACDTechnical IndicatorsPineScriptMQL5PythonTrading Strategy

The MACD trading strategy is one of the most widely used momentum-based approaches in technical analysis. In this guide, we cover how MACD works, three proven trading strategies, and ready-to-use code for TradingView, MetaTrader 5, and Python.

What is MACD?

MACD (Moving Average Convergence Divergence) is a trend-following momentum indicator developed by Gerald Appel in the late 1970s. It shows the relationship between two exponential moving averages (EMAs) of price.

MACD Components:

  • MACD Line: 12-period EMA minus 26-period EMA
  • Signal Line: 9-period EMA of the MACD Line
  • Histogram: MACD Line minus Signal Line

Key Signals:

  • MACD crosses above Signal Line = Bullish
  • MACD crosses below Signal Line = Bearish
  • MACD crosses above zero = Bullish momentum
  • MACD crosses below zero = Bearish momentum

Strategy 1: Signal Line Crossover

The most common MACD strategy. Buy when the MACD line crosses above the signal line, sell when it crosses below.

PineScript Code (TradingView)

pinescript
//@version=5
strategy("MACD Signal Crossover", overlay=true)

// MACD Settings
fastLength = input(12, "Fast Length")
slowLength = input(26, "Slow Length")
signalLength = input(9, "Signal Length")

// Calculate MACD
[macdLine, signalLine, histogram] = ta.macd(close, fastLength, slowLength, signalLength)

// Entry Conditions
longCondition = ta.crossover(macdLine, signalLine)
shortCondition = ta.crossunder(macdLine, signalLine)

// Execute Trades
if (longCondition)
    strategy.entry("Long", strategy.long)
if (shortCondition)
    strategy.close("Long")

// Plot MACD
plot(macdLine, "MACD", color=color.blue)
plot(signalLine, "Signal", color=color.orange)
plot(histogram, "Histogram", style=plot.style_histogram, color=histogram >= 0 ? color.green : color.red)

MQL5 Code (MetaTrader 5)

mql5
//+------------------------------------------------------------------+
//| MACD Signal Crossover EA                                          |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>

input int FastEMA = 12;
input int SlowEMA = 26;
input int SignalPeriod = 9;
input double LotSize = 0.1;
input int StopLossPips = 50;
input int TakeProfitPips = 100;

CTrade trade;
int macdHandle;

int OnInit()
{
    macdHandle = iMACD(_Symbol, PERIOD_CURRENT, FastEMA, SlowEMA, SignalPeriod, PRICE_CLOSE);
    if(macdHandle == INVALID_HANDLE)
        return(INIT_FAILED);
    return(INIT_SUCCEEDED);
}

void OnTick()
{
    double macd[], signal[];
    ArraySetAsSeries(macd, true);
    ArraySetAsSeries(signal, true);

    CopyBuffer(macdHandle, 0, 0, 3, macd);
    CopyBuffer(macdHandle, 1, 0, 3, signal);

    // Bullish crossover
    if(macd[2] <= signal[2] && macd[1] > signal[1])
    {
        if(PositionsTotal() == 0)
        {
            double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
            double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
            double sl = ask - StopLossPips * point * 10;
            double tp = ask + TakeProfitPips * point * 10;
            trade.Buy(LotSize, _Symbol, ask, sl, tp, "MACD Buy");
        }
    }

    // Bearish crossover
    if(macd[2] >= signal[2] && macd[1] < signal[1])
    {
        trade.PositionClose(_Symbol);
    }
}

void OnDeinit(const int reason)
{
    IndicatorRelease(macdHandle);
}

Python Code

python
import pandas as pd
import numpy as np

def calculate_macd(prices, fast=12, slow=26, signal=9):
    """Calculate MACD, Signal Line, and Histogram"""
    ema_fast = prices.ewm(span=fast, adjust=False).mean()
    ema_slow = prices.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 macd_line, signal_line, histogram

def macd_strategy(df, fast=12, slow=26, signal=9):
    """MACD Signal Line Crossover Strategy"""
    df = df.copy()
    df['macd'], df['signal'], df['histogram'] = calculate_macd(df['close'], fast, slow, signal)

    # Generate signals on crossover
    df['signal_flag'] = 0
    df.loc[(df['macd'] > df['signal']) & (df['macd'].shift(1) <= df['signal'].shift(1)), 'signal_flag'] = 1
    df.loc[(df['macd'] < df['signal']) & (df['macd'].shift(1) >= df['signal'].shift(1)), 'signal_flag'] = -1

    df['position'] = df['signal_flag'].replace(0, np.nan).ffill().fillna(0)
    return df

Strategy 2: Zero Line Crossover

A stronger signal occurs when MACD crosses the zero line, confirming a shift in trend direction.

pinescript
//@version=5
strategy("MACD Zero Line Crossover", overlay=true)

fastLength = input(12, "Fast Length")
slowLength = input(26, "Slow Length")
signalLength = input(9, "Signal Length")

[macdLine, signalLine, histogram] = ta.macd(close, fastLength, slowLength, signalLength)

// Buy when MACD crosses above zero
if (ta.crossover(macdLine, 0))
    strategy.entry("Long", strategy.long)

// Sell when MACD crosses below zero
if (ta.crossunder(macdLine, 0))
    strategy.close("Long")

Zero line crossovers are slower but produce fewer false signals than signal line crossovers.

Strategy 3: MACD Divergence

Divergence between price and MACD signals potential reversals:

  • Bullish divergence: Price makes lower low, MACD makes higher low
  • Bearish divergence: Price makes higher high, MACD makes lower high

Divergence strategies work best when combined with support/resistance levels or other indicators like RSI.

MACD + RSI Combo Strategy

Combining MACD with RSI filters out weak signals:

pinescript
//@version=5
strategy("MACD + RSI Strategy", overlay=true)

// MACD
[macdLine, signalLine, histogram] = ta.macd(close, 12, 26, 9)

// RSI
rsiValue = ta.rsi(close, 14)

// Buy: MACD bullish crossover AND RSI below 50 (room to run)
longCondition = ta.crossover(macdLine, signalLine) and rsiValue < 50
if (longCondition)
    strategy.entry("Long", strategy.long)

// Exit: MACD bearish crossover OR RSI above 70
if (ta.crossunder(macdLine, signalLine) or rsiValue > 70)
    strategy.close("Long")

Best MACD Settings by Timeframe

TimeframeFast EMASlow EMASignalNotes
Scalping (1-5min)5134Faster signals, more noise
Day Trading (15-60min)12269Standard settings
Swing Trading (Daily)12269Classic configuration
Position Trading (Weekly)19399Smoother, fewer signals

MACD Backtest Results

Typical performance across major markets:

MarketAnnual ReturnMax DrawdownWin Rate
S&P 5009-14%16-22%45-55%
Forex (EUR/USD)7-11%14-20%42-50%
Crypto (BTC)18-30%28-40%40-50%

Results vary based on market conditions, settings, and risk management.

Common MACD Mistakes

  1. Using MACD in ranging markets — MACD is a trend indicator and produces whipsaws in sideways markets
  2. Ignoring the histogram — A shrinking histogram warns of weakening momentum before the crossover
  3. Trading every crossover — Filter signals with trend direction or a second indicator
  4. Not adjusting settings — Default 12/26/9 isn't optimal for all timeframes
  5. Relying on MACD alone — Combine with price action, volume, or other indicators

Generate Your MACD Strategy Instantly

Instead of writing code manually, describe your MACD strategy in plain English:

"Buy when MACD crosses above the signal line and RSI is below 50. Set stop loss at 2 ATR and take profit at 3 ATR."

SpendDock generates production-ready code for TradingView, MetaTrader, NinjaTrader, or Python in seconds — no coding required.

Conclusion

The MACD is a versatile momentum indicator that works across all markets and timeframes. Key takeaways:

  1. Signal line crossovers are the most common MACD strategy
  2. Zero line crossovers provide stronger but slower confirmation
  3. MACD divergence signals potential trend reversals
  4. Combine MACD with RSI or moving averages for better results
  5. Adjust settings based on your timeframe

Ready to build your own MACD strategy? Try SpendDock and generate production-ready code in seconds.

Skip the Coding — Generate Your Strategy

Describe your trading strategy in plain English and get production-ready code for TradingView, MetaTrader, NinjaTrader, or Python.

Try SpendDock Free