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)11.6
Lexical diversity (MATTR-50)0.83
Consecutive similar sentences2
Repeated paragraph starts (≥3)0
AI-marker phrases0
Demonstrated experience3
Avg sentence length (words)21.3
Repeated 5-grams0
H2 section balance (50–500w)0 off
YMYL risk disclaimeryes
Mechanics verified vs codeyes
Primary keyword coverageyes
Internal links + CTA5
Content visuals8
Every figure has a caption8/8
Alt / caption text coverage100%
Distributed (≥1 per section)6/8 (75%)
Filenames sluggedn/a (inline)
Live interactive chart4 real
Aggressor-tagged prints1,029,274
Bar proxy vs the tape75.3% agree
Learn · Trading Indicators · Microstructure

Order Flow Trading: What the Tape Records, and What Candles Cannot

Order flow trading reads individual trades rather than bars, and it hangs on one fact a candle chart simply does not carry: for every print, which side reached across to make it happen. Buyer lifted the offer, or seller hit the bid. That single boolean is the whole difference between volume and flow.

Our engine keeps those two families in separate crates with no shared code path, which tells you how differently they are built. This page covers the exact rules the tape-side one folds trades with, a measurement of how badly the bar-side proxy disagrees with it on real prints, and an honest list of the order flow concepts our crate never implemented at all.

What order flow trading actually is

BTC/USDT daily — a real order flow window detected 2026-08-14, price rose +0.59% while the tape lifted the offer — delta and price agreed for once.

Every trade has two counterparties, and one of them was waiting.

The resting order was the maker; the order that crossed the spread and consumed it was the taker, or aggressor. Order flow classifies each print by which side aggressed, then sums the result into a bought half and a sold half, with the gap between them as the reading. That difference is delta, and running it forward gives cumulative delta.

None of this survives into a candlestick chart. Open, high, low, close and total volume are the same numbers whether the session's buying was patient or frantic, so a bar chart shows you the outcome of the auction and hides the pressure that produced it. The BTC window below is sixty minutes of real prints with the classification applied: price and flow moved together, which is the case people expect and — as the rest of the page shows — not the case you should plan around.

The one boolean everything rests on

classify(t) — three lines, and everything rests on themis_buyer_maker = falsethe BUYER crossedfull size → buy volumeis_buyer_maker = truethe SELLER crossedfull size → sell volumea venue that publishes no flag gets the field’s DEFAULTfalse → every print classified as aggressive buyingno downstream check can see it happen
Measured on 1,029,274 aggregated prints from 2026-08-14: the seller was the aggressor on 40.1% to 61.5% of trades depending on the symbol, while the share of VOLUME bought stayed far closer to half.

Our crate calls it "the one load-bearing semantic of the whole crate", and it is three lines long.

How Vike computes it. classify(t) returns Sell when the trade's is_buyer_maker flag is set and Buy otherwise, because that flag means the buyer was the resting maker and therefore the seller crossed. signed(t) then routes the trade's entire size to that one side. There is no tick rule, no quote test and no inference anywhere at trade level — the aggressor comes from the venue, or it does not come at all.

Across 1,029,274 aggregated prints from one UTC day on six symbols, the share of trades where the seller was the aggressor ran from 40.1% on LINK to 61.5% on XRP, while the share of volume bought sat between 42.3% and 54.1%. Count and size disagree because aggressive sellers and aggressive buyers do not trade in the same clip sizes, which is itself a flow reading and one that a single delta number hides.

One caveat sits upstream of all that arithmetic. Venues that publish no aggressor flag get the field's default, which is false — and false classifies as a buy. So a feed without the flag reports every single print as aggressive buying, silently, at 100% confidence. When I add a venue I check that it publishes the field before I trust a delta from it, because nothing downstream can detect the failure.

Delta, the footprint and a value area

