Adaptive Composite MA (ACMA)

Category: Indicators By: Nicolas Created: February 5, 2026, 4:02 PM
February 5, 2026, 4:02 PM
Indicators
4 Comments

After extensive research and development, I’m releasing the Adaptive Composite Moving Average (ACMA), a moving average designed to address the limitations of traditional MAs by combining multiple proven adaptive techniques into a single, configurable indicator.

 

The goal was to create an MA that reduces whipsaws in ranging markets, responds quickly in trending markets, adapts automatically to changing conditions, and gives traders control over behavior through intuitive parameters.

 

Theoretical Foundations

 

ACMA builds upon established concepts from technical analysis literature:

 

  • The Efficiency Ratio was developed by Perry Kaufman for his KAMA indicator in 1995. ACMA uses it to detect whether the market is trending or ranging. Reference: “Trading Systems and Methods” by Perry Kaufman.
  • Distance Weighting comes from ALMA and Gaussian filter concepts. ACMA uses it to give higher weights to prices closer to the mean. Reference: ALMA Technical Documentation by Arnaud Legoux.
  • Recency Weighting is the foundation of classic WMA and EMA indicators. ACMA uses it to give higher weights to recent prices. Reference: Standard technical analysis literature.
  • Volatility Adaptation originates from Tushar Chande’s VIDYA indicator. ACMA uses it to adjust behavior based on volatility conditions. Reference: “The New Technical Trader” by Tushar Chande.

 

What Makes ACMA Original

 

While individual components are well-established, ACMA introduces several original elements:

 

  1. the Composite Weighting Architecture provides four selectable weighting modes in one indicator, allowing traders to switch strategies without switching tools.
  2. the Blended Stability Filter uses proportional blending instead of binary hold/update logic. This eliminates the “stair-step” artifacts common in other stability filters.
  3. the Regime-Aware Mode (Mode 4) dynamically combines distance and recency weighting based on market conditions. In trending markets it favors recency for faster response. In ranging markets it favors mean proximity for noise reduction.
  4. the Unified Sensitivity Control provides a single parameter that adjusts weighting aggressiveness across all modes consistently.

 

Parameters

 

  • LENGTH is the lookback period for calculations. Range is 5 to 100, default is 20.
  • WEIGHTMODE selects the weighting algorithm. Range is 1 to 4, default is 4.
  • SENSITIVITY controls weighting aggressiveness. Range is 1.0 to 5.0, default is 2.0.
  • STABILITYON enables or disables the stability filter. Set to 0 or 1, default is 1.

 

Weighting Modes Explained

 

  • Mode 1 (Distance): Prices near SMA receive higher weight. This produces smooth, stable output best suited for ranging markets.
  • Mode 2 (Recency): Recent prices receive higher weight. This produces reactive, fast output best suited for trending markets.
  • Mode 3 (Combined): Blends distance and recency weighting. This produces balanced output suitable for mixed conditions.
  • Mode 4 (Regime Adaptive): The Efficiency Ratio drives the blend automatically. In trends it behaves like Mode 2. In ranges it behaves like Mode 1. This is the recommended mode for most traders.

 

Recommended Settings

 

  • For Scalping: LENGTH=10, WEIGHTMODE=2, SENSITIVITY=3.0, STABILITYON=0
  • For Day Trading: LENGTH=20, WEIGHTMODE=4, SENSITIVITY=2.0, STABILITYON=1
  • For Swing Trading: LENGTH=30, WEIGHTMODE=3, SENSITIVITY=1.5, STABILITYON=1
  • For Position Trading: LENGTH=50, WEIGHTMODE=1, SENSITIVITY=1.0, STABILITYON=1
