No, you cannot trade longshot-favorite bias on Polymarket. I tested more than 100 algorithms against terabytes of data, as taker and as maker, and none was profitable. The market looks fair — and that is exactly the result worth publishing.
A few months ago a friend told me about the bias and I went to check. I built a system that collects every bet placed in the crypto markets on Polymarket since June 3rd, and on Kalshi since mid-June, tied to coin prices at millisecond resolution, a backtest simulator on top of it, and a team of agents that runs a nightly research lab over both.
The bias: one white ball, nine black
Put one white ball and nine black balls in a box, and let passers-by pay 10 shekels (about $3) to pick:
- 11 shekels if they draw a black ball (90% chance of winning)
- 100 shekels if they draw the white ball (10% chance of winning)
Try it and you will find that more than 10% of people bet on the white ball. People are drawn to the unlikely side because of the multiple, not because of the odds.
Why it should be tradeable on Polymarket specifically
Polymarket is a binary betting venue priced peer to peer. No house sets the payout — the bettors set it between themselves, so the bias does not stay in the gambler’s head. It rolls straight into the price.
Back to the box. Put that game on Polymarket, discover that 20% of people pick white, and the white payout drops to 50 shekels while black rises to 12 — without the probability of winning moving a millimeter. At which point you can argue, correctly, that you should just always bet black and collect.
The argument is right on paper. The only question is what survives fees, latency, and bots faster than mine.
The machine
The collection pipeline
Three processes on ECS Fargate from one image: one collects, one archives, one enriches each fill with on-chain wallet identity. Behind them, Postgres on RDS and Parquet on S3. What goes in: Polymarket’s full order book (snapshots, every level-2 delta, every trade), Kalshi, and the external feeds — Binance at sub-second resolution (@aggTrade and @bookTicker) and Chainlink both as a one-second series and as on-chain oracle rounds.
The most important decision was a boring one: one clock. Every row from every feed is stamped the moment the frame comes off the socket, not the moment it lands in the database. Without that, lining up a move in Bitcoin against a move in Polymarket’s book is an educated guess.
The volumes are not small: one day of order-book updates is roughly 88 GB in Postgres, so archiving runs per market — each market that closes is drained to S3 and deleted within minutes. Kalshi has the opposite constraint, around 2,675 active markets against roughly 10 requests per second without an API key, so its sampling is tiered — 15-minute markets every 20-30 seconds, hour- and day-long ones every 15 minutes.
The simulator
On top of the data I built a backtest engine, and this is the part that took far more human-CPU than I expected. It replays the book event by event, fills orders by walking the depth rather than at the midpoint, charges 0.07·p·(1−p) on every taker fill (verified against real fee-bearing fills), and models latency instead of assuming it — every engine run reports the full sweep rather than one assumed delay. (The lab’s separate scorer, the one that produced the numbers below, prices at a single point: the fee-inclusive executable fill at the snapshot.)
The maker side is harder, because level-2 data does not show where my order sits in the queue. The fill is bracketed between an optimistic and a conservative queue assumption and reported at both ends. The price of that honesty: a maker edge below about 5 cents per fill is undecidable here, because the bracket itself is 3 to 8 cents wide. Better to say so than to invent a number.
The rule that paid off most: anything the engine cannot price correctly — cancellations, selling as a maker — raises an error rather than quietly mispricing it.
The nightly lab
I hand the data and the simulator to a team of agents on Tuesday and Wednesday nights (my weekly Claude session ends on Thursday, so that is how I finish the tokens), plus whatever compute they need from AWS. Five roles: a principal investigator, a skeptic, three explorers. Each iteration is a fresh context — read the shared state, do one unit of work, log it, exit.
The rules matter more than the researchers:
- Register the hypothesis with an id before producing any number.
- Every profit claim goes through one blessed scorer: fee-inclusive, out-of-sample by date, with a clustered confidence interval.
- The holdout is served without outcomes until the campaign is frozen, and any day whose results someone has looked at goes on a burned-days list and can never serve as holdout again.
- The skeptic has one job: killing candidates. Shuffled predictions, shuffled row selection, alternate splits, per-day and per-coin breakdowns, a leakage audit, a capacity check.
- Negative results are wins. Every dead end goes on a DO-NOT-RETRY list.
And no agent promotes anything into the conclusions file. It writes a “proposed conclusion” in that cycle’s report, and I approve it or I don’t.
Where the time actually went
In early July I stopped everything and ran an adversarial code review on the research itself — eight dimensions, every finding reproduced before it was accepted. What came out was unpleasant and useful:
- Selling as a taker executed against the wrong side of the book.
- A limit order that crossed the book was recorded as a resting maker order — dodging the fee entirely. The same order, priced once with fees and once without.
- The split labeled “valid” fell inside the models’ own training window, while the tool proudly printed that it was out of sample.
- The canonical evaluation files had been mutated without versioning, so no recorded number could be reproduced.
I threw out every conclusion produced before that date, including several I liked. This is the part nobody mentions next to a pretty equity curve: a broken backtest does not give a randomly wrong answer. It gives a positive one. Almost every bug on the taker side tilted the result in my favor — on the maker side a couple tilted against me, cancellations silently doing nothing chief among them.
What came out
Across the three campaigns that ran after the hardening, 47 hypotheses were pre-registered and 0 confirmed. The last campaign alone: 39 hypotheses in five waves, 0 confirmed.
The strongest result is a model combining every feature panel, worth about 0.002 of AUC over the market price. There is something there — just something the fee consumes entirely. Detectable, not tradeable.
And the most instructive trap: one candidate showed +2.14 cents per trade with a confidence interval entirely above zero, over 704 trades. The skeptic killed it — on the 5-minute timeframe it was a clean null, its AUC improvement was on the order of 0.0001, and when you run 39 hypotheses somebody has to look good. Textbook winner’s curse. Without a skeptic it would have made it onto a slide.
The bias itself showed up in the analysis I ran before the hardening. I threw those conclusions out with everything else from before July 3rd and never re-derived it under the hardened harness. What did get measured afterwards is duller: after the fee, the market price is fair. One morning Claude announced that in its view the market is “fair” — no first-order market failures. I am inclined to agree.
About the people who prompted “make money”
If you are dazzled by the charlatans who claim they gave a model a “make money” prompt and it produced $12,000 overnight — don’t. It’s nonsense. I checked, with terabytes of data, a simulator that charges fees and models latency, and an agent paid to kill every green number that shows up.
What I did get
Agents are excellent at running an experiment. They are terrible at deciding whether the experiment was honest. All the value here sat in the machinery that can say no: pre-registration, a single scorer, a sealed holdout, a skeptic knocking down every positive result. Without it, 100 algorithms and available compute will always produce something that looks profitable.
The same holds in far more boring projects. When I put AI into an organization, the expensive part is not getting the model to do something — it is building the check that separates “it worked” from “it looked like it worked”. That is how I work, step by step.