Skip to content
Open RaamTrade

McGinleyDynamic — McGinley Dynamic

An average that adjusts its own speed to the gap between itself and price: the further price runs, the harder the line chases. Designed to avoid the whipsaw of a fixed-period average when the market changes pace.

Signature

McGinleyDynamic(period, on=<source>)
Argument Type Required Notes
period int Param or literal Yes Base speed. Default 14, bounds 1–400.
on= symbol, OHLCV field, or indicator No Source. Defaults to the trade symbol’s close.

Formula

$$ MD_t = MD_{t-1} + \frac{C_t - MD_{t-1}}{N,(C_t / MD_{t-1})^4} $$

The fourth power is what makes the response asymmetric: it accelerates hard when price runs away from the line.

Warmup

Starts at the first close; no window to fill.

Reading the value

md.value
self.trade.close > md.value

Example

class McGinleyTrail(Strategy):
"""Follow the dynamic line; it tightens automatically when price accelerates."""
period = Param(14, min=1, max=400)
trade = Symbol()
sizing = FixedCapital()
def execute(self):
md = McGinleyDynamic(self.period, on=self.trade)
if self.trade.close > md.value and self.trade.is_flat:
self.buy(self.trade, reason="Above McGinley")
if self.trade.close < md.value and self.trade.is_long:
self.sell(self.trade, self.trade.position, reason="Below McGinley")

Notes

  • John R. McGinley, Journal of Technical Analysis.
  • Proven by an assert-via-trade run on SPY daily (matched an independent strategy-side recursion within 0.05; zero alarm trades).
  • Guarded against a non-positive line value (it would make the ratio meaningless); on that bar the line resets to price.
  • A different recipe from pandas_ta’s mcgd(10), not a different scale: measured on a 300-bar tape ours stays about 0.7 % away and never converges to it, because the construction (window offset, seed, weight normalisation) is its own.