Chande Momentum Oscillator (Tushar Chande, 1994) — the normalised
difference between the up moves and the down moves of the last period
bars, bounded −100..100:
cmo =100 · (Σ up − Σ down) / (Σ up +Σ down)
where up and down are the positive and negative parts of the bar-over-bar
change (upDownLegValues) and both sums are plain, unsmoothed
window sums.
Appends one column; undefined for the first period rows. Note that is
period, not period − 1: CMO is computed from differences, so a
period-bar sum of them needs period + 1 bars of input — the rsi
warm-up, for the same reason.
Definition — Chande's unsmoothed sums, deliberately not TA-Lib's CMO
TA-Lib's CMO is a different indicator, and it is one this package
already ships. TA-Lib smooths the two legs with Wilder's recursion before
taking the ratio, which makes its CMO exactly 2 · RSI − 100 — measured
on the oracle's own input, talib.CMO and 2 · talib.RSI − 100 agree to
2.8e-14 at both period 14 and period 5. So shipping TA-Lib's
definition would have added a study that is an affine re-scaling of
rsi: a second name for a shipped column, differing from it
invisibly. Step 0 of the studies README exists to catch precisely that.
What ships is therefore Chande's original: unsmoothed sums over the
window, which is also the form the corpus names (ChartIQ: "unsmoothed
up/down sums") and the one VIDYA's adaptive smoothing constant is defined
on. It is a genuinely different series from the Wilder-smoothed one, not a
warm-up transient: measured against talib.CMO on the oracle input it
differs by up to 68.28 points at period 14 and 131.55 at
period 5, on a scale that only spans 200. The two agree on where the
warm-up ends (both first emit on bar period), which is what makes the
difference a definition rather than an alignment.
A caller who wants TA-Lib's number has it exactly, today, as
2 · rsi(...) − 100 — a fact the oracle asserts rather than a claim this
docstring makes.
Edges
Bounded −100..100 by construction: |Σup − Σdown| ≤ Σup + Σdown.
+100 is a window with no down bars, −100 one with no up bars; both
are real readings, not saturation.
A perfectly flat window (Σup + Σdown = 0) → undefined. The ratio
is 0/0: there is no momentum to normalise, and 0 is the value CMO
gives for a balanced window, so emitting it here would conflate "no
movement" with "movement that cancelled". The rsi precedent. No
guard is written for it — with non-negative legs a zero denominator
forces a zero numerator, so the case is0/0 and arrives as NaN on
its own; a guard would be code no test could distinguish from its
absence.
An unchanged bar counts as neither up nor down — it contributes 0
to both sums, which shrinks nothing but the ratio's sensitivity.
Scale- and shift-invariant: the legs are differences (so a constant
added to every price cancels) and the ratio is homogeneous of degree
zero (so a scale factor cancels). Both pinned by property tests — CMO is
on the rsi side of the scale pair, not the atr side.
A leading gap shifts the start (running over another study's output
begins that many bars later) — the sums are windowed, not recursive, so
nothing is poisoned.
An interior gap costs the windows containing it, and CMO recovers
once it leaves: the bar with the gap and the period bars after it are
undefined, then values resume. This is the window rule, and it is the
deliberate asymmetry against rsi, whose Wilder recursion carries
an interior gap to the end of the series.
Chande Momentum Oscillator (Tushar Chande, 1994) — the normalised difference between the up moves and the down moves of the last
periodbars, bounded−100..100:where
upanddownare the positive and negative parts of the bar-over-bar change (upDownLegValues) and both sums are plain, unsmoothed window sums.Appends one column;
undefinedfor the firstperiodrows. Note that isperiod, notperiod − 1: CMO is computed from differences, so aperiod-bar sum of them needsperiod + 1bars of input — the rsi warm-up, for the same reason.Definition — Chande's unsmoothed sums, deliberately not TA-Lib's
CMOTA-Lib's
CMOis a different indicator, and it is one this package already ships. TA-Lib smooths the two legs with Wilder's recursion before taking the ratio, which makes itsCMOexactly2 · RSI − 100— measured on the oracle's own input,talib.CMOand2 · talib.RSI − 100agree to 2.8e-14 at bothperiod 14andperiod 5. So shipping TA-Lib's definition would have added a study that is an affine re-scaling of rsi: a second name for a shipped column, differing from it invisibly. Step 0 of the studies README exists to catch precisely that.What ships is therefore Chande's original: unsmoothed sums over the window, which is also the form the corpus names (ChartIQ: "unsmoothed up/down sums") and the one VIDYA's adaptive smoothing constant is defined on. It is a genuinely different series from the Wilder-smoothed one, not a warm-up transient: measured against
talib.CMOon the oracle input it differs by up to 68.28 points atperiod 14and 131.55 atperiod 5, on a scale that only spans 200. The two agree on where the warm-up ends (both first emit on barperiod), which is what makes the difference a definition rather than an alignment.A caller who wants TA-Lib's number has it exactly, today, as
2 · rsi(...) − 100— a fact the oracle asserts rather than a claim this docstring makes.Edges
−100..100by construction:|Σup − Σdown| ≤ Σup + Σdown.+100is a window with no down bars,−100one with no up bars; both are real readings, not saturation.Σup + Σdown = 0) →undefined. The ratio is0/0: there is no momentum to normalise, and0is the value CMO gives for a balanced window, so emitting it here would conflate "no movement" with "movement that cancelled". The rsi precedent. No guard is written for it — with non-negative legs a zero denominator forces a zero numerator, so the case is0/0and arrives asNaNon its own; a guard would be code no test could distinguish from its absence.0to both sums, which shrinks nothing but the ratio's sensitivity.periodbars after it areundefined, then values resume. This is the window rule, and it is the deliberate asymmetry against rsi, whose Wilder recursion carries an interior gap to the end of the series.