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; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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