Documentation
¶
Overview ¶
Package forecast holds OpenMRP's standard monthly demand forecaster.
Seasonal EMA is used by both the analytics demand-forecast endpoint and the production scheduler, so it lives here rather than in either caller. It mirrors dashboard/packages/utils/src/seasonal-ema.ts; the two must stay in step or the schedule and the dashboard will disagree about the same demand.
Method:
- Seasonal factors — each calendar month's average divided by the overall average, then shrunk toward 1. Most items sell in only a handful of months a year, so the raw factors fit twelve parameters to a few observations and largely memorise noise; shrinking keeps whatever shape is real and discards the amplitude.
- Deseasonalize, then smooth to a current base run rate (alpha = 2 / (min(observations, 12) + 1), so recent months weigh more) carrying a damped additive trend.
- Forecast = (level + damped slope) x seasonal factor.
- Fixed-width confidence band from the last 12 residuals x seasonal factor x z.
The trend term is additive on a deseasonalized series and damped, so it converges to level + slope*phi/(1-phi) instead of compounding. This is not the Holt-Winters that was removed: that trend was multiplicative and produced runaway exponential forecasts. Without any trend at all the forecaster over-forecast a declining book by roughly a fifth, month after month, because nothing in the model could lower the level fast enough to keep up.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Observation ¶
Observation is one complete month of history. The series must be sorted ascending and must exclude the current partial month, which would otherwise read as a collapse in demand.
type Point ¶
Point is one forecast month. Date is stamped end-of-period (one month past the month being forecast) to match the dashboard's display convention.
func SeasonalEMA ¶
func SeasonalEMA(completeMonths []Observation, baseForecastStart time.Time, numMonths int, zScore float64) []Point
SeasonalEMA forecasts numMonths forward from baseForecastStart, which is the start of the last complete month. Point k covers baseForecastStart + (k + 1) months.
Returns an empty slice for an empty series rather than guessing a level.