Aggressor Side in Trade Data: What It Is and Why It Matters

Every trade has two sides: passive (limit order, waited in the book) and aggressive (market order, matched immediately). Knowing which side was aggressive is the foundation of order flow analysis — and something OHLCV data completely discards.

The is_buyer_maker Field

  • is_buyer_maker = True: buyer was passive (maker). Seller was the aggressor — bearish pressure.
  • is_buyer_maker = False: buyer was aggressive (taker). Buy market order hit the ask — bullish pressure.

Computing Aggressor Statistics

import polars as pl

df = pl.read_parquet("BTC_trades.parquet")

stats = df.group_by("is_buyer_maker").agg([
    pl.len().alias("trade_count"),
    pl.col("qty").sum().alias("total_qty"),
    pl.col("quote_qty").sum().alias("notional_usdt"),
]).with_columns(
    (pl.col("notional_usdt") / pl.col("notional_usdt").sum() * 100).alias("pct_volume")
)
print(stats)

Why the Ratio Changes Over Time

During bull markets, buy-aggressive volume exceeds sell-aggressive volume. During capitulation events, sell-aggressive volume spikes. Monitoring this ratio gives you a real-time measure of market sentiment that candlestick charts cannot show.

Validate Before Trusting

Always validate with a known event: find a period where price was clearly rising and verify buy-aggressive volume was dominant. If it was not, your aggressor field may be inverted — a silent bug that corrupts all order flow metrics built on top of it.

Audited tick data with documented aggressor-side schema for BTC, ETH and 8 more assets. Every schema difference is disclosed. → Browse the catalog

Summary

The aggressor side field turns a trade record from a passive price observation into an active signal about market intent. Understand your schema before computing it, and validate against known market events before trusting the output.