SimpleFunctions

Sports.

$5M+/month in liquidity rewards. Almost nobody is collecting.

Polymarket pays market makers to quote both sides of sports markets under a quadratic scoring function. EPL, NBA, UCL, CS2, IPL, NFL. You don't pick winners; you ship tight quotes and uptime. SimpleFunctions runs the pre-game and live engines, handles circuit breakers, and skews sizes when a thesis edge appears.

A 1530 Calcio Fiorentino match in Piazza Santa Croce — two teams in colored Renaissance livery, packed stands, a scribe at the bookmaker's table tallying bets in chalk

Calcio Fiorentino · 1530 Piazza Santa Croce — sport, crowd, and the scribe at the bookmaker's table all in one frame.

What the runtime optimizes

Tight is exponentially better. Two-sided is 3x.

Polymarket sports MM optimizes a fixed reward pool through a quadratic function — different objective from spread capture, different constraints. Seven fields per market drive every quoting decision.

quadraticScore

S(v, s) = ((v − s)/v)² — the formula Polymarket uses to allocate the daily reward pool.

tickFromMid

Distance from midpoint, in cents. Default 1¢ both sides for max score on a 3¢-cap market.

twoSidedDepth

Bid + ask both at top-of-book, equal size. Single-sided scores ~⅓ of two-sided.

rewardShare

Your score ÷ total qualifying score in that pool. ~20% target share is achievable for top-3 makers.

adverseSelection

~$50/EPL-game from 2.5 avg goals × 20¢ impact × 100 contracts. <3% of revenue at scale.

circuitBreaker

Pull all quotes on a sudden mid jump (±5¢ in <2s default), cool 10s, recompute, requote.

skewBias

When a thesis edge says one side is mispriced, skew sizes — score near-max, inventory leans.

Per-game reward pools

At ~20% market-share for a top-3 maker, most leagues clear $300-$3,500/game. Live mode is ~72% of the pool; the engine handles both modes from one config.

LeaguePer gamePreLive
UCL$4,800$1,344$3,456
EPL$2,000$560$1,440
NBA (regular)$1,800$504$1,296
NFL$1,500$420$1,080
CS2 (major)$1,100$308$792
La Liga$660$185$475
IPL$450$126$324
Serie A$660$185$475

Estimates assume top-3 reward share. Source: Polymarket liquidity-rewards docs.

Why a purpose-built sports engine

ApproachWhat it gives youWhere it breaks

Hand-quoting on Polymarket UI

You see the market with full context

No quadratic-score optimization, no circuit breakers, no two-sided depth automation

Generic MM bot

Familiar tooling for equities / perps

Wrong objective function — reward pool ≠ spread capture; no event-aware circuit breaks

DIY Python script

Total flexibility, no vendor lock-in

Months of work to handle goals, halftime, lineup, scoring, circuit, polling cadence

SimpleFunctions sfmm + QuoteEngine

Pre + live, all leagues, BYOK on Polymarket

Quadratic-score optimal, sub-100ms requoting, edge-aware skew, full circuit handling

Who runs sports MM

Six recurring shapes. Capital scales sub-linearly with reward share — most operators run multi-league for coverage, not single-league for size.

Sports MM firms

Multi-stream operation across EPL/UCL/NBA — coverage capacity matters more than per-game bias.

Quant prop desks

Sports as low-correlation alpha; reward pool capture independent of equities P&L.

Esports specialists

CS2 / LoL — discrete-round structure, $5,500/match pools, digital-native flow underserved.

Cricket-focused makers

IPL is the largest unrebated cricket pool; clear cadence, light competition for top-3 share.

Underwriting models

Run sfmm + your model: thesis-skewed quotes that earn the pool AND lean toward conviction side.

Discretionary punters

Use sf scan + sf book to find edge, hand-quote with the engine handling tick-distance + circuit.

Run it from anywhere

The bot is open source. The data feed is the same one the rest of the runtime uses. Wire it into your ops Slack, your IC pack, or your agent.

github.com/spfunctions/polymarket-sports-mm

Pre and live, side by side

Two different operational modes. Same engine, different polling cadence, different circuit-breaker thresholds, different reward economics.

PRE-GAME · 28% pool
$ sfmm run --mode pre --leagues epl,ucl

PRE Liverpool vs Arsenal (3 markets)

  Match Result YES   bid 0.54×100 ask 0.56×100
  Over 2.5 Goals     bid 0.61×100 ask 0.63×100
  Both Teams Score   bid 0.58×100 ask 0.60×100

Score: 44.4/min · est reward $560/game
Polling: 5s · Status: quoting

Risk window: lineup announcement (~5 min)
Circuit: ±5¢ in <30s
LIVE · 72% pool
$ sfmm run --mode live --leagues epl

