Interactive demo · Forecasting into decisions
What should we order today?
A forecast is the start. Explore how demand uncertainty, delivery timing and stock already on order shape a replenishment decision.
Synthetic data Invented demand and inventory inputs for an independent educational demonstration. No employer data, production system or commercial results.
Default worked example. Enable JavaScript to change the synthetic inputs.
Frequent, regular demand with a mild trend and a repeating 13-week pattern.
From demand to a decision
Synthetic data- Demand history
- Point forecast
- 80% weekly interval
- Today
- New order arrives
New order: start of week 3 · Cover: next 3 weeks (2 + 1 review week)
Model used: Additive damped Holt–Winters (13 weeks)
Additive damped Holt–Winters (13 weeks) had the lowest validation RMSE of the six candidates on this series. RMSE 2.56, MAE 2.04, MASE 0.59 on the chronological H1–H9 hold-out. The ADI/CV² label describes the history; it does not choose the model.
3. Set the replenishment inputs
Review every 1 week · Pack size 10 units
Current backorders: 0
4. Inspect the decision
Recommended order: 110 units
Awaiting valid inputs. The calculation below is the last valid example.
- Expected protection-period demand
- 200.8
- + Uncertainty buffer
- 5.3
- = Stock target
- 206
- − Inventory position
- 100
- = Unrounded requirement (minimum 0)
- 106
- → Pack-rounded order
- 110
All quantities in units. Displayed decimals are rounded; the calculation uses full precision. The uncertainty buffer is included once. Changing the forecasting method can change this order because it changes the predictive distribution.
Why this order?
Cover 3 weeks: 2 weeks of lead time plus 1 week between reviews. The 95% demand coverage target gives a stock target of 206 units. You have 80 units on hand and 20 due at the start of week 2. The 106-unit requirement rounds up to 110 units in packs of 10, arriving at the start of week 3.
Inspect the data and receipt schedule
Smooth: 260 weeks · Mean 52.45 · Standard deviation 8.43 · Zero-demand weeks 0 / 260 · ADI 1.00 · CV² 0.03 · classified smooth.
Synthetic weeks use relative indices, not business dates. The chart shows weeks 235–260; the forecast starts after week 260. ADI is the average interval between positive-demand weeks. CV² is the squared coefficient of variation of those positive sizes. Syntetos–Boylan thresholds of 1.32 and 0.49 label the series; they do not select the forecast.
What the four demand types mean
| Type | Rule | What it means here |
|---|---|---|
| Smooth | ADI < 1.32 and CV² < 0.49 | Demand occurs in almost every period, and the positive sizes do not swing wildly. |
| Erratic | ADI < 1.32 and CV² ≥ 0.49 | Demand is still frequent, but the size of those orders is highly variable. |
| Intermittent | ADI ≥ 1.32 and CV² < 0.49 | Many inactive periods, with comparatively consistent sizes when demand does occur. |
| Lumpy | ADI ≥ 1.32 and CV² ≥ 0.49 | Both inactivity and large, irregular spikes. The hardest of the four patterns to forecast from weekly totals alone. |
These are descriptive labels for the generated histories. A lumpy series is not required to use a sparse-demand model, and a smooth series is not required to use Holt–Winters. Recommended is the candidate with the lowest chronological RMSE on that series.
Expected stock by future week
Receipts arrive at the start of the week; demand occurs during it. Today's recommended order arrives at the start of week 3. Closing balances retain earlier shortages as backorders.
| Future week | Existing receipt | New receipt | Expected demand | Expected closing stock |
|---|---|---|---|---|
| 1 | 0 | 0 | 63.7 | 16.3 |
| 2 | 20 | 0 | 66.7 | -30.4 |
| 3 | 0 | 110 | 70.4 | 9.2 |
| Future week | Point | 10th percentile | 90th percentile |
|---|---|---|---|
| 1 | 63.4 | 60.5 | 66.7 |
| 2 | 66.1 | 64.5 | 69.4 |
| 3 | 70.1 | 67.3 | 73.4 |
| 4 | 70.6 | 69.0 | 74.7 |
| 5 | 71.2 | 67.4 | 74.6 |
| 6 | 68.3 | 66.7 | 72.3 |
| 7 | 64.6 | 60.8 | 68.0 |
| 8 | 60.7 | 59.1 | 64.8 |
| 9 | 58.5 | 54.8 | 61.9 |
All 260 historical observations
| Historical week | Demand |
|---|---|
| 1 | 42 |
| 2 | 45 |
| 3 | 52 |
| 4 | 49 |
| 5 | 50 |
| 6 | 46 |
| 7 | 41 |
| 8 | 41 |
| 9 | 38 |
| 10 | 36 |
| 11 | 34 |
| 12 | 38 |
| 13 | 40 |
| 14 | 45 |
| 15 | 46 |
| 16 | 51 |
| 17 | 52 |
| 18 | 54 |
| 19 | 47 |
| 20 | 45 |
| 21 | 40 |
| 22 | 35 |
| 23 | 38 |
| 24 | 34 |
| 25 | 35 |
| 26 | 39 |
| 27 | 43 |
| 28 | 46 |
| 29 | 53 |
| 30 | 48 |
| 31 | 51 |
| 32 | 48 |
| 33 | 48 |
| 34 | 41 |
| 35 | 44 |
| 36 | 37 |
| 37 | 39 |
| 38 | 40 |
| 39 | 40 |
| 40 | 48 |
| 41 | 51 |
| 42 | 55 |
| 43 | 54 |
| 44 | 56 |
| 45 | 52 |
| 46 | 47 |
| 47 | 44 |
| 48 | 41 |
| 49 | 40 |
| 50 | 37 |
| 51 | 41 |
| 52 | 42 |
| 53 | 47 |
| 54 | 48 |
| 55 | 53 |
| 56 | 53 |
| 57 | 56 |
| 58 | 54 |
| 59 | 47 |
| 60 | 42 |
| 61 | 39 |
| 62 | 40 |
| 63 | 39 |
| 64 | 39 |
| 65 | 45 |
| 66 | 47 |
| 67 | 51 |
| 68 | 53 |
| 69 | 59 |
| 70 | 54 |
| 71 | 54 |
| 72 | 49 |
| 73 | 45 |
| 74 | 42 |
| 75 | 45 |
| 76 | 42 |
| 77 | 40 |
| 78 | 42 |
| 79 | 49 |
| 80 | 47 |
| 81 | 57 |
| 82 | 56 |
| 83 | 59 |
| 84 | 54 |
| 85 | 50 |
| 86 | 46 |
| 87 | 46 |
| 88 | 43 |
| 89 | 45 |
| 90 | 40 |
| 91 | 44 |
| 92 | 49 |
| 93 | 54 |
| 94 | 54 |
| 95 | 59 |
| 96 | 57 |
| 97 | 54 |
| 98 | 54 |
| 99 | 48 |
| 100 | 46 |
| 101 | 43 |
| 102 | 46 |
| 103 | 41 |
| 104 | 48 |
| 105 | 51 |
| 106 | 55 |
| 107 | 58 |
| 108 | 57 |
| 109 | 59 |
| 110 | 54 |
| 111 | 50 |
| 112 | 52 |
| 113 | 47 |
| 114 | 39 |
| 115 | 43 |
| 116 | 42 |
| 117 | 48 |
| 118 | 51 |
| 119 | 57 |
| 120 | 62 |
| 121 | 56 |
| 122 | 63 |
| 123 | 55 |
| 124 | 53 |
| 125 | 55 |
| 126 | 44 |
| 127 | 41 |
| 128 | 43 |
| 129 | 47 |
| 130 | 49 |
| 131 | 56 |
| 132 | 58 |
| 133 | 58 |
| 134 | 62 |
| 135 | 60 |
| 136 | 56 |
| 137 | 54 |
| 138 | 51 |
| 139 | 47 |
| 140 | 45 |
| 141 | 47 |
| 142 | 45 |
| 143 | 49 |
| 144 | 54 |
| 145 | 58 |
| 146 | 63 |
| 147 | 63 |
| 148 | 62 |
| 149 | 61 |
| 150 | 55 |
| 151 | 53 |
| 152 | 48 |
| 153 | 46 |
| 154 | 47 |
| 155 | 51 |
| 156 | 48 |
| 157 | 55 |
| 158 | 60 |
| 159 | 61 |
| 160 | 62 |
| 161 | 58 |
| 162 | 58 |
| 163 | 54 |
| 164 | 52 |
| 165 | 45 |
| 166 | 47 |
| 167 | 46 |
| 168 | 52 |
| 169 | 50 |
| 170 | 57 |
| 171 | 59 |
| 172 | 62 |
| 173 | 64 |
| 174 | 67 |
| 175 | 59 |
| 176 | 59 |
| 177 | 53 |
| 178 | 51 |
| 179 | 50 |
| 180 | 54 |
| 181 | 43 |
| 182 | 51 |
| 183 | 59 |
| 184 | 57 |
| 185 | 63 |
| 186 | 64 |
| 187 | 63 |
| 188 | 63 |
| 189 | 62 |
| 190 | 53 |
| 191 | 57 |
| 192 | 48 |
| 193 | 49 |
| 194 | 52 |
| 195 | 55 |
| 196 | 60 |
| 197 | 61 |
| 198 | 63 |
| 199 | 66 |
| 200 | 66 |
| 201 | 69 |
| 202 | 55 |
| 203 | 52 |
| 204 | 53 |
| 205 | 48 |
| 206 | 50 |
| 207 | 56 |
| 208 | 58 |
| 209 | 62 |
| 210 | 62 |
| 211 | 69 |
| 212 | 67 |
| 213 | 66 |
| 214 | 65 |
| 215 | 63 |
| 216 | 54 |
| 217 | 55 |
| 218 | 50 |
| 219 | 51 |
| 220 | 53 |
| 221 | 55 |
| 222 | 60 |
| 223 | 63 |
| 224 | 66 |
| 225 | 68 |
| 226 | 69 |
| 227 | 66 |
| 228 | 63 |
| 229 | 61 |
| 230 | 58 |
| 231 | 54 |
| 232 | 50 |
| 233 | 57 |
| 234 | 54 |
| 235 | 57 |
| 236 | 60 |
| 237 | 69 |
| 238 | 69 |
| 239 | 68 |
| 240 | 68 |
| 241 | 65 |
| 242 | 57 |
| 243 | 58 |
| 244 | 53 |
| 245 | 53 |
| 246 | 58 |
| 247 | 58 |
| 248 | 61 |
| 249 | 69 |
| 250 | 65 |
| 251 | 70 |
| 252 | 72 |
| 253 | 68 |
| 254 | 64 |
| 255 | 61 |
| 256 | 62 |
| 257 | 53 |
| 258 | 52 |
| 259 | 55 |
| 260 | 58 |
Method, equations and assumptions
An offline experiment, not a browser model
Candidate forecasts are fitted in Python and exported as compact JSON. The static site and the visitor's browser never train a model. Deep-learning families such as N-HiTS or N-BEATS can be added later as further offline adapters; they are omitted here because a poorly trained network would be a label, not evidence.
Candidate models
Baseline: the mean of all 260 observations, with future weeks sampled independently from that history. Statistical: additive damped Holt–Winters with a 13-week season, plus Croston, Syntetos–Boylan approximation (SBA) and Teunter–Syntetos–Babai (TSB) with smoothing constants 0.1. ML: a direct multi-horizon histogram gradient-boosted tree. Each horizon is a separate prediction from features known at the origin only (lags 1, 2, 3, 4, 13 and 26; rolling means, standard deviations and occurrence rates over 4, 13 and 26 weeks; the target week's 13- and 26-week seasonal position). Every point forecast is truncated at zero.
Chronological validation and Recommended
Models are refitted at rolling origins using only y[:origin]. Calibration origins are every second week from 104 to 176; validation origins are every fourth week from 188 to 248. The primary score is pooled H1–H9 RMSE; MAE and MASE (in-sample naïve scale) are reported alongside. Recommended is the lowest validation RMSE, with the model id breaking exact ties. Statistical is the same rule restricted to Holt–Winters, Croston, SBA and TSB. Percentage errors are avoided because zero-demand weeks would make them undefined or misleading.
Forecast uncertainty
For the baseline, 20,000 nine-week futures are independent draws from the observed history. For every other model, whole out-of-sample error vectors from the calibration origins are resampled jointly and added to the current point forecast, then truncated at zero. That keeps horizon dependence and the model's observed bias. A zero point forecast can still have positive uncertainty. The path-mean can therefore differ from the raw point; both are exported. The weekly interval is the 10th–90th percentile of those paths. It is pointwise, not an 80% simultaneous band.
One simulation, consistent horizons
Each path is cumulatively summed: Dₕ = d₁ + … + dₕ. All horizons use prefixes of the same paths. Quantiles use NumPy's inverted-cdf definition. Nonnegative demand makes every path total nondecreasing with horizon.
The stock target uses a quantile of these cumulative totals, never a sum of weekly upper bounds. Expected protection-period demand is the sum of that model's simulated weekly path means.
The replenishment decision
H = L + R, with R = 1 week
S = quantileα(DH)
Expected demand = sum of simulated weekly path means over H
Uncertainty buffer = S − expected demand
IP = on hand + on order − backorders
Requirement = max(0, S − IP)
Q = 10 × ceil(requirement / 10)
This is a periodic-review order-up-to policy with fixed lead time, a fixed ten-unit pack and zero current backorders. Demand coverage plays the role of a one-sided planning service target. It is not a measured fill rate, observed cycle-service level or guarantee against stockout.
The existing receipt is due at the start of week 2. The new order arrives at the start of week L + 1. Both count towards inventory position, but they are posted to their own weeks in the expected-stock schedule. Today's order cannot resolve a shortage before its arrival. There is no expediting, cancellation, lost-sales model, capacity limit or cost optimisation.
How the synthetic histories are generated
Smooth: 42 + 0.08t + 8 sin(2πt/13) + N(0, 2), rounded to a positive integer. Erratic: a 13-week seasonal level with a mild trend, lognormal size noise (σ = 0.65) and a 6% chance of a threefold surge. Intermittent: occurrence probability 0.12 + 0.0004t, plus 0.22 if the previous week was positive; positive sizes 40 + 0.03t + N(0, 3). Lumpy: occurrence 0.10 + 0.0003t, plus 0.25 after a positive week; positive sizes follow a weak 26-week pattern times a lognormal(−0.5, 1) shock. Zeros are observed zero demand, not missing values.
Generator version 2 uses NumPy Generator seeds 20260910–20260913. Each model's simulation seed is the scenario seed plus 1000 plus the model's index. There is no promotion, actual SKU, supplier, price or stockout-censored sales data.
What the uncertainty leaves out
Resampled errors assume future residual structure resembles the calibration window. They exclude parameter uncertainty, regime change, supplier delay and unseen extremes. Twenty thousand simulations reduce sampling noise; they do not create twenty thousand weeks of evidence. No accuracy, service attainment or commercial performance is claimed.
This is an independent educational demonstration using standard public methods. It does not reproduce the Priory Direct forecasting/procurement system or expose proprietary KTP implementation.
Background: Forecasting: Principles and Practice — prediction intervals; Syntetos, Boylan and Croston, “On the categorisation of demand patterns”, JORS 56 (2005); MIT — probabilistic inventory policies (PDF).