StatsHub Docs
Specs

Bet Builder — Team-Budget (multiXPlayer) Model for Same-Team SOT Multis

The design record for the team shots-on-target budget model the bet builder prices against. Written 2026-07-10.

Date: 2026-07-10 Status: Design — awaiting spec review Author: James McCoy (+ Claude)


Problem & goal

The current same-team SOT/shots teammate model (Round 5, scalar R by role/line/threshold) is wrong-signed and over-aggressive: direct measurement on our DB + the bookiebashing reference (#13, floor-at-1 = never shorten) + physical reasoning all show it should be lengthen/neutral, never the −19% shortening it currently ships — and it has a bug that lengthens forward stacks. Worse, whether a combo should shorten or lengthen depends on the matchup, and a scalar factor can't express that.

Replace it with a generative team-budget model (the multiXPlayer approach bookiebashing uses): model how a team's shots-on-target are produced and shared, and let the correct joint — and its sign — fall out instead of being guessed. Everything market-derived and margin-free, so it's directly comparable to a de-margined bookiebashing.

Keep unchanged: the single-player shots+SOT joint (thinning model, 2026-07-10 spec) — a different, validated, genuinely-positive effect (one player's SOT ⊆ their shots).

The model

For 2+ same-team player SOT (or shots) legs in one slip:

  1. Team-total distribution P(T) — from the market (§2.1).
  2. Per-player rate λᵢ — from each player's fair SOT odds (§2.2); shares wᵢ = λᵢ/Σλ, scaled so the players' expected total matches the market team total.
  3. Allocation — given T, distribute the T shots-on-target among appearing players multinomially by wᵢ. This is "competing for the same shots" and enforces the hard ceiling (they can't collectively exceed T).
  4. Joint P(all legs clear their lines) = Σ_T P(T) · P(multinomial(T, w) clears every line).
  5. Correction R = joint ÷ Π(marginalᵢ), applied to the same-team player-leg product in combinedFairOdds (replacing the Round-5 scalar factor). legFloor remains the backstop.

2.1 Team-total distribution from the market

Devig the team's SOT over/under ladder → P(team SOT ≥ k) at each offered line, then fit a Negative Binomial (mean μ + dispersion) to those survival points.

  • Preferred source: Total Shots on Target Home/Away — carries a multi-line ladder (e.g. this fixture: Home 2.5/3.5/4.5/5.5/6.5). ≥2 lines → fit both μ and dispersion from the market (the dispersion is what sets the co-fire/cannibalise sign, so getting it from the odds keeps the whole thing forward-looking & match-specific).
  • Fallback: Team Shots on Target Home/Away — often a single line → devig for μ only, take dispersion from a DB-measured prior (team-SOT VMR by strength tier, one number).
  • No team-SOT market at all → §5 safe fallback.

2.2 Per-player rate & budget consistency

λᵢ from the player's fair SOT odds (implied mean; we already have this from the thinning work / lambdaNumber). Two independent reads on team volume — market team μ and Σλᵢ — are reconciled by anchoring to the market team total and scaling the shares wᵢ = λᵢ/Σλᵢ, so the budget is coherent even when player props and the team line come from different books.

Why this resolves the sign debate

The teammate covariance is an output of one market-derived quantity:

Cov(Nᵢ, Nⱼ) = wᵢ·wⱼ·E[T]·(VMR − 1)      VMR = Var(T)/E[T] of the team total
  • VMR > 1 (team SOT swings) → co-fire → shorter.
  • VMR = 1 (Poisson) → independent → naive product exact.
  • VMR < 1 (steady) → cannibalise → longer.

And the multinomial hard cap makes extreme demands (e.g. 3 players needing 13 SOT from a team that rarely makes 11) collapse toward impossible → naturally lengthens/locks exactly where a fixed-budget intuition says it should — no special case. One mechanism reproduces co-fire, cannibalisation, and the ceiling, each in its right regime.

Bookiebashing comparison (validation, not shipped)

A dev-only harness:

  1. De-margin BB #13 (a=−0.081, b=1.1153) by dividing out the b base to approximate their fair implied correlation.
  2. Run the same combos (2–3 players × SOT lines × team totals) through our model and de-margined BB, tabulate R_ours vs R_BB.
  3. Expect agreement on shape (mild mid-range, blow-up at the ceiling); document divergences. This is how we sanity-check our numbers before shipping.

Safe fallback when no team-SOT market

Per owner: never make punters think there's value when there isn'tnever shorten a same-team SOT/shots multi we can't model. With no team-total distribution:

  • Price at the naive product (R = 1) — the neutral, defensible default (we don't fabricate a co-fire uplift we can't justify), and
  • The legFloor still applies. We do not apply any shortening without a team model.

(Optionally a mild BB-style lengthen later; for v1, naive-floor is the safe-ish thing.)

Integration

  • New module src/lib/bet-builder-team-sot-model.ts: fitTeamTotal(devigged survival points) → {pmf}, teammateJoint(legs, teamTotal, shares) → prob, teammateR(...).
  • Devig helper for the team SOT ladder (reuse existing devig + the odds-comparison team-SOT markets already surfaced by buildTeamShotLineCtx, extended to return the ladder).
  • combinedFairOdds: same-team SOT/shots player cluster → teammateR (replaces playerClusterFactor's SOT/shots path). Single-player shots+SOT joint unchanged. Different teams independent.
  • Ctx: extend with the per-team team-total distribution (built on the page from the devigged ladder), alongside the existing player-shot ctx.
  • Retire the Round-5 scalar role/line/threshold factor for SOT/shots (kills the wrong-signed shortening + the forward bug). Compat un-lock stays (same-team SOT priceable).

Testing (TDD)

  1. fitTeamTotal reproduces a NegBin from survival points; monotone; sane μ/VMR.
  2. teammateJoint multinomial math: 2- and 3-player joints; degenerate (1 player) = marginal; sums bounded by Fréchet.
  3. Sign as output: synthetic high-VMR total → R>1 (shorter); VMR=1 → R≈1; low-VMR → R<1.
  4. Ceiling: demand > team's reachable total → joint → ~0, R pushes long / combo flags infeasible.
  5. Co-fire moderate: "2 players each 2+ SOT" on an over-dispersed total → mild R>1.
  6. Budget consistency: Σλ scaled to market μ.
  7. Fallback: no team market → R=1 (naive), never <1.
  8. BB comparison harness runs and tabulates (smoke).
  9. No regression: single-player shots+SOT joint, teammate different-team, single legs, legFloor all unchanged.

Out of scope / risks

  • Shots (vs SOT) teammate: same machinery with the team shots ladder; ship SOT first.
  • Player↔team-market and goals-scorer joints — unchanged (still locked / separate).
  • NegBin fit needs ≥2 ladder lines for market dispersion; else prior — flagged per pricing.
  • Constants (prior dispersion, clamps) isolated for recalibration.
  • Real-time cost: sum over T≤~25 × multinomial tails for 2–4 players — cheap.

On this page