Aggressor-Side Classification in Order-Flow Indicators: Quote Rule, Tick Rule, and Unknown Trades
A trade print tells us that a transaction occurred at a particular price and size. It does not always tell us whether the buyer or seller initiated it. Yet footprint charts, bid/ask volume displays, and cumulative delta all depend on assigning trades to a side. A classification error made at ingesti

on can propagate into every downstream visualization. There is no universally correct fallback for missing or stale quote data. The useful engineering question is not simply “Was this a buy or a sell?” It is “What evidence supports this classification, and what do we do when that evidence is incomplete?” Some feeds provide an aggressor-side indicator. Others provide trades and quotes that let you infer one.
Verify the feed's documented semantics before treating either as ground truth. Equities may require a consolidated best bid/offer; a futures feed may supply venue-specific inside quotes. These inputs are not interchangeable without a data-policy decision. Trade at or above the contemporaneous ask: buyer-aggressed candidate.
Trade at or below the contemporaneous bid: seller-aggressed candidate. Trade inside the spread, or with inconsistent quotes: unknown. “Contemporaneous” does a lot of work here. Quote and trade messages may be delivered on different channels, arrive out of order, or use timestamps with different precision.
Comparing a trade with the quote that happens to be most recently received can silently contaminate the result. Validate source, ordering, quote age, and whether the quote was actually applicable at execution time. If both comparisons appear true because the market is locked or crossed, do not let branch order arbitrarily pick a winner: flag the quote as unusable under your documented policy. Higher than the previous print → buy candidate.
Lower than the previous print → sell candidate. Same price → apply an explicit zero-tick policy, such as retaining the previous nonzero price-change direction, or mark unknown. This is a heuristic, not a substitute for a contemporaneous quote or an exchange-provided aggressor flag. It can behave poorly when spreads are wide or the tape contains gaps or reordering.
In a report or indicator settings panel, name the method rather than simply labeling the output “true buy volume.” A classification function with an honest third state The example below is standalone C#-style application logic, not a drop-in NinjaScript indicator. It illustrates a deliberately conservative quote policy, an optional tick-rule fallback, and a separate unknown outcome. enum Side { Buy, Sell, Unknown } sealed class TradePrint sealed class Quote static Side Classify( if (quoteUsable) { if (trade.Price >= quote.Ask) return Side.Buy; if (trade.Price <= quote.Bid) return Side.Sell; return Side.Unknown; // Inside spread: no forced side } if (!previousTradePrice.HasValue) return Side.Unknown; if (trade.Price > previousTradePrice.Value) return Side.Buy; if (trade.Price < previousTradePrice.Value) return Side.Sell; return previousTickDirection; // Configurable zero-tick policy } The time threshold is a policy input, not a universal constant. Timestamp checks cannot fix unsynchronized providers or missing quote changes.
Also, previousTickDirection must be maintained from the previous nonzero price change, not accidentally overwritten with Unknown on every tied print. A production pipeline should preserve a classification method and ideally a confidence/provenance field alongside the side label. Otherwise, a chart may combine exchange flags, quote-rule guesses, and tick-rule guesses while making them look equally certain. A useful diagnostic is to compare classification rates by instrument, session, feed, and replay/live mode.
A sudden rise in unknown volume may indicate a quote-availability change or timestamp alignment issue—not a change in market sentiment. Ingestion: validate timestamps, ordering, trade sizes, and quote provenance. Classification: apply a selected policy and record the method used. Aggregation: map prices to integer tick indices and maintain buy/sell/unknown counters without floating-point price-key drift.
Rendering: consume consistent snapshots rather than mutable accumulation buffers. This separation lets you replace a fallback method without rewriting the footprint renderer. It also makes feed comparisons testable: run the same recorded prints through two classification policies and inspect where they disagree. For wider context on order-book, tape, and delta concepts, see the ICF Market volume and order-flow education series.
The classification policy described here is an educational design example, not a claim about any proprietary ICF Market implementation. Discussion: If you have both a feed-supplied aggressor flag and the quote rule, do you treat one as authoritative, record the disagreement, or surface both? Disclosure: This article was prepared with AI assistance. The code is illustrative and has not been tested against a live market-data feed.
This is educational material, not trading advice.
Key Takeaways
- •There is no universally correct fallback for missing or stale quote data.
- •This story was reported by Dev.to, covering developments in the dev space.
- •AI advancements continue to reshape industries — read the full article on Dev.to for complete coverage.
📖 Continue reading the full article:
Read Full Article on Dev.to →


