Strategy · Low risk · Beginner
Arbitrage
Buy YES + NO when their combined price is below $1. The closest thing to a free lunch in prediction markets — if you can size, fill, and settle.
Published Apr 10, 2026
The idea in one sentence
A binary prediction market resolves to exactly $1 on one side and $0 on the other. If you can buy YES + NO for less than $1 combined, you lock in the difference as profit — with zero directional exposure.
Why this exists
Prediction markets are fragmented. Polymarket, Kalshi, and Opinion all quote similar markets, and order books on each aren’t synchronised. Takers chase one side, makers post stale quotes on the other. The combined price of YES + NO can drift below $1 for seconds to minutes at a time — long enough to fill if you’re listening to both books.
Classical arbitrage in equities evaporated as HFT tightened. In prediction markets, it’s still there because:
- Latency to fill is higher (on-chain settlement, wallet signing).
- Order books are thin; a single taker can move one side 2–3 cents.
- Cross-venue arbitrage is harder because collateral and identity aren’t shared.
polybot’s arbitrage strategy exploits within-venue YES/NO mispricings. Cross-venue is the job of statistical-arbitrage and resolution-arbitrage.
How polybot implements it
- Scanner service subscribes to order-book updates on all enabled markets via the venue connector.
- On each update, the strategy computes
best_ask(YES) + best_ask(NO). - If that sum is below
1 - min_edge(defaultmin_edge = 0.015, i.e. 1.5 cents), it emits aSignalfor both legs. - The executor sends both orders concurrently (via NNG
PUSHchannel) and reconciles the fills. - Position sizing is the minimum of: available capital, best-bid size on each leg, and a per-market cap.
# simplified core of src/polybot/strategies/arbitrage.py
edge = 1.0 - (best_ask_yes + best_ask_no)
if edge >= self.config.min_edge:
size = min(
self.config.max_size,
book.yes.ask_size,
book.no.ask_size,
self.risk.available_usd / (best_ask_yes + best_ask_no),
)
self.emit(Signal(market_id, side="YES", price=best_ask_yes, size=size))
self.emit(Signal(market_id, side="NO", price=best_ask_no, size=size))
When it works
- High-volume events in the last 24–72 hours before resolution, when order flow is heavy and both books are active.
- Politics, sports, and crypto event markets with multiple aggressive liquidity providers.
- Any time a venue is adding volume quickly and makers haven’t caught up.
When it fails
- One-leg fills. If YES fills and NO’s quote moves away, you now have a directional position. Mitigation: IOC orders and bounded slippage; if one leg misses, the other is cancelled. polybot enforces this via the executor’s two-phase submit.
- Fee drag. Polymarket CLOB has no maker-taker split, but network gas on cancels eats edge. Kalshi has a fee schedule. Don’t target < 1c edge.
- Resolution risk. If the market resolves ambiguously or is cancelled, your “risk-free” pair becomes a refund — but you’ve paid gas and borne the opportunity cost.
Configuration
polybot strategy enable arbitrage
polybot strategy config arbitrage \
--min-edge 0.015 \
--max-size-usd 500 \
--markets-include "politics,crypto" \
--markets-exclude "weather"
polybot strategy shadow arbitrage --enable # stay in paper until you see N fills/day
polybot strategy shadow arbitrage --disable # promote to live
Risk profile
| Dimension | Assessment |
|---|---|
| Directional exposure | None (hedged by construction) |
| Execution risk | Medium — single-leg fills need tight management |
| Capital turnover | High — positions close at resolution |
| Dependence on AI | None — purely mechanical |
| Good starter strategy? | Yes |
FAQ
Is this actually risk-free? Only if both legs fill at the quoted prices. polybot’s executor uses short-TTL IOC orders and cancels on partial fill, but slippage and venue downtime are real. Size accordingly.
Why not trade this manually? Windows are 1–60 seconds wide and require simultaneous fills on both sides. Humans can’t close them at scale; a bot can.
Can I do this across venues (Polymarket vs Kalshi)? That’s a different strategy — see statistical arbitrage. Cross-venue requires correlated-but-not-identical market matching and separate collateral on each venue.
Does polybot handle venue fees correctly? Yes. Fees are subtracted from edge before the min_edge comparison, so you’re always computing net edge.
Read the strategy source at src/polybot/strategies/arbitrage.py.
Want this strategy tuned for your book?
Cryptuon can adapt polybot strategies to your capital, risk budget, and markets. Shadow-deployed before you go live.