QA GATE · GOOD 18/18 automated ai-check.js · 18 readability, YMYL and image gates · mechanics verified against vike-indicators · live real-data chart embedded
Burstiness (sentence-length SD)9.4
Lexical diversity (MATTR-50)0.82
Consecutive similar sentences2
Repeated paragraph starts (≥3)0
AI-marker phrases0
Demonstrated experience2
Avg sentence length (words)16.6
Repeated 5-grams0
H2 section balance (50–500w)0 off
YMYL risk disclaimeryes
Mechanics verified vs codeyes
Primary keyword coverageyes
Internal links + CTA4
Content visuals10
Every figure has a caption10/10
Alt / caption text coverage100%
Distributed (≥1 per section)5/6 (83%)
Filenames sluggedn/a (inline)
Live interactive chart5 real
Breadth series299 pairs · 364,147 bars
Learn · Trading Indicators

McClellan Oscillator: The Breadth Data We Do Not Have, and the Crypto Analogue We Built

The McClellan Oscillator is a breadth indicator, and breadth is the one thing our engine structurally cannot compute. Saying so is more useful than pretending otherwise, so that is where this page starts.

Its definition is simple enough to state in a line: take the number of advancing issues minus declining issues each day, smooth that series with a 19-period exponential average and a 39-period one, and subtract the second from the first. Sherman and Marian McClellan published it in 1969 for the New York Stock Exchange. Our indicator engine ships the smoother and nothing else.

What breadth measures, and why it needs a market

16 of 20 rosebroad participation6 of 20 rosethe same index gainone vote per member, regardless of size
The price of the index is identical in both panels. Breadth is the only family of measures that can tell them apart, and it needs a membership list to do it.

An index can rise while most of its members fall. Breadth is the family of measures built to catch exactly that discrepancy, one member at a time.

Think of it as a headcount rather than a price. If an index gains 1% because four megacaps rallied and 380 constituents drifted lower, the price series looks healthy and the participation behind it is thin. A breadth reading exposes the gap because it weights every member the same — one vote each, regardless of size.

That definition carries a requirement most indicator descriptions gloss over: you need a defined membership list. Someone has to say which issues are in the market before you can count how many rose, and that list has to stay reasonably stable, or the count measures the list instead of the market.

What our engine ships, and what it cannot

no functionmcclellan — 0 hitsadvance_decline — 0 hitssummation_index — 0 hitsbreadth — 11 hits, allbroker reconciliation proseno datano NYSE issue listno advancing / declining countsno membership historythe harder gap of the twowhat stands between this engine and a McClellan readingeverything below is a crypto ANALOGUE, not the indicator
Naming the empty shelves is the point. A page that quietly substituted crypto pairs for NYSE issues would read as the same measurement and would not be one.

Two separate absences, and only one of them is about code.

Searching every crate for mcclellan, advance_decline and summation_index returns zero hits. breadth returns eleven, and every one of them is broker-reconciliation prose — phrases like "recon-breadth" describing venue coverage in the IBKR and OANDA bridges, with nothing indicator-shaped anywhere near.

A deeper reason is structural. Every function in the single-series registry is handed one slice of bars through vectorize(&self, bars: &[Bar]), so a function there cannot see a universe even in principle. Cross-instrument work lives on a separate seam, and that seam holds pair functions taking exactly two series — still not a market.

Missing data is the bigger gap of the two. We do not carry equity breadth: no NYSE issue list, no daily advancing and declining counts, no membership history. Anything below that resembles the classic indicator is a crypto analogue built from our own universe, and it answers a different question.

The smoother, and the two averages it runs

breadth seriesone value per dayema(·, 19)alpha = 2 ÷ 20ema(·, 39)alpha = 2 ÷ 40subtractoscillatoradd each value to the running total and you have the Summation Indexmath.rs:200 · SMA seed at index n − 1, then alpha × value + (1 − alpha) × previousport vs the Python twin at lengths 9, 19 and 39: 0.000e+00 over 1,073,305 values
Structurally this is the MACD with a headcount in place of a price. Nothing in the smoother knows or cares what it is being fed.

Our crate does ship the exact kernel the oscillator is made of, twice.

How Vike computes it. batch_ema at base.rs:43 is a thin wrapper over math.rs:200. That kernel writes a plain average of the first n values at index n − 1 as its seed, then runs alpha × value[i] + (1 − alpha) × previous with alpha = 2 ÷ (n + 1). Registered as ema in the overlap family, default length 20, accepted range 1 to 1000. Before the seed index the output is nothing at all, not a partial value.

Run that kernel at 19 and at 39 over a breadth series, subtract, and you have the oscillator. The exponential moving average page covers the smoother on its own terms, and the structure will look familiar from the MACD, which is the identical two-average difference applied to price instead of to a headcount.

