Portfolio Economics Engine
A working demonstration, not a slide: move a price and watch the portfolio-level profit consequence, cannibalisation included, calculated live from public grocery data.
Pricing power is a portfolio question.
Most FMCG teams still decide price one product at a time, in a spreadsheet, and the knock-on across the rest of the range stays invisible until the quarter closes. This is a working demonstration of the alternative: a demand engine built entirely on public grocery data that estimates how a price move on one tier ripples across the others, and shows the net effect on portfolio contribution, not just the product you touched.
Two things worth knowing about how to read it. It separates three effects usually blurred together (own-price response, genuine cannibalisation, and promotional halo) and quantifies each only where the data can identify it. And where the evidence won't support a confident answer, it says so: too close to call, rather than a decisive-looking number that wouldn't survive scrutiny.
Built on the public dunnhumby Complete Journey dataset. Short-run, observational estimates across two portfolios: a method demonstration, not a market forecast.
Portfolio comparison
Category: Soft drinks (carbonated)
The same 12-pack price move, two portfolios, two different stories
Move the 12-pack can price and watch what happens to Portfolio A and Portfolio B: how much of the volume stays inside each range, how much leaves, and whether the move grows profit once cannibalisation is counted.
Portfolio A and B, think of two big rival soft-drink makers going head-to-head in the same category, shown anonymised. Each "portfolio" is that company's whole range of pack sizes (12-pack cans, 2-litre, single-serve and so on, not a single brand or a single pack). What separates them is the shape of that range: how many pack types shoppers can trade across without leaving the company altogether.
How to read it. Move the 12-pack price and each card shows the result for that company's whole soft-drink range: whether it grows profit, how far the 12-pack's own sales move, and where the lost volume goes. It either stays in their range (shoppers trade to their other packs) or leaves (buys less, or switches to a rival).
How it reasons
Three effects, kept apart
A raw sales history blurs three different things together. The engine separates them, and puts a number on each one only where the data genuinely supports it.
Own-price response
How much a product's own volume moves when its price moves. Measured from two years of weekly sales, after setting aside promotions, seasonality and trend so that the price effect stands on its own.
Cannibalisation
How much of that volume turns up in the same portfolio's other pack sizes rather than leaving. Counted only where the data shows it clearly. Where it cannot be separated, the engine says so and treats that volume as leaving, rather than guessing.
Promotional halo
On weeks when one pack size is on a deep deal, the same brand's other packs often sell more, not less. That is a brand effect, not switching between packs, so it is kept out of the cannibalisation numbers rather than counted as a saving.
Runs on your own data
It needs sales by product and week, with prices and promotion flags: the kind of data most manufacturers and retailers already hold. This demonstration uses a public grocery panel; the same engine would run on a real portfolio's history.
Answers the portfolio question, not win/loss
It tells you what a move does to your own range's profit after cannibalisation. Volume that leaves the range is counted as leaving; which competitor picks it up is outside what it models. It is a short-run estimate, not a forecast.
Under the hood
For analysts: elasticities and t-statistics, the response-basis multiplier, the full destination breakdown and cross-price matrix, an own-price simulator for any product or tier, literature validation, and the complete list of caveats.
Response basis
Deal response versus a sustained move
This setting drives the comparison above as well as everything in this section.
Decomposition detail
Where the 12-pack volume goes, cell by cell
Cross-price matrix
Estimated cells, identification and diversion ratios
Promotional halo
Why the 2-litre column is excluded
Own-price simulator
Any product or tier, one price at a time
Pick a soft-drink or cold-cereal product, or a whole tier, and drag its price. Volume, revenue and contribution follow the estimated elasticity, with the uncertainty carried through.
| Base | Scenario | Change | 95 % range | |
|---|---|---|---|---|
| Price | ||||
| Volume (units / week) | ||||
| Revenue | ||||
| Contribution |
Baseline basis: SKU scenarios start from the median realised (paid) price; tier scenarios start from the tier's median regular shelf price. The two are not like-for-like.
Literature validation
How the estimates sit against published benchmarks
Method, scope and caveats
What this does and does not show
Reads outputs/elasticities.json and outputs/cannibalisation.json. Serve the repository root over HTTP and open /app/.
What it needs, and what it doesn't do yet
- What it needs. Sales by pack, by week, with price and promotion flags, the kind of data most manufacturers and retailers already hold. No competitor panel, no loyalty data.
- What it answers. The portfolio question: what a price move does to your own range's profit after cannibalisation. Not competitive win or loss; which rival picks up the volume that leaves sits outside what it models.
- What it is. Built on the public dunnhumby Complete Journey dataset. A method demonstration, short-run and observational, not a market forecast.
Next
If this is the kind of modelling your organisation needs, let us talk.