Last active
April 26, 2018 08:32
-
-
Save bobular/914eed165f77a0ee54624a328deeb411 to your computer and use it in GitHub Desktop.
Same model as previous v3 version but with a step change expected return in the contribution period.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
# -*- mode: cperl -*- | |
# | |
# The purpose of this little model is to figure out what kind of | |
# investment returns the pension fund needs to make in order to meet | |
# its defined benefits promises. | |
# | |
# It assumes a single employee with their own "pot" and a fixed payout | |
# period. I'm not suggesting euthanasia... Obviously in reality the | |
# longevity risk is shared by the many thousands of scheme | |
# members. I'm trying to keep this simple... | |
# | |
# Salary progresses through early career to a fixed level until | |
# retirement. A very simple career-averaged earnings approach is used | |
# to calculate the pension payout. | |
# | |
# This is 100% defined benefit. There is no 55k cap (as found in the | |
# USS scheme). No in-service death benefits are included. | |
# | |
# In v3 - an annual payrise parameter is added, and the lump sum and payout parameters | |
# are changed to be expressed as annual accrual fractions | |
# | |
# In this (v4) version, the expected growth can be different for the first B years. Fixed small bug in annual_increment. | |
# | |
# ./pension-model-with-USS-returns.pl 0.23 0.01 10 0.04 35000 20 60000 20 0.02 3/75 1/75 0.02 25 | |
# | |
# 0.23 = C, fraction of salary contribution total (employer+employee) | |
# 0.01 = I, expected annual asset investment return (e.g. 1%) | |
# 10 = B, number of years at investment return rate I | |
# 0.04 = K, expected investment return after B years (e.g. 4%) | |
# 35000 = S, starting salary | |
# 20 = X, number of years working with linear annual salary increments | |
# 60000 = T, salary after X years of increments | |
# 20 = Y, number of years working at fixed salary T until retirement | |
# 0.02 = R, annual above-inflation payrise | |
# 3/75 = L, lump sum accrual rate | |
# 1/75 = A, annual pension accrual rate | |
# 0.02 = J, expected annual asset return in drawdown period* | |
# 25 = Z, number of years retirement | |
# | |
# (* in a large and long-running scheme with good cashflow there is no | |
# need to de-risk and be more prudent here, but I give the option anyway) | |
# | |
# example output shows that USS's projection of 1% return for first 10 years | |
# followed by 4% for the next 30 years (and then 2% return thereafter to be | |
# conservative) | |
# will require | |
# 15% contributions will fund current benefits: | |
# 1/75 accrual rate, 3/75 accrual of lump sum | |
# | |
# | |
# ./pension-model-with-USS-returns.pl 0.15 0.01 10 0.04 35000 20 60000 20 0 3/75 1/75 0.02 25 | |
# Starting salary was 35000 and after 20y it was 60000 | |
# Career averaged salary over 40 years is 53437 | |
# Pot is 682301 after 40y contributions at 15% of salary and 1% (then 4% after 10 years) annual growth of pot | |
# Lump sum payout of 1.6 x career avg salary = 85500 upon retirement | |
# After 25y retirement paying out 53% of career-averaged salary, the pot (with 2% annual return) is 47994 | |
# | |
# If you reduce the 0.15 (15% contribution rate) any lower, the pot ends | |
# up in negative territory | |
# | |
use strict; | |
use warnings; | |
my ($contrib, $growth1, $growth1_years, $growth2, $start_salary, $years_1, $end_salary, $years_2, | |
$payrise, $lump_sum_accrual, $accrual, $growth3, $years_retired) = @ARGV; | |
$lump_sum_accrual = eval $lump_sum_accrual; | |
$accrual = eval $accrual; | |
my $pot = 0; | |
my $salary = $start_salary; | |
my $annual_increment = ($end_salary-$start_salary)/$years_1; | |
my $sum_salary = 0; # for calculating career-averaged salary | |
my $total_years = $years_1+$years_2; | |
my $year = 0; # year counter used to decide between growth rates 1&2 | |
for (1 .. $years_1) { | |
$year++; | |
$pot *= 1+($year <= $growth1_years ? $growth1 : $growth2); | |
$pot += $salary*$contrib; | |
$sum_salary += $salary; | |
$salary += $annual_increment; | |
$salary *= 1+$payrise; | |
$annual_increment *= 1+$payrise; | |
} | |
for (1 .. $years_2) { | |
# same as above but without the annual increment | |
$year++; | |
$pot *= 1+($year <= $growth1_years ? $growth1 : $growth2); | |
$pot += $salary*$contrib; | |
$sum_salary += $salary; | |
$salary *= 1+$payrise; | |
} | |
printf "Starting salary was %d and after %dy it was %d\n", | |
$start_salary, $years_1, $salary; | |
my $career_averaged_salary = $sum_salary/$total_years; | |
printf "Career averaged salary over %d years is %d\n", | |
$total_years, $career_averaged_salary; | |
printf "Pot is %d after %dy contributions at %d%% of salary and %d%% (then %d%% after %d years) annual growth of pot\n", | |
$pot, $total_years, $contrib*100, $growth1*100, $growth2*100, $growth1_years; | |
my $lump_sum = $career_averaged_salary*$total_years*$lump_sum_accrual; | |
$pot -= $lump_sum; | |
printf "Lump sum payout of %.1f x career avg salary = %d upon retirement\n", | |
$total_years*$lump_sum_accrual, $lump_sum; | |
for (1 .. $years_retired) { | |
$pot -= $career_averaged_salary*$total_years*$accrual; | |
$pot *= 1+$growth3; | |
} | |
printf "After %dy retirement paying out %d%% of career-averaged salary, the pot (with %d%% annual return) is %d\n", | |
$years_retired, 100*$total_years*$accrual, $growth3*100, $pot; |
Late joiners are expensive too...
In a flat CPI+2% growth scenario (wages at CPI+0%), someone joining 10 years before retirement at 50k and progressing to 60k requires 28% contributions on career-averaged basis and 31% contributions in a final salary scheme.
Here's the career-averaged run:
$ ./pension-model-with-USS-returns.pl 0.28 0.02 10 0.02 50000 10 60000 0 0.0 3/75 1/75 0.02 25
Starting salary was 50000 and after 10y it was 60000
Career averaged salary over 10 years is 54500
Pot is 166592 after 10y contributions at 28% of salary and 2% (then 2% after 10 years) annual growth of pot
Lump sum payout of 0.4 x career avg salary = 21800 upon retirement
After 25y retirement paying out 13% of career-averaged salary, the pot (with 2% annual return) is 138
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Modifying the script to final salary basis (not shown, but it's trivial: replace $career_averaged_salary with $salary in last few lines) the example given above (-1% then +1.7% returns on assets) - requires 26% contributions to break even. This assumes a salary trajectory of 35k to 60k in 20 years and then flatlining after that - I call this "lecturer".
Then factor in just 1% above CPI salary growth into that and you need a whopping 32% contributions:
$ ./pension-model-final-salary.pl 0.32 -0.01 10 0.017 35000 20 60000 20 0.01 3/75 1/75 0.02 25
Starting salary was 35000 and after 20y it was 89331
Career averaged salary over 40 years is 66332
Pot is 1118311 after 40y contributions at 32% of salary and -1% (then 1% after 10 years) annual growth of pot
Lump sum payout of 1.6 x final salary = 142930 upon retirement
After 25y retirement paying out 53% of final salary, the pot (with 2% annual return) is 43654
Assuming flat asset growth of CPI+2% throughout the entire period, final salary costs around 24% contributions with no above inflation salary growth and 29% with CPI+1% pay growth.
Now let's change the salary trajectory to resemble a "professor": progression from 35k to 90k in the first 30 years and then flat for the last 10. No above-inflation. This costs 29% contributions - compare with the 24% above.
$ ./pension-model-final-salary.pl 0.29 0.02 10 0.02 35000 30 90000 10 0.0 3/75 1/75 0.02 25
Starting salary was 35000 and after 30y it was 89999
Career averaged salary over 40 years is 68687
Pot is 1130186 after 40y contributions at 28% of salary and 2% (then 2% after 10 years) annual growth of pot
Lump sum payout of 1.6 x final salary = 143999 upon retirement
After 25y retirement paying out 53% of final salary, the pot (with 2% annual return) is 49739
On a career-average basis (using the script above unmodified), these same scenarios cost: 21% (lecturer) and 22% (professor).
Final salary was unjust and expensive!