---
title: "Microstructure-Aware Market Maker"
description: "Use VPIN, order flow imbalance, and structural break detection to make smarter quotes."
icon: "microscope"
---

<Note>**Pro Feature.** Requires a Pro or Ultra subscription. [Get started at api.mathematicalcompany.com](https://api.mathematicalcompany.com)</Note>

A market maker that uses microstructure signals - toxic flow detection (VPIN), order flow imbalance (OFI + Kyle's lambda), and structural break detection (CUSUM) - to dynamically adjust its quoting.

## Full Code

```python
"""Microstructure-aware market maker: VPIN + OFI + CUSUM."""

import horizon as hz
from horizon.context import FeedData


# ── Pipeline components ──

# VPIN: Volume-synchronized probability of informed trading
vpin_detector = hz.toxic_flow(
    feed_name="polymarket",
    window=50,
    threshold=0.7,    # flag toxicity above 0.7
)

# Order flow imbalance + Kyle's lambda
micro = hz.microstructure(
    feed_name="polymarket",
    ofi_window=20,
    lambda_window=50,
)

# CUSUM: detect structural breaks in price
cusum = hz.change_detector(
    feed_name="polymarket",
    threshold=3.0,    # 3 sigma threshold
    drift=0.5,
)


def quoter(ctx: hz.Context, fair: float) -> list[hz.Quote]:
    """Adjust quotes based on microstructure signals."""
    vpin = ctx.params.get("vpin", 0.5)
    ofi = ctx.params.get("ofi", 0.0)
    kyles_lambda = ctx.params.get("kyles_lambda", 0.0)
    cusum_alert = ctx.params.get("cusum_alert", False)

    # No quotes during structural breaks
    if cusum_alert:
        print(f"  CUSUM break detected - pausing quotes")
        return []

    # Widen spread when toxic flow is high
    base_spread = 0.03
    spread = base_spread + vpin * 0.08  # up to 11 cents at max toxicity

    # Skew quotes based on order flow imbalance
    skew = ofi * kyles_lambda * 0.01
    skewed_fair = fair - skew

    # Reduce size when toxicity is elevated
    size = 10.0 if vpin < 0.5 else 5.0

    print(f"  VPIN={vpin:.2f} OFI={ofi:.2f} λ={kyles_lambda:.4f} spread={spread:.3f}")
    return hz.quotes(skewed_fair, spread, size=size)


hz.run(
    name="microstructure_mm",
    markets=["election-winner"],
    feeds={
        "polymarket": hz.PolymarketBook("election-winner"),
    },
    pipeline=[vpin_detector, micro, cusum, quoter],
    risk=hz.Risk(max_position=100, max_drawdown_pct=5),
    interval=1.0,
    mode="paper",
)
```

## How It Works

1. **`toxic_flow()`** computes VPIN (Volume-synchronized Probability of Informed Trading):
  - Low VPIN (< 0.3) → mostly retail flow, safe to quote tight
  - High VPIN (> 0.7) → informed traders present, widen spread
2. **`microstructure()`** tracks order flow imbalance (OFI) and Kyle's lambda:
  - OFI measures net buying/selling pressure
  - Kyle's lambda estimates the price impact per unit of order flow
  - Combined, they predict the direction and magnitude of short-term moves
3. **`change_detector()`** runs CUSUM on price residuals:
  - When the cumulative sum exceeds the threshold, a structural break is flagged
  - The quoter pauses during breaks to avoid quoting into a regime change
4. The **quoter** combines all three:
  - Spread = base + VPIN-scaled component
  - Fair value is skewed by OFI × lambda
  - Size is reduced when toxicity is elevated

## Standalone Microstructure Functions

Use the Rust microstructure functions directly for research:

```python
import horizon as hz

# Kyle's lambda: price impact coefficient
lam = hz.kyles_lambda(
    prices=[0.50, 0.51, 0.49, 0.52, 0.51, 0.53],
    volumes=[100, 150, 80, 200, 120, 180],
)
print(f"Kyle's lambda: {lam:.6f}")

# LOB imbalance
imb = hz.lob_imbalance(bid_size=150.0, ask_size=100.0)
print(f"LOB imbalance: {imb:.4f}")  # positive = buy pressure

# Weighted mid-price
wmid = hz.weighted_mid(bid=0.50, ask=0.52, bid_size=150.0, ask_size=100.0)
print(f"Weighted mid: {wmid:.4f}")
```

## Run It

```bash
python examples/microstructure_mm.py
```

See [Quantitative Methods](/quant) for the full microstructure reference.
