A first-principles guide to the math and finance behind the SPR Cohort Allocation Explainer.
A note before we start. Everything below is an illustrative model built for explanation. The numbers in the tool are teaching defaults. They are deliberately simple and legible, not calibrated to any real fund, and nothing here is financial advice. The point is to make a genuinely complex piece of pension machinery understandable, so that anyone (a trustee, a journalist, a saver, a curious engineer) can see how the pieces fit together. When a real fund wants real figures, it enters its own validated assumptions. We'll come back to that.
The Netherlands is in the middle of the largest pension reform in its history. Under the new law, known as the Wet toekomst pensioenen (the Future Pensions Act), most funds are moving to a solidarity-based defined-contribution scheme, known in Dutch as the solidaire premieregeling, or SPR.
Here is the part that trips people up, and the reason this tool exists:
The fund invests as one. But it reports results per generation.
There is a single collective pot of money. The asset manager runs one portfolio. There is no separate account for people born in the 1960s and another for people born in the 1990s. And yet, at the end of each period, every age group, every cohort, is told its own credited return. A 30-year-old and a 70-year-old, sharing the exact same pool of assets, can be told they earned very different returns. Sometimes wildly different. Sometimes the youngest savers are credited a return higher than the fund itself made.
That sounds impossible, or like a trick. It is neither. It is the deliberate, lawful, and rather elegant consequence of a set of accounting rules. The whole difficulty is that those rules are invisible. You can't see one return becoming many.
The SPR Cohort Allocation Explainer makes them visible. It takes the fund's one collective result, splits it into streams, and shows, as a flowing diagram, exactly how each euro travels from "what the fund earned" to "what your generation was credited." This article explains the finance and the math underneath that picture, from first principles, with no code and no jargon left unexplained.
Start with the single most important idea: there is one portfolio, and cohorts are an accounting overlay on top of it.
When the fund earns (or loses) money in a period, that result is real and collective. What each cohort "gets" is not a separate pile of assets. It is a bookkeeping allocation: a share of the collective result, handed out according to a predetermined rulebook the fund has published in advance. In Dutch these rules are called toedelingsregels, or "allocation rules."
So nothing is being moved between accounts. Nobody's money is being taken and given to someone else. The fund simply says, in advance: "When the collective result comes in, here is the formula for how we attribute it across generations." The tool dramatises that attribution (one result becoming many credited returns), not a transfer between people.
This is the heart of the design. The single collective result is conceptually separated into two very different kinds of return, because they behave differently and are meant to serve different people.
1. Protection return (beschermingsrendement). This is the stabilising return. Its job is to keep a participant's protected pension on track as interest rates move. It is driven by rates, not by the stock market, and it is deliberately steady. Think of it as the part of the result designed to make a near-retiree's pension predictable.
In the real world, a fund delivers this protection return in one of two ways:
The tool collapses both of those methods into a single intuitive knob (a base return plus a sensitivity to rate changes), because for understanding the mechanism, the two delivery methods produce the same conceptual stream. (The real methods are named in the tool for credibility, but it doesn't separately simulate them.)
2. Excess return (overrendement). This is the growth return: the result of the return-seeking portfolio (equities, credit, and other risk assets). This is the volatile part. In a great year it's large and positive. In a bad year it goes negative. And here is the crucial design choice: younger cohorts are allocated mostly excess return. They have decades for markets to recover, so they're handed amplified exposure to the growth engine. Pensioners are allocated mostly protection, so a market crash barely touches them.
That single asymmetry, young savers ride the markets, old savers ride the rates, is the entire risk-sharing philosophy of the reform, made concrete.
Layered on top is a third element: the solidarity reserve (solidariteitsreserve). This is a collective buffer with its own rules, and it is what makes the scheme solidair (shared) rather than purely every-cohort-for-itself.
It works like a reservoir:
So the reserve smooths outcomes across time and across generations. Good years quietly set money aside; bad years quietly release it where it's needed most. It is the mechanism of intergenerational solidarity, expressed as a buffer.
A "cohort" here is simply a birth-year group. The Dutch reporting standard is five-year birth cohorts (for example, everyone born 1956 to 1960). The tool defaults to those five-year bands but lets you look more finely, at one-year or even one-month groups, which surfaces a subtle and genuinely important wrinkle we'll get to in Part 4.
One reassuring point worth stating plainly: no individual data is ever used. The standard is cohort-level, and so is the tool. We're always talking about generations, never named people.
Now let's turn the finance into arithmetic. Don't worry if formulas aren't your thing. Every line has a plain-English translation, and we'll plug in real numbers in Part 3. All amounts are in millions of euros (€m), and we'll compute a single illustrative period.
These are the inputs. The right-hand column shows the teaching defaults the tool ships with.
| Symbol | Meaning | Default |
|---|---|---|
C | Total collective capital (the size of the whole pot) | €10,000M |
p | Protection level: the share of capital sitting in the protection (matching) portfolio | 0.60 |
r_m | Market return on the return-seeking portfolio | +6% |
Δr | Change in interest rates this period | 0% |
b | Base matching return (a coefficient) | 2% |
β | Rate sensitivity (a coefficient) | 2.0 |
And the reserve's own rules: it starts at 5% of the pot, is capped at 10%, fills by taking 10% of positive excess, and can drain at most 3% of the pot in a bad year.
First, divide the capital into its two jobs:
Protection capital: C_prot = p · C
Return-seeking capital: C_rs = (1 − p) · C
In words: a fraction p of the money does the stabilising job; the rest chases growth.
Next, work out the two returns that the fund's result is made of. The protection return rate is where the rate-driven logic lives:
r_prot = b − β · Δr
Read that formula slowly, because it encodes a real intuition. When interest rates fall (Δr negative), the protection return rises: more has to be credited to keep protected pensions on track, because a lower rate makes a future pension promise more expensive today. When rates rise, the protection return falls. And notice what's absent: the market return r_m. Protection deliberately doesn't care what the stock market did. That's the whole point of it.
Now turn rates and markets into euros:
Protection return (€): Π = C_prot · r_prot
Excess return (€): X = C_rs · r_m
Collective result (€): Collective = Π + X
So the fund's single headline result, Collective, is just protection euros plus excess euros. Two streams, one total.
Before any of the excess is handed to cohorts, the reserve takes its turn. Let B₀ be the reserve's starting balance and B_max its cap:
B₀ = 5% · C (start balance)
B_max = 10% · C (cap)
If it was a good year (excess X is positive), the reserve fills:
in = min( 10% · X , room left in the tank )
X* = X − in ← excess still available to give to cohorts
It skims 10% of the positive excess, but never more than will fit under the cap. X* (read "X-star") is what's left of the excess after the reserve takes its slice; that's the amount cohorts actually share.
If it was a bad year (excess X is negative), the reserve drains to cushion:
out = min( B₀ , 3% · C ) ← release up to the drain cap, but you can't spend what isn't there
draw = out
X* = X ← the loss itself is shared by cohorts, in full
In a bad year, the full loss X still flows to cohorts (that's X* = X), but the drained amount draw is added back as a cushion. The new tank balance is just the old one plus what went in, minus what came out, kept within its floor of zero and its cap:
B₁ = clamp( B₀ + in − out , 0 , B_max )
Now the interesting part: handing the three pools (protection Π, allocatable excess X*, and reserve draw draw) to the cohorts.
Each cohort i has two things.
First, a capital weight, its share of the total pot:
wᵢ = capitalᵢ / (total capital)
Second, an allocation row: three numbers describing its appetite for each stream, which always sum to 1:
(aᵢ, eᵢ, gᵢ) → protection, excess, reserve propensities, with aᵢ + eᵢ + gᵢ = 1
A young cohort's row might be mostly e (excess). A retiree's row might be mostly a (protection) with a little g (reserve cushion). This allocation matrix is literally the fund's toedelingsregels, the published rulebook, expressed as numbers.
Each pool is then distributed by capital × appetite, normalised so each stream's shares add up to exactly 1:
Protection share to cohort i: sᴾᵢ = (wᵢ · aᵢ) / Σₖ (wₖ · aₖ)
Excess share to cohort i: sˣᵢ = (wᵢ · eᵢ) / Σₖ (wₖ · eₖ)
Reserve share to cohort i: sᴿᵢ = (wᵢ · gᵢ) / Σₖ (wₖ · gₖ)
(The Σₖ just means "sum over all cohorts"; it's the normaliser that makes each stream's shares total 100%.)
Finally, each cohort's credited euros and its return:
creditedᵢ = sᴾᵢ · Π + sˣᵢ · X* + sᴿᵢ · draw
returnᵢ = creditedᵢ / capitalᵢ
A cohort's credited amount is its slice of protection, plus its slice of the shared excess, plus its slice of any reserve cushion. Divide by the cohort's own capital and you get its credited return: the number on the right edge of the diagram, the headline each generation sees.
Here's a small piece of mathematical bookkeeping that turns out to matter enormously for trust. Because each share vector sums to 1, when you add up everything credited to every cohort, the per-cohort shares collapse and you're left with:
Σ creditedᵢ = Π + X* + draw
Nothing leaks; nothing is conjured. Spelled out for the two cases:
Σ creditedᵢ = Collective − in. The euros credited to cohorts, plus the euros that went into the reserve, exactly equal the collective result. (The fill went into the tank, not to a cohort.)Σ creditedᵢ = Collective + draw. Cohorts receive the collective result plus the drained reserve. (The tank balance falls by exactly that amount.)This conservation law is what lets the diagram be a flow diagram. Every euro that enters on the left leaves on the right, into a cohort or into the tank, and never anywhere else. When you watch the picture, you are watching an accounting identity hold.
One last detail for the curious. To produce sensible defaults, the tool needs an opinion about how much capital each age holds and how its appetite for each stream changes with age. It uses smooth illustrative curves: capital builds through working life and tapers in old age; the appetite for excess fades with age while the appetite for protection (and a touch of reserve cushion) grows. These are only defaults. Every one of them (the capital figures, the age range, the appetite matrix, the coefficients) is editable. The curves exist so the tool opens to something reasonable, not so it can hide a hard-coded answer.
Let's run the default scenario all the way through. Capital C = €10,000M, protection level p = 0.60, market return r_m = +6%, no rate change, base match b = 2%, sensitivity β = 2.0.
Split the pot and find the two returns:
C_prot = 0.60 · 10,000 = 6,000 C_rs = 4,000
r_prot = 0.02 − 2.0 · 0 = 2%
Π = 6,000 · 0.02 = €120M ← the "Protection" figure in the tool
X = 4,000 · 0.06 = €240M ← the "Excess" figure
Collective = 120 + 240 = €360M ← a 3.6% result on €10,000M
Run the reserve (a good year, so it fills):
B₀ = 5% · 10,000 = €500M B_max = €1,000M
in = min(10% · 240, 1,000 − 500) = min(24, 500) = €24M
X* = 240 − 24 = €216M
B₁ = 500 + 24 = €524M ← tank: started at 500, +24, ends at 524
Check that it adds up:
Σ credited = Π + X* = 120 + 216 = €336M = 360 − 24 ✓
The €336M credited to cohorts plus the €24M parked in the reserve equals the €360M the fund made. Perfect conservation.
Same scenario, but the return-seeking portfolio loses 12% (r_m = −12%):
X = 4,000 · (−0.12) = −€480M ← excess turns into a red loss
out = min(500, 3% · 10,000) = €300M draw = €300M X* = −€480M
Collective = 120 − 480 = −€360M ← the fund is down 3.6%
Check conservation again:
Σ credited = Π + X* + draw = 120 + (−480) + 300 = −€60M
= Collective + draw = −360 + 300 ✓
Here's what that means for people. The young cohorts, allocated mostly excess, post deep negative returns; they're fully exposed to that −€480M. But the €300M reserve draw, weighted toward retirees, cushions the oldest cohorts and pulls them back toward flat. The same crash lands very differently on a 30-year-old and a 70-year-old, by design. Drag the market slider down in the tool and you can watch the young cohort nodes turn red while the old ones barely move.
In the good-year scenario, the fund made +3.6%, yet the youngest cohort is credited roughly +9.8%. How can a generation earn nearly three times the fund's return when they all share one portfolio?
This is not a bug, and it's not leverage in the borrowing sense. It falls straight out of the conservation math. A cohort's return from the excess stream works out to:
returnˣᵢ = sˣᵢ · X* / capitalᵢ = eᵢ · X* / ( C · Σₖ wₖ·eₖ )
Don't worry about the algebra; here's the intuition in one sentence:
The excess pool is generated by all of the return-seeking capital, but it's allocated onto a much smaller base: only the cohort capital that actually has an appetite for excess.
Run the numbers. The €216M of allocatable excess was earned by the entire €4,000M return-seeking sleeve. But it gets distributed across only about €2,000M of "excess-exposed" cohort capital, because the older cohorts hold most of the total capital yet have almost no appetite for excess, so they barely participate in this pool. Concentrate €216M onto a ~€2,000M base and a fully excess-exposed (young) cohort earns about +10% per euro, even though the fund as a whole made +3.6%.
It's the same money, simply concentrated on the savers who signed up to carry the market risk. And that concentration is a two-way street, which is the real lesson:
Young cohorts get amplified exposure to the growth engine: wonderful in good years, brutal in bad ones. The same arithmetic that gives them +9.8% when the market is up gives them a deep red number when it's down. The reform's central trade-off, made visible.
Recall that you can view results in five-year, one-year, or one-month groups. There are really two kinds of granularity, and the distinction matters:
Now the key insight, which is a deep point about information:
Combining fine groups into coarse ones is just addition: exact and reversible. Splitting a coarse group into fine ones has no single right answer.
If you know each one-year cohort's result, the five-year result is simply their sum: lossless, unarguable. But go the other way (you know the five-year band's result and want to split it into five one-year slices) and there is no unique inverse. A band can be divided many different ways, and the choice changes the per-year numbers you report.
So when you ask the tool to zoom in past where the rules are defined, it does the honest thing: it stops and asks you which splitting rule to apply, and then badges the result "assumption applied" so nobody mistakes a choice for a fact. The three rules it offers make the lesson concrete:
Watching identical bands produce different per-year curves under different rules is the whole teaching moment: disaggregation is a modelling choice, not a measurement. (Whichever rule you choose, re-combining the slices always returns the original band exactly; the split is honest, just not unique.)
The entire value of a tool like this rests on credibility with insiders. So the model is not a black box. Every coefficient is editable:
| What you can change | Effect |
|---|---|
| Base matching return | Lifts or lowers the whole protection stream |
| Rate sensitivity | How hard protection reacts when rates move |
| Collective capital | The notional fund size (scales the euros; leaves the percentages unchanged) |
| Reserve start / cap | The buffer's level and ceiling |
| Fill rate | How quickly the reserve fills in good years |
| Drain cap | The maximum cushion it can release in a bad year |
As you type, a live formula shows the protection rate updating (protection return = base − sensitivity × rate change), so you can see the mechanism respond. A fund's validated assumptions travel with the design when it's exported, which is how the responsible-use gate (below) gets satisfied fund by fund.
A quick tour of the experience:
Used as intended, this is a teaching instrument, and it's worth being explicit about its limits:
| Dutch | English | What it is here |
|---|---|---|
| Wtp (Wet toekomst pensioenen) | Future Pensions Act | The reform being explained |
| solidaire premieregeling (SPR) | solidarity-based DC scheme | The scheme modelled |
| toedelingsregels | allocation rules | The allocation matrix, the rulebook |
| beschermingsrendement | protection return | The stable, rate-driven stream |
| overrendement | excess return | The volatile, market-driven stream |
| solidariteitsreserve | solidarity reserve | The shared buffer, or "the tank" |
| collectief vermogen | collective capital | The size of the whole pot (C) |
| cohort | birth-year group | The generations on the right edge |
| uitlegbaarheid | explainability | The reason this tool exists at all |
If you remember nothing else, remember this:
There is one pot of money and one investment result. Everything else (the two returns, the reserve, the per-cohort numbers) is a transparent set of rules for attributing that one result across generations, in a way that protects the old from market shocks and gives the young the growth they have time to ride.
The reform asks a lot of trust from people who can't see any of that happening. The Explainer's job is to let them watch it happen: one return becoming many, every euro accounted for, nothing hidden.
Explore it yourself at spr-cohort-explainer.wtpdatalab.com. Drag the market slider, crash a scenario, follow a single cohort, and copy a link to whatever you find. Illustrative model: not a calculation of any specific fund, and not advice.