Skip to content

Apply replacement_rate_adjust to every pension system - #1201

Open
marcelolafleur wants to merge 1 commit into
PSLmodels:masterfrom
marcelolafleur:pension-replacement-rate-adjust
Open

Apply replacement_rate_adjust to every pension system#1201
marcelolafleur wants to merge 1 commit into
PSLmodels:masterfrom
marcelolafleur:pension-replacement-rate-adjust

Conversation

@marcelolafleur

@marcelolafleur marcelolafleur commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Fixes #1200.

replacement_rate_adjust is a table of multipliers on pension benefits, one per year and income group. It lets a country phase benefits down over time.

It was only read inside SS_amount, so it worked under US-Style Social Security and did nothing at all under Defined Benefits, Notional Defined Contribution and Points System. Setting it under those three changed nothing and gave no warning.

pension_amount now applies it to the other three systems as well.

The only fiddly part is looking up the right year. In the steady state there is one year, so the multiplier is the last row of the table. Along the transition the model computes a block of years at once, and each row of that block is a different year — the block starts at year t, so its first row needs the multiplier for year t, its second row year t + 1, and so on. A small helper does that lookup and returns the multipliers shaped to line up with the benefits array. This is what SS_amount was already doing for US-Style; the helper does the same for the rest.

SS_amount itself is unchanged, so US-Style results cannot move.

With this fix, thame call, with the multiplier halved:

                     mult=1.0    mult=0.5
US-Style              3.60000     1.80000
Defined Benefits      0.92659     0.46329     (before this was 0.92659 as well)

Tests

  • test_replacement_rate_adjust_applies_to_every_system : halving the multiplier must halve benefits, under all four systems. Fails on master for DB, NDC and PS.
  • test_replacement_rate_adjustment_indexes_by_cohort_year : checks the year lookup: on the transition, row n of the block must get the multiplier for year t + n, and the steady state must get the last row. Using one year's multiplier for the whole block would still pass a test with a flat table, and would quietly cancel out a phase-down. The existing test_pension_amount sets the table to all ones, so it cannot catch this.

test_pensions.py, test_tax.py and test_aggregates.py pass, 122 total.

cc: @jdebacker @rickecon

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.66667% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.78%. Comparing base (2b6a668) to head (ed31a6d).

Files with missing lines Patch % Lines
ogcore/pensions.py 86.66% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1201      +/-   ##
==========================================
+ Coverage   72.74%   72.78%   +0.03%     
==========================================
  Files          22       22              
  Lines        5768     5783      +15     
==========================================
+ Hits         4196     4209      +13     
- Misses       1572     1574       +2     
Flag Coverage Δ
unittests 72.78% <86.66%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
ogcore/pensions.py 69.01% <86.66%> (+0.85%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

replacement_rate_adjust is ignored by every pension system except US-Style Social Security

3 participants