LIVE Liverpool vs Arsenal — 67'
  Match Result YES   bid 0.71×100 ask 0.73×100
  Score: 44.4/min · est reward $1,440/game

[72'] ⚠ GOAL — Liverpool 2-1
[72'] CIRCUIT BREAK — quotes pulled
[72'] cooldown 10s ...
[72'] ✓ requoted at new mid 0.78
      bid 0.77×100 ask 0.79×100
SCORE MATH · why tight is exponential
S(v, s) = ((v - s) / v)²

v = 3¢ (max qualifying spread)

s = 1¢   →  score = 0.444 per contract
s = 2¢   →  score = 0.111 per contract  ← 4x worse
s = 3¢   →  score = 0     (cap reached)

Two-sided quoting (bid + ask) ≈ 3x score
Tighter is exponentially better.
SKEW ON THESIS · QuoteEngine v2
$ sf quote create LIVERPOOL-ARSENAL-MATCH \
    --thesis-id liverpool-vs-injuries \
    --skew-from-edge

✓ active · auto-skew from edge feed
  default: bid 100 / ask 100 (symmetric)
  thesis edge says +5¢ Liverpool YES
    → bid 130 / ask 70 (favored side leans)
  score stays 0.43/min · inventory tilts

FAQ

What is Polymarket sports market making?

Polymarket pays market makers to quote both sides of sports markets through a quadratic scoring function. Every minute the platform samples your resting orders; the closer your bid/ask sit to the midpoint and the more two-sided depth you provide, the more of the daily reward pool you receive. About $5M+/month flows through the EPL/NBA/UCL/CS2/IPL pools combined.

How does quadratic scoring actually work?

Score(v, s) = ((v − s)/v)² where v is the maximum qualifying spread (3¢ on most sports markets) and s is your distance from midpoint. At s=1¢ you score 0.444 per contract; at s=2¢ only 0.111. Two-sided quoting (bid + ask) scores ~3x single-sided. Tighter is exponentially better — you can not just brute-force volume.

Pre-game vs live mode — what changes?

Pre-game ~28% of the pool, slow price moves, 5-second polling, low adverse selection (only lineup announcements really move the book). Live ~72% of the pool, sub-second polling required, circuit-breaker on midpoint jumps, 2.5-3x more reward but you absorb adverse selection on every goal/score change. The runtime ships both modes; sfmm run --mode pre|live picks one.

Adverse-selection math for soccer?

EPL average: 2.5 goals per game, ~20¢ price impact per goal, ~100 contract exposure → ~$50 cost per game. Reward at 20% pool share is ~$2,000 per game live, ~$560 pre-game. Adverse selection is roughly 2.5% of revenue. The numbers work because soccer is "96% safe time" — long stretches of stable quoting between rare high-impact events.

Which leagues does the runtime cover?

Soccer: EPL, La Liga, Bundesliga, Serie A, UCL, UEL, Conference, MLS, J-League. Basketball: NBA, EuroLeague, college (NCAAM/NCAAW). Esports: CS2 majors, LoL, Valorant. Cricket: IPL, T20I, Test. American football: NFL, college bowls. New leagues are wired by configuring contract patterns; the engine is league-agnostic.

Capital requirement to start?

Soccer-only single-stream: $3,000-$5,000 USDC, depending on league mix. Multi-sport: $10,000-$25,000 to spread inventory across overlapping windows. Capital scales sub-linearly with reward share — once you are top-3 on a market, more inventory mostly buys depth not score, so you cap inventory and add markets instead.

How does the runtime decide quote sizes?

The default is symmetric (no view): bid 100×, ask 100×. When a thesis or edge feed gives you a side-bias (e.g., your model says +5¢ on Liverpool YES), the bot skews sizes — more on the favored side, score stays near-maximum, inventory leans toward your edge. This is QuoteEngine v2 in the CLI.

What about circuit breakers?

On any sudden midpoint jump (configurable: default ±5¢ in <2s on live), the engine pulls all quotes, cools down for 10s, recomputes fair from new mid, and requotes. This is the difference between a +$1,440 live game and a -$300 ride after a goal you did not see coming.

How is this different from a standard MM bot?

Standard MMs optimize for spread capture on equities/perps where the spread is wide and volume is volatile. Polymarket sports MM optimizes a fixed reward pool through a quadratic function — different objective, different constraints. The runtime is purpose-built for the Polymarket scoring rules and the sports-specific event structure (kickoff, lineup, halftime, goal, period end).

Open source?

sfmm (the Python sports MM bot) is public on GitHub. QuoteEngine v2 lives in the supported @spfunctions/cli npm package and uses the same BYOK execution path as the rest of sf.

Related surfaces