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 on Polymarket using Black-Scholes binary pricing, spread-based toxicity estimation, and GLFT adverse selection spread with inventory skew.
Full Code
"""GLFT Market Maker on Polymarket (paper mode)."""
import math
import horizon as hz
from horizon.context import FeedData
def black_scholes_binary(price: float, strike: float, vol: float, tte: float) -> float:
"""Binary option fair value: Phi(d2)."""
if tte <= 0:
return 1.0 if price >= strike else 0.0
d2 = (math.log(price / strike) - 0.5 * vol**2 * tte) / (vol * math.sqrt(tte))
return 0.5 * (1 + math.erf(d2 / math.sqrt(2)))
def spread_toxicity(bid: float, ask: float) -> float:
"""Spread-based toxicity proxy: wider spread = more toxic flow."""
if bid <= 0 or ask <= 0:
return 0.5
mid = (bid + ask) / 2.0
if mid <= 0:
return 0.5
relative_spread = (ask - bid) / mid
return min(1.0, max(0.0, relative_spread * 100.0))
def glft_spread(fair: float, tox: float, inventory: float, gamma: float = 0.1) -> float:
"""GLFT adverse selection spread with inventory penalty."""
base = 0.02
inv_penalty = gamma * abs(inventory) * 0.001
tox_adj = tox * 0.04
return base + inv_penalty + tox_adj
# --- Pipeline functions ---
def fair_value(ctx: hz.Context) -> float:
btc_price = ctx.feeds.get("btc", FeedData()).price or 100_000
strike = 100_000
vol = 0.6
tte = 30 / 365 # 30 days to expiry
return black_scholes_binary(btc_price, strike, vol, tte)
def toxicity(ctx: hz.Context) -> float:
feed = ctx.feeds.get("btc", FeedData())
return spread_toxicity(feed.bid, feed.ask)
def quoter(ctx: hz.Context, fair: float, tox: float) -> list[hz.Quote]:
spread = glft_spread(fair, tox, ctx.inventory.net, gamma=0.1)
return hz.quotes(fair, spread, size=5)
if __name__ == "__main__":
hz.run(
name="btc_mm",
exchange=hz.Polymarket(private_key="0x_demo_key"),
markets=["will-btc-hit-100k-by-end-of-2025"],
feeds={"btc": hz.BinanceWS("btcusdt")},
pipeline=[fair_value, toxicity, quoter],
risk=hz.Risk(max_position=100, max_drawdown_pct=5),
interval=0.5,
mode="paper",
dashboard=False,
)
Pipeline Breakdown
Stage 1: Fair Value
Uses the Black-Scholes binary option formula to price a prediction market as a digital option:
P(binary) = Φ(d₂)
where d₂ = (ln(S/K) - 0.5σ²T) / (σ√T)
S = current BTC price (from Binance feed)
K = strike price ($100k)
σ = implied volatility (0.6)
T = time to expiry (30/365 years)
Stage 2: Toxicity
Uses spread-based toxicity as a proxy for informed flow. A wider bid-ask spread on the underlying suggests more adverse selection:
- Tight spread → low toxicity → tighter quotes
- Wide spread → high toxicity → wider quotes
Stage 3: Quoter
The GLFT spread combines three components:
spread = base_spread + γ × |inventory| × 0.001 + toxicity × 0.04
- Base spread: minimum spread (2 cents)
- Inventory penalty: widens spread as position grows
- Toxicity adjustment: widens spread when flow is more informed
Run It
# Paper mode (default)
python examples/polymarket_mm.py
# Live mode
python -m horizon run examples/polymarket_mm.py --mode=live --dashboard