// =============================================
// ADAPTIVE COMPOSITE MOVING AVERAGE (ACMA)
// =============================================
// https://www.prorealcode.com
// Sharing ProRealTime Knowledge
// Version: 1.0
// Author: Nicolas
// Platform: ProRealTime
//
// =============================================
// OVERVIEW
// =============================================
// The ACMA is a moving average that combines multiple proven adaptive techniques
// into a unified, user-configurable indicator. It addresses common MA problems:
//
// • Whipsaws in ranging markets
// • Lag in trending markets
// • Static parameters that don’t adapt to changing conditions
//
// The indicator dynamically adjusts its behavior based on market regime,
// offering four distinct weighting modes to suit different trading styles.
//
// =============================================
// THEORETICAL FOUNDATIONS
// =============================================
// ACMA builds upon several well-established concepts:
//
// 1. EFFICIENCY RATIO (Perry Kaufman, 1995)
// Originally developed for KAMA (Kaufman Adaptive Moving Average)
// ER = Direction / Noise = |Close – Close[n]| / Σ|Close[i] – Close[i+1]|
// Range: 0 (choppy) to 1 (trending)
// Reference: “Trading Systems and Methods” by Perry Kaufman
//
// 2. DISTANCE-BASED WEIGHTING (Gaussian/ALMA concepts)
// Prices closer to the mean receive higher weights
// Similar to Arnaud Legoux Moving Average (ALMA) kernel approach
// Reference: “ALMA” by Arnaud Legoux and Dimitrios Kouzis-Loukas
//
// 3. RECENCY WEIGHTING (Classic WMA/EMA)
// Recent prices receive higher weights than older prices
// Foundation of Weighted Moving Average (WMA) and EMA
// Reference: Standard technical analysis literature
//
// 4. VOLATILITY REGIME ADAPTATION (VIDYA concepts)
// Adapts smoothing based on volatility conditions
// Similar to Tushar Chande’s VIDYA (Variable Index Dynamic Average)
// Reference: “The New Technical Trader” by Tushar Chande
//
// =============================================
// WHAT MAKES ACMA ORIGINAL
// =============================================
// While individual components are established, ACMA’s originality lies in:
//
// 1. COMPOSITE WEIGHTING ARCHITECTURE
// Four selectable weighting modes in a single indicator, allowing traders
// to switch strategies without changing indicators
//
// 2. BLENDED STABILITY FILTER
// Unlike binary hold/update logic, ACMA uses proportional blending:
// – When price and MA diverge with small magnitude, output blends smoothly
// – Eliminates “stair-step” artifacts common in stability filters
// – Formula: output = previous + (current – previous) × blendFactor
//
// 3. REGIME-AWARE MODE (Mode 4)
// Dynamically combines distance and recency weighting based on ER:
// – High ER (trending): Favors recency → faster response
// – Low ER (ranging): Favors mean proximity → noise reduction
// This dual-adaptive approach is not found in standard MAs
//
// 4. UNIFIED SENSITIVITY CONTROL
// Single parameter controls weighting aggressiveness across all modes,
// providing consistent behavior adjustment
//
// =============================================
// PARAMETERS
// =============================================
// LENGTH : Lookback period for calculations (default: 20)
// WEIGHTMODE : Weighting algorithm selection (1-4)
// 1 = Distance-based (prices near SMA weighted higher)
// 2 = Recency-based (recent prices weighted higher)
// 3 = Combined (distance × recency)
// 4 = Regime Adaptive (ER-driven blend)
// SENSITIVITY : Weighting aggressiveness, 1.0-5.0 (default: 2.0)
// Higher = more aggressive weighting
// STABILITYON : Enable stability filter, 0 or 1 (default: 1)
// Reduces whipsaws when price/MA diverge
//
// =============================================
// RECOMMENDED SETTINGS BY TRADING STYLE
// =============================================
// Scalping : LENGTH=10, WEIGHTMODE=2, SENSITIVITY=3.0, STABILITYON=0
// Day Trading : LENGTH=20, WEIGHTMODE=4, SENSITIVITY=2.0, STABILITYON=1
// Swing Trading : LENGTH=30, WEIGHTMODE=3, SENSITIVITY=1.5, STABILITYON=1
// Position : LENGTH=50, WEIGHTMODE=1, SENSITIVITY=1.0, STABILITYON=1
//
// =============================================

// === PARAMETERS ===
LENGTH = 20
WEIGHTMODE = 4
SENSITIVITY = 2.0
STABILITYON = 1

// === CORE CALCULATIONS ===
sma = average[LENGTH](close)
stdev = std[LENGTH](close)

IF stdev = 0 THEN
stdev = 0.0001
ENDIF

// === EFFICIENCY RATIO ===
// Measures trend strength: 0 = choppy/ranging, 1 = strong trend
// Formula from Kaufman’s Adaptive Moving Average (KAMA)
direction = ABS(close – close[LENGTH])
noise = 0

