Sports Dashboard

MI Bivariate Poisson + Dixon-Coles + Elo

← Back to Blog
|Signal Test|REJECTED

Better xG, Worse Bets: Why Shot-Level Accuracy Doesn't Help

A/B tested FotMob shot-level xG (82.1% regression) vs FootyStats match-level (75.6%) for non-Big-5 variance filter. Shot xG removed 524 profitable bets (entry-adj ROI +9.9%) and added 219 bad ones (ROI -9.5%). Net: -0.2pp ROI, -17u P&L. Better regression accuracy doesn't equal better bet selection.

ROI Delta
-0.2pp
shot xG is worse
Bets Removed
524
entry-adj ROI +9.9%
Bets Added
219
ROI -9.5%

Better xG, Worse Bets: Why Shot-Level Accuracy Doesn't Help

We had a clean hypothesis: FotMob shot-level xG achieves 82.1% regression accuracy for non-Big-5 leagues vs FootyStats's 75.6%. Swap the variance filter's data source, get 6.5pp better regression detection, make more money.

It didn't work. Shot-level xG produces slightly *worse* betting results.

The Question

Our variance filter identifies teams overperforming their xG and skips bets backing them (they'll regress). The xG source determines who gets flagged. FootyStats provides match-level aggregates; FotMob provides per-shot coordinates we can run through our XGBoost model. The shot-level approach should be more precise — it captures shot *quality* independent of finishing outcomes.

Does better regression accuracy translate to better bets?

What We Found

MetricFootyStats (production)FotMob ShotsDelta
Bets12,52212,217-305
CLV+11.8%+11.8%0.0pp
Closing ROI-3.1%-3.4%-0.2pp
Entry-adj ROI+7.3%+7.1%-0.2pp
P&L-393.7u-410.7u-17.0u

The bet pools overlap 96%. The 4% difference is where it matters — and it favors FootyStats.

The Nuance

The critical finding is *which* bets change:

  • Shot xG removed 524 bets that were profitable (entry-adj ROI +9.9%, hit rate 57.4%)
  • Shot xG added 219 bets that were bad (ROI -9.5%, entry-adj ROI +0.1%)

The "more accurate" xG source is removing our best bets and replacing them with mediocre ones.

By league, no consistent pattern: League One -1.7pp, Championship -1.1pp, Eredivisie -0.5pp. Small positives in Brazil +0.4pp and Portuguese Liga +0.3pp don't offset.

Walk-forward: shot xG wins 8 of 17 seasons, loses 9. Pure noise.

Why Better Regression Accuracy Didn't Help

The 82.1% vs 75.6% regression rate was measured offline: "what fraction of teams flagged as overperforming actually regressed?" But the variance filter's job isn't just to identify regression — it's to identify regression *that the betting market hasn't already priced in*.

FootyStats's "noisier" xG creates a different set of regression candidates than the shot-level model. Some of those candidates are teams the market has already adjusted for (the regression is priced in). The production system's calibration — thresholds, lookback windows, interaction with other filters — has been tuned around FootyStats's characteristics. Swapping the data source breaks that calibration without providing a compensating improvement.

The deeper lesson: xG precision and betting edge are different metrics. A noisier signal that's been well-calibrated can outperform a precise signal that hasn't been.

What This Means

Keep production as-is. FootyStats match-level xG stays as the non-Big-5 variance filter source. The shot-level infrastructure remains useful for other purposes (player finishing multipliers, advanced metrics) but doesn't improve bet selection.

What's Next

Nothing further on this path. Tested twice (1 season, then 3-4 seasons), same result both times. The variance filter is well-calibrated at its current data resolution. Future improvements should focus on *what to do* with regression candidates (sizing, conditional filters) rather than *how to identify* them.

REJECTEDSignal: fotmob-shot-xg-variance|2026-04-07