Ballhockey.com← Back to ratings
The math behind the caps

The Big-Brain Breakdown

Every formula, assumption and worked example behind the league ratings and the team cap. Calculators encouraged. Snacks recommended. Nobody will check your work, but you can check ours.

0The short version

  1. Every player in the league gets a whole-number rating from 1 to 7.
  2. Each team's strength is measured as its average rating scaled to an 18-player roster, so teams of different sizes compare fairly.
  3. For each division we find the average team strength and how spread out the teams are (the standard deviation).
  4. The cap is set at roughly one standard deviation above the division average, then moved into the nearest clear gap between teams.
  5. A roster fits a division when its total rating is at or under the cap, nobody is above the individual ceiling, and it has 11 to 20 players (22 in Division 1). Rosters whose average rating is above the division's threshold are flagged for review.

1Notation

A handful of symbols do all the work on this page.

\(r_i\)
The rating of player \(i\), a whole number from 1 to 7.
\(n\)
The number of players on a roster, goalies included.
\(S\)
A roster's total rating: \(S = \sum_{i=1}^{n} r_i\).
\(\bar r\)
A roster's average rating: \(\bar r = S / n\).
\(T\)
Team strength on the 18-player scale (section 3).
\(k\)
The number of teams in a division.
\(\mu,\ \sigma\)
The average team strength in a division and its standard deviation.
\(C_d\)
The team cap for division \(d\).
\(c_d\)
The individual ceiling for division \(d\), the highest rating one player can hold there.
\(\theta_d\)
The roster average threshold for division \(d\).
\(m_d\)
The provisional (new player) minimum for division \(d\).

2Player ratings

Each player carries one rating \(r_i \in \{1,2,3,4,5,6,7\}\) across the whole league, whatever team or division they play in. Ratings are whole numbers only, with no half points.

A rating is a judgment, not the output of a formula. It weighs league history, points per game, the division those points were scored in, defensive and positional impact, and outside hockey experience. Goalies are rated separately from Forward/Defense, so someone who has played both appears once for each position.

The math on this page starts after the ratings exist. Everything below uses ratings as inputs. None of it decides what any individual's rating should be.

One player, one number, everywhere

If a player appears more than once with the same name and position, the higher rating is used:

$$ r_{\text{player}} = \max\big(r^{(1)}, r^{(2)}, \dots\big) $$

This stops a lower duplicate from quietly saving cap space.

3Team strength on one scale

Rosters vary in size, and adding up ratings would reward teams that simply carried more players. So every team was first converted to an 18-player equivalent:

$$ T \;=\; 18 \times \bar r \;=\; 18 \times \frac{\sum_{i=1}^{n} r_i}{n} $$

18 is the base roster the caps were built on. Multiplying the average by 18 answers one question: how much total rating would this team carry if it had exactly 18 players of the same average quality?

Worked example

TeamPlayers \(n\)Total \(S\)Average \(\bar r\)Strength \(T\)
Team A15553.66766.0
Team B20723.60064.8

Team B has the bigger raw total (72 vs 55), but Team A is slightly stronger per player, and the 18-player scale shows it: 66.0 vs 64.8.

If one person is listed twice on the same team, as a Forward/Defense and as a spare goalie, they were counted once at their higher rating so no team is inflated.

Measuring vs. enforcing

The 18-player scale is used to set the caps. Once set, a cap is enforced on a roster's actual total \(S\), not on \(T\). That means every extra player uses cap room, which is deliberate: depth is a real advantage. Dividing each cap by 18 shows the average rating per player the cap allows on a full 18-player roster:

$$ \bar r_{\text{implied}} = \frac{C_d}{18} $$
DivisionCap \(C_d\)\(C_d/18\)

4The average team and the spread

For a division with \(k\) teams and strengths \(T_1, \dots, T_k\), the average team is:

$$ \mu = \frac{1}{k}\sum_{j=1}^{k} T_j $$

The standard deviation measures how far teams typically sit from that average:

$$ \sigma = \sqrt{\frac{1}{k}\sum_{j=1}^{k} \big(T_j - \mu\big)^2} $$

Why divide by \(k\) and not \(k-1\)?

