Microstructure Invariance

Kyle-Obizhaeva framework for bet sizing, impact estimation, and informed trade detection

Kyle and Obizhaeva’s microstructure invariance describes universal scaling laws connecting volume, volatility, and trade count to the “natural” bet size in any market. These model-free relationships hold across equities, futures, FX, and crypto.

API

Trading activity

Compute the market’s trading activity index, which measures how much “information” flows through the market per unit time.

python
activity = hz.trading_activity(
    volume=1_000_000,    # daily dollar volume
    volatility=0.02,     # daily volatility (decimal)
    n_trades=5000,        # number of trades per day
)
# Returns: float -- trading activity index

Invariant bet size

Given the trading activity, compute the “natural” bet size — the size at which a single trade has a standardized market impact.

python
bet_size = hz.invariant_bet_size(activity)
# Returns: float -- dollar size of a "natural" bet in this market

print(f"Natural bet size: ${bet_size:,.0f}")

Detecting abnormal trades

Compare observed trade sizes against the invariant bet size:

python
activity = hz.trading_activity(volume, volatility, n_trades)
natural_size = hz.invariant_bet_size(activity)

for trade in recent_trades:
    ratio = trade.notional / natural_size
    if ratio > 5.0:
        print(f"Large informed bet: {ratio:.1f}x natural size at {trade.price}")

The invariance principle

The key insight: across all markets and time periods, the distribution of bets — when normalized by the invariant bet size — follows the same universal distribution. A “1x natural bet” in Apple stock and a “1x natural bet” in Bitcoin have the same proportional market impact, despite vastly different absolute sizes.

This means:

  • Liquid markets have larger natural bet sizes (you can trade more before moving the price)
  • Volatile markets have smaller natural bet sizes (each trade has more impact)
  • Active markets (many trades) have smaller individual bet sizes (information is split across more trades)

Sizing orders using invariance

Use the invariant bet size to calibrate your order sizes to the market’s liquidity:

python
activity = hz.trading_activity(
    volume=daily_volume,
    volatility=daily_vol,
    n_trades=daily_trades,
)
natural = hz.invariant_bet_size(activity)

# Size your order as a fraction of the natural bet
# 0.5x natural: low impact, patient execution
# 1.0x natural: moderate impact
# 2.0x natural: will move the market
max_order_size = 0.5 * natural

When to use

  • Order sizing: determine the maximum order size that won’t significantly move the market.
  • Informed trade detection: flag trades that are multiples of the natural bet size — they likely carry private information.
  • Cross-market comparison: compare liquidity across markets on a normalized basis (a $10K trade in an illiquid prediction market may be equivalent to a $10M trade in SPY).
  • Impact budgeting: estimate how much market impact your execution will cause before submitting.

Next