Market Making on Prediction Markets: Quoting Both Sides of a Binary Contract
Prediction market volumes have exploded. Kalshi and Polymarket together generated somewhere between $38 and $44 billion in combined trading volume in 2025, depending on methodology: Kalshi counts volume at $1 face value per contract, while Polymarket counts taker notional (contracts multiplied by the price paid), so the figures are not directly comparable. Monthly combined volume hit nearly $24 billion by April 2026. That liquidity has to come from somewhere. Most of it comes from market makers quoting continuous two-sided markets on contracts that settle at exactly $0 or $1. This post covers the mechanics of doing that well.
Why Binary Contracts Are Different
In equities or FX, your inventory risk is diffuse. A stock can trade at $50 tomorrow, or $49, or $51. In a binary prediction contract, there is no diffuse range. The contract pays $1 if the event resolves YES and $0 if it resolves NO. That payoff structure concentrates inventory risk in a specific way: the closer you get to resolution, the more your net position starts to look like a binary option at expiry. A position that looked like modest directional risk at 60 cents becomes a hard $1/$0 gamble in the final hours. Unlike traditional markets where inventory can be held indefinitely, prediction market contracts settle to one of two terminal values, making aggressive position management near resolution non-optional.
The standard market-making P&L identity still applies. You earn the spread on round-trip volume and lose on adverse selection. What changes is the shape of both terms.
Inventory Risk on a 0/1 Payoff
Think of your fair-value estimate as p, the probability of YES. Your bid is p minus half your spread, your offer is p plus half your spread. If you get hit on the bid (someone sells to you), you are now long. If p is 0.50 and you bought at 0.48, your expected P&L on that position is 0.50 - 0.48 = 2 cents, before accounting for the risk that p moves against you.
The standard inventory-skew response is straightforward: as your net position grows long, shade your bid and offer down. This attracts sellers and discourages more buyers. Conversely, skew up when short. The magnitude of the skew should scale with both inventory size and time to resolution. A net-long inventory at p = 0.50 with two weeks to go is manageable. The same inventory at p = 0.50 with two hours to go is a near-coin-flip on a hard $1/$0 terminal, and your skew should reflect that. Research on inventory management in prediction market bots confirms that removing inventory skew entirely can swing P&L by several dollars per session even on modest size.
Full collateralization compounds this. Most prediction markets are fully collateralized: to post a $1,000 bid you lock $1,000. That caps your return on capital in a way options market makers never face, and it means your position sizing has to be disciplined from the start.
Adverse Selection Around News
Prediction markets differ from equity markets in one important structural way: trading on publicly available information is legal and is the core mechanism for price discovery. In a traditional equity market, insider trading is a federal crime. On CFTC-regulated prediction markets, trading on your views about public events is expected. That said, CFTC designation has now brought insider trading laws to these markets too. Real cases have emerged: Israeli Air Force personnel were indicted for trading on classified information about military strikes on Polymarket. The practical implication for market makers is not that informed trading is risk-free to trade against; it is that the information asymmetry in prediction markets is legal for public-information traders, but can carry criminal exposure for those trading on material non-public information, which does not reduce your adverse-selection risk at all.
A working paper circulating in 2026 adapted Kyle's lambda and the Glosten-Harris decomposition to measure adverse selection directly using a large sample of Kalshi trades. Single-name markets (a specific person does X, a specific company announces Y) showed greater informed price impact than broad-based markets. One-sided order flow, measured via VPIN, predicts maker losses in single-name markets specifically. The practical implication: broad macro markets (Fed rate, unemployment print) are safer for market makers than narrow single-name contracts where a small circle of insiders can trade ahead of you.
The news-shock problem is the acute version of this. Markets can move 40-50 points instantly on a headline. If you are quoting 0.50/0.52 and the fair value jumps to 0.90, your 0.52 offers fill before you can cancel, and you are short a near-certain $1 contract at 0.52. The speed of your cancel-and-requote loop is not a nice-to-have feature. It is the primary determinant of whether news events are catastrophic or just expensive.
When to Widen or Pull Quotes
A few concrete triggers for widening or pulling entirely:
- One-sided fill rate: if you are consistently filling on one side (all bids, no offers, or vice versa) without the mid moving, someone knows something you do not. Widen immediately.
- Scheduled catalysts: earnings calls, economic data releases, court decisions, election results. These are known unknowns. Pull quotes or widen to 10+ ticks before the event window.
- Thin book: in illiquid markets, a single $1,000 order can move price 10 points. You have less cancel protection and more slippage on the other side if you need to unwind.
- Near resolution: as the contract approaches its determination date, the cost of being wrong is increasingly binary. Widen spreads or reduce size aggressively in the final hours.
- Elevated VPIN: one-sided order-flow toxicity is a leading indicator of informed trading. If your real-time flow data shows sustained imbalance, treat it as a warning.
The behavioral quirk documented in recent microstructure research is worth noting: traders systematically overbuy YES in markets that predominantly settle NO. This generates a behavioral surplus that, on average, partially offsets adverse selection losses for makers. It does not eliminate them, but it does explain why market makers can earn a positive edge even in markets where informed traders exist.
Where to Make Markets: Kalshi vs. Polymarket
For US traders, the regulatory picture is clear. Kalshi is a CFTC-designated contract market and fully accessible to US persons. The international polymarket.com site blocks US persons as a condition of Polymarket's 2022 CFTC settlement, which imposed a $1.4 million civil penalty. Polymarket US, operated by QCX LLC and designated by the CFTC in late 2025, is the correct venue for US market makers who want exposure to Polymarket order flow. Both venues use central limit order books, so standard maker strategies (limit orders, quote refresh, cancel-on-fill) apply directly. One practical caveat: as of April 2026, Polymarket US had $1.3 billion in monthly trading volume versus $9 billion on the international platform, so liquidity on the US venue is meaningfully thinner across most markets.
Sports contracts dominate Kalshi volume (around 80% of total since mid-2024) while Polymarket has more exposure to politics (roughly 32-34%) and crypto (roughly 18%). Sports markets have lower adverse-selection risk per contract because the information set is relatively symmetric at game time. Politics and single-name markets carry more informed-trader risk.
A Concrete Strategy Sketch in Python (Banger)
Below is a minimal market-making strategy using the Banger runtime. It maintains a fair-value estimate, skews quotes for inventory, and widens on one-sided flow. Install with pip install bangertrades, then paper-trade it with banger run mm_strategy.py --paper before running live.
import banger
class PredictionMarketMaker(banger.Strategy):
"""
Symmetric market maker for a single binary contract.
Parameters are intentionally conservative for first deployment.
"""
# --- config ----------------------------------------------------------
BASE_SPREAD = 0.04 # 4-tick spread at midpoint (2 ticks each side)
MAX_SPREAD = 0.16 # widen to this on adverse-flow signal
SKEW_PER_UNIT = 0.005 # shift mid by this per net $100 position
ORDER_SIZE = 50 # dollars per side
MAX_INVENTORY = 300 # pull quotes above this net exposure
# ---------------------------------------------------------------------
def on_start(self, ctx):
self.net_pos = 0.0 # positive = net long YES
self.fill_side = [] # rolling window of recent fill sides
def fair_value(self, ctx) -> float:
"""Last traded price as a simple fair-value proxy.
Replace with your own probability model for an edge."""
return ctx.market.last_price
def spread(self, ctx) -> float:
"""Widen spread when recent fills are one-sided (VPIN-lite)."""
if len(self.fill_side) >= 10:
buy_ratio = self.fill_side[-10:].count("buy") / 10
if buy_ratio > 0.8 or buy_ratio < 0.2:
return self.MAX_SPREAD
# Also widen as resolution approaches (hours remaining)
hours_left = ctx.market.hours_to_close
if hours_left < 4:
return self.BASE_SPREAD * (1 + (4 - hours_left) * 0.5)
return self.BASE_SPREAD
def on_tick(self, ctx):
# Pull quotes entirely if position is too large
if abs(self.net_pos) >= self.MAX_INVENTORY:
ctx.cancel_all()
return
p = self.fair_value(ctx)
sp = self.spread(ctx) / 2
# Inventory skew: shift mid toward reducing position
skew = -self.SKEW_PER_UNIT * (self.net_pos / 100)
mid = p + skew
bid = round(max(0.01, mid - sp), 2)
ask = round(min(0.99, mid + sp), 2)
# Avoid crossing the book
if bid >= ask:
ctx.cancel_all()
return
ctx.cancel_all()
ctx.limit_order(side="buy", price=bid, size=self.ORDER_SIZE)
ctx.limit_order(side="sell", price=ask, size=self.ORDER_SIZE)
def on_fill(self, ctx, fill):
if fill.side == "buy":
self.net_pos += fill.size
self.fill_side.append("buy")
else:
self.net_pos -= fill.size
self.fill_side.append("sell")A few notes on this sketch. The fair_value() function is a placeholder. In production you want a model: polling aggregators, your own Bayesian prior, or an implied probability from correlated contracts. The spread() function implements a simplified VPIN check (10-fill rolling window of buy/sell imbalance) and a resolution-proximity widener. The inventory guard at MAX_INVENTORY is a hard stop that pulls all quotes rather than trying to trade through a large position at bad prices. The Banger risk envelope (per-trade cap, daily loss stop, kill switch) sits outside this code and catches anything the strategy misses.
The Bottom Line
Market making on binary contracts is viable but the risks are structurally different from equities. Inventory concentrates at resolution. Adverse selection is abundant, especially in single-name markets, and trading on material non-public information now carries the same legal exposure it does on any CFTC-regulated exchange. Speed of cancel and requote is critical around news. The behavioral surplus from YES-overbuying provides some cushion, but it does not substitute for a real probability model and disciplined inventory management. Start with liquid broad-based markets on CFTC-regulated venues, paper-trade your quoting logic against live order flow, then size up incrementally once your edge per fill is consistently positive net of adverse selection.