Weather Bot — Episode 4: Why Simple Price Rules Beat My Complex Math on Polymarket
After the 0-7 week, I did what I should've done from the start. I stopped trying to invent a strategy and started studying what the people who were actually making money were doing.
Not their Twitter takes. Not their Medium posts. Their on-chain trades. Every buy, every sell, every exit point — it's all public on Polygon. So I pulled up gopfan2's history and went through it trade by trade.
What I found made my EV formulas and probability distributions feel like I'd been looking at the wrong thing.
What This Post Covers
The strategy pivot that turned a 14% win rate into something that might actually work. Three specific changes I made to the bot, why each one mattered, and the backtesting data that convinced me. If you read Episode 3 and wondered how this project survived, this is the answer.
What gopfan2 Actually Does
I'd described gopfan2's approach in Episode 1 — buy cheap YES shares, bet $1, repeat. But sitting down with the actual trade data revealed details I'd missed.
The buy threshold is remarkably consistent: YES priced below $0.15. Sometimes $0.10, sometimes $0.18, but almost never above $0.20. And there's no complex probability calculation behind it. It's just a price rule. "Is this cheap enough? Does the forecast roughly point here? Buy."
But the part that really changed my thinking was the exit behavior. gopfan2 doesn't always wait for resolution. If the price rises to around $0.45 before the market closes, the position gets sold. Lock in the gain and move on, instead of waiting to find out whether the forecast was actually right.
That second part broke something in my head. I'd been obsessing over forecast accuracy — was my prediction correct? — when the profitable strategy doesn't even require being correct. It just requires the price moving in your direction before resolution.
The First Thing I Changed: Model Maximum
This one came straight from the Episode 3 data. My 0-7 record used model averaging. Every actual temperature was higher. ECMWF was consistently the closest model.
The fix was obvious once I stopped overthinking it: instead of averaging the three models, take the highest value.
model_max = max(gfs_value, ecmwf_value, icon_value)
adjusted = model_max + city_bias
Basically: Instead of blending three opinions into a compromise that's wrong in a predictable direction, I'm going with whichever model predicts the highest temperature — which, based on my data, is usually closest to reality.
I went back and retroactively applied this to my 7 failed trades. Model average: 1/7 (14%). Model maximum: 4/7 (57%). Same trades, same data, different selection method. That gap was enough to convince me.
City-Specific Bias
Even with model maximum, some cities had a persistent gap between prediction and reality. So I started tracking the difference for each city and applying corrections.
After collecting 21 data points across 5 cities, the pattern was clear:
| City | Bias Correction | Verified Accuracy |
|---|---|---|
| Ankara | +0.5°C | 80% (4/5) |
| Buenos Aires | +0.0°C | 100% (2/2) |
| Paris | +0.0°C | 67% (2/3) |
| Wellington | +0.0°C | 50% (2/4) |
| Seoul | +0.5°C (when models disagree) | 50% (3/6) |
Small sample sizes, I know. But Ankara at 80% with a +0.5°C correction was enough to make it my primary market. Paris at 67% on HIGH confidence only was also promising. Seoul was a coin flip — but interestingly, adding the bias correction when models disagreed pushed its accuracy up from 33% to 50%.
Dynamic Exit
This was the gopfan2 insight. Instead of holding every position to resolution and praying my forecast was right, I set up price-based exit rules:
| Time Held | Sell When Price Hits |
|---|---|
| < 4 hours | 2.0× buy price |
| 4-12 hours | 1.8× buy price |
| 12-24 hours | 1.5× buy price |
| 24+ hours | 1.3× buy price |
The logic: early price movement means the market is repricing toward your forecast. Later movement is smaller but still worth taking. The longer you hold, the lower the bar for exiting.
I had one data point that sold me on this completely. Ankara on March 10 — the price went from $0.045 at 3 AM to $0.110 at 7 AM. That's a 2.4× move in four hours. With the dynamic exit rule, that triggers a sell at the 4-hour tier. Profit: +138% on that position. And it didn't matter that my forecast was technically wrong — the trade was profitable anyway.
Fallback Bucket
Sometimes the adjusted forecast points to a temperature bucket that's already priced above $0.20 — too expensive to meet the buy threshold. But the bucket one degree below might be cheap.
Ankara on March 11: my adjusted forecast said 14.4°C, pointing to the 14°C bucket. YES was priced at $0.77. Way too expensive. But the 13°C bucket? YES at $0.135. If the actual temperature came in slightly lower than forecast — which happens — the 13°C bucket would resolve correctly.
The bot now checks one bucket below whenever the forecast bucket is too pricey. Simple addition, but it roughly doubled the number of trading opportunities.
The Confidence Filter
Not all forecasts deserve the same trust. When the three models basically agree, the prediction is solid. When they're spread apart, you're guessing.
I set different rules per city. Ankara, Paris, and Wellington only trade on HIGH confidence — all models within 1.5°C. Seoul and Buenos Aires are allowed MEDIUM confidence (1.5-3.0°C spread) because they get the +0.5°C bias correction to compensate.
Anything above 3.0°C spread? Skip. The data showed those trades were basically coin flips, and I'd rather miss an opportunity than throw money at noise.
The Numbers After All Changes
With everything applied retroactively to the same 21 data points:
| Method | Win Rate |
|---|---|
| Model average (v1.0-v1.3) | 1/7 — 14% |
| Model max + city bias (v1.5) | 4/7 — 57% |
| Model max + city bias + HIGH confidence only | ~62% |
21 data points isn't proof, obviously. But it's the difference between a strategy that obviously doesn't work and one that might. And "might" was enough to keep going.
Key Takeaways
- gopfan2's real edge isn't forecast accuracy — it's price-based entry ($0.15 threshold) and time-based exit ($0.45 or resolution). You don't need to predict the weather perfectly.
- Model maximum beat model average on every metric in my data. 14% → 57% win rate, same trades.
- City-specific bias corrections matter. Ankara +0.5°C alone pushed accuracy to 80%.
- HIGH confidence trades (models within 1.5°C) win at 62%. MEDIUM wins at 38%. Over 3.0°C spread? Don't bother.
What's Next
The strategy was rebuilt. On paper, the numbers looked promising. In Episode 5, I'll walk through the actual bot code — how the forecast engine, market scanner, position tracker, and dynamic exit logic all fit together. Not a tutorial, just what I actually built and the decisions behind it.
← Previous: Episode 3: I Lost 7 Straight Weather Trades on Polymarket Next: Episode 5: Building a Polymarket Weather Bot in Python →
More updates on the way. If you're working on something similar or found a smarter way to do it, drop it in the comments — the more we share, the faster we all move.
Disclaimer: This blog documents my personal learning journey. Nothing here is financial advice.
Comments
Post a Comment