K-04
Forecast Bias
Does the forecast systematically run high or low — and is bias a signed percentage, a tracking signal, or a streak count, with which sign convention?
There is a reference build of this metric: the Demand Forecast Accuracy dashboard in the showcase runs this definition over frozen, simulated data — not a live client system.
Definitions and source tables below are current to the date above — verify against current SAP, Oracle, Microsoft, Infor, and Databricks documentation before you build.
What forecast bias measures
Bias is the direction of the error, and it is exactly what absolute-error metrics are built to destroy. WAPE and MAPE take the absolute value first, which is the right thing to do when you want to know how far off the forecast was — and the wrong thing when you want to know which way.
The two failures are independent. A forecast can post a perfectly respectable accuracy while running high every single month, because a consistent 8% over-forecast is a small absolute error and a large systematic one. That is how inventory quietly accumulates: nothing on the accuracy dashboard ever looks alarming, and the excess arrives anyway, one planning cycle at a time.
Bias is also the more tractable problem. Random error is reduced with better models and more signal; systematic error is usually a behavior — a demand plan padded for safety, a sales input never reconciled, a promotion assumption nobody retired. Finding it needs the sign kept, the window long enough for a pattern to show, and the grain low enough that offsetting item biases do not cancel to a comfortable zero at the top.
Also answers to Bias · MPE · Signed Error · Tracking Signal
The decision switches
Three switches, and the second one causes more arguments than it should: two teams reporting bias under opposite sign conventions will describe the same forecast in opposite words.
| Switch | Settings | Practice default |
|---|---|---|
| Metric form | Signed % error · Tracking signal · Streak count | Signed percentage as the headline, streaks beside it as the conversation-starter. |
| Sign convention | Forecast − actual · Actual − forecast | Pick one, print it on the chart, and never flip between decks. |
| Window | Single period · Rolling 3–6 periods | Rolling, at the same lag as the accuracy metric it sits beside. |
Metric form
- dependsSigned % error — summed forecast minus summed actual, over summed actual — the practice default
- dependsTracking signal — cumulative signed error over mean absolute deviation — the control-chart form
- dependsStreak count — months consecutively high or low; robust, legible, and hard to argue with
Practice default Signed percentage as the headline, streaks beside it as the conversation-starter.
Sign convention
- dependsForecast − actual — over-forecast is positive — the practice default
- dependsActual − forecast — over-forecast is negative; equally valid, and the reason decks contradict each other
Practice default Pick one, print it on the chart, and never flip between decks.
Window
- dependsSingle period — noisy — one month of signed error is mostly randomness
- dependsRolling 3–6 periods — where persistent bias separates itself from noise
Practice default Rolling, at the same lag as the accuracy metric it sits beside.
Formula & grain
Bias % = (Σ forecast − Σ actual) ÷ Σ actual
- Numerator
- Signed error summed over the window
- Denominator
- Actuals summed over the same window
- Grain
- The same item × location × period × lag as the forecast accuracy metric
- Note
- Positive means over-forecast under the stated convention — state the convention wherever the number appears.
Common pitfalls
- Aggregate zero hiding item bias — Over-forecast items and under-forecast items net to roughly nothing at portfolio level, which reads as an unbiased forecast. Check bias at the grain someone acts on before concluding there is none.
- Good WAPE, bad bias — Accuracy and bias fail independently, so neither one covers for the other. Report both, from the same fact, at the same lag.
- Sign flips between reports — One deck defines bias as forecast minus actual and the next as actual minus forecast, and the meeting spends twenty minutes discovering it agrees. Fix the convention once and label it on every chart.
- Zero bias achieved by chasing — Re-forecasting toward actuals mid-period drives measured bias to zero without improving a single decision — the same laundering mechanism as rebooking a promise date to fix lateness. Score bias at a fixed lag so late edits cannot reach it.
- The service-level anchor — A service-level target sitting on the forecasting screen biases the forecast itself. In controlled experiments that included experienced professional forecasters, people told the target was high over-forecast, people told it was low under-forecast, and people shown no target at all were unbiased. The remedy is structural: keep the target off the forecast input screen, and carry the forecast and the plan as two numbers, the forecast unbiased and the plan carrying the buffer. It sits upstream of “Zero bias achieved by chasing”.
Source tables — SAP
Source tables — JD Edwards
Source tables — Dynamics 365
Same sources as forecast accuracy — the components are identical; only the aggregation keeps the sign. The forecast model and the company stay in the key.
Source tables — Infor M3
Source tables — Oracle EBS
Same sources as forecast accuracy — the components are identical; only the aggregation keeps the sign. The designator remains the identity of the forecast being scored.
Source tables — Oracle Fusion
Same source as forecast accuracy — fulfillment lines are the demand actuals; only the aggregation keeps the sign. The plan side still arrives through BICC extracts rather than this table.
Store the components, not the ratio
Every switch above is a different way of reading the same underlying facts, so the components — quantities, dates, values, flags — are what belongs in the gold layer, never the finished percentage. Bronze keeps the source tables as extracted, silver resolves the encodings once, and gold carries a component-level fact that each variant of Forecast Bias reads as a SELECT — the pattern worked through in full in the OTIF entry's landing pattern.