All research
10 min readMethodologyMarket MakingStatisticsLive Trading

The city that wasn't there: thirty groups, one survivor, and the split that killed the rest

Sorted by city, six weeks of live prediction-market P&L spans +13.66 to −10.04 per $100. Exactly one city's confidence interval clears zero — and 1.5 were expected by chance. Ranked on the first half and tested on the second, city scores rho +0.18 and category scores −0.20. The only selector that replicates is one you cannot observe until it is too late.

What this is about

Polymarket is a prediction market. You buy shares in a yes-or-no question — will the highest temperature in Tokyo be 24°C on 22 September? — and at settlement each share pays exactly $1.00 or exactly $0.00. Nothing in between. Questions cover weather, sports, elections and crypto prices, and most resolve within days.

I run an automated market maker on it. The bot quotes both sides of a market and earns the spread: buy one YES and one NO on the same market and the pair redeems for exactly $1.00 whatever happens, so the profit is locked the moment the second leg fills. Polymarket also pays a maker rebate for providing liquidity. The risk is the leftover — shares whose other half never filled, which go to settlement alone and pay 1.00 or 0.00.

Everything below comes from six weeks of live quoting with real money: 701 settled markets, $19,889 of deployed capital, one account, one venue.

A large share of the markets the bot quotes are daily temperature questions for specific cities — will the highest temperature in Madrid be 29°C today? Each city, each day, produces its own set of markets. That makes city a natural way to slice six weeks of results, and it is the slice that looked most promising.

This piece is about what happened when that slice was tested properly: whether any observable property of a market predicts whether quoting it makes money.

Slicing a losing book by category until a profitable subset appears is the oldest way to lose money slowly. Everyone knows this. Almost nobody applies the correction, because the profitable subset always looks so specific: not “weather markets” but Warsaw, and Warsaw made money, and here is the number.

What follows is what happened when I applied the correction properly. It is a negative result about almost everything I tested, and a strongly positive one about a single variable that turns out to be unusable as a filter.

The spread that looks like signal

Thirty cities with at least eight settled markets each, P&L per $100 of capital, rebate included at the blended rate:

CityMarketsNet / $100
Warsaw11+13.66
Dallas17+6.51
Milan12+4.86
Paris25+3.25
…
Manila15−4.80
Ankara16−6.71
Amsterdam16−10.04

A 23-point spread. Twelve cities positive, eighteen negative. It is extremely easy to write the paragraph that begins “Warsaw and Dallas show that liquidity in mid-size European and US metros…”

The correction

Bootstrap a 95% confidence interval per city, clustered by market. Cities whose interval clears zero: 1 of 30. Expected by chance at 95%: about 1.5.

One survivor against 1.5 expected from noise alone. The finding is that there is no finding.

The stronger test is out-of-sample. Rank the groups on the first 350 settled markets, then measure that ranking on the last 351 — a genuine split, not a re-slice:

SelectorSpearman rho across halves
Trade count+1.00
City+0.18
Category−0.20

City barely predicts itself between halves. Category is mildly anti-correlated — last period's best category is marginally more likely to be next period's worst than its best.

Both would have passed a naive significance screen applied group by group. Neither survives being asked to predict.

What does replicate

Trade count — how many times the market traded over its whole life — is monotonic in both halves measured independently:

TradesFirst 350Last 351All 701Capital
≤2−43.72−45.23−44.63$323
3–9−7.02−0.13−3.54$3,212
10–29−2.88+0.37−1.21$9,279
30++2.91+3.28+3.00$7,074

The top bucket is profitable in both halves. Selecting the better half on the first period turns −0.81 into +0.52 in the second.

And the tail is where the programme dies:

91 markets ended at two trades or fewerShare
of the market count13%
of the capital1.6%
of the total loss51%

Half the loss on 1.6% of the capital. These are markets that got one leg filled and never paired — a single share bought, the other side never reached, then settlement at zero or one.

The trap inside the good result

capital also replicates at rho +1.00. For about ten minutes that looked like a second independent finding. It is not: r(trades, capital) = +0.988. They are the same variable wearing different clothes, and both are outcomes — measured at settlement, unknowable at entry.

So the one selector that survives validation cannot be used to select. Every parameter I tested that is observable when the decision is made failed:

Entry-observable parameterResult
Cityrho +0.18
Categoryrho −0.20
Hours from entry to market endbuckets within noise (−3.34 / −0.61 / −0.74 / −1.46)
Entry hour, leg counttoo few groups to test

Nor is size a filter. Halving entry size would save $73 on the stranded book and cost $83 on the profitable one — and since it halves deployed capital too, the per-$100 figure does not move at all. It scales both ends.

And there is no fat tail to cut. The 91 stranded markets are all small — median $3.40 of capital, largest $7.16 — and the eight worst account for only 27% of their damage. It is 91 small bleeds, not three big ones.

What I would want to be true, and am not claiming

“No entry-observable filter works” is not what this shows. It shows no filter works among the things currently recorded. The most likely place for one has never been written down: the selector's own inputs — measured trades per hour, cash flow per hour, rebate per share, price at entry, hours to resolution — live in memory and are overwritten every cycle. They have never been persisted at the moment of selection, so the question “does anything the selector already measures predict which markets strand?” is unanswerable rather than answered.

That instrumentation now exists and is waiting on a rebuild. It is the only lead this analysis produced that has not already been closed.

Method, and what it cannot see

701 settled markets, $19,889 capital, one account, one venue, six weeks, live orders. P&L is merge income plus resolution outcome plus the mark on unclaimed losing legs, with the maker rebate allocated by capital weight from actual payout receipts rather than a published rate.

The split is chronological, not random — first 350 against last 351 by first trade. That is the right split for a question about whether a ranking predicts, and it means any result is also exposed to regime change between the halves. The trade-count effect holding in both halves is therefore a stronger claim than the same effect measured once across all 701.

Per-market standard deviation is 32.3 per $100. At that dispersion, most of what looks like structure in a 30-group slice is dispersion.