When I ported the kernel I checked it against the Python engine that the crate mirrors, at lengths 9, 19 and 39, across every symbol on our tape. All 1,073,305 values matched at 0.000e+00. Accumulate that difference and you have the McClellan Summation Index, which is one line of arithmetic on top.

Why the raw advance-decline count is unusable here

1,626 of 3,286 days carry at least 120 symbolssymbols per day: min 120 · median 169 · max 279raw advances − declines95152first half above, second half belowratio-adjusted656.7712.1same days, same rule, divided by total issuesscale differs too: adjusted spans -192.0 to +220.6, raw spans -40.5 to +40.6so a threshold copied from a textbook is in the wrong units
Bars are the median absolute daily reading. The raw form is measuring how many pairs were listed, which is a fact about the exchange rather than about the market.

This is the trap that would have made every number on this page wrong.

Our coverage is not uniform. Across 3,286 calendar days, only 1,626 have at least 120 symbols reporting, and on those the count still climbs from 120 to 279 — a 2.3-fold change in the size of the universe. A raw advances − declines figure grows with participation whether or not anything changed about the market, and it duly does: the median absolute value runs 95 in the first half of the window and 152 in the second.

McClellan anticipated exactly this for a growing exchange and published a ratio-adjusted form, which divides by total issues and scales up. Measured the same way, that version reads 656.7 and then 712.1 — still drifting, far less. Every chart below plots the adjusted series, and the raw one is shown only to make the difference visible.

Scale changes too, and dramatically. Over the same days the ratio-adjusted oscillator spans −192.0 to +220.6, while the raw form spans −40.5 to +40.6. Anyone comparing an oscillator level against a threshold from a textbook is comparing two different units.

What the crypto analogue showed

157 moved the same way157 moved the other waythe ten days after a zero crossingan exact split, unrounded317 crossings over 1,588 readings — about one a weeka breadth crossing is a description of days that already closed
Nothing was filtered to produce this. Every crossing with ten bars of forward data on the proxy is in the count.
BTC/USDT daily — a real breadth reading detected 2024-08-05, the deepest reading on the tape, -192.0 -> BTC +6.5% over the next 10 days.
BTC/USDT daily — a real breadth reading detected 2023-01-14, the highest reading on the tape, +220.6 -> BTC +8.0% over the next 10 days.
BTC/USDT daily — a real breadth reading detected 2022-06-10, breadth turned negative at -33.7 -> BTC -29.3% over the next 10 days.
BTC/USDT daily — a real breadth reading detected 2026-01-27, breadth turned positive at +13.4 -> BTC went the other way, -20.9%.
BTC/USDT daily — a real breadth reading detected 2024-07-26, breadth turned positive at +4.4 -> BTC went the other way, -20.5%.
Read the two panes carefully. The candles are BTC, the proxy for the market, and the line underneath is computed from all 299 pairs — it is not derived from the candles above it. Three of the five readings were followed by a move the other way.

Five real readings sit below, and three of them were followed by the opposite move.

Some findings first. Over 1,588 daily readings the line crossed zero 317 times — roughly once a week — which already argues against treating a crossing as rare. The deepest value on record, −192.0, printed on 2024-08-05, the day of the yen carry unwind; ten days later Bitcoin was 6.5% higher. The highest, +220.6, came on 2023-01-14, and that one did continue.

Then the number that matters most. Of 314 zero crossings with enough forward data, the proxy moved the same way over the following ten days on 157 and the other way on 157. An exact split, unrounded. I have seen no cleaner demonstration that a breadth crossing describes the past and nothing else.

None of this says the original indicator is worthless on equities. It says our version measures a universe of crypto pairs with unstable membership, and it would be dishonest to import a stock-market interpretation onto it.

Frequently asked questions

What is a McClellan Oscillator reading of zero? Only that the fast and slow averages of breadth are equal. On our data the line crossed zero every five days on average, so the state itself is unremarkable.

How is the McClellan Summation Index built? By accumulating the oscillator. No separate function is needed — add each value to the one before it and you have the series.

Can this be computed for crypto? An analogue can, and this page publishes one. It measures something else, though: our universe changes size by a factor of 2.3 across the window, and an exchange listing does not.

Why 19 and 39? Those are McClellan's own lengths, corresponding to 10% and 5% smoothing constants. Every figure here uses them unchanged rather than searching for something that scores better.

Does Vike ship a breadth indicator? No. The registry holds no breadth entry, the crate contains no advance-decline logic, and we carry no equity breadth data — the smoother is ours, the rest is arithmetic in a script.

This is educational material, not financial advice. Every figure on this page was measured on bars that have already closed, past behavior generalizes poorly to future bars, and trading carries real risk of loss — size any position so that being wrong stays survivable.

Read the exponential moving average breakdown