Markets coveredMatch OddsCorrect ScoreOver / UnderFirst HalfSecond Half
Statometrics
Model Library · Bayesian methods and time series

Markov Chain Monte Carlo (MCMC)

A simulation engine that draws thousands of plausible parameter values from a Bayesian model when the maths is too messy to solve directly.

Advancedpre-matchevaluation

In one sentence

MCMC is a way of sampling from a posterior distribution by taking a guided random walk through the possible parameter values, spending more time where the values are more plausible.

How it works

Simple Bayesian models have neat formulas. Real betting models, with team ratings, home advantage, time decay and priors that do not match the data type, usually do not. MCMC gets round this by simulation: instead of calculating the posterior, it produces a long list of draws from it.

The classic version, Metropolis sampling, works like a walker in fog on a hillside. At each step it proposes a nearby value; if that spot is higher (more plausible given prior and data) it moves there, and if it is lower it sometimes moves anyway, with a probability that shrinks the lower it is. Over many steps the time spent in each area matches the posterior.

Once you have the draws, anything you want is an average over them: a team's expected goals, a win probability, a fair price, or a range of uncertainty. Modern samplers such as NUTS (used in PyMC and Stan) take smarter steps, but the principle is the same.

The maths

The Metropolis acceptance rule for moving from the current value θ to a proposed value θ′ is:

α=min⁡(1,P(data∣θ′) P(θ′)P(data∣θ) P(θ))\alpha = \min\left(1, \frac{P(\text{data} \mid \theta')\, P(\theta')}{P(\text{data} \mid \theta)\, P(\theta)}\right)
  • θ: the current parameter value, for example a team's scoring rate.
  • θ′: the proposed new value, usually the current value plus a small random nudge.
  • P(data given θ): the likelihood of the observed results at that value.
  • P(θ): the prior plausibility of that value.
  • α: the probability of accepting the move.

In plain English: always step uphill, sometimes step downhill, and the path you trace ends up mapping the posterior.

Worked betting example

You want a fair price for a team to score 2 or more goals. Betfair offers 1.95, implied probability ≈ 51.3%.

  1. Prior. You believe the team's scoring rate is around 1.3 goals per game, and you express this on the log scale (a normal prior on the log of the rate, centred on the log of 1.3 with spread 0.25). This prior is not conjugate, so there is no neat formula.
  2. Data. Six matches: 3, 1, 2, 2, 0, 4 goals, 12 in total, 2.0 per game.
  3. Sampling. Run 22,000 Metropolis steps, discard the first 2,000 as warm-up. About 59% of proposals are accepted, a healthy rate.
  4. Posterior. The mean scoring rate across the draws is about 1.56 goals, with a 90% range of roughly 1.09 to 2.11. A direct numerical calculation gives 1.56 too, confirming the sampler.
  5. Price. Averaging the Poisson probability of 2+ goals over every draw gives about 45.6%, fair odds ≈ 2.19.
  6. Decision. A £10 back at 1.95 with 2% commission has expected profit ≈ 0.456 × £9.50 × 0.98 minus 0.544 × £10 ≈ minus £1.19. The naive 2.0 goals-per-game view (P ≈ 59.4%, fair 1.68) would have shown about +£1.47. No bet.

Where it's good

  • Fitting hierarchical team or horse models with many linked parameters.
  • Any model where you want honest uncertainty ranges, not just point estimates.
  • Non-standard priors and likelihoods: time-decayed Dixon-Coles, ordinal finishing positions, custom in-play models.
  • Propagating parameter uncertainty into prices, which stops you over-staking on thin evidence.

Limitations and pitfalls

  • Slow. A model that takes minutes to fit is fine pre-match but useless for in-play decisions measured in seconds.
  • Convergence is not guaranteed. Always check R-hat values near 1.00, effective sample sizes and trace plots; a stuck chain gives confident nonsense.
  • Results depend on the prior and the model structure, and MCMC will happily fit a bad model very precisely.
  • Tuning matters: steps too small or too large leave the chain wandering or stuck.
  • It does not find edges by itself. If the market already prices the same information, the extra precision earns nothing.
  • It is easy to overfit with too many parameters; check on held-out matches.

How to build it

  • PyMC (Python) or Stan via cmdstanpy or brms (R); both use the NUTS sampler and report diagnostics.
  • ArviZ for trace plots, R-hat and posterior summaries.
  • Data: whatever your model needs, typically match results with dates and teams.
  • Practical tip: always test a new model on fake data where you know the true parameters, and confirm the sampler recovers them.
18+ only. Educational content, not financial or betting advice. Past results do not guarantee future returns. If gambling stops being fun, get free, confidential help at BeGambleAware.org.
Members