ADXVMA Indicator: The Volatility-Adaptive Moving Average That Goes Flat During Chop
Overview #
Every adaptive moving average tries to solve the same problem: how do you build a trend indicator that actually flattens during consolidation instead of whipsawing through it? The ADXVMA (ADX Volatility Moving Average) is one of the most sophisticated answers to that question. It uses three consecutive layers of exponential smoothing to build a volatility index — where simpler alternatives like VIDYA use one — and that extra smoothing is precisely what makes it go flat and stay flat when markets are ranging.
The result is an indicator that trades raw responsiveness for superior consolidation detection. It will lag behind KAMA or a simple EMA when a trend reverses, but it's less likely to fire false signals during the 70% of the day when futures markets are going nowhere. For discretionary traders who use it as a filter, and for automated strategy developers who want a regime classifier, that trade-off is often the right one.
Understanding the ADXVMA properly requires understanding what it actually calculates — not the name, which implies an ADX-based formula, but the math, which reveals it as a heavily-smoothed descendant of Tushar Chande's VIDYA. Once you see how those three smoothing layers interact, the indicator's behavior stops being mysterious and starts being predictable.
The Origins: VIDYA, CMO, and the ADX Connection #
The ADXVMA name creates a misleading impression that it derives from Welles Wilder's ADX. It doesn't — not directly. As [Fat Tails clarified on NexusFi] [1], there's no direct link to the ADX formula and the indicator doesn't even use the true range. The connection is conceptual.
Both ADX and ADXVMA split bar-to-bar moves into separate up-moves and down-moves before doing anything else. You can think of ADXVMA as "a nephew of the ADX" — it borrows the directional movement decomposition idea from Wilder's work, then applies Chande's adaptive smoothing framework on top of it.
The real parent is VIDYA (Variable Index Dynamic Average), created by Tushar Chande. VIDYA is an exponential moving average with a dynamic smoothing constant — instead of a fixed k = 2/(n+1), the smoothing constant is modulated by the absolute value of the CMO (Chande Momentum Oscillator). When CMO is high (strong trend), the smoothing is faster. When CMO is near zero (ranging market), the smoothing is minimal and the average barely moves.
ADXVMA takes that core concept and replaces Chande's CMO-based volatility measurement with a different one — one that uses three consecutive EMA layers instead of a single-pass CMO. The practical effect, as [Big Mike described it in plain English] [2], is: "It uses a VMA and ADX together to plot the MA. The MA is primarily based on the VMA of price but uses the ADX values to determine volatility, adjusting the VMA by the volatility."
How ADXVMA Actually Calculates: The Three Layers #
The ADXVMA formula proceeds through three distinct smoothing layers before it touches the price. Understanding each layer explains the indicator's behavior. The clean NinjaTrader code [published by Fat Tails] [3] after he debugged multiple buggy versions is the clearest reference.
Layer 1: EMA-smooth the directional moves.
Each bar splits into an up-move (currentUp = max(Close - Close[1], 0)) and a down-move (currentDown = max(Close[1] - Close, 0)). Both are smoothed with a Wilder-style EMA using k = 1/period (note: this uses the Wilder period convention, not the more common 2/(n+1) formula):
up.Set((1-k)*up[1] + k*currentUp)
down.Set((1-k)*down[1] + k*currentDown)
Then fractions are calculated:
fractionUp = up / (up + down)
fractionDown = down / (up + down)
Layer 2: EMA-smooth those fractions.
The normalized fractions from Layer 1 are themselves smoothed with another EMA pass:
ups.Set((1-k)*ups[1] + k*fractionUp)
downs.Set((1-k)*downs[1] + k*fractionDown)
A normalized difference is then calculated: normDiff = |ups - downs| divided by ups + downs. This value gets one more EMA pass to create the volatility index:
index.Set((1-k)*index[1] + k*normFraction)
Layer 3: Min-max normalization over the lookback period.
The volatility index index is then scaled to a 0-to-1 range using its highest and lowest values over the lookback period:
vIndex = (index - LLV(index, period+1)) / (HHV(index, period+1) - LLV(index, period+1))
Finally, vIndex drives the adaptive smoothing:
ADXVMA = (1 - k*vIndex)*ADXVMA[1] + k*vIndex*Input
When vIndex ≈ 0, the smoothing is nearly zero and ADXVMA barely moves — this is the flat "neutral" state. When vIndex ≈ 1, the smoothing is at full speed k and ADXVMA tracks price closely — this is the trend state.
Why three layers matter. VIDYA (and its CMO-based approach) uses one smoothing pass before calculating its volatility index. ADXVMA uses three. As Fat Tails explained in his [detailed comparison post] [1]: "Those additional layers slow the ADXVMA further down... ADXVMA therefore lags compared to the VMA, it detects consolidation at a later stage, but once it has detected a consolidation it stays flat for a longer time."
This is the core trade-off. ADXVMA is slower to recognize a transition but more committed once it does.
The Three Color States: Rising, Falling, and Neutral #
One of the most useful aspects of Fat Tails' NinjaTrader implementation (anaADXVMA) is the explicit trend state exposure. Rather than making you infer trend direction from the slope of the line, the indicator provides a public IntSeries Trend that returns:
- +1: Uptrend (ADXVMA is rising — each bar above the previous)
- -1: Downtrend (ADXVMA is falling)
- 0: Neutral (ADXVMA is flat — within a threshold of the previous value)
This makes ADXVMA genuinely useful as a strategy component, not just a visual aid. As [Fat Tails explained for strategy developers] [4]:
// Check for uptrend
if(anaADXVMA(period).Trend[0] == 1)
// do something here
// Check for downtrend
if(anaADXVMA(period).Trend[0] == -1)
// do something here
// Check for neutral trend
if(anaADXVMA(period).Trend[0] == 0)
// do something here
The neutral state is the key differentiator from simply checking the slope of an EMA. An EMA always has a slope, even during consolidation. ADXVMA explicitly codes "I don't know" as a distinct state you can act on.
In chart display, most implementations use this three-state structure to color the line: green during uptrends, red during downtrends, and a neutral color (typically blue or yellow) when flat. The visual effect is striking — during ranging markets you see a flat, non-committal line that makes it obvious no directional trade is warranted.
Parameter Settings: Starting Points and Calibration #
ADXVMA has a single primary parameter: the period. The default across most implementations is 14. This follows the convention of ADX and many Wilder-based indicators (ATR, RSI) which all use 14 periods as their baseline.
Starting parameters by instrument:
- ES (E-mini S&P 500): Period 14 on 5-minute or 1,000-tick charts as a primary filter
- NQ (Nasdaq): Period 11-14 on similar timeframes (NQ trends more, can use faster setting)
- CL (Crude Oil): Period 14-21 — CL has more whipsaw; slower setting keeps you out of noise
- ZN (10-year Treasury): Period 14-21 on higher timeframes; bonds trend slowly
- 6E (Euro FX): Period 14 on 5-minute; currency futures trend well
Shorter periods (8-11): The volatility index reacts faster, generating more signals. During trending periods you'll get earlier entries. The cost is more flat-to-trend transitions during consolidation that turn out to be false starts — the indicator exits flat sooner and enters trend mode more readily.
Longer periods (18-21): More smoothing at every layer. The indicator stays flat longer during ranges and takes more committed trend action to shift its state. Better at filtering out noise in choppy instruments. The cost is later entries and later exits — you'll miss the early portion of moves.
Calibration approach: The most useful calibration method is to observe how many "false trend" periods the indicator generates on your instrument during known consolidation days (tight-range days, Holiday sessions, pre-announcement waiting periods). If you see multiple brief trend flashes during these periods, the period is too short. If it never seems to flag strong trends during obvious trending days, the period is too long.
Platform Availability and Implementation Notes #
The ADXVMA exists in multiple platform implementations, with varying quality.
NinjaTrader 7 (Fat Tails' anaADXVMA): This is the reference implementation for most serious users. [Big Mike's original EasyLanguage post] [5] from 2010 documented the conversion from an unknown NT source, and [Fat Tails subsequently rewrote the NT code] [3] to eliminate a "number of bugs and inconsistencies" in earlier versions. The cleaned-up anaADXVMA exposes the Trend IntSeries and is available from the NexusFi download section.
EasyLanguage (TradeStation / MultiCharts): The EasyLanguage version posted by Big Mike as a function + indicator is available in the NexusFi download section as a .pla file for MultiCharts. The function structure allows you to embed ADXVMA logic directly in strategy signals.
Sierra Chart: An ADXVMA implementation exists in the User Contributed Studies section. As [bobwest noted] [6], the logic is relatively straightforward to port if you want to implement it yourself.
NinjaTrader 8: The NT7 code requires modification for NT8's API but the math is identical — it's primarily syntax changes.
For NT7 strategy access: The Trend IntSeries is a public property, so you can access it from any manually-coded strategy: if(anaADXVMA(period).Trend[0] == 1). Note that the strategy builder UI does not expose this property — you need hand-coded strategies to use it as a filter.
The Multi-Timeframe Strategy Approach #
The most powerful use of ADXVMA in futures trading is as a multi-timeframe trend filter. The approach was documented by [MXASJ in a NexusFi post] [7]: a momentum strategy using ADXVMA across two timeframes — 4 Range bars for entries and 11 Range bars for the higher-timeframe filter.
The logic is clean:
- Entry timeframe: Only enter longs when the ADXVMA on 4 Range bars shows
Trend[0] == +1(three consecutive rising bars) - Filter timeframe: Also require the ADXVMA on 11 Range bars to show
Trend[0] == +1 - Additional filters: ADX(5) > 30 confirms the directional trend isn't weak
- Result: You only take entries when both timeframes confirm an uptrend — neutral states on either timeframe block the entry
In NinjaTrader strategy code:
if (ADXVMA(BarsArray[1], ADXVMAPeriod).ADXVMAPlot[0] > ADXVMA(BarsArray[1], ADXVMAPeriod).ADXVMAPlot[1]
&& ADXVMA(ADXVMAPeriod).ADXVMAPlot[0] > ADXVMA(ADXVMAPeriod).ADXVMAPlot[1]
&& ADX(ADXPeriod)[0] > ADXThreshold
&& Rising(ADX(ADXPeriod)) == true)
{
if (Position.MarketPosition == MarketPosition.Flat)
EnterLong("Long 1a");
}
MXASJ tested this on ES, 6E (Euro FX), FESX (European index), FXBL (Bund), and ZN (10-year Treasury note). The strategy performed well in high-volatility periods but "the last three months of low vol has taken a chunk of that back" — exactly what you'd expect from a trend-following approach during extended low-volatility environments.
ADXVMA vs. Other Adaptive Moving Averages #
The [adaptive MA family] [8] includes several options that traders encounter regularly. Understanding how ADXVMA compares helps you choose the right tool.
vs. KAMA (Kaufman Adaptive Moving Average): KAMA uses an Efficiency Ratio — the net directional movement divided by the total path length. This directly measures whether price is moving efficiently (trending) or inefficiently (choppy). KAMA is more responsive than ADXVMA because it uses a single smoothing layer and responds quickly to the efficiency ratio change. It's better if you want faster adaptation; ADXVMA is better if you want stronger noise rejection.
vs. VIDYA (Variable Index Dynamic Average): As [Fat Tails detailed] [1], ADXVMA is a "modified VMA" where the simple moving average in Chande's original CMO calculation is replaced with an exponential moving average, and additional layers of smoothing are added. VIDYA (using the CMO-based approach) has one smoothing layer; ADXVMA has three. VIDYA reacts faster; ADXVMA stays flat longer.
vs. Standard EMA: The fundamental difference is that a standard EMA never truly flattens — it always has a non-zero slope because it's always tracking price. ADXVMA can go genuinely flat (near-zero slope) during ranging periods. As [bobwest explained the trick] [8]: "In a highly volatile market (whippy but not much net change), the average effectively acts like a long-term ema and it changes slowly; in a trending market, going mostly one way, it acts effectively like a shorter-term ema and it changes more quickly."
Practical guidance: Use ADXVMA over a standard EMA when your primary problem is false signals during consolidation. Use KAMA when you want faster trend recognition and can tolerate more signals during ranges. Use VIDYA as a middle ground. For strategy development, ADXVMA's explicit three-state output (Trend[0]) is often cleaner to work with than inferring states from slope calculations.
Practical Limitations and Common Mistakes #
The lag problem on reversals. ADXVMA's strength during consolidation becomes a weakness at trend reversals. Because the volatility index needs to build through three smoothing layers before the smoothing constant updates, the indicator can take several bars to recognize that a strong trend has reversed. If you're using ADXVMA to time exits in addition to entries, this lag can give back significant open profits. Consider using faster exits (ATR stops, momentum-based exits) rather than relying on ADXVMA state changes to exit positions.
Period selection isn't universal. A period-14 ADXVMA on ES 5-minute bars behaves very differently from the same period on ES daily bars or on CL 5-minute bars. The instrument's inherent volatility, the bar type (time-based, range bars, tick bars, volume bars), and the typical consolidation-to-trend ratio all affect which period works best. Don't transplant settings from one context to another without recalibrating.
The neutral state isn't a short signal. Trend[0] = 0 means the ADXVMA doesn't know what the trend is, not that the market is about to reverse. In practice, neutral states are often followed by continuation of the prior trend rather than reversal. Don't fade the prior trend just because ADXVMA goes flat.
Multiple ADXVMA instances are computationally expensive. Each ADXVMA instance requires tracking multiple smoothed series (up_ema, down_ema, ups_ema, downs_ema, index, plus lookback arrays). When running multi-instrument strategies with multiple timeframes, the computational overhead adds up. If performance is a concern, consider computing ADXVMA only on the timeframe that matters most for filtering and using faster/cheaper indicators for finer-grained entries.
Platform bug risk. As Fat Tails found when he rewrote the NT code, "the NinjaTrader code was extremely dirty with a number of bugs and inconsistencies." If you're using a third-party ADXVMA implementation, verify it against the EasyLanguage reference or Fat Tails' cleaned NinjaTrader code. The key verification points: double.Epsilon comparisons instead of zero comparisons (critical for floating-point safety), proper initialization of the first ADXVMA value, and correct lookback period for the HHV/LLV calculation.
Combining ADXVMA with Order Flow #
ADXVMA is a price-based indicator — it tells you about price momentum structure but nothing about the order flow generating that structure. The natural extension is using ADXVMA to define the regime and order flow to time entries within that regime.
The most practical combination:
- ADXVMA defines trend state: Only trade in the direction of
Trend[0]. If neutral, wait. - Order flow (footprint, cumulative delta) confirms entry timing: Within an ADXVMA-defined uptrend, look for delta exhaustion on pullbacks, absorption at support levels, or bullish delta divergence to identify the specific entry bar.
- ADXVMA state change serves as a soft stop signal: When the ADXVMA transitions from uptrend to neutral, reduce position size or tighten stops. When it transitions to downtrend, exit.
This combination addresses ADXVMA's main weakness (lag on reversals) by not waiting for it to flip to downtrend before exiting — instead treating the neutral state as a warning signal.
The absorption article and cumulative delta article cover the order flow side of this combination in depth. For context on how ADXVMA fits within broader trend analysis frameworks, see trend following in futures trading.
Summary #
ADXVMA is an adaptive moving average designed to solve the whipsaw problem in trend following. Its three-layer smoothing architecture produces a volatility index that explicitly drives the average to flatline during consolidation — superior to single-layer alternatives like VIDYA at the cost of more lag at trend reversals. The three-state output (rising/flat/falling) maps cleanly to strategy logic in NinjaTrader and EasyLanguage, making it one of the more practical adaptive indicators for automated trading. Start with period 14, test on your specific instrument and bar type, and use the neutral state as a "hands off" signal rather than a trade trigger.
Knowledge Map
Citations
- — Ask any Trading Question (2013) 👍 9
- — EasyLanguage ADXVMA Indicator (2010) 👍 3
- — EasyLanguage ADXVMA Indicator (2012) 👍 8
- — Want your NinjaTrader STRATEGY created for free? (2015) 👍 6
- — EasyLanguage ADXVMA Indicator (2010) 👍 12
- — Attack of the Robots - An Algo Journal (2020) 👍 2
- — Pimp My Strat! (2009) 👍 9
- — How many of you use a moving average as a profit target? (2019) 👍 4
