Guppy Multiple Moving Average (GMMA)

Haiyue
13min

I. What is the Guppy MMA Indicator

The Guppy Multiple Moving Average (GMMA or Guppy MMA) is an indicator system composed of 12 Exponential Moving Averages (EMAs). It is divided into a short-term group and a long-term group. By observing the expansion, contraction, and crossover relationships between the two groups, traders can assess trend conditions and the behavior of different market participants.

Historical Background

GMMA was invented by Australian trader and financial columnist Daryl Guppy. He systematically presented this method in his 2004 book Trend Trading. His core insight was that markets are driven by two types of participants — short-term traders and long-term investors — and two groups of EMAs with different periods can represent the behavior of each group respectively.

Guppy’s innovation lies not in the calculation of the moving averages themselves, but in reading multiple moving averages as a whole to interpret market structure. GMMA is more of an analytical framework than a single indicator.

Indicator Classification

  • Type: Overlay indicator, plotted on the price chart
  • Category: Moving Averages, multiple moving average system
  • Default Parameters:
    • Short-term group (Traders): EMA(3), EMA(5), EMA(8), EMA(10), EMA(12), EMA(15)
    • Long-term group (Investors): EMA(30), EMA(35), EMA(40), EMA(45), EMA(50), EMA(60)

II. Mathematical Principles and Calculation

Core Formula

Each line in GMMA is a standard EMA:

EMAt(p)=αpPt+(1αp)EMAt1(p)EMA_t^{(p)} = \alpha_p \cdot P_t + (1 - \alpha_p) \cdot EMA_{t-1}^{(p)}

where αp=2p+1\alpha_p = \frac{2}{p + 1} and pp is the corresponding period.

Short-term group (Traders Group) — 6 EMAs:

{EMA(3), EMA(5), EMA(8), EMA(10), EMA(12), EMA(15)}\{EMA(3),\ EMA(5),\ EMA(8),\ EMA(10),\ EMA(12),\ EMA(15)\}

Long-term group (Investors Group) — 6 EMAs:

{EMA(30), EMA(35), EMA(40), EMA(45), EMA(50), EMA(60)}\{EMA(30),\ EMA(35),\ EMA(40),\ EMA(45),\ EMA(50),\ EMA(60)\}

Interpretation Methods

The core of GMMA is not the formula, but interpreting visual patterns. The following dimensions should be observed:

1. Intra-group Separation

The spacing between the 6 lines within each group reflects the degree of consensus among that type of participant:

Intra-group SeparationMeaning
Wide expansionStrong trend conviction — participants agree on direction
Narrow contractionIndecision — participants may be changing direction

2. Inter-group Relationship

PatternMeaning
Short-term group aboveTraders are bullish, driving prices up
Long-term group aboveInvestors are bearish or holding short
Two groups intertwinedTrend unclear, bulls and bears in tug-of-war

3. Compression-to-Expansion Transitions

CompressionExpansion=New trend forming\text{Compression} \rightarrow \text{Expansion} = \text{New trend forming} ExpansionCompression=Trend weakening\text{Expansion} \rightarrow \text{Compression} = \text{Trend weakening}

Core Concept

According to Guppy:

  • The short-term group represents short-term traders — their sentiment changes quickly and is easily affected by noise
  • The long-term group represents institutional investors — their decisions are more stable, representing “smart money”
  • When both groups expand in the same direction, the trend is strongest; when the long-term group begins to contract, the major trend may be ending

III. Python Implementation

import numpy as np
import pandas as pd

def guppy_mma(close: pd.Series) -> pd.DataFrame:
    """
    Calculate Guppy Multiple Moving Average (GMMA)

    Parameters
    ----------
    close : pd.Series
        Close price series

    Returns
    -------
    pd.DataFrame
        DataFrame containing 12 EMAs
    """
    # Short-term group (Traders)
    short_periods = [3, 5, 8, 10, 12, 15]
    # Long-term group (Investors)
    long_periods = [30, 35, 40, 45, 50, 60]

    result = pd.DataFrame(index=close.index)

    for p in short_periods:
        result[f"ST_{p}"] = close.ewm(span=p, adjust=False).mean()

    for p in long_periods:
        result[f"LT_{p}"] = close.ewm(span=p, adjust=False).mean()

    return result


