Skip to main content
Pro Feature. Requires a Pro or Ultra subscription. Get started at api.mathematicalcompany.com

Market-Making Arbitrage

Quote on one exchange (earn the bid-ask spread), hedge on another exchange (neutralize directional risk). Combines Avellaneda-Stoikov market making with cross-venue delta hedging.

How It Works

  1. Generate quotes on the quoting exchange using Avellaneda-Stoikov (reservation price + optimal spread)
  2. Track net position (delta) from fills
  3. When |delta| > hedge_threshold: submit aggressive FOK orders on the hedge exchange
  4. Result: you earn the spread on exchange A while staying delta-neutral via exchange B

MMArbConfig

config = hz.MMArbConfig(
    quote_exchange="polymarket",
    hedge_exchange="kalshi",
    quote_feed="polymarket",
    hedge_feed="kalshi",
    base_spread=0.04,
    gamma=0.5,
    max_position=100.0,
    hedge_threshold=10.0,
    hedge_aggression=0.01,
    size=5.0,
)
ParameterTypeDefaultDescription
quote_exchangestrrequiredExchange to quote on
hedge_exchangestrrequiredExchange to hedge on
quote_feedstrrequiredFeed for quoting exchange
hedge_feedstrrequiredFeed for hedge exchange
base_spreadfloat0.04Base spread width
gammafloat0.5Avellaneda-Stoikov risk aversion
max_positionfloat100.0Max hedge order size
hedge_thresholdfloat10.0Delta threshold to trigger hedge
hedge_aggressionfloat0.01Price improvement for hedge orders
sizefloat5.0Quote size

Pipeline: mm_arb

quoter = hz.mm_arb(config)

hz.run(
    name="mm_arb_bot",
    pipeline=[quoter],
    ...
)
Returns list[Quote]: generates quotes for the quoting exchange. Hedges are side-effects via the engine.

Example

import horizon as hz

config = hz.MMArbConfig(
    quote_exchange="polymarket",
    hedge_exchange="kalshi",
    quote_feed="polymarket",
    hedge_feed="kalshi",
    base_spread=0.04,
    gamma=0.3,
    hedge_threshold=15.0,
    size=5.0,
)

hz.run(
    name="cross_venue_mm",
    exchanges=[
        hz.Polymarket(private_key="0x..."),
        hz.Kalshi(api_key="..."),
    ],
    markets=["election-winner"],
    feeds={
        "polymarket": hz.PolymarketBook("election-winner"),
        "kalshi": hz.KalshiBook("KXELECTION-25"),
    },
    pipeline=[hz.mm_arb(config)],
    interval=0.5,
)
MM Arb composes existing reservation_price() and optimal_spread() Rust functions. See the Market Making docs for details on Avellaneda-Stoikov parameters.