A comment on Hacker News asked: if the probability of an event differs from the odds a prediction market offers, can't you just arbitrage it? It's a good question, and the answer is the first thing a trading firm would teach you about sizing.
A mispriced contract is a bet
Say a contract pays $1 if the event happens and trades at 40c, and you think the real chance is 50%. You expect to make 10c a contract. Half the time, though, you lose your whole 40c.
Buy one contract on each of ten independent events like that. You win 60c on each one that happens and lose 40c on each one that doesn't, so you finish down if three or fewer happen. With a 50% chance each, that is
So you'd still be down overall about one time in six. Also, your 50% is only an estimate, and when the market disagrees with you it's quite often because it knows something you don't.
Arbitrage is when the risk cancels
If you can buy YES on one venue and NO on the same event on another for less than $1 between them, you get $1 back whatever happens. Even then you're exposed to fees, to the money being tied up until settlement, and to the two venues reading the resolution rules differently. That last one has caught out plenty of people.
How much to stake: Kelly
For a binary contract at price p when you believe the probability is q, buying YES pays (1 - p)/p per unit staked when you win. The Kelly fraction of your bankroll is
In the example, (0.5 - 0.4)/0.6 is about 17% of your bankroll per bet.
If you bet twice that, your long-run growth goes to roughly zero, and past that it goes negative. You can be right about the odds and still go broke by betting too much. Most traders bet a fraction of Kelly, often a half, because their q is an estimate and the cost of overbetting is much worse than the cost of underbetting.
Checking it yourself
A quick simulation in Python shows the growth curve:
import numpy as np
rng = np.random.default_rng(1)
p, q, n = 0.4, 0.5, 10_000
for f in (0.08, 0.167, 0.33, 0.5):
win = rng.random(n) < q
growth = np.where(win, np.log1p(f * (1 - p) / p), np.log1p(-f)).mean()
print(f"stake {f:.3f}: log growth per bet {growth:+.4f}")
Growth peaks near 0.167, falls to about zero near 0.33, and turns negative at 0.5.
I've written up more expected value and sizing questions of this kind, the sort asked in market making interviews: https://geodesicpartners.co.uk/quant-questions-market-making
Top comments (0)