Rolling Forecast Builder
When to use
Use whenever the year is partway through and the full-year view needs updating with real actuals, replacing a forecast that either ignores actuals entirely (still showing the original budget) or quietly assumes an accelerating pace for the remaining months with no stated reason.
What it does
Blends actual results for completed months with a forecast for remaining months via a bundled calculator, computes the resulting full-year view, bridges it against the original plan, and explicitly flags when the forecast run rate for remaining months is meaningfully higher than the actual run rate achieved so far — the most common way rolling forecasts quietly turn optimistic without anyone noticing.
Method
- Pull actuals for every completed month, not an estimate — the forecast is only as trustworthy as the actuals it's anchored to.
- Build the forecast for remaining months from real drivers, using the same driver-based-budget-builder discipline, updated with anything learned from the actuals so far (a channel that's underperforming, a cost that's running higher than planned).
- Run the bundled calculator (
scripts/rolling_forecast.py) to get the full monthly view (actual and forecast months together), the resulting full-year total, and the bridge against the original annual plan.
- Read the run-rate comparison explicitly. If the forecast's monthly run rate for remaining months is more than 15% above the actual run rate achieved in completed months, that's a flag worth resolving before the forecast goes out — either there's a specific, named reason (a signed deal, a seasonal pattern, a planned launch) or the forecast is quietly assuming things get better with no basis.
- State the bridge to plan in both dollars and percentage, and be explicit about whether the business is tracking ahead, on, or behind the original commitment — a rolling forecast's job is to catch a miss early, not to smooth it into invisibility.
- Update the forecast on a fixed cadence (monthly or quarterly), not ad hoc — a rolling forecast that only gets refreshed when someone remembers to do it defeats its own purpose.
- Carry forward the reasons behind material changes from one forecast cycle to the next, so a pattern of consistently over-optimistic remaining-month forecasts becomes visible over time, not just within a single cycle.
Inputs
- Actual results by month for completed months
- Forecast for remaining months, built from updated drivers
- The original annual plan to bridge against
- Config saved as JSON matching the format documented at the top of
scripts/rolling_forecast.py
Output format
Month-by-month table of actuals and forecast with running cumulative total; full-year forecast total; bridge to original plan in dollars and percentage; actual vs. forecast monthly run-rate comparison with an explicit flag if the forecast assumes unexplained acceleration.
Example
Five months of actuals average $1.9M per month; the forecast for the remaining seven months averages $2.24M, an 18% jump the calculator flags automatically. The team traces it to a genuinely signed enterprise deal starting month 7, a specific, defensible reason, so the forecast stands, but the flag forced that justification to be stated explicitly rather than the acceleration passing through unquestioned.
Common pitfalls
- Forecasting remaining months at a faster pace than actuals have shown, with no specific driver behind the acceleration.
- Refreshing the forecast irregularly instead of on a fixed cadence, so it drifts out of date exactly when it matters most.
- Reporting the bridge to plan only in dollars or only in percentage, when both tell a different part of the story.
1---2name: rolling-forecast-builder3description: Blends actuals-to-date with a forward forecast via a bundled calculator, bridges the result against the original plan, and flags when the forecast's implied run rate jumps well above what's actually been achieved so far without a named reason. Use whenever the user needs an updated full-year view partway through the year, wants a rolling or continuous forecast rather than a once-a-year budget, or has a re-forecast where the remaining months quietly assume a faster pace than the actuals have shown with no explanation.4---56# Rolling Forecast Builder78## When to use9Use whenever the year is partway through and the full-year view needs updating with real actuals, replacing a forecast that either ignores actuals entirely (still showing the original budget) or quietly assumes an accelerating pace for the remaining months with no stated reason.1011## What it does12Blends actual results for completed months with a forecast for remaining months via a bundled calculator, computes the resulting full-year view, bridges it against the original plan, and explicitly flags when the forecast run rate for remaining months is meaningfully higher than the actual run rate achieved so far — the most common way rolling forecasts quietly turn optimistic without anyone noticing.1314## Method151. **Pull actuals for every completed month**, not an estimate — the forecast is only as trustworthy as the actuals it's anchored to.162. **Build the forecast for remaining months from real drivers**, using the same driver-based-budget-builder discipline, updated with anything learned from the actuals so far (a channel that's underperforming, a cost that's running higher than planned).173. **Run the bundled calculator** (`scripts/rolling_forecast.py`) to get the full monthly view (actual and forecast months together), the resulting full-year total, and the bridge against the original annual plan.184. **Read the run-rate comparison explicitly.** If the forecast's monthly run rate for remaining months is more than 15% above the actual run rate achieved in completed months, that's a flag worth resolving before the forecast goes out — either there's a specific, named reason (a signed deal, a seasonal pattern, a planned launch) or the forecast is quietly assuming things get better with no basis.195. **State the bridge to plan in both dollars and percentage**, and be explicit about whether the business is tracking ahead, on, or behind the original commitment — a rolling forecast's job is to catch a miss early, not to smooth it into invisibility.206. **Update the forecast on a fixed cadence** (monthly or quarterly), not ad hoc — a rolling forecast that only gets refreshed when someone remembers to do it defeats its own purpose.217. **Carry forward the reasons behind material changes** from one forecast cycle to the next, so a pattern of consistently over-optimistic remaining-month forecasts becomes visible over time, not just within a single cycle.2223## Inputs24- Actual results by month for completed months25- Forecast for remaining months, built from updated drivers26- The original annual plan to bridge against27- Config saved as JSON matching the format documented at the top of `scripts/rolling_forecast.py`2829## Output format30Month-by-month table of actuals and forecast with running cumulative total; full-year forecast total; bridge to original plan in dollars and percentage; actual vs. forecast monthly run-rate comparison with an explicit flag if the forecast assumes unexplained acceleration.3132## Example33Five months of actuals average $1.9M per month; the forecast for the remaining seven months averages $2.24M, an 18% jump the calculator flags automatically. The team traces it to a genuinely signed enterprise deal starting month 7, a specific, defensible reason, so the forecast stands, but the flag forced that justification to be stated explicitly rather than the acceleration passing through unquestioned.3435## Common pitfalls36- Forecasting remaining months at a faster pace than actuals have shown, with no specific driver behind the acceleration.37- Refreshing the forecast irregularly instead of on a fixed cadence, so it drifts out of date exactly when it matters most.38- Reporting the bridge to plan only in dollars or only in percentage, when both tell a different part of the story.