This is the population standard deviation. The \(k-1\) version estimates the spread of a bigger population from a sample. Here we aren't sampling: every team in the division is included, so the division is the population.

Worked example Example teams for illustration

Nine illustrative teams, chosen so their average matches Division 5's real average of 55.6:

Team\(T_j\)\(T_j-\mu\)\((T_j-\mu)^2\)
152.2−3.411.56
253.1−2.56.25
354.0−1.62.56
454.6−1.01.00
555.3−0.30.09
656.00.40.16
756.91.31.69
857.41.83.24
960.95.328.09
Sum500.40.054.64
$$ \mu = \frac{500.4}{9} = 55.6 \qquad \sigma = \sqrt{\frac{54.64}{9}} = \sqrt{6.071} \approx 2.46 $$

The deviations always add to zero. That's a handy check that the average is right.

5Setting the cap

The starting point for each cap is one standard deviation above the division average:

$$ C_d^{*} = \mu + 1\sigma $$

Why one standard deviation?

If team strengths in a division were roughly bell-shaped (normal), the share of teams sitting below \(\mu + 1\sigma\) would be:

$$ \Phi(1) = \int_{-\infty}^{1} \frac{1}{\sqrt{2\pi}}\,e^{-x^2/2}\,dx \approx 0.841 $$

About 84% of teams fit comfortably under the line, and only rosters clearly stronger than their division are pushed to move up. A cap at \(\mu\) would push half the division up, while \(\mu + 2\sigma\) (about 97.7%) would barely catch anyone.

Then into a gap

A real division has a handful of teams, not a smooth curve, and \(\mu + \sigma\) usually isn't a whole number. So the line is moved to a nearby whole number that sits in a clear gap between teams. That way no cap splits two nearly identical rosters. Informally:

$$ C_d = \text{a whole number near } \mu+\sigma \text{ that maximises the distance to the closest team, } \min_j \lvert T_j - C_d \rvert $$

In the example: \(\mu + \sigma = 55.6 + 2.46 = 58.06\). The nearest teams sit at 57.4 and 60.9, so 58 sits inside the gap and becomes the cap. Eight of nine teams fit under it, and the one at 60.9 is clearly stronger.

Measured in standard deviations (a z-score), that cap lands at \(z = (58 - 55.6)/2.46 \approx 0.98\), so on a normal curve about \(\Phi(0.98) \approx 83.6\%\) of teams sit under it.

6Division 5, for real

When the caps were set, Division 5's average team, measured on the 18-player scale from the previous season's rosters, came out at 55.6. One standard deviation above that lands at about 58, and 58 became the cap:

$$ C_5 \approx \mu_5 + \sigma_5 \approx 55.6 + 2.4 = 58 $$

The other caps were placed the same way, each in the clear gap above the middle of its division. Division 2's 92 corresponded to an average just over 5 per player on an 18-player roster (\(92/18 \approx 5.11\)), with Division 1 left open above it. Caps are recalibrated as each season's results come in, so the current numbers are always in the tables on this page.

7Individual ceilings

The cap limits the total. The ceiling limits any single player:

$$ \max_{i} \; r_i \;\le\; c_d $$

Without a ceiling, a team could carry one 7 and a group of 1s and still fit a low cap. The ceiling makes sure the very top players can't be dropped into lower divisions at all.

DivisionCeiling \(c_d\)Who can't play there

The ceiling also applies to spares: a spare's rating must satisfy \(r \le c_d\) for the division they're sparing in. Moving up is never restricted, since every division above has a ceiling at least as high.

8Average thresholds

A third check looks at the roster average:

$$ \bar r = \frac{S}{n} \;>\; \theta_d \;\;\Rightarrow\;\; \text{flagged for review} $$

Thresholds sit above the cap's implied average (\(\theta_d > C_d/18\)), so a normal full roster never trips one. They're there for short rosters. The cap is a total, so a team carrying only 11 strong players could stay under it while being much stronger per player than the division.

Example Example numbers

Division 4 has \(C_4 = 70\) and \(\theta_4 = 4.5\). An 11-player roster totalling 66 is under the cap, but:

