McGinley Dynamic MACD

An adaptive MACD variant that replaces traditional moving averages with McGinley Dynamic lines, reducing lag and whipsaws inherent in standard MACD calculations.

About the McGinley Dynamic MACD

The McGinley Dynamic MACD is an adaptive variant of the classic Moving Average Convergence Divergence (MACD) indicator. Where standard MACD uses exponential moving averages, this indicator replaces them with McGinley Dynamic lines — self-adjusting averages that automatically adapt to market speed. The result is a MACD-style oscillator with reduced lag during fast-moving markets and less noise during slow or ranging conditions.

This indicator is already an optimized form of MACD by design. The McGinley Dynamic mechanism adjusts its smoothing factor based on the ratio between the current price and the indicator value raised to the fourth power. This built-in adaptation removes the need for separate parameter tuning, making the McGinley Dynamic MACD a more robust baseline for momentum analysis.

What It Measures

The McGinley Dynamic MACD measures the difference between a short-period and a long-period McGinley Dynamic average, producing an adaptive momentum oscillator. The signal line is a McGinley Dynamic average of the MACD — an adaptive, self-adjusting smooth that highlights when momentum is accelerating or reversing. When the MACD line is above the signal line, bullish momentum is dominant; when below, bearish momentum prevails.

When to Use

  • Momentum confirmation: Identify whether bullish or bearish momentum is building before entering a trade
  • MACD/Signal crossovers: When the MACD line crosses above its McGinley Dynamic signal line, it suggests momentum is turning bullish; a cross below is bearish
  • Zero-line crossovers: A cross above zero signals shifting to positive momentum; a cross below zero signals shifting to negative momentum
  • Trend alignment: Use in conjunction with a trend-following overlay to confirm that entries are in the direction of the prevailing trend

Interpretation

  • MACD above Signal: Bullish crossover — momentum is turning up; consider long entries
  • MACD below Signal: Bearish crossover — momentum is turning down; consider short or exit
  • Positive and rising: Upward momentum is accelerating; bullish bias
  • Positive and falling: Upward momentum is weakening; watch for reversal or consolidation
  • Negative and falling: Downward momentum is accelerating; bearish bias
  • Negative and rising: Downward momentum is weakening; potential bottoming signal
  • Zero-line cross: Strong trend signal — a MACD cross above zero is bullish, below zero is bearish

Example Usage

use centaur_technical_indicators::momentum_indicators::bulk::mcginley_dynamic_macd_line;
use centaur_technical_indicators::moving_average::bulk::mcginley_dynamic;

pub fn main() {
    // fetch the data in your preferred way
    // let prices = vec![...];  // closing prices

    let short_period = 12;
    let long_period = 26;
    let signal_period = 9;
    let previous_short_mcginley = 0.0;  // Use 0.0 for the first calculation
    let previous_long_mcginley = 0.0;   // Use 0.0 for the first calculation

    let result = mcginley_dynamic_macd_line(
        &prices,
        short_period,
        previous_short_mcginley,
        long_period,
        previous_long_mcginley,
    ).expect("Failed to calculate McGinley Dynamic MACD");

    // Each element is (macd_value, short_mcginley_dynamic, long_mcginley_dynamic)
    let macd_values: Vec<f64> = result.iter().map(|t| t.0).collect();

    // Compute McGinley Dynamic signal line, seeded from the first MACD value
    let signal_values = mcginley_dynamic(&macd_values, macd_values[0], signal_period);

    println!("MACD values: {:?}", macd_values);
    println!("Signal values: {:?}", signal_values);
}
import centaur_technical_indicators as cti

# fetch the data in your preferred way
# prices = [...]  # closing prices

short_period = 12
long_period = 26
signal_period = 9
previous_short_mcginley = 0.0  # Use 0.0 for the first calculation
previous_long_mcginley = 0.0   # Use 0.0 for the first calculation

result = cti.momentum_indicators.bulk.mcginley_dynamic_macd_line(
    prices,
    short_period=short_period,
    previous_short_mcginley=previous_short_mcginley,
    long_period=long_period,
    previous_long_mcginley=previous_long_mcginley,
)

# Each element is a tuple (macd_value, short_mcginley_dynamic, long_mcginley_dynamic)
macd_values = [t[0] for t in result]

# Compute McGinley Dynamic signal line, seeded from the first MACD value
signal_values = cti.moving_average.bulk.mcginley_dynamic(
    macd_values,
    previous_mcginley_dynamic=macd_values[0],
    period=signal_period,
)

print("MACD values:", macd_values)
print("Signal values:", signal_values)
import init, {
    momentum_bulk_mcginleyDynamicMacdLine,
    ma_bulk_mcginleyDynamic
} from 'https://cdn.jsdelivr.net/npm/centaur-technical-indicators@latest/dist/web/centaur-technical-indicators.js';

await init();

// fetch the data in your preferred way
// const prices = [...];  // closing prices

const shortPeriod = 12;
const longPeriod = 26;
const signalPeriod = 9;
const previousShortMcginley = 0.0;  // Use 0.0 for the first calculation
const previousLongMcginley = 0.0;   // Use 0.0 for the first calculation

const result = momentum_bulk_mcginleyDynamicMacdLine(
    prices,
    shortPeriod,
    previousShortMcginley,
    longPeriod,
    previousLongMcginley,
);

// Each element is [macd_value, short_mcginley_dynamic, long_mcginley_dynamic]
const macdValues = result.map(t => t[0]);

// Compute McGinley Dynamic signal line, seeded from the first MACD value
const signalValues = ma_bulk_mcginleyDynamic(macdValues, macdValues[0], signalPeriod);

console.log("MACD values:", macdValues);
console.log("Signal values:", signalValues);