Fpa backtest learn
The FP&A toolbelt for AI coding agents. Claude Code or Codex does the thinking; openfpa gives it a tested finance kernel, durable company memory, and a Karpathy inspired research loop that improves forecasts against your actuals. By Guiderail and Jeff Brines.
npx -y skills add JeffBrines/openfpa --skill fpa-backtest-learnAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when you want the model to learn from how its past forecasts actually turned out - scoring forecasts against the company's real actuals, backtesting assumptions on history, and proposing ratified improvements. Runs at/after monthly close.
SKILL.md
4.5 KB, as published. Nobody here has run it
Backtest & Learn (Operate)
Overview
The model should get measurably better at this business over time. This skill
scores past forecasts against the company's actuals, surfaces what keeps missing,
and proposes improvements a human ratifies. The objective metric is reconciliation
error against the user's own books (pyfpa.score_forecast) - the FP&A analog of a
validation loss.
Core principle: self-experimenting, but never self-promoting. The AI may run
and discard bounded challengers autonomously; a human approves replacement of
the champion. Everything learned lives as plain files in .fpa/.
Memory (.fpa/)
forecasts/<period>.snapshot.yaml- each forecast's assumptions + predictions, and (after close) its score.scorecard.md- the running track record (rendered, never hand-edited).experiments/<slug>.experiment.yaml- each tested model change, its evidence, changed files, checks, before/after metrics, and decision.learnings.md- every accepted change: what, the evidence, the backtest delta, the date.
Workflow
- Snapshot every forecast. When you produce a forecast, persist it:
snapshot_forecast(cfg, forecast_df, label=<period>, created=<today>)→save_snapshot(..., ".fpa/forecasts/<period>.snapshot.yaml"). - Score at close. When a period closes (actuals via fpa-configure-actuals),
load that period's snapshot,
score_forecast(snap.predicted, actuals), write the score back into the snapshot, and re-renderscorecard.mdwithrender_scorecard. - Attribute each material per-line miss to a driver (volume / price / cost ratio
/ working-capital timing). Run the fpa-cfo-judgment one-time-item screen first -
never blame the model for a one-off.
- Monitor applied corrections: if a
type: parametriccorrection's target line keeps missing, flag it as possibly stale (applied → superseded) for the human - never auto-revert.
- Monitor applied corrections: if a
- Create an experiment before changing the model. State the financial
hypothesis, CFO question, evidence, fit periods, holdout periods, and files
expected to change. Save it with
pyfpa.save_experiment. - Propose, tagged by type:
- Parametric (an assumption change): re-score it with
holdout_backteston the company's history. Surface it only if it lowers holdout fitness (not in-sample), ranked by the delta. Clamp the proposed move withmagnitude_cap(±25%/cycle). - Structural (a methodology/skill change, e.g. a revenue-recognition lag): surface
only when
persistent_missis true for the line (same-signed across K≥2 closes) and it survived the one-time screen. Hand it to fpa-learn-business to generate the skill on approval - propose, don't auto-write.
- Parametric (an assumption change): re-score it with
- Evaluate. Record before/after metrics and explicit checks in the experiment. A model change that breaks reconciliation or another accounting invariant is failed even if one headline metric improves.
- Ratify + log. Present proposals; the human accepts/rejects. On accept, add
an
ExperimentDecision, setstatus: accepted, save with explicitoverwrite=True, update the company model, and append tolearnings.md. Rejected and reverted experiments remain in memory. - Run
fpa-research-loopwhen the miss warrants multiple autonomous challenger epochs instead of one manually proposed change.
Bootstrap (day one)
If the company already has ~12+ months of actuals, you don't have to wait: run
holdout_backtest immediately (fit on the earlier months, hold out the recent ones)
to report current accuracy and the first round of parametric proposals.
Guardrails (always)
- Never score on data the model was fit on (
holdout_backtestenforces this). - No proposal off a single period - require a persistent, same-signed miss.
- A parametric change must improve holdout fitness, not in-sample fit.
- Cap how far any assumption moves per cycle (
magnitude_cap). - Human ratifies champion promotion; autonomous failed epochs are logged and reversible.
- Missing or zero actuals are insufficient evidence, not perfect forecast performance.
Next
Scored + learned → fpa-board-briefing (report the forecast and how it's tracking).