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.