def guppy_analysis(close: pd.Series) -> pd.DataFrame:
    """
    GMMA analysis: calculate moving averages and generate
    inter-group / intra-group metrics

    Returns
    -------
    pd.DataFrame
        DataFrame with GMMA lines and analysis metrics
    """
    short_periods = [3, 5, 8, 10, 12, 15]
    long_periods = [30, 35, 40, 45, 50, 60]

    df = pd.DataFrame(index=close.index)

    # Calculate all EMAs
    short_emas = []
    for p in short_periods:
        col = f"ST_{p}"
        df[col] = close.ewm(span=p, adjust=False).mean()
        short_emas.append(col)

    long_emas = []
    for p in long_periods:
        col = f"LT_{p}"
        df[col] = close.ewm(span=p, adjust=False).mean()
        long_emas.append(col)

    # Short-term group mean
    df["ST_mean"] = df[short_emas].mean(axis=1)
    # Long-term group mean
    df["LT_mean"] = df[long_emas].mean(axis=1)

    # Short-term group spread (standard deviation)
    df["ST_spread"] = df[short_emas].std(axis=1)
    # Long-term group spread
    df["LT_spread"] = df[long_emas].std(axis=1)

    # Inter-group gap
    df["group_gap"] = df["ST_mean"] - df["LT_mean"]

    # Trend determination
    df["trend"] = np.where(
        df["group_gap"] > 0, "BULLISH",
        np.where(df["group_gap"] < 0, "BEARISH", "NEUTRAL")
    )

    # Trend strength (inter-group gap / long-term group spread)
    df["trend_strength"] = np.abs(df["group_gap"]) / (df["LT_spread"] + 1e-10)

    return df


# ========== Usage Example ==========
if __name__ == "__main__":
    np.random.seed(42)
    dates = pd.date_range("2024-01-01", periods=200, freq="D")

    # Construct price series: trend -> consolidation -> trend
    trend = np.concatenate([
        np.linspace(0, 15, 70),       # Uptrend
        np.random.randn(60) * 0.2,    # Consolidation
        np.linspace(0, -12, 70),      # Downtrend
    ])
    price = 100 + trend + np.random.randn(200) * 0.4

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

    # Calculate GMMA
    gmma = guppy_mma(df["close"])
    print("=== GMMA 12 Moving Averages (Last 5 Rows) ===")
    print(gmma.tail(5).round(2))

    # Detailed analysis
    analysis = guppy_analysis(df["close"])
    print("\n=== GMMA Trend Analysis ===")
    cols = ["ST_mean", "LT_mean", "group_gap", "ST_spread",
            "LT_spread", "trend", "trend_strength"]
    print(analysis[cols].tail(10).round(3))

    # Trend change signals
    analysis["trend_change"] = analysis["trend"] != analysis["trend"].shift(1)
    changes = analysis.loc[analysis["trend_change"], ["trend", "group_gap"]]
    print("\n=== Trend Change Points ===")
    print(changes)

    # Spread analysis
    print("\n=== Spread Statistics ===")
    print(f"Short-term group average spread: {analysis['ST_spread'].mean():.4f}")
    print(f"Long-term group average spread: {analysis['LT_spread'].mean():.4f}")
    print(f"Average trend strength: {analysis['trend_strength'].mean():.2f}")

IV. Problems the Indicator Solves

1. Trend Confirmation and Strength Assessment

GMMA provides richer trend information than a single moving average:

ObservationAssessment
Both groups expanding in same directionStrong trend established
Short-term group crosses long-term groupPotential trend reversal
Long-term group begins to contractMajor trend weakening
Both groups fully intertwinedNo trend / consolidation

