World Cup 2026 predictor

It picked Spain to win, a month before kickoff, by simulating the real 48-team bracket.

# rows are runs, columns are matches
N_SIMULATIONS = 20_000
home = rng.poisson(lam_home, size=(N_SIMULATIONS, n_matches))
away = rng.poisson(lam_away, size=(N_SIMULATIONS, n_matches))
winner = np.where(home > away, team_home, team_away)
The simulator, simplified.
When
2026
Status
Finished
Code
Private repository
Stack
Python, NumPy, SciPy, XGBoost, Streamlit, GitHub Actions

A forecast that retrained itself daily

  1. Dixon-Coles scorelines

    A bivariate Poisson model with the low-score fix, in an ensemble with Elo and XGBoost.

  2. Vectorized Monte Carlo

    NumPy plays the whole 48-team bracket as arrays, not loops.

  3. A pipeline that updates itself

    A cron ran ten times a day and retrained nightly; each commit redeployed the app.

  4. Honest evaluation

    Walk-forward validation and de-vigged odds. Live, it called 44 of 72, level with Elo.

  • 32,290# international matches in the training set
  • 20,000# tournament simulations per run
  • 60.8%# holdout accuracy on 3,601 matches, against a 47.3% baseline