Smart Money Concepts: The Vocabulary, and What Our Engine Actually Ships
Smart money concepts is a naming system for shapes on a price chart. Order blocks, fair value gaps, liquidity sweeps, breaks of structure, changes of character — five terms, and every one of them describes something you can point at.
Our indicator engine ships none of them. I searched the whole Rust workspace for each term before writing a word of this, and the count is zero: no order block, no fair value gap, no liquidity sweep, no break of structure, no change of character, no smc anything. What the engine does ship is four small functions for finding swings, and the honest version of this page is what those four can and cannot support.
The vocabulary, in one place
Strip the branding and each term is a geometric claim about bars.
An order block is the last opposite-coloured candle before a strong move. A fair value gap is three consecutive bars where the first and third do not overlap, leaving a band of price nothing traded through. A liquidity sweep is price poking past an obvious prior extreme and closing back on the original side. A break of structure is a close beyond the last swing point in the direction things were already going, and a change of character is the first such break the other way.
None of that is mystical, and none of it requires believing anything about who was buying. The claims are checkable, which is exactly why they should be checked.
What the engine ships instead
crates/vike-indicators registers 171 indicators. Four of them live in structure.rs, and that file is 223 lines long.
batch_pivot_points computes seven floor-pivot levels off the prior bar. batch_volume_profile_poc buckets a trailing window's volume by close and returns the busiest bucket's centre. batch_zigzag tracks a running extreme and confirms it once price counter-moves by a deviation percentage. batch_williams_fractal marks a bar whose high is strictly above the two bars either side. That is the complete list.
The searches that found nothing are worth naming, because a null result is only as good as the queries behind it. order_block, orderblock, fair_value_gap, fvg, liquidity_sweep, break_of_structure, choch, change_of_character, smart_money — zero hits each, across every crate. The word "imbalance" does appear, in vike-chart's study list, where it means depth imbalance in a live order book and needs an L2 feed to compute. The phrase "order block" appears once, in a Bybit error-code comment about the 110xxx range. Those are homonyms, and treating either as a hidden SMC implementation would be a lie by search result.
A swing high is not one thing
Everything in that vocabulary hangs off a swing point. So it matters a great deal that the engine's two swing finders disagree.
Run both over 299 pairs and 364,147 daily bars. batch_zigzag at its registered 5% deviation names 150,839 swing points. batch_williams_fractal at its registered n = 2 names 99,061. They land on the same bar, on the same side, 87,266 times — 53.6% of the union. Of the zigzag pivots, 42.3% are on bars no fractal marks at all.
Neither is wrong. They answer different questions: one asks "has price moved 5% away from here yet", the other asks "is this bar higher than its four neighbours". Both definitions are defensible. They are both in the same binary, and they cannot both be the level your order block hangs off — so before a single zone is shaded, the anchor is already a choice, and it is the same choice that decides where a fibonacci retracement lands.
The shapes, and how often they turn up
Rarity is the load-bearing assumption. A shape that appears constantly cannot be a footprint of anything unusual.
So I computed three of them with plain arithmetic — written on this page, not borrowed from the crate, because the crate has none — over the same daily tape. Fair value gaps: 65,026, or one every six bars, with a median width of 2.09% of price. Sweeps of a batch_williams_fractal extreme: 59,777, again one every six bars. Closes beyond the last confirmed zigzag pivot: 111,756, one every three bars.
That is roughly one named event every other day per instrument, on daily candles, before you go looking on lower timeframes where the counts multiply. When I first ran this I expected the gap count to be small and it is not remotely small. A vocabulary this dense describes the tape rather than distinguishing parts of it, and any chart will supply as many instances as the reading requires.
Change of character is a flag, not a discovery
One term collapses entirely when you look at the code, and it is the one that sounds most like insight.
batch_zigzag carries a direction variable. It is 1 while the function is tracking a new high and -1 while it is tracking a new low, and it flips at every confirmed pivot — the same line that writes the pivot out. A change of character, defined as the first break against the prevailing swing direction, is that flip. There were 150,839 of them on this tape, one per pivot, no extra rule required.
Which also fixes the price of the concept. That flag cannot turn until price has moved a full 5% against the extreme, because the counter-move is the confirmation condition. So the term is never free and never early: it costs exactly the deviation you configured, and you paid it before it applied.
When you could actually have known
Timing decides whether any of this is tradable. On that, the crate is unusually blunt about itself.
Of 171 registered indicators, exactly three are flagged batch_only, meaning they read bars from the future and their streaming value is a best-effort guess. Two of the three are zigzag and williams_fractal — the two swing finders every SMC level is built on. A fractal cannot be decided until n bars later, always, by the shape of its centred window. A zigzag pivot is written backwards into the bar it happened on, once the counter-move confirms it, so on a live chart the most recent pivot can appear, move, or vanish as bars arrive.
Lag turns out to be small in practice: the median pivot became knowable one bar after it printed, though the worst case in this sample took 207. Small is not the same as zero, and it is never zero on the bar you are looking at. Anything drawn on the right-hand edge of a live chart is provisional, which is not a criticism of the method so much as the single fact that separates a marked-up screenshot from a decision.
Frequently asked questions
Do order blocks exist in your engine?
No. There is no order block function anywhere in crates/vike-indicators, and no hidden equivalent — the nearest thing the engine computes is batch_volume_profile_poc, which returns where volume actually traded rather than where somebody thinks it did.
Are smart money concepts just support and resistance? Largely, with a vocabulary on top. The underlying objects are swing points and untraded gaps, which is what pivot points and the volume profile address with rules you cannot adjust after the fact.
How common is a fair value gap? One every six bars on daily crypto candles, median width 2.09% of price, across 364,147 bars. Treat any claim about their rarity with that number in hand.
Can I see real institutional flow instead? On-chain you can see settlement rather than infer it, which is a different kind of evidence entirely — the on-chain primer covers what is actually observable.
Which swing definition should I use? Whichever one you fix before looking. The two the engine ships agree 53.6% of the time, so the choice is real and it is yours; making it after the move is how a candlestick reversal or a zone becomes unfalsifiable.
This is educational material, not financial advice. Every figure here was measured on past bars, past behavior generalizes poorly to future bars, and trading carries real risk of loss — size any position so that being wrong stays survivable.