how much of an hour the busiest price level really holdsbar scale: 0 to 20% of the hour’s volumeBTC10.4%19 levels · value area 12ETH15.5%14 levels · value area 6SOL15.6%15 levels · value area 7XRP12.5%17 levels · value area 11DOGE6.8%38 levels · value area 27LINK6.5%40 levels · value area 24only levels that actually traded exist in the structure
Point of control is the fullest cell, ties going to the lower price, and the value area grows one bucket at a time toward the larger neighbour until it holds 70%. A decisive-sounding level, holding a tenth of the hour.

Three primitives sit on top of the classification, and each one throws something away.

An order flow bar carries the two halves of the split, their difference as delta = buy − sell, and a trade count. Cumulative delta is a running fold of those deltas — deliberately a naive one, and the chart-side code says "no compensation" in its own comment, which is a documented precision limit rather than an oversight.

A footprint keeps more, splitting each bar into price levels and recording how much of each side aggressed at every one. Levels that never traded do not exist in the structure, so a footprint bar is sparse by construction. Bucket width comes from the price itself, roughly two basis points snapped to a 1-2-5 grid — on Bitcoin that produced 19 traded levels in an hour, on Dogecoin 38.

From those cells the crate builds a profile with a point of control and a 70% value area, expanding one bucket at a time toward the larger neighbour with ties going down. Worth noting how thin the point of control usually is: over the hours measured here the busiest level held between 6.5% and 15.6% of the hour's volume, which is a long way from the decisive level the phrase suggests. The volume profile page covers the bar-derived cousin of that calculation in full, and market profile covers the time-based one.

What a candle-derived proxy gets wrong

batch_obv’s direction vs the tape’s, per minutebar scale starts at 50% — a coin flipBTC79.5%ETH75.5%SOL78.1%XRP73.2%DOGE76.0%LINK69.4%75.3% over 7,653 minutes — and the proxy books 100% of a bar to one sidewhile the real split left a median |delta| of 52.4% of bar volume
One comparison of two closes decides where an entire bar’s trading gets booked. On roughly one minute in four that decision pointed the opposite way from the prints themselves.
ETH/USDT daily — a real order flow window detected 2026-08-14, aggressive buying the whole way down: delta stayed positive while price fell -0.61%.

On-balance volume is the closest thing an OHLCV series has to a delta, and I've wanted to put a number on that gap for a long time.

How Vike computes it. batch_obv adds the bar's whole volume when the close rose, subtracts the whole volume when it fell, and adds nothing when the close is unchanged. One comparison of two closes decides where an entire bar's trading gets booked.

Set that against the tape's own delta over the same minutes. Over 7,653 one-minute bars the two agreed on direction 75.3% of the time — so roughly one minute in four, the proxy pointed at buyers while the tape had been dominated by sellers, or the reverse. BTC was the best behaved at 79.5%; LINK the worst at 69.4%.

Magnitude is further off than direction. The proxy books 100% of a bar's volume to one side, while the real split left a median absolute delta of 52.4% of bar volume — so even when the sign is right, the size is close to double. Watch the ETH window below, where aggressive buying persisted the whole way down: any close-derived proxy reads that stretch as selling, and the tape says otherwise.

What we actually record

Neither delta nor cumulative delta is stored. Both are computed when a chart asks, so a cumulative line always starts at zero at the left edge of the range you picked — its level is a property of your zoom, not of the market.

Vike runs this pipeline live, and the shape of what gets stored is worth stating plainly.

Trade websockets from eight perpetual venues and seven spot venues feed a single process that classifies every print by aggressor side and folds it into one-minute buckets per venue and symbol: buy count, sell count, buy notional, sell notional, and the same four again restricted to prints above a size threshold. Notional is in dollars, not base units, so BTC and DOGE flow can be added. Prints above $10,000 are additionally kept individually, with their price, size, aggressor side and a size tier running up to $1,000,000.

Delta and cumulative delta are not stored anywhere. Both are computed when a chart asks for them, which has a consequence worth knowing before you read one: a cumulative delta line always starts at zero at the left edge of whatever range you selected, so its absolute level is a property of your zoom rather than of the market.