$$ \bar r = \frac{66}{11} = 6.0 \;>\; 4.5 $$

It is flagged. That's exactly the "small, stacked roster" the threshold exists to catch. A flagged team isn't moved automatically. It's reviewed, and it may be asked to move up.

Division\(C_d/18\)Threshold \(\theta_d\)

9Provisional ratings

A player with no league history gets the minimum for the division they're joining:

$$ r_{\text{new}} = m_d $$

If they also register in another, higher division, their rating rises to the highest minimum among every division they're registered in, on every team:

$$ r_{\text{new}} = \max_{d \,\in\, D} \; m_d \qquad (D = \text{the divisions they're registered in}) $$

It only moves up, never down. That stops anyone from claiming a low rating in a recreational division while also playing at a higher level. After one season, a provisional rating is replaced by a full rating, and it can be adjusted mid-season if a player is clearly well above or below it.

Division joiningMinimum \(m_d\)

10The full eligibility test

Put together, a roster \(R\) with ratings \(r_1, \dots, r_n\) fits division \(d\) exactly when all three hold:

$$ \underbrace{\sum_{i=1}^{n} r_i \le C_d}_{\text{team cap}} \quad\wedge\quad \underbrace{\max_i r_i \le c_d}_{\text{ceiling}} \quad\wedge\quad \underbrace{n_{\min} \le n \le N_d}_{\text{roster size}} $$

Here \(N_d\) is the division's maximum roster (see the reference tables), and divisions with no cap or no ceiling simply skip that test. Separately, it's flagged when \(\bar r > \theta_d\).

The lowest division a roster fits

Divisions are ordered from most recreational to most competitive. Caps and ceilings never decrease going up, so once a roster fits one division it fits every division above it (roster size aside). The roster builder checks each division from the bottom up and reports the first one that passes:

$$ d^{*}(R) = \min \{\, d \;:\; R \text{ fits } d \,\} $$

New players are counted at each division's own provisional minimum during that check, so the answer is honest for every division, not just the one picked.

11A roster, start to finish Example roster

Seventeen players registering in Division 4 (\(C_4 = 70\), \(c_4 = 6\), \(\theta_4 = 4.5\)):

RatingsCountSubtotal
616
5210
41040
339
111
Total1766
$$ S = 66 \le 70 \;\checkmark \qquad \max r_i = 6 \le 6 \;\checkmark \qquad 11 \le 17 \le 20 \;\checkmark \qquad \bar r = \tfrac{66}{17} \approx 3.88 \le 4.5 \;\checkmark $$

It fits Division 4 with 4 points of room. Could it play Division 5? \(66 > 58\), and its 6 is above Division 5's ceiling of 5, so no. Division 4 is its lowest eligible division.

Now add one more player rated 5: \(S = 71 > 70\). The roster builder flags it 1 point over. Swapping any 4 for a 3, or dropping one rated player, brings it back under.

12Assumptions and limits

Honest math says what it assumes:

  • Ratings are treated as additive. Adding ratings assumes a 6 contributes about twice what a 3 does. Ratings are really ordered categories, so this is an approximation. It's a reasonable one for balancing rosters, but it isn't a law of nature.
  • Divisions are small. With a handful of teams per division, \(\mu\) and \(\sigma\) move when a single team changes. That's one reason the caps are nudged into real gaps instead of copied to two decimal places.
  • The bell curve is a guide. The 84% figure assumes a roughly normal spread. Real divisions are lumpier, so the actual share under each cap can differ.
  • Ratings are judgments. The math is only as good as its inputs. That's why every rating is public, appeals exist, and both ratings and caps are recalibrated after each season using the new results.

Think a rating is off? Send a review request with Appeal a rating at the bottom of the ratings site before your team's registration deadline. You'll get an email with the decision and the reason.

13Reference tables

Current numbers for Fall/Winter 2026. These update automatically when league management changes a cap, ceiling or threshold.

DivisionCap \(C_d\)Ceiling \(c_d\)Threshold \(\theta_d\)Max roster \(N_d\)New player min \(m_d\)

Every roster needs at least 11 players, goalies included. Co-ed rosters also need at least 4 women. The Women's division sits outside the cap system.