Skip to main content

Module adx

Module adx 

Source
Expand description

§Average Directional Index (ADX) / +DI / −DI / DX

Wilder directional movement system (period (N), classic 14):

+DM = up-move if up > down and up > 0 else 0
−DM = down-move if down > up and down > 0 else 0
TR  = true range
Smooth TR, +DM, −DM with Wilder (seed = SMA of first N, then Wilder)
+DI = 100 * smooth(+DM) / smooth(TR)
−DI = 100 * smooth(−DM) / smooth(TR)
DX  = 100 * |+DI − −DI| / (+DI + −DI)
ADX = Wilder smooth of DX (first ADX = SMA of first N DX values)

Warm-up: first bar has no prior close (TR = H−L; DM from first change needs bar 1).
First DI/DX at index N−1 after N TR/DM samples; first ADX after N DX values (index roughly 2N−2 on a continuous path).


§Trading perspective

SignalHabit (classic, not a rule)
ADX rising / > ~25Trend strength — trend systems “allowed”
ADX low / fallingRange — oscillators / mean-reversion more natural
+DI > −DIBullish directional bias
−DI > +DIBearish directional bias
DI crossDirection change screen (filter with ADX level)

ADX is not direction — only strength. Always read +DI / −DI (or price structure) for side.

§vs ATR / Supertrend / MACD

ADX/DIATRSupertrendMACD
MeasuresTrend strength + DI directionVolatility sizeTrail stop / sideMomentum of closes
Good atRegime filterStops / sizeIn/out of trendTiming / hist flips

§Pairs well with

  • Supertrend / SAR / Donchian — take breakouts only if ADX confirms trend.
  • RSI / WillR / CCI — fade extremes only if ADX is weak (range regime).
  • Moving averages — DI side + MA slope agreement.

§Engineering

AdxParamsadx / AdxStateadx_solution.
Batch uses AdxState end-to-end. After seeds, each push is O(1).
Smoothing uses the same average-seed then Wilder style as this crate’s ATR (SMA of first N samples, then ((prev·(N−1)+x)/N)).

§Word problem

Can ADX be defined on a series shorter than (2N−1) bars?

Usually no for a full ADX value (need N DM/TR seeds then N DX for ADX seed).

use finance_solution::stocks::ta::{adx, AdxParams};
let n = 40usize;
let h: Vec<_> = (0..n).map(|i| 101.0 + i as f64 * 0.2).collect();
let l: Vec<_> = (0..n).map(|i| 99.0 + i as f64 * 0.2).collect();
let c: Vec<_> = (0..n).map(|i| 100.0 + i as f64 * 0.2).collect();
let s = adx(&h, &l, &c, AdxParams::period_14()).unwrap();
assert!(s.adx.iter().any(|x| x.is_some()));
assert!(s.plus_di.iter().any(|x| x.is_some()));

Structs§

AdxBarOutput
One-bar ADX pack (any field may still be warming up).
AdxParams
ADX / DI Wilder period.
AdxSeries
AdxSolution
AdxState
Incremental ADX / DI / DX.
ValidatedAdx

Functions§

adx
adx_solution
Examples