What our crate deliberately does not detect

in the cratenot implemented anywhereaggressor classificationdelta & cumulative deltafootprint cellsprofile POC + value areatoxicity estimatorsorder-to-trade ratioabsorptionexhaustionstacked imbalancediagonal imbalanceunfinished auctiondelta divergencesearched by name across the whole tree — every apparent hit was unrelated language
Most of what is sold as order flow education lives in the right-hand column. Naming that boundary is cheaper than discovering it inside a strategy that assumed the detector existed.

This is the section that would not exist if the engine were not the source.

Absorption is not implemented. Neither is exhaustion, nor stacked imbalance, nor diagonal bid-ask imbalance, nor unfinished auctions, nor delta divergence. Those six ideas make up most of what gets sold as order flow education, and searching the crate for any of them returns nothing — every apparent hit is unrelated language elsewhere in the tree.

What does exist is narrower and stated with its limits attached. The information-driven bar builders implement a fixed threshold and openly call the adaptive version "a documented future extension". The order-to-trade ratio counts messages by diffing consecutive top-of-book snapshots, and its own header calls that "a visible-window proxy, not exchange message truth". A toxicity estimator ships in two variants, one of which needs no aggressor flag at all.

Every one of those admissions lives in the source rather than in a footnote somebody wrote later, and I would rather hand you that list than a longer one I could not stand behind.

Where order flow trading fails

SOL/USDT daily — a real order flow window detected 2026-08-14, price finished +0.04% and the aggressor delta still ran to +35.2% of traded volume.
XRP/USDT daily — a real order flow window detected 2026-08-14, aggressive buying the whole way down: delta stayed positive while price fell -0.22%.

Flow is a description of what happened, not a claim about what happens next.

Its clearest failure is the one the ETH window already showed, and XRP repeats it below: sustained aggressive buying into a falling market. The naive reading calls that accumulation, and sometimes it is — but it is equally the picture of buyers being filled by a larger resting seller who never has to cross the spread at all. Passive size does not appear in delta by construction, and no amount of tape reading recovers it.

Then there is the venue problem. A delta computed on one exchange describes that exchange, and crypto's flow is fragmented across dozens with different fee schedules and different maker incentives. Our own pipeline hard-excludes two venues from these reads because their reported activity is not trustworthy, which is a filter you have to apply somewhere.

And flat sessions still produce confident-looking numbers. SOL, below, finished a full hour within a rounding error of where it started while the aggressor delta ran to a substantial share of traded volume. The line has a slope, the story has none, and the same trap catches every cumulative measure — including VWAP, whose session reset exists precisely to stop yesterday's accumulation leaking into today.

Frequently asked questions

Where does order flow trading get its edge? From reading individual trades by which side crossed the spread, rather than reading bars. The aggressor flag is the only input a candle does not contain, and it is what makes flow different from volume.

Is cumulative volume delta the same as volume? A running total of buy volume minus sell volume, where each trade's whole size is booked to whichever side aggressed. Our fold is deliberately naive, and its starting point depends on the range you asked for.

Can you get order flow from candlestick charts? Not reliably. The closest OHLCV proxy, batch_obv, pointed the wrong way on 24.7% of the one-minute bars measured here, and overstated the imbalance by roughly double when it agreed.

What does a footprint chart show? It draws one bar as a column of price levels, each carrying the bought and sold totals for that level alone. Levels with no trades are absent rather than empty, so the shape is sparse.

Does order flow work in crypto? The arithmetic works wherever a venue publishes an aggressor flag. Fragmentation across venues and unreliable reported volume make it noisier than in a single-venue futures market, and a feed missing the flag will classify everything as buying without ever saying so.

This is educational material, not financial advice. Order flow describes trades that have already printed, every figure above was measured on one day of real tape, and trading carries substantial risk of loss.

Read the trading indicators overview