polyarb

Measurement-first harness for prediction-market arbitrage.

1What is arbitrage

A prediction market sells shares in an outcome. A YES share pays exactly $1 if it happens and $0 if it does not; NO is the mirror. So the price is just the implied probability: YES at 0.63 means "63% likely" and pays 1 / 0.63 = 1.59x if it hits.

The trick: YES + NO together always pay exactly $1 at resolution, no matter which side wins.

The locked profit. If you can buy the complete set for less than $1, the difference is yours, risk-free. You never need a buyer: you just hold to resolution and redeem for $1.

2The gap

The gap is $1 - (sum of every outcome's ask price). It exists only when the outcomes' implied probabilities add up to under 100%. In practice these gaps are tiny, 1 to 3 cents, and live for well under a second before someone closes them.

Worked example. YES asks at 0.62, NO asks at 0.35. Ask sum = 0.97, so the raw gap is 3¢ per share. Buy one of each for $0.97; the set pays $1 at resolution. Before fees, that is 3¢ of profit on every share you can fill on both legs.

3Why fees decide everything

The taker fee follows fee = shares x rate x p x (1 - p). That p x (1 - p) term peaks at p = 0.50, which is exactly where most gaps cluster, so fees bite hardest precisely where the opportunities are.

Same gap, two venues. Take the 3¢ gap near p = 0.5, where p x (1 - p) is about 0.25.
Sports, rate 0.03: fee is about 0.03 x 0.25 = 0.75¢ across both legs, so roughly 2¢ of net edge survives. A trade.
Crypto, rate 0.07: fee is about 0.07 x 0.25 = 1.75¢, which nearly eats the whole 3¢. A trap.
Identical gap on screen; the fee schedule decides.

4Taker vs maker

There are two ways to fill the legs of an arb.

Taker. You cross the spread right now and pay the current ask plus the taker fee. You fill immediately, which is what you want when a gap is about to vanish. This dashboard models the taker.

Maker. You rest a limit order below the ask and wait for someone to trade into you. If it fills you get a better price (sometimes a rebate), but you are last in a FIFO queue, you suffer adverse selection (you tend to fill exactly when the price is moving against you), and you carry leg risk.

Maker example. YES asks at 0.62, NO asks at 0.35. Instead of taking both, you rest a NO bid at 0.34 hoping to shave a cent. The YES leg fills at 0.62. But your 0.34 NO never trades, and the market drifts: NO now asks 0.45. You are holding a bare YES position, no longer hedged.
That is leg risk. An arb needs every leg filled. With one leg on, you are a naked directional bet. If the price keeps moving you get liquidated at a loss that can dwarf the few cents you were chasing. The maker's better price is not free: it is paid for in fill uncertainty.

5How the bot actually runs

The harness watches roughly 400 markets at once, about 300 on Polymarket and 100 on Kalshi, ranked by 24 hour volume. It does not scan on a slow timer: it reacts to the order books as they move.

Polymarket streams over a websocket, so a book update arrives the instant it happens, sub-second. Kalshi has no public push feed, so it is polled once per second over REST. Either way, every book update is immediately re-checked for a gap, and the taker math (ask sum vs $1, minus fees) is recomputed on the fresh prices.

Why every trade is Polymarket. Kalshi's public API returns only the bid side, so the ask side has to be inferred as 1 minus the opposing bid. Bids always sit below asks, so the inferred YES ask plus NO ask almost always sums to more than $1: no gap. Combined with negative-risk multi-outcome groups being a Polymarket feature, the real gaps come from Polymarket, and Kalshi mainly serves as a live cross-venue reference.
When it tries a maker order. On every detected gap the harness also rests a limit buy one tick above the best bid on each leg, but only if those limit prices would still lock an edge when all legs fill. It waits up to 120 seconds; if the gap has not filled by then it cancels the unfilled legs. Any leg that did fill gets liquidated at market, which is exactly the leg-risk loss you see in the maker chart on the Live gaps page.

6Cross-venue gaps

Sometimes two venues price complementary outcomes of the same event so that YES on one plus NO on the other sums to under $1. The disagreement between venues is the gap.

The catch. This only works if both markets resolve on identical criteria. If the rules differ even slightly, the "arb" is really a hidden bet on the difference, so cross-venue pairs must be verified by hand in mappings.yaml, never matched automatically.

7Ladder arbitrage

A token's price is just the market's probability, so a more likely event should always cost more. Crypto lists ladders of threshold markets on the same asset and date, like "BTC above $60k", "above $64k", "above $68k on July 16". A bigger move is always less likely than a smaller one, so as the strike climbs the price must fall. The cheapest rung should be the least likely, and the priciest rung the most likely.

Sometimes the market gets this backwards and a more likely rung trades cheaper than a less likely one. That is a mispricing. We buy the underpriced likelier rung and pair it against the other so the payout is locked whichever way the price lands.

Worked example. "BTC above $60k" is trading at 0.50 while "BTC above $64k" is at 0.55. Being above $64k means you are automatically above $60k too, so above $60k is the more likely event and should be the pricier one. Here it is cheaper, backwards. Buy the $60k YES and the $64k NO for 0.50 + 0.45 = 0.95. Whatever BTC does, that pair pays at least $1, so the 5 cent gap is locked risk-free profit.
Why it is rare. Market makers watch these ladders closely, so clean mispricings are small and vanish fast, and the crypto fee (the highest on Polymarket) eats the tiny ones. The Ladder arb page only books a trade when the gap clears the fees.

8Fair value (binary options)

A YES share is a bet that pays $1 if an event happens, so its price is just the market's probability. A crypto threshold market ("Will BTC be above $64k on Friday?") is exactly a binary option: it pays $1 if the price finishes above the strike. Options pricing gives an independent fair probability from three inputs the market cannot argue with: the live spot price, how volatile the asset has been, and how much time is left.

Black-Scholes turns those into fair = Φ(d2). When the market's price and this model probability disagree by more than fees, that gap is the signal: the market is pricing the event differently than a principled options model would.

Worked example. BTC spot $64,800, strike $64,000, two days to expiry, recent volatility about 60% annualized. The model puts the odds of finishing above $64k at roughly 60%. If the YES share trades at 0.52, the market is 8 cents too cheap versus the model, a positive divergence.
Not arbitrage. Unlike the gaps above, this is a directional, model-dependent bet: the "edge" is only real if the volatility estimate is right, and a single outcome can go either way. It is higher variance and strictly measurement-only here, no orders. Every measurement records the model's hyperparameters so we can see how it performs and tune it.