Polymarket Bot Tutorial · Chapter 13 of 32
A market maker quotes both sides of a market all day and earns the small gap between them - no opinion on who wins required. This chapter is the honest version: the three ways a maker gets paid, the inventory risk that eats those gains, a working quoting bot, and the markets where it actually pays.
Market making in 60 seconds
Picture a currency-exchange booth at an airport. It always shows two prices: one to buy your dollars, a slightly better one to sell them back. The booth does not care which way the exchange rate drifts; it earns the gap between those two prices, over and over, all day. A market-making bot does exactly that on a Polymarket book - it rests a buy price (the bid) just below the middle and a sell price (the ask) just above it, and earns the spread each time both sides trade.
You are not betting on whether the YES wins. You are renting out liquidity and collecting a fee for it. The strategy is well understood in traditional finance; what makes Polymarket different is sharper adverse selection (the trader hitting your quote often knows something you do not) and the fact that every market eventually resolves. This chapter is the honest math behind whether it pays. Here is what we cover.
- Market making in plain English
- The three ways a maker gets paid
- Inventory risk and skew
- When MM works on Polymarket (and when not)
- Code skeleton: quote both sides at +/- N cents
- Adjusting quotes on news flow
- Killing the bot when adverse selection spikes
Market making in plain English
A market maker continuously quotes a buy price (the bid) below the middle price and a sell price (the ask) above it. When someone hits your bid, you buy cheap; when someone lifts your ask, you sell dear; the difference between the two is your revenue per round trip. That middle point, halfway between the best bid and best ask, is the midpoint.
The strategy is order-flow-driven, not directional. You take no view on whether YES wins - you take the view that flow will keep coming and the spread will keep being paid.
The catch is adverse selection: the people taking your quote often know something you do not, so the moment they fill you, you are frequently on the wrong side. Over time, market-making profit comes down to one question - is your spread wide enough to cover the losses to those informed traders?
The three ways a maker gets paid
It helps to keep the revenue streams separate, because they pay in different ways and people constantly mix them up.
| Stream | What it is | When it pays | Notes |
|---|---|---|---|
| Spread capture | The gap between your bid and ask | When both sides fill - a full round trip | Usually the biggest stream |
| Maker rebate | A share of the taker fee on your filled order | When your resting order gets taken | A separate program; relevant because makers fill. Rates change - check the live rewards page |
| Liquidity rewards | A daily payment for resting near the midpoint | Whether or not you ever fill | A different program again - see the liquidity-rewards-farming chapter |
For most markets, spread capture is the largest of the three. The maker rebate is a useful top-up that grows when you quote the wide, busy markets Polymarket wants deeper (election season, major playoffs). Liquidity rewards you earn almost by accident, just by resting near the mid - but if that is your main goal, you are really farming, not making, and the farming chapter is the right read. Do not assume any of these rates is fixed; pull the current numbers before you size a strategy around them.
Inventory risk and skew
A maker who keeps getting hit on the bid quietly builds a long position. The danger is that the midpoint drops while you are long - you give back the spread you earned, and then some, on the inventory itself.
Three defenses, and you want all three:
- Quote skew - when you are long, move the bid lower and the ask lower so the next fills push you back toward flat. When short, do the inverse.
- Inventory cap - simply stop quoting the side you are already too long on.
- Active rebalancing - once in a while, cross the spread on purpose to cut a position that is stuck at the cap.
The math is blunt: if 60% of the fills on your bid never get exited on the ask before the price moves 2 cents against you, those fills alone are losing money - no spread covers that. Skew hard once fill imbalance passes roughly 65/35.
When MM works on Polymarket (and when not)
Market making pays when three things hold at once.
- A liquid book - enough competing quotes that your spread is competitive but not zero. Major NFL and NBA games, big political markets, and the busier crypto up/down markets qualify.
- Two-sided flow - both buyers and sellers active. A market that has effectively resolved (sitting at 0.95+) gives a maker nothing to capture.
- Bounded price moves - a single 5-cent jump eats a lot of 2-cent spreads. Stable mid-range markets (0.40 to 0.60) are the friendliest.
It fails on news-driven markets where the midpoint jumps faster than you can re-quote, on illiquid books where you are the only quote and the next trade walks five levels, and on resolution-imminent markets where one side is converging to 0 or 1. When in doubt, paper-trade the market for a day first and look at your fill imbalance before you risk real capital.
Code skeleton: quote both sides at +/- N cents
The simplest viable maker. It quotes a fixed spread around the midpoint, skews away from whichever side it is too long on, and caps inventory. Treat it as a starting point, not a finished bot.
SPREAD_CENTS = 2
INVENTORY_CAP_SHARES = 50
def make_loop(token_id):
while True:
book = fetch_book(token_id)
mid = (book.best_bid + book.best_ask) / 2
inv = chain_balance(token_id)
# skew: nudge prices to push inventory back toward flat
bid_px = mid - SPREAD_CENTS/200 - (0.005 if inv > INVENTORY_CAP_SHARES * 0.6 else 0)
ask_px = mid + SPREAD_CENTS/200 + (0.005 if inv < -INVENTORY_CAP_SHARES * 0.6 else 0)
cancel_my_existing_quotes(token_id)
if inv < INVENTORY_CAP_SHARES:
place_gtc(token_id, side="BUY", price=bid_px, size=5)
if inv > -INVENTORY_CAP_SHARES:
place_gtc(token_id, side="SELL", price=ask_px, size=min(5, inv))
time.sleep(2)
Production makers add per-side inventory tracking, cancel-before-place ordering so you are never doubly exposed, a little jitter on the re-quote interval so you are not predictable, and the kill switch in the last section.
Adjusting quotes on news flow
When news hits, fair value moves before your quotes do, and a maker that does not pull its quotes gets picked off in seconds. So you watch for the move and step back.
The signal: incoming fills jumping above roughly 3x their baseline rate inside 30 seconds, or a wider event cross-check (a headline feed, the market's own chatter). When you see it, pull every quote for 60 to 120 seconds, let the new midpoint settle, then re-quote around the new center.
The simplest version watches the last-trade-price stream for the token: a jump of more than two standard deviations from the rolling mean triggers a pause, and the bot re-engages only after the price has held steady for 30+ seconds. Slower and safer beats fast and picked-off.
Killing the bot when adverse selection spikes
The hard exit. If your fill PnL over the last 50 fills turns sharply negative, something has changed: either the market is now news-driven and you should not be making it, or your spread is too tight for the current level of adverse selection. Encode the kill conditions so the bot acts before you would:
- 5 bid fills in a row with no ask fill, and the midpoint down more than 1 cent since the first.
- Realized PnL over the last 25 round trips below -25% of expected.
- A WebSocket disconnect or a stale book.
- Inventory stuck at the cap on either side for more than 5 minutes.
When any of these trips, cancel everything, flatten at market, and halt for at least 15 minutes. A maker without a kill switch keeps bleeding through a volatile stretch until you notice by hand - which always takes longer than you think.
Key takeaways
- You earn the spread for renting out liquidity - no view on who wins required.
- Three separate streams pay you: spread capture (biggest), maker rebate (a taker-fee share on fills), and liquidity rewards (for resting). Keep them straight.
- Inventory is the real risk. Skew, cap, and rebalance - or one news move erases days of spread.
- It works in liquid, two-sided, mid-range markets; it fails in news-driven, thin, or resolution-imminent ones.
- A kill switch is non-negotiable, and latency matters - paper-trade first, then go live small.


