Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Drive-Outcome D/ST Scoring

A new way to score fantasy football defenses — based on what happens on each drive rather than end-of-game counting stats. Kill a drive, get points (more for better field position handed to your offense); allow a score, lose a little. Every down matters and the score climbs all game instead of spiking on splash plays.

PITCH.md has the full case: the scoring table, calibration methodology, VAR correlations vs Yahoo, rank-movement analysis, and the 2025 out-of-sample validation.

The scoring (final)

Defined canonically in src/scoring.js. Per opponent drive: stops score +1 / +1.5 / +2.5 / +3.5 by where your offense takes over (inside own 20 / out to midfield / past midfield / inside their 20), stop ending a half +1.5, TD allowed −1, FG allowed −0.5, def/ST TD +6, safety +2 plus the takeover tier (a safety is a stop and 2 real points and possession).

Headline numbers: weekly VAR Spearman vs Yahoo ≈ 0.79–0.82, season VAR ≈ 0.83–0.90, negative-score weeks 7.5% (Yahoo: 7.6%). Calibrated on 2022–24, held up out-of-sample on 2025.

Repo layout

src/
  scoring.js          THE scoring system (config + per-drive scorer)
  espn.js             ESPN API helpers (fetch, yardline conversion)
  fetch-season.js     download a season of game JSONs   → data/raw/<year>/
  fetch-week.js       download a single week (in-season use)
  extract-drives.js   raw JSONs → data/drives.csv
  extract-scores.js   raw JSONs → data/game-scores.csv
  smoke-test.js       fetch one known game, eyeball the parsing

  eval-lib.js         analysis core: Yahoo baseline, scorers, metrics
  evaluate.js         report card for the final config (vs unconstrained optimum)
  var-analysis.js     VAR correlations, value-by-rank, rank movement
  validate.js         bootstrap CIs, parameter sensitivity, EP grounding
  search.js           the broad grid search that found this family (~87k configs)
  clean-search.js     the "memorable values" constrained search that picked G1b

data/
  drives.csv          one row per drive, 2022–25 regular seasons (~23.6k drives)
  game-scores.csv     one row per game: final scores + team sacks
  raw/<year>/         cached ESPN game JSONs (gitignored, ~880 MB)
npm run extract    # rebuild the CSVs from data/raw
npm run evaluate   # full report card
npm run var        # VAR deep-dive (optionally: node src/var-analysis.js 2025)
npm run validate   # robustness checks
node src/fetch-season.js 2026   # when the time comes

Data notes

  • yl100 coordinate: yards from the possessing team's scoring end zone. 0 = about to score, 100 = own goal line. next_start_yl100 on a stop = where the defense's own offense takes over — that's the field-position signal scoring uses. It's empty when possession didn't change or the half ended.
  • drives.csv columns: season, week, game_id, home/away_team, pos_team, def_team, drive_num, result (normalized), result_raw (ESPN's string — distinguishes pick-six vs return TD), start/end/next_start_yl100, end_period, end_clock.
  • Known blind spots in ESPN drive data: kickoff-return TDs are buried in ordinary "TD" drives (~5–7/season league-wide), and special-teams fumbles don't appear as drive results. Both only matter for Yahoo-baseline measurement, not for the system.

Status / next steps

Scoring is final (June 2026). Next: applying it to a Sleeper league in real time during the season — Sleeper has no public write API, so this will take creativity (likely: compute scores from live ESPN drive data and surface them to the league via bot/page/spreadsheet rather than writing into Sleeper itself).

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages