Wyckoff Method: The Four Kernels Our Engine Ships, and the Phase Labels It Does Not
The Wyckoff method is a way of reading a chart, not a formula you can run. Richard Wyckoff taught traders to see a sideways range as a story — someone large accumulating, then a test of the lows, then a markup — and every step of that reading is a judgement.
Our crate contains none of it. Grep every Rust file for wyckoff, spring, upthrust or accumulation phase and you get nothing at all. What the indicator engine does ship is the geometry underneath: four structure kernels that find the swings, levels and busiest prices a Wyckoff reader draws a box around.
What the method actually claims
Sideways price is the setup, and the claim is about who is on the other side of it.
Wyckoff's framework says a large operator cannot buy a position quickly without moving the price against themselves, so they accumulate inside a range, shake out weak holders with a brief break of the lows, and only then let price mark up. Distribution runs the same story inverted. The vocabulary — spring, upthrust, sign of strength, last point of support — labels the stages.
Notice what kind of claim that is. It is an assertion about intent, inferred from shape and volume, and intent is not observable in a candle. That does not make the framework useless; plenty of durable ideas about support and range behavior came out of it. It does mean the labels are a reader's interpretation rather than a measurement, and any page telling you a detector emits them is selling something.
What our engine ships for it
Four kernels, one file, 223 lines. That is the complete extent of the engine's opinion about chart structure.
How Vike computes them.structure.rsdefines exactly four:batch_pivot_pointsat line 22,batch_volume_profile_pocat line 49,batch_zigzagat line 100 andbatch_williams_fractalat line 158. None ispub— the file contains zero public functions, and each kernel is reached only through its macro-generated struct, re-exported atmod.rs:397. So the accurate phrase is "the kernel behindZigzag", never "the crate exposesbatch_zigzag".
Map those onto the method and the fit is partial but real. Swing highs and lows come from the zigzag kernel and give you the boundaries of a range. Pivot points give you levels derived mechanically from the previous bar, which cannot be adjusted after the fact. And the point of control from the volume profile kernel answers "where did most business get done", which is the closest thing in the engine to Wyckoff's notion of a range's centre of gravity.
Nothing there labels a phase. Assembling four numbers into "this is accumulation" remains an act of interpretation, and the same absence is why the smart money concepts page exists in the form it does.
Drawing the range, and when you could have drawn it
Every level in this method comes from a swing, so the honest question is when that swing became knowable.
The zigzag kernel walks forward tracking an extreme and flips direction once price retraces by deviation percent, registered at 5.0. At that moment it writes the extreme's price back at the extreme's own bar index. That is a lag rather than a repaint — the write happens once, inside a single forward pass, and is never revised — but a level drawn at bar 40 may not have existed for anyone at bar 40.
When I measured that gap across 148,917 pivots on our daily tape, the median came back at one bar and so did the ninetieth percentile. The worst case was 207. So the typical swing is confirmable almost immediately while a small tail of them is not, which beats both "it repaints" and "it is fine" as an answer.
Both swing finders are flagged batch_only in the registry precisely because of this, and the fractal kernel is blunter still: its window is centred at n = 2, so its confirmation lag is exactly two bars, always.
Springs and upthrusts, whose rule is ours not the engine's
Below are four real events. Two behaved and two did not, and the rule that found them is mine rather than the crate's.
Stating it in full, because a page that hides its definition is doing the thing it criticises. A range here is any stretch of at least 30 bars whose entire span fits inside 30% of its own low. A spring is a bar inside that range whose low breaks the range low while its close returns above it; an upthrust mirrors it at the high. Wyckoff would also demand volume confirmation and phase context, neither of which is mechanised here.
Run over 275 pairs, that turned up 1,987 ranges — median length 37 bars, longest 436 — containing 3,172 springs and 2,582 upthrusts. Twenty bars later, 1,597 of the springs had a higher close and 1,649 of the upthrusts a lower one. Both sit close enough to half that the shapes are describing volatility rather than intent, which is roughly what I use them for.
One result I did not expect. On the last bar of each range, the volume-profile point of control sat at a median of 52% of the range height — dead centre. The busiest price in a sideways market is the middle of it, which sounds obvious and is worth knowing before you read significance into a POC that has drifted a little.
The half that lives in another crate
Wyckoff's "effort versus result" is an order-flow question, and our engine answers it somewhere this tape cannot reach.
vike-orderflow is a separate crate with a separate input type. It carries CvdAccumulator for cumulative volume delta at cvd.rs:6, an OrderflowBar whose delta field is buy_vol − sell_vol at bars.rs:10, depth_imbalance over the top n book levels at imbalance.rs:18, a tick-level VolumeProfile with a real value area at profile.rs:16, and a VPIN toxicity estimate. That set is much closer to what Wyckoff was reasoning about than anything in structure.rs.
Every one of those functions reads TradeTick values, though. A daily candle does not contain trades, so none of it can be computed from the bars on this page, and approximating delta from candle shape is a well-known way to produce a confident number that means nothing. The order flow trading page works with the real inputs; market profile covers the distribution view of the same range.
Frequently asked questions
Does Vike detect Wyckoff phases? No. There is no phase logic, no schematic and no event tag anywhere in the crate, and a phase label is a judgement across dozens of bars rather than a per-bar number.
Is a spring a reliable buy signal? Our mechanical version was followed by a higher close 20 bars later on 1,597 of 3,172 occurrences, which is close to a coin flip. Treat it as one input, not a trigger.
What is the difference between Wyckoff and smart money concepts? Vocabulary and vintage, mostly. Both infer a large participant from price shape, and the crate ships detectors for neither.
Which timeframe suits the method? The framework is scale-free, and every measurement here is daily. Ranges on lower timeframes are more numerous and noisier, which cuts both ways.
Can I automate it? You can automate the geometry — ranges, swings, false breaks — as this page does. Automating the phase labels means encoding an opinion about intent, and you should be clear with yourself that this is what you have built.
This is educational material, not financial advice. Every count here 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.