The Scanner That Cried Arbitrage
I built a scanner to hunt for free money on a betting exchange. It flagged 293 opportunities. Every single one was a trap — and the traps are the fun part.
Let me start with the thing that felt like a glitch in the matrix.
Kalshi is an exchange where you bet real money on whether things will happen. You buy a share for some number of cents; if you turn out to be right it pays you exactly one dollar, and if you're wrong it pays you a heartfelt nothing. Since a share that was certain to pay a dollar would simply cost a dollar, the price is really just the crowd's guess at the odds — a share trading at thirty cents is the market mumbling "eh, thirty percent."
One afternoon I was looking at a market titled "Best AI this month?", with four contenders — Claude, Gemini, ChatGPT, and Qwen — where for each one you could bet Yes (this model wins) or No (this one doesn't). Here's the detail that made me sit up. Exactly one model can win the month. So if I bet No on all four at once, three of those four bets are guaranteed to come true, because three of the four models are, with the certainty of the sunrise, going to lose. Each winning No pays a dollar. Three dollars, locked in, no matter who wins.
The four No bets, added together, cost 298 cents. The guaranteed payout was 300. That is two cents of profit requiring no knowledge of artificial intelligence, no prediction, and no risk — just arithmetic that the market had, somehow, fumbled.
Two cents is not a lot of money. It is, frankly, an insulting amount of money. But it was insulting me for free, and — this is the dangerous thought — if it could happen once, maybe it happened a thousand times, and a thousand times two cents is suddenly a car payment. So I sketched out two pieces of software. First, a scanner: a program to comb the entire exchange and flag every one of these little mistakes the instant it appeared. Then, if the scanner turned up enough of them, a bot: an app to place the bets automatically and rake in the free pennies while I slept. This is the story of the scanner — and, it turns out, the story of why the bot was never worth building.
The scanner, and its first disappointment
The scanner is not clever, and that's rather the point. It reads the current prices for every market on the exchange (all of which Kalshi publishes for free), gathers up the markets that belong to the same underlying question, and checks whether their prices are even allowed to coexist. The four AI models are bound by an ironclad rule — exactly one wins — and when a set of related prices breaks its rule, that's the crack you slip the crowbar into. And notice what the scanner never does: it doesn't place a single bet. It only ever reads and flags. Placing the bets was always going to be the bot's job.
It knows a small menagerie of these cracks. There's the all-No basket you just met. There's its mirror image, where you bet Yes on every outcome for less than the dollar one of them is guaranteed to pay. There's a sneaky one where the cheapest way to bet on the favorite is to bet against everybody else instead. And there are a couple that play with time — if something is going to happen "before November," it has definitely also happened "before January," and occasionally the market forgets to price that in.
But before the scanner could get clever, it had to learn about the one guest who ruins every party: the fee. Kalshi, like every casino, toll road, and cousin who "knows a guy," takes a cut of each trade. And its cut is shaped like a small hill — smallest on the near-certainties and the long shots, and largest, naturally, right in the middle, on the coin-flip bets. The trouble is that the edges I was hunting are usually a cent or two, and the fee is very often bigger than the entire edge. If your free money is smaller than the toll to go collect it, it was never free and it was never money. So I taught the scanner to do the fee arithmetic to the exact penny before it flagged anything at all. An "edge" that hasn't paid its fee yet isn't an edge — it's a trap with good lighting, and the bot that trades it is a bot on a short road to broke.
Then I turned the scanner loose on the whole exchange. Kalshi calls each of these questions an event, and every event holds a handful of individual markets — the separate Yes/No contracts you actually bet on. (That "Best AI this month?" question from the top? One event, four markets, one per model.) At the time there were about 6,800 events on the exchange, holding roughly 28,900 markets between them, and the scanner priced and checked every single one. It lit up like a slot machine. Two hundred and ninety-three opportunities.
Trap one — the fee eats it
The most common by a mile: the edge was real right up until the fee, and negative right after it — like spotting a two-dollar discount that rings up with a two-fifty handling charge. The scanner kept these anyway, flagged in a mournful amber, because they're a true and slightly heartbreaking fact about the market: a genuine mistake, just too small to be yours. Not money.
Trap two — the list of outcomes wasn't complete
This one is worth tattooing somewhere discreet. There is a real Kalshi market — "How many bills will President Trump sign this month?" — that lets you bet on the exact count: zero bills, one, two, and so on up to seven. Buy Yes on all of them and, when the scanner looked, it cost about 89¢ — which looked like eleven cents of guaranteed profit, a sure dollar on sale.
It was not. Count the buckets again: zero through seven, and then nothing. There is no "eight or more." So if the President signed eight bills that month, every share I owned would pay zero and I'd lose the whole eighty-nine cents. That price wasn't a mistake — it was the market quietly, correctly pricing in the chance the answer was eight, a possibility the list of buckets simply forgot to include.
It's the oldest trick in gambling wearing a spreadsheet's clothes: betting against every horse in the race is a bulletproof plan, right up until you notice there's an eighth horse standing quietly in the parking lot. The formal way to say it is that the outcomes were mutually exclusive — no two could happen at once — but not exhaustive: they didn't cover every possibility. Those two phrases look like synonyms and are not, and the entire gap between them is where fake arbitrage goes to live. (Kalshi wasn't even consistent about it — some months this market did include an "eight or above" catch-all, and some months it just… didn't. Which is precisely why you can never assume.) From then on, the scanner refused to trust a set of outcomes until it could prove nothing was hiding in the parking lot.
Trap three — the price was a mirage
To explain this one I finally have to tell you how the prices actually work, because it is the punchline. When you trade, you're not haggling with "the market" in the abstract — you're taking one of the specific offers other people have left lying around. At any given moment there's a best price at which someone is willing to buy, and a best price at which someone is willing to sell, and the two are almost never the same number. The distance between them is called the spread, and on a busy, healthy market it's tiny — a penny, maybe two.
The strategy that builds a favorite out of its rivals kept finding gigantic edges that vanished the instant you looked at them. In one, the scanner became utterly convinced that a rugby match ending in a Tie — an outcome with roughly the odds of a snowstorm in July — was the "favorite," because a single ancient sell order was parked out at ninety-four cents that no living person would ever take. As far as I can tell it had been sitting there since the Bronze Age. The scanner then measured a magnificent "edge" against a price that did not, in any meaningful sense, exist: the spread on that market was the better part of a dollar wide — the buyers and the sellers weren't within shouting distance of one another. The fix was a rule with a certain weary wisdom to it. If a "favorite's" market is so wide that nobody is really trading in it, it isn't a favorite. It's a hallucination with a price tag.
Trap four — real, and one dollar wide
The quietest trap, and the one that actually stings — because the market that started this whole adventure, the AI one, turned out to be it. Remember the two cents of free money from the top? Here is what it was actually worth. The four No bets did cost 298¢ and did pay a guaranteed 300¢ — a real two-cent edge, no asterisk on that part. But the exchange takes its cut on each of the four bets — about a cent and a half, all told — which quietly turns your two cents into roughly four-tenths of one cent. And even that sliver was available in a quantity of about one contract: try to bet more and the price moved and it was gone. So the founding glitch in the matrix was real, cleared its fees by a hair, and let the bot win — after all of it — somewhere around half a penny, one time. A genuine edge you can photograph but cannot fit through a doorway. In trading, an edge you can't do at any size isn't an edge. It's a souvenir.
Trap five — real, sizable, and slower than a savings account
Trap four killed the edges too thin to size. But a handful were sizable — real, fee-proof, no mirage, deep enough to bet actual money into. Those were the ones the bot was built for: have the scanner find them automatically and trade them around the clock, with no lunch breaks and no feelings, while I slept. So would the bot get rich off those? Still no — and the reasons are precisely the ones that starve a bot.
A profit means nothing on its own. It only means something next to two other numbers: how much cash the bot has to tie up to earn it, and for how long. And the genuinely real edges — the few that clear the fees and aren't mirages — have a cruel habit of living on markets that don't pay out for months.
Take the friendliest possible version, my all-No basket. Suppose the scanner turns up a real one and the bot pounces: it commits a few hundred dollars and is guaranteed a couple of dollars more back than it put in. Genuinely free — except the market doesn't settle until it settles, and the real ones still sitting unclaimed tend to be the ones that settle half a year out. Two dollars on three hundred is about two-thirds of one percent, and with the money frozen in that position for six months, that works out to roughly one to two percent a year. A government Treasury bill pays around three percent for the same six months — no fees, no settlement risk, nothing to babysit. The bot's own money would earn more doing absolutely nothing.
And here's the quietly damning part: this isn't bad luck, it's a filter. The arbitrages that pay a decent yearly rate are the ones that settle soon — and those are exactly the ones snatched in milliseconds by bots that are faster than mine and sitting in the same building as the exchange. My bot loses that race every single time. What's left lingering long enough for any scanner to even find is, by definition, the stuff whose annual return rounds to nothing. The free money that lasts, lasts because it isn't worth anyone's capital — human or machine. There is no free money here, even for a bot. Which is exactly why the bot never got built: the scanner did its job, flagged its 293 mirages, and I let it stay exactly what it was — read-only.
Why it was always going to end here
Both halves point at the same thing, and it turned out to be the moral of this entire website. The all-No basket is the single most obvious thing you can possibly compute from a list of prices — you could teach it to a bright twelve-year-old over lunch. And precisely because it is that obvious, it is the very first thing every trading bot on the exchange is already checking, thousands of times a second — most of them faster, and sitting closer to the exchange, than anything I could build. The mistakes you can catch with simple arithmetic are, by their nature, the mistakes everyone else already caught with the same arithmetic, years ago — and the handful that slip the net slip it only because they're too small, too slow, or too locked-up to be worth taking.
The plan for this entire project — which, in a detail I still find funny, a chatbot wrote for me before I'd typed a single line of code — had said all of this in advance. It told me to treat tiny after-fee edges with suspicion, warned me in those exact words that "mutually exclusive is not the same as exhaustive," and reminded me that a genuine edge you have to lock your money into for six months is just a savings account wearing a cape. I read every word, nodded sagely, and went and found out for myself anyway.
Not convinced, or just want to see the actual numbers? The technical teardown has the funnel, the fee curve, the live bucket data, and the method to reproduce all of it.