Building an Autonomous WC2026 Trading Bot: ELO, Monte Carlo, and Kelly Criterion on Polymarket
We built a system that watches FIFA World Cup 2026 prediction markets on Polymarket
We built a system that watches FIFA World Cup 2026 prediction markets on Polymarket, identifies mispriced outcomes using an ELO rating model and Monte Carlo tournament simulation, sizes positions using the Kelly criterion, and executes trades autonomously from users' self-custodied wallets. This article walks through the math and engineering behind each layer.
System Overview
The system has three components:
- Prediction engine — ELO ratings calibrated on live match results, fed into a 10,000-iteration Monte Carlo simulation to produce probabilities for every tournament outcome (match wins, group qualification, bracket advancement, tournament winner).
- Risk engine — Compares model probabilities against Polymarket prices, computes edge, sizes positions using fractional Kelly criterion, and selects a diversified portfolio subject to category and correlation constraints.
- Execution engine — Places orders on Polymarket's CLOB through users' Gnosis Safe wallets via delegated server signing, monitors settlement, and collects performance fees on winning bets.
The prediction engine runs every 30 minutes, execution every 15 minutes, and settlement checks every 5 minutes.
1. ELO Rating System
The Core Formula
We use the standard ELO expected score formula. Given two teams with ratings RA and RB:
This is a logistic function with base 10 and a scale factor of 400. A 400-point rating difference corresponds to a 10:1 expected score ratio. Two equally rated teams yield EA=0.5.
Rating Updates
After each match, ratings are updated using:
Where:
- K=32 (sensitivity factor, standard for international football)
- SA is the actual result: 1 for a win, 0.5 for a draw, 0 for a loss
- EA is the expected score from the formula above
- G is the goal difference multiplier
Goal Difference Multiplier
A 1-0 win and a 7-1 win shouldn't produce the same rating change. The multiplier G accounts for this:
Where d is the goal difference. This is the same formula FIFA uses in their World Rankings. A 3-goal margin yields G=1.75; Germany's 7-1 over Curacao yields G=2.25.
Seeding
Teams are seeded with ELO ratings derived from their FIFA ranking:
As of matchday 3, after 40 real WC2026 results have been applied, these seeds have shifted. Germany's 7-1 win over Curacao boosted their rating by 32×2.25×(1−0.98)≈1.432×2.25×(1−0.98)≈1.4 points (they were already heavy favorites), while Curacao dropped proportionally. But Canada's 6-0 over Qatar, a more surprising result, shifted ratings more because ECAN was closer to 0.5.
From Match ELO to Three-Way Probabilities
Binary ELO gives you P(home wins or draws)=EA. Football needs three outcomes. We decompose EA into home win, draw, and away win:
The draw probability is modeled as:
The base rate of 0.26 reflects international football's historical draw frequency (~26% across World Cup matches). As the rating gap widens, draws become less likely, a 600+ point gap drives the draw probability to zero.
Home win and away win absorb the remaining probability mass:
Then all three are renormalized to sum to 1.0. World Cup matches are treated as neutral ground (no home advantage adjustment), except for USA, Canada, and Mexico who play at home venues.
Confidence
Model confidence is a linear function of the rating gap:
Two equally-rated teams yield 50% confidence. A 450-point gap (e.g., Germany vs. Curacao) yields 95% confidence. This feeds into both the prediction blender and the portfolio scoring.
2. Monte Carlo Tournament Simulation
Match-level probabilities give us P(Spain beats Saudi Arabia). But Polymarket also has markets for "Spain to win the World Cup" and "Spain to reach the semi-final." These require simulating the entire tournament structure.
Method
We run 10,000 independent tournament simulations. Each simulation:
Group stage: For each group of 4 teams, simulate all 6 round-robin matches. Each match outcome is drawn from the three-way probability distribution. If r∼U(0,1):
Goal counts are sampled conditional on the result: a win produces 1-3 goals for the winner and 0 to (winner goals - 1) for the loser. Draws produce 0-2 goals each.
Teams are ranked by (points, goal difference). Top 2 advance. The 8 best third-place teams across all 12 groups also advance, ranked by (points, GD) globally.
Knockout rounds: 32 teams enter single elimination. Draws are resolved by coin flip (50/50), modeling the unpredictability of penalty shootouts.
Output
After 10,000 iterations, we count how often each team reaches each stage:
This gives us probabilities for every Polymarket market type:
- TOURNAMENT: P(win) directly
- BRACKET: P(reach stage X) from cumulative counts
- GROUP: P(finish top 2 or best 3rd)
- MATCH: Direct from ELO (no simulation needed)
The simulation captures path dependencies that simple multiplication misses. Argentina's probability of winning the tournament isn't just P(win QF)×P(win SF)×P(win F), it depends on who they face, which depends on other group outcomes.
3. Edge Detection
For each Polymarket market, we compute the edge:
Where Pmodel is our probability estimate and Pmarket is the current Polymarket price (which represents the market's implied probability).
A positive edge means the market underestimates the probability, a buying opportunity. We require a minimum edge threshold of 3% to account for model uncertainty and transaction costs.
Example: If our model gives Spain a 72% chance of winning Group H, and Polymarket prices it at 64%, the edge is:
4. Kelly Criterion Position Sizing
The Math
The Kelly criterion maximizes the long-run growth rate of a bankroll. For a binary outcome with model probability p and decimal odds b:
Where:
- p = model probability of winning
- q= 1−p = probability of losing
- b= 1/Pmarket−1 = net decimal odds
This is the fraction of your bankroll that maximizes E[log(wealth)], the expected logarithm of wealth. Kelly is optimal in the sense that it provably outperforms any other strategy in the long run, but it's aggressive.
Fractional Kelly
Full Kelly is volatile. A single bad estimate can blow up a significant portion of the bankroll. We use quarter Kelly (0.25×f*), which sacrifices ~44% of the theoretical growth rate but reduces variance by ~75%.
Guardrails
The raw Kelly fraction is further constrained:
- Minimum bet: $50 (below this, transaction costs dominate)
- Maximum bet: min(user’s max bet setting,$500)min(user’s max bet setting,$500)
- If factual×balance<$50factual×balance<$50, the bet is skipped
Worked Example
Spain to win Group H: p=0.72, market price = 0.64.
With a $1,000 balance: bet $55.60. With a $5,000 balance: bet 278, capped to min(278, max user bet).
5. Portfolio Construction
Individual bets might have edge, but a portfolio of 50 correlated bets on Argentina can blow up if Argentina has a bad tournament. We apply a 5-factor scoring system and diversification constraints.
Opportunity Scoring
Each market is scored on a weighted composite:
Where:
- Sedge=min(|edge|/0.20,1)×100 — how much edge we have, saturating at 20%
- Sconf=confidence×100 — model confidence from the ELO gap
- Sliq=min(liquidity/$5M,1)×100 — market depth
- Sind=max(0,1−team_count/5)×100 — penalizes concentration on a single team
- Sval=min(EV/50,1)×100 — expected value as a percentage of stake
Diversification Constraints
Opportunities are sorted by score and selected greedily, subject to:
Maximum 5 bets per team. Portfolio capped at 50 total bets. This prevents the model from going all-in on a single bracket path.
6. Data Pipeline
ESPN Scraper
Every 2 hours, we fetch the FIFA World Cup 2026 scoreboard from ESPN's API:
This returns structured JSON with match results, scores, dates, and fixture schedules, no parsing of HTML or wikitext required. We resolve ESPN's display names (e.g., "Bosnia-Herzegovina", "Turkiye") to 3-letter FIFA codes via a lookup table.
Group compositions come from Wikipedia's structured templates as a fallback. ESPN doesn't expose group assignments in its scoreboard API.
After scraping, we re-apply all match results to the ELO model and regenerate tournament probabilities. This means the model adapts in near real-time as the tournament progresses.
Polymarket Market Discovery
We query Polymarket's Gamma API for World Cup markets:
Each event contains multiple markets (e.g., "Spain vs Saudi Arabia" has YES/NO markets for each team). We classify markets by event slug patterns:
- world-cup-winner-* → TOURNAMENT
- world-cup-*-reach-* → BRACKET
- -win-group-* → GROUP
- fifwc-* → MATCH
Prop markets (exact scores, number of goals) are filtered out.
7. Execution Architecture
Wallet Model
Each user gets a Gnosis Safe (smart contract wallet) on Polygon. The Safe is deterministically derived from the user's Privy EOA address:
The user delegates signing authority to Privy's server wallet infrastructure. This means the bot can sign transactions on behalf of the user without holding any private keys, Privy's TEE (Trusted Execution Environment) handles the actual ECDSA signing.
The flow:
- Bot decides to place a bet (model says there's edge)
- Bot calls POST /api/bot/place-order on the web app
- Web app constructs the order, signs it using Privy's server signer
- Signed order is submitted to Polymarket's CLOB
- Bot records the bet in Supabase
The user's funds never leave their Safe. The bot can place trades from the Safe but cannot transfer funds out of it.
Settlement and Fee Collection
Every 5 minutes, the settlement loop:
- Fetches all ACTIVE bets from the database
- Groups them by market
- Checks each market's resolution status on Polymarket
- For winning bets, computes profit and fees:
The 12% fee is collected via a gasless USDC.e transfer from the user's Safe to the revenue wallet, executed through Polymarket's relayer. Losing bets incur zero fees, the incentive structure is fully aligned.
8. Scale and Performance
As of matchday 3 of the WC2026 group stage:
- 48 teams across 12 groups
- 40 match results processed through ELO
- 32 upcoming fixtures in the pipeline
- 254 predictions written to Supabase across all market categories
- 50 opportunities in the active portfolio with positive edge
- 10,000 Monte Carlo iterations per prediction cycle
The entire prediction cycle: scrape, ELO update, Monte Carlo simulation, market comparison, portfolio selection, and database write, runs in under 30 seconds on a single Railway container.
Technical Stack
- Web app: Next.js 14, Privy (auth + server wallet signing), Supabase (PostgreSQL + RLS), deployed on Vercel
- Bot service: Python, FastAPI, async scheduler loops, deployed on Railway
- On-chain: Gnosis Safe on Polygon, Polymarket CLOB + relayer, USDC.e
- Data sources: ESPN API (match results), Polymarket Gamma API (market prices), Wikipedia API (group compositions)
The system is live and trading the FIFA World Cup 2026. The platform is at https://pop.zerith.studio/.