← Notebook

Experiments · Rejected

NBA Cup games: are they higher scoring?

Point differential is a Cup tiebreaker, so teams might keep starters in. Across 180 group-stage games, scoring and late-game behavior looked like regular games.

Hypothesis

In NBA Cup group play, ties in the standings are broken by point differential. A team leading by 18 in the fourth quarter has a reason to keep its starters in and push to 25, where it would normally empty the bench. If teams really do that, Cup group games should score more and finish with wider margins, and leaders should give back fewer points in the fourth quarter.

Finding the Cup games

The database has no Cup flag. The public NBA schedule does: each game has a gameSubtype, and "in-season" marks a Cup group game. The comparison group is regular games played inside the same weeks, so the season, the calendar and the injury picture match.

web/scripts/notebook_figures.pylines 128–166
def cup(q):
    """NBA Cup group games against regular games played in the same weeks."""
    from nba_api.stats.endpoints import scheduleleaguev2
    kinds = {}
    for season in ("2023-24", "2024-25", "2025-26"):
        path = os.path.join(CACHE, f"subtype_{season}.json")
        if not os.path.exists(path):
            df = scheduleleaguev2.ScheduleLeagueV2(season=season, league_id="00", timeout=60).get_data_frames()[0]
            os.makedirs(CACHE, exist_ok=True)
            json.dump({str(r.gameId): r.gameSubtype for r in df.itertuples()}, open(path, "w"))
        kinds.update(json.load(open(path)))

    g = q("""SELECT g.nba_game_id, g.game_id, g.game_date, g.season,
                    (g.home_score + g.away_score)::float total,
                    p.home_score_predicted::float - p.away_score_predicted::float pred,
                    (g.home_score - g.away_score)::float actual,
                    h.q1_points + h.q2_points + h.q3_points - a.q1_points - a.q2_points - a.q3_points lead3,
                    h.q4_points - a.q4_points q4
             FROM games g
             JOIN team_box_scores h ON h.game_id = g.game_id AND h.team_id = g.home_team_id
             JOIN team_box_scores a ON a.game_id = g.game_id AND a.team_id = g.away_team_id
             LEFT JOIN predictions p ON p.game_id = g.game_id AND p.model_version = 'wf-v2'
             WHERE g.is_final AND g.season_type = 'Regular Season'
               AND g.season IN ('2023-24','2024-25','2025-26')""")
    g["kind"] = g.nba_game_id.astype(str).map(kinds).fillna("")
    g["cup"] = g.kind.eq("in-season")
    # regular games inside each season's Cup group-stage window
    win = g[g.cup].groupby("season").game_date.agg(["min", "max"])
    g = g.join(win, on="season")
    same_weeks = g[(g.game_date >= g["min"]) & (g.game_date <= g["max"])]

    def summ(x):
        big = x[x.lead3.abs() >= 15]
        give_back = (-np.sign(big.lead3) * big.q4)          # leader's Q4 points given back
        return dict(n=len(x), total=r1(x.total.mean()), total_se=r1(x.total.std() / np.sqrt(len(x))),
                    abs_margin=r1(x.actual.abs().mean()), n_big=len(big), give_back=r1(give_back.mean()))
    return dict(cup=summ(same_weeks[same_weeks.cup]), regular=summ(same_weeks[~same_weeks.cup]),
                by_season=[dict(label=s, cup=r1(x[x.cup].total.mean()), regular=r1(x[~x.cup].total.mean()))
                           for s, x in same_weeks.groupby("season")])

Findings

Same weeks, 2023-24 to 2025-26Cup group gamesOther games
Games180379
Average total points229 (±1.6)229.8 (±1)
Average winning margin1211.9
Games with a 15+ point lead after three quarters3670
Points those leaders gave back in the fourth2.92

Average total points: other games vs Cup group games

Same weeks of each season.

Average total points: other games vs Cup group games Other games Cup group games 222224226228230232234236 difference 2023-24: other games 229.2, cup group games 229.2 pts 2023-24 +0.0 2024-25: other games 226.1, cup group games 224.5 pts 2024-25 −1.6 2025-26: other games 232.8, cup group games 233.4 pts 2025-26 +0.6
Data table
Other gamesCup group gamesDifference
2023-24229.2229.20.0
2024-25226.1224.5-1.6
2025-26232.8233.40.6
  • Scoring is the same. The overall gap is under one point, well inside the noise, and it changes direction from season to season.
  • Margins are the same. If teams were running up scores, winning margins would be wider.
  • Leaders did not hold on harder. Teams up 15 or more after three quarters gave back about as many points in the fourth, slightly more in Cup games, though on only 36 games.

There was one faint hint in the other direction: favorites beat the model’s forecast margin by about 1.8 points in Cup group games (±1.2 standard error). That is too weak to act on. The 18 knockout games were forecast about 5.6 points too high on the total, but they play more like playoff games, and 18 is far too few.

Decision

Not added as a feature. A narrower version could be worth revisiting with 2026-27 Cup data: flag only the final group game, and only when point differential can still change who advances.