FOR i = 0 TO LENGTH – 2
noise = noise + ABS(close[i] – close[i + 1])
NEXT

IF noise > 0 THEN
efficiencyRatio = direction / noise
ELSE
efficiencyRatio = 0.5
ENDIF

// === WEIGHTED MOVING AVERAGE CALCULATION ===
sumWeights = 0
weightedSum = 0

FOR i = 0 TO LENGTH – 1
currentPrice = close[i]

// Calculate normalized distance from mean
distance = ABS(currentPrice – sma) / stdev
IF distance < 0.1 THEN
distance = 0.1
ENDIF

// === WEIGHTING MODE SELECTION ===

IF WEIGHTMODE = 1 THEN
// ─────────────────────────────────────────────────
// MODE 1: DISTANCE-BASED
// Concept: Prices closer to SMA are more “reliable”
// Effect: Smooths outliers, stable in ranges
// ─────────────────────────────────────────────────
weight = POW(1 / distance, SENSITIVITY)

ELSIF WEIGHTMODE = 2 THEN
// ─────────────────────────────────────────────────
// MODE 2: RECENCY-BASED
// Concept: Recent prices are more relevant
// Effect: Reactive, follows price closely
// ─────────────────────────────────────────────────
weight = POW(LENGTH – i, SENSITIVITY)

ELSIF WEIGHTMODE = 3 THEN
// ─────────────────────────────────────────────────
// MODE 3: COMBINED
// Concept: Balance proximity and recency
// Effect: Moderate reactivity with noise filtering
// ─────────────────────────────────────────────────
distWeight = POW(1 / distance, SENSITIVITY / 2)
recWeight = POW(LENGTH – i, SENSITIVITY / 2)
weight = distWeight * recWeight

ELSE
// ─────────────────────────────────────────────────
// MODE 4: REGIME ADAPTIVE (Recommended)
// Concept: Let market conditions drive the blend
// – Trending (high ER): Favor recency
// – Ranging (low ER): Favor mean proximity
// Effect: Self-adjusting to market regime
// ─────────────────────────────────────────────────
trendWeight = POW(LENGTH – i, SENSITIVITY * efficiencyRatio)
meanWeight = POW(1 / distance, SENSITIVITY * (1 – efficiencyRatio))
weight = trendWeight * meanWeight

ENDIF

weightedSum = weightedSum + (currentPrice * weight)
sumWeights = sumWeights + weight
NEXT

IF sumWeights > 0 THEN
acmaRaw = weightedSum / sumWeights
ELSE
acmaRaw = sma
ENDIF

// === STABILITY FILTER ===
// Reduces whipsaws when price and MA move in opposite directions
// Uses blended transition instead of hard switching to avoid stair-steps

IF STABILITYON = 1 THEN
priceChange = close – close[1]
acmaChange = acmaRaw – acmaRaw[1]

// Adaptive threshold: tighter in trends, looser in ranges
stabilityThreshold = 0.1 + (0.3 * (1 – efficiencyRatio))

IF acmaRaw[1] <> 0 THEN
relativeChange = ABS(acmaChange / acmaRaw[1])
ELSE
relativeChange = 0
ENDIF

// Detect divergence: price and MA moving opposite directions
isDiverging = (priceChange > 0 AND acmaChange < 0) OR (priceChange < 0 AND acmaChange > 0)

IF isDiverging AND relativeChange < stabilityThreshold THEN
// Smooth blend instead of hard hold
blendFactor = relativeChange / stabilityThreshold
acma = acmaRaw[1] + (acmaRaw – acmaRaw[1]) * blendFactor
ELSE
acma = acmaRaw
ENDIF
ELSE
acma = acmaRaw
ENDIF

// === OUTPUT ===
RETURN acma AS “ACMA”

Feedback Welcome

This is version 1.0. I’m actively developing this indicator and welcome feedback from the community. If you have suggestions or find issues, please comment below.

Download
Filename: ACMA-moving-average.png
Downloads: 15
Download
Filename: PRC_Adaptive-Composite-MA.itf
Downloads: 49
Nicolas Master
I created ProRealCode because I believe in the power of shared knowledge. I spend my time coding new tools and helping members solve complex problems. If you are stuck on a code or need a fresh perspective on a strategy, I am always willing to help. Welcome to the community!
Author’s Profile

Comments

Logo Logo
Loading...