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.

← All demos · Decision chain in the Technical Lab

Default worked example. Enable JavaScript to change the synthetic inputs.

1. Choose a demand pattern

Frequent, regular demand with a mild trend and a repeating 13-week pattern.

From demand to a decision

Synthetic data
Weekly demand, forecast and replenishment timing Smooth synthetic demand with Additive damped Holt–Winters (13 weeks). Last 26 of 260 historical weeks in a solid dark line; next 9 weeks show the model’s H1–H9 point forecast from 63.4 to 58.5 units and an 80% weekly modelled interval. Today's order arrives after 2 weeks. Cover 3 weeks including the review interval. Axes: weeks and units per week. The vertical scale changes with the selected scenario and model. units / week 04080
Last 26 weeksNext 9 weeks
  • Demand history
  • Point forecast
  • 80% weekly interval
  • Today
  • New order arrives
Point forecast: 63.4 to 58.5 units/week. Week-1 interval: 60.5–66.7 units. The weekly interval describes individual weeks. The order uses a one-sided quantile of total demand over the protection period; it does not add weekly upper bounds. The vertical scale adjusts to the demand pattern and selected model.

New order: start of week 3 · Cover: next 3 weeks (2 + 1 review week)

2. Choose a forecasting method

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

Synthetic replenishment inputs

Today's new order arrives after this many full weeks.

Choose a stock target that covers total protection-period demand in this percentage of modelled futures.

Whole units, from 0 to 10,000. All values are illustrative.

The existing open order arrives in 1 week, at the start of week 2. Its date stays fixed when lead time changes.

Review every 1 week · Pack size 10 units
Current backorders: 0

4. Inspect the decision

Recommended order: 110 units

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
Syntetos–Boylan demand-type labels
TypeRuleWhat it means here
SmoothADI < 1.32 and CV² < 0.49Demand occurs in almost every period, and the positive sizes do not swing wildly.
ErraticADI < 1.32 and CV² ≥ 0.49Demand is still frequent, but the size of those orders is highly variable.
IntermittentADI ≥ 1.32 and CV² < 0.49Many inactive periods, with comparatively consistent sizes when demand does occur.
LumpyADI ≥ 1.32 and CV² ≥ 0.49Both 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.

Expected-stock timing diagnostic — units
Future weekExisting receiptNew receiptExpected demandExpected closing stock
10063.716.3
220066.7-30.4
3011070.49.2
Weekly modelled forecast — units; central 80% interval from the selected model
Future weekPoint10th percentile90th percentile
163.460.566.7
266.164.569.4
370.167.373.4
470.669.074.7
571.267.474.6
668.366.772.3
764.660.868.0
860.759.164.8
958.554.861.9
All 260 historical observations
Synthetic weekly demand — units
Historical weekDemand
142
245
352
449
550
646
741
841
938
1036
1134
1238
1340
1445
1546
1651
1752
1854
1947
2045
2140
2235
2338
2434
2535
2639
2743
2846
2953
3048
3151
3248
3348
3441
3544
3637
3739
3840
3940
4048
4151
4255
4354
4456
4552
4647
4744
4841
4940
5037
5141
5242
5347
5448
5553
5653
5756
5854
5947
6042
6139
6240
6339
6439
6545
6647
6751
6853
6959
7054
7154
7249
7345
7442
7545
7642
7740
7842
7949
8047
8157
8256
8359
8454
8550
8646
8746
8843
8945
9040
9144
9249
9354
9454
9559
9657
9754
9854
9948
10046
10143
10246
10341
10448
10551
10655
10758
10857
10959
11054
11150
11252
11347
11439
11543
11642
11748
11851
11957
12062
12156
12263
12355
12453
12555
12644
12741
12843
12947
13049
13156
13258
13358
13462
13560
13656
13754
13851
13947
14045
14147
14245
14349
14454
14558
14663
14763
14862
14961
15055
15153
15248
15346
15447
15551
15648
15755
15860
15961
16062
16158
16258
16354
16452
16545
16647
16746
16852
16950
17057
17159
17262
17364
17467
17559
17659
17753
17851
17950
18054
18143
18251
18359
18457
18563
18664
18763
18863
18962
19053
19157
19248
19349
19452
19555
19660
19761
19863
19966
20066
20169
20255
20352
20453
20548
20650
20756
20858
20962
21062
21169
21267
21366
21465
21563
21654
21755
21850
21951
22053
22155
22260
22363
22466
22568
22669
22766
22863
22961
23058
23154
23250
23357
23454
23557
23660
23769
23869
23968
24068
24165
24257
24358
24453
24553
24658
24758
24861
24969
25065
25170
25272
25368
25464
25561
25662
25753
25852
25955
26058
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).