An analytical model built for fun and discussion — not advice. Every number is a probability with real uncertainty, not a prediction.
How the Forecasts Work
Simulation Methodology
A technical explainer for readers who want to know how we arrive at the numbers on the league, tournament, and parity pages, including championship odds, playoff-qualification probabilities, and projected final standings.
What this is, and what it isn't. This is an analytical model built for insight and conversation — "how might the season play out, and how sure are we?" It exists purely for entertainment and to explore how well statistical models can describe a youth hockey season — not to inform any decision that matters. Youth hockey is high-variance and our data is thin (about 34 games per team in a season), so every number here is a genuine probability with real uncertainty around it, not a prediction of what will happen.
1. The question the simulation answers
Given the games played so far, we want the probability distribution of ways the rest of the season could go. There is no formula for these numbers — the only honest way to compute them is to play the remaining games thousands of times and count how often each thing happens. That's a Monte Carlo simulation.
2. The two kinds of uncertainty (this is the important part)
A good forecast has to account for two separate sources of randomness. This split is a standard idea in uncertainty quantification, and getting it right is the difference between an honest number and an overconfident one.
Randomness in the event itself, not in our knowledge of it — even a perfectly-known matchup still has to be played. With only a handful of goals scored in a typical game, an unlucky bounce or two is enough to flip a result that could have gone either way, even between two truly evenly-matched teams.
Uncertainty in what we know, not in the event — we don't actually know how good each team is, only an estimate from ~34 games, which is not many. The team that looks best on paper might genuinely be the best — or, for example, might have had a friendly early schedule or some good luck go their way.
A simulation that only models the first kind looks far more confident than it should. It effectively says "assume our power ratings are exactly correct, now roll the dice" — and the ratings are not exactly correct. We model both.
Other sources of uncertainty exist too — injuries, lineup changes, a goalie having a hot week — that we don't have the data to quantify directly. We don't pretend to model them by name; instead the bootstrap in Step 2 below naturally widens around any team whose results have been inconsistent, which absorbs some of that unmodeled variance even without identifying its cause.
3. The pipeline, end to end
-
Rate the teams (Dixon-Coles)
We fit a Dixon-Coles model, the standard approach for goal-scoring sports. It gives every team an attack rating (how many goals they tend to score) and a defense rating (how many they tend to allow), estimated jointly from every game's final score so that each team's rating is adjusted for the estimated strength of the opponents it actually played — no team's rating is looked up in isolation; all of them are fit together. From any two teams' ratings the model produces the full probability of every possible scoreline. The ratings are then shrunk toward the league average: with only ~34 games of evidence, raw estimates over-react to small samples, so we pull them gently toward "average" by an amount tuned and validated on five years of data. (We're working on a dedicated page walking through why and how — for now, this note is the summary.)
-
Capture rating uncertainty (the bootstrap)
To represent the fact that we don't know the ratings, we don't fit them just once. We refit them many times on bootstrap resamples of the season — each resample draws the same number of games at random, with replacement, so each refit sees a slightly different version of the season and produces a slightly different set of ratings. The spread across these refits is our uncertainty about each team's true strength. (In a future version these refits become draws from a Bayesian posterior, which is the same idea done more formally; the bootstrap is the current implementation.)
-
Play the rest of the season, many times
For each rating sample from Step 2, we run a share of the Monte Carlo trials. In every trial:
- Each remaining game is simulated by drawing a random scoreline from the Dixon-Coles probabilities for that matchup.
- Already-played games are kept as they really happened — we never re-simulate a completed result.
- Ties that must be broken (a tournament game that can't end level) are resolved by a 50/50 overtime coin flip.
- Standings are computed with the league's real tiebreaker chain: points → regulation wins → head-to-head (two-way ties only) → goal quotient → regular-season seed.
- Pool winners advance into the crossover bracket (1A vs 2B, 1B vs 2A), and the bracket is played out to a champion.
We tally who finished where. Because this step runs across many different rating samples from Step 2, the final tallies fold together both kinds of uncertainty at once.
-
Turn tallies into probabilities
A team's championship probability is simply the fraction of all trials in which it won. Advancement and finish-position probabilities are counted the same way.
4. How many simulations, and how precise?
5. How to read the numbers
-
They're probabilities, not predictions. "Team X: 73% to make playoffs" means that if this exact situation played out many times, they'd qualify in about 73 of 100 — and miss in about 27. Upsets are not bugs; they're the 27.
-
Round, don't squint. We show rounded figures and ranges on purpose. The difference between 71% and 73% is noise; the difference between 30% and 70% is real.
-
Two close teams may be a genuine toss-up. When the ranges overlap, the model is telling you it can't separate them — that tells you the race is closer than the standings alone suggest.
6. Assumptions and limitations (in plain terms)
-
1.
Games are treated as independent given the ratings. We don't model momentum, injuries, or who's in net on a given night — we have no reliable data for those, and inventing them would add false precision. Goaltending in particular is the biggest thing we can't yet see: research on goal-based vs. shot-based metrics suggests how a team's shots turn into goals — which goaltending drives heavily — matters as much as the shots themselves.
-
2.
Tournament games are simulated at a neutral site. In practice, tournament games are often played at one of the two teams' home rink even though the format is nominally neutral — we don't model that home-ice edge in tournament play, which is a real limitation, not just a simplification.
-
3.
Overtime is a 50/50 coin flip. A slightly better team probably wins a bit more than half the time, but we keep this simple.
-
4.
One season of data. Ratings reflect the current season only; a team that improves mid-season is captured as the season's games accumulate, but we don't yet carry a memory across seasons.
-
5.
We trust the box score as recorded. The model can only see what's in the data — coaching, line matchups, a kid having a breakout month, all beyond how it shows up in goals — and it treats whatever the scorekeeper entered as the truth, errors and all. Our forecasts are only as good as that underlying data collection.
7. Reproducibility
Every simulation stores the random seed it used, so any published number can be regenerated exactly. We're working on a technical companion page — pseudocode and diagrams that walk through the simulation step by step — for readers who want to go deeper than this page.
Model Research, coming soon. We're building out a section that will publish the analysis behind the model's design and validation, including the uncertainty-propagation work referenced in Step 2 above.