2. Distinguishing Trader and Investor Behavior

This is GMMA’s most unique perspective:

  • Short-term group expanded: Short-term capital is in agreement on direction
  • Long-term group expanded: Institutional capital has a clear stance
  • Short-term group compressed but long-term group expanded: Short-term profit-taking, but the major trend is intact
  • Both groups expanded simultaneously: Market-wide consensus, strongest trend

3. Entry and Exit Timing

Entry signals:

  • Short-term group crosses above long-term group from below, and both groups begin to expand
  • When long-term group remains expanded, short-term group pulls back (contracts) then expands again (pullback buy)

Exit signals:

  • Short-term group begins to contract and approaches the long-term group
  • Long-term group begins to contract (precursor to major trend ending)

4. False Breakout Identification

When price breaks through a level, observe the long-term group’s reaction:

  • Long-term group begins expanding and follows along -> true breakout
  • Long-term group remains unmoved -> likely a false breakout
Important

GMMA is a visual analysis system and does not produce precise numerical buy/sell signals. Its value lies in providing a panoramic view of market structure, helping traders understand trend quality and participant behavior, rather than replacing precise entry/exit calculations.

During an uptrend, price pullbacks come in two varieties:

  • Healthy pullback: Short-term group contracts and touches the long-term group, but the long-term group remains expanding upward -> trend continuation, buying opportunity
  • Trend termination: Short-term group crosses through the long-term group, and the long-term group begins to contract -> trend may be ending
Practical Rules of Thumb
  • “Short follows long” -> Short-term group follows long-term group direction -> Trend confirmed
  • “Short kisses long” -> Short-term group pulls back to touch long-term group -> Pullback buy point
  • “Short crosses long” -> Short-term group crosses through long-term group -> Potential trend reversal
  • “Full compression” -> All moving averages converge -> Major move imminent

V. Advantages, Disadvantages, and Use Cases

Advantages

AdvantageDescription
Information-rich12 moving averages provide multi-dimensional market information
Participant differentiationUniquely separates market participants into traders and investors
Trend qualityJudges trend quality and sustainability through spread analysis
Simple calculationUses only standard EMAs with no complex mathematics
Visually intuitiveVisual patterns on charts are very intuitive

Disadvantages

DisadvantageDescription
High subjectivityPattern interpretation depends on trader experience and judgment
Hard to quantifyDifficult to convert visual patterns into precise quantitative signals
Chart clutter12 moving averages displayed simultaneously make charts complex
All laggingFundamentally still EMAs, all lines have lag
Not suited for automationPrimarily designed as a visual analysis tool, difficult for automated strategies

Use Cases

  • Manual trend trading: Visually assess trend quality and direction from charts
  • Swing trading: Use short-term group pullback-to-long-term-group patterns to find entry points
  • Trend confirmation: After other strategies generate signals, use GMMA to confirm trend quality
  • Daily and higher timeframes: GMMA works best on higher timeframes

Comparison with Other Moving Average Systems

System# of MAsCore ConceptUsage Method
GMMA12 EMAsTraders vs InvestorsVisual analysis
Dual MA crossover2Fast/slow line crossoverSignal-driven
Triple MA system3Short/medium/long alignmentSignal + filter
MA ribbonMultipleTrend bandwidthVisual analysis
Notes
  1. GMMA is not a “set parameters and auto-trade” indicator. It requires the trader to have the ability to interpret visual patterns.
  2. Beginners tend to over-interpret small changes in GMMA. Focus on major patterns (such as inter-group crossovers, long-term group expansion/contraction) and ignore minor daily fluctuations.
  3. To use GMMA in quantitative strategies, visual patterns need to be digitized (such as intra-group spread, inter-group distance, etc.), but be aware that this digitization may lose some nuanced information from visual analysis.
  4. GMMA is best suited for medium-to-long-term trend analysis. It does not perform well on very short timeframes (such as 1-minute charts).