Documentation Index
Fetch the complete documentation index at: https://mathematicalcompany.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
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
"""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
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
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
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
- 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:
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
python examples/microstructure_mm.py
See Quantitative Methods for the full microstructure reference.