walk-forward-validation
Skill0 starsChanged 28 days agoMITView on GitHub
Evaluates sports models in time order: expanding or rolling windows, season-by-season holdouts, bye weeks and season rollover, baselines, and significance. Use when user asks how to validate an NFL model, whether k-fold is acceptable, why backtest results look too good, how many seasons to train on, or how to compare a model to the closing line. Do not use for building features, see feature-engineering. Do not use for betting profit simulation, see backtesting. Do not use for probability checks, see probability-calibration.
6 other projects use a version of this.
Adopted by
Most recently taken up by
- noahowsh/birdieapi-mcptheir own version, first seen Oct 25, 2026
- PuckAPI/claude-sports-analyticstheir own version, first seen Oct 14, 2026
- noahowsh/acesapi-mcptheir own version, first seen Oct 13, 2026
- IngAs8/ClaudeSkilltheir own version, first seen Sep 28, 2026
- Serennity007/claude-trading-skills-67their own version, first seen Aug 25, 2026
- agiprolabs/claude-trading-skillstheir own version, first seen Mar 11, 2026
Other versions6 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 6
- agiprolabs/claude-trading-skills★ 366same name
- PuckAPI/claude-sports-analytics★ 3same name
- noahowsh/acesapi-mcp★ 1same name
- IngAs8/ClaudeSkill★ 0same name
- noahowsh/birdieapi-mcp★ 0same name
- Serennity007/claude-trading-skills-67★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository15 other files it gives its agents.
- backtestingSkill
- college-footballSkill
- dispatchSkill
- edge-detectionSkill
- endzoneapi-toolSkill
- epa-analysisSkill
- feature-engineeringSkill
- game-lookupSkill
- game-previewSkill
- next-gen-statsSkill
- odds-analysisSkill
- odds-explorerSkill
- player-scoutingSkill
- probability-calibrationSkill
- prop-modelingSkill
The file
We split this skill into the rules it gives an agent
1 rule. 0 are common, 1 is distinctive, and 0 are very specific to this project.
0
Common
Most of the 6 edited versions we read keep these.
1
Distinctive
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 113
If the interval contains zero, say the models are not separated on this data.
“Common” is measured: kept by at least 6 in 10 of the 6 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Walk-Forward Validation
Default data tool: EndzoneAPI (
endzoneapi-tool). Data is the same asfeature-engineering:get_games(5 credits per query) for seasons of results and consensus lines. Validation itself uses no credits.
You are an expert in evaluating predictive models on time-ordered data. Your goal is to estimate how a model would have done if used live, and to refuse any evaluation that lets the future inform the past.
When to Use
- "How do I test my NFL model?"
- "Can I use cross-validation?"
- "My model has 58% against the spread in testing"
- "How many seasons should I train on?"
- "Does my model beat the closing line?"
When NOT to Use
- Constructing inputs, see
feature-engineering - Betting returns, bankroll, drawdown, see
backtesting - Checking if 70% means 70%, see
probability-calibration
Commands Available
| Command | Use Here | Credits |
get_games | Season results, scores, consensus lines for the test and baseline | 5 per query |
get_standings | Sanity check of season records | 2 |
Commands That Do NOT Exist
| Not Available | Use Instead |
get_train_test_split | Do it in your own code by season and week |
get_model_predictions | Not provided; bring your own |
get_closing_line | get_games consensus close |
Why Random Splits Fail
Random k-fold puts week 12 games in the training set for a week 5 test game. Team strength is persistent, so the model learns the team from the future. In football, a coach, quarterback or scheme carries across weeks. Results from random splits are optimistic and the amount is not predictable. Walk-forward only.
The Procedure
- Sort games by kickoff time.
- Choose an initial training window and a step. For NFL, the natural step is one week (retrain weekly) or one season (retrain yearly).
- For each step: fit on data strictly before the step, predict the step, store predictions.
- Concatenate predictions. Evaluate once, on the stitched out-of-sample set.
def walk_forward(df, first_test_season, step="week"):
preds = []
for (season, week), test in df[df.season >= first_test_season].groupby(["season", "week"]):
train = df[(df.season < season) | ((df.season == season) & (df.week < week))]
model = fit(train) # features already shift(1)-safe
test = test.assign(pred=model.predict(test))
preds.append(test)
return pd.concat(preds)Fit hyperparameters inside the training window (nested), not on the final test set. Choosing the best of 20 settings on the test seasons and reporting that score is a leak.
Football Specifics
Season rollover. Rosters, coaches and quarterbacks change. The first weeks of a season rely on priors; evaluate weeks 1 to 4 separately from weeks 5 to 18. A model that is strong only late hides an early-season problem.
17-game seasons. A season has about 272 regular season games, plus about 13 postseason games. Test over several seasons. One season of 272 games has a standard error on a hit rate near 3 percentage points (sqrt(0.25 / 272) is about 3.0 points). A 55% result on one season is within noise of 50%.
Window choice. Expanding window (all past data) is stable. Rolling window (last N seasons) adapts to rule changes: kickoff rules, passing-friendly officiating, and so on. Compare both by walk-forward error.
Bye weeks and short weeks. Rows with a bye the prior week have no prior-week game; handle features for them explicitly.
Postseason. Fewer games, different incentives. Report regular season and postseason separately, and do not tune on the postseason.
Weeks 17 and 18. Teams with clinched seeds rest starters. The market sees that; a model without lineup information will not.
Baselines (the comparison that matters)
| Baseline | What It Tests |
| Home team always wins | Floor for accuracy |
| Market-implied probability from the closing line | The hard bar |
| Elo-only model | Does your complexity add value |
| Previous season win percentage | Persistence |
Metrics to report, vs each baseline on the same games:
- Log loss and Brier score for probabilities (lower is better). Accuracy alone hides confidence.
- Mean absolute error of the predicted margin vs the closing spread's error. In public NFL data the closing spread's margin error is a hard benchmark to beat.
- Calibration (see
probability-calibration).
A model that does not beat the closing line on log loss does not produce an edge by betting at the closing line, however well it picks winners.
Significance
Differences between two models on the same games are paired. Use a paired bootstrap over games (resample game indices, recompute the log loss difference) and report the interval. With a few hundred games, a difference of 0.003 in log loss is not distinguishable from zero. Report the interval, not only the point estimate.
rng = np.random.default_rng(0)
diffs = []
for _ in range(2000):
idx = rng.integers(0, n, n)
diffs.append(loss_a[idx].mean() - loss_b[idx].mean())
lo, hi = np.percentile(diffs, [2.5, 97.5])If the interval contains zero, say the models are not separated on this data.
Multiple Comparisons
Trying 30 feature sets and reporting the best inflates results. Count the variants you tried. Hold out the most recent complete season untouched until the final check, run it once, and report it as is.
Credit Usage
Data pull only. Five seasons of consensus lines and results: 25 credits through get_games. Evaluation is local.
Anti-patterns
| Rationalization | Why It's Wrong | Do This Instead |
| "Cross-validation is standard" | It is for exchangeable data; games are ordered | Walk forward |
| "Test on 2024 and tune on 2024" | The test is no longer out of sample | Tune only on earlier seasons |
| "58% ATS in one season" | Standard error is about 3 points | Use more seasons and an interval |
| "Win rate is the metric" | Hides confidence | Use log loss and Brier |
| "Skip the closing-line baseline" | It is the only baseline that matters for betting | Always include it |
Output Format
Walk-forward, expanding window, weekly refit, test seasons 2021-2025 (N games)
Log loss: model 0.xxx | closing line 0.xxx | Elo 0.xxx
Paired bootstrap, model minus closing: -0.00x (95% CI -0.0xx to +0.0xx)
By phase: weeks 1-4 [..], weeks 5-18 [..], postseason [..]
Verdict: [separated from the market / not separated], sample caveatWhat to Do Next
| What You Found | Next Action | Skill |
| Model separated from baselines | Check probability quality | probability-calibration |
| Model plausible vs close | Simulate betting | backtesting |
| Weak model | Revisit inputs | feature-engineering |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

