Using Python and Monte Carlo to predict my Student Loan Repayment | by Luke Vassor | Towards Data Science

I became frustrated with the numbers not making sense on my Student Loan statements and speculative opinions about why you should not try to pay it off quicker if you are able to. I wanted to gauge my likelihood of paying off the full loan and practice my Data Science skills, so I simulated my earnings using Monte Carlo written in Python. Here I give a walk-through and evaluation of the findings.
Full code available on my GitHub.
Skip to Method and Results if you’re short of time!
In the UK, students can take out university loans for both tuition fees and living costs with Student Finance England, who provide loans underwritten by the Student Loans Company. Once you enter employment as a graduate, you then begin to pay off your loan on a monthly schedule as part of your tax deductions. Crucially, if you do not pay off your loan, plus interest, in 30 years, your loan is cancelled. They’re also substantial — approximately £42,000 one year after graduating in many cases.
I found documentation surrounding repayment murky and dense. It’s confusing, and no-one online or in my circle could give me clear answers.
Conflicting opinions surrounding repayment— “it comes out of my tax so I don’t even notice it” and “most students won’t pay it off and it will get cancelled, so paying extra upfront might be wasting your money” — but this paints “most students” with a broad brush, which spans a huge variance in earnings (and therefore amortisation) between subjects, university attended and industry.
I wanted to cut through the noise and capture the dynamics between the accruing interest and monthly tax repayments to quantify my own probability of paying it off.
1. How likely am I to pay off my student loan inside of the 30-year payment window, given my probable salary progression?2. If you manage to save money, or come across a sum of money (e.g. inheritance), should you pay off some or all of your loan in the form of voluntary payments?
Students taking out loans since 2012 are on “Plan 2” loans, and they are split up into instalments which you receive throughout your degree.
Graduates only start paying back towards their loan when they earn more than £2,214 a month or £26,568 a year (pre-tax) as of the date this article was published.
Loan repayments are deducted from your salary when you are paid by your employer (in the UK, usually the last working day of the month) — these are due the April after graduating if you earn above the threshold.
You begin accruing interest from the day of your first loan instalment (i.e., shortly after arriving at university).
Interest accrues daily.
Plan 2 loans are written off 30 years after the April you were first due to repay if you are still repaying.
The amount you pay back on your Student Loan is calculated as a percentage of how much you earn above a threshold, so it behaves much more like a tax, rather than regular loan repayments.
Interest rates are variable, not fixed — they are calculated as the RPI (Retail Price Index) measure of inflation, plus 3%, so rates have been as high as 6.6% in recent years.
Interest rates change each academic year (September 1st), using the RPI inflation for the financial year ending in the previous March (i.e., March 2019 RPI is used for the rate set on September 1st 2020).
Build a simulator in Python which runs through 30 years of payments towards the loan, with the loan simultaneously accruing interest daily.
Simulate across many different salary trajectories, using Monte Carlo (more below).
import os
import pandas as pd
import numpy as np

# Working with datetime objects
from datetime import date, timedelta
from pandas.tseries.offsets import BMonthEnd

# Scraping interest rates off the web
import requests
from bs4 import BeautifulSoup

# Plotting
import matplotlib.pyplot as plt
%matplotlib inline

def calc_student_finance_PM(grossSalaryPA):
    '''
    Calculates student finance payments per month deducted
    from gross salary based on thresholds published by
    Student Finance England.
    '''
    grossSalaryPM = grossSalaryPA/12
    thresholdPM = 2143
    if grossSalaryPM > thresholdPM:
        StudentFinPM = 0.09*(grossSalaryPM-thresholdPM)
    else:
        StudentFinPM = 0
    return StudentFinPM

Get interest rates for past academic years from the government website, using a simple web scraper (BeautifulSoup library) and store them in a lookup dictionary.Build a function which could take any date during my degree and find the interest rate for instalments paid at that point in time from the dictionary.
Get interest rates for past academic years from the government website, using a simple web scraper (BeautifulSoup library) and store them in a lookup dictionary.
Build a function which could take any date during my degree and find the interest rate for instalments paid at that point in time from the dictionary.
## Web scrape historic interest rates

url = 'https://www.gov.uk/guidance/how-interest-is-calculated-plan-2'
headers = {'User-Agent': 'Mozilla/5.0'}
page = requests.get(url, headers=headers)
soup = BeautifulSoup(page.content, 'html.parser')
results = soup.find('table')
table_rows = results.find_all('tr')

# Store interest rates in dictionary of academic years
historicInterest = {}
for tr in table_rows:
    td = tr.find_all('td')
    row = [i.text for i in td]
    if len(row) > 0:
        row[0] = row[0].split('to')
        row[0][0] = pd.Timestamp(row[0][0])
        row[0][1] = pd.Timestamp(row[0][1])
        year = str(row[0][0].year)
        historicInterest.setdefault(year, 0)
        historicInterest[year] = {}
        historicInterest[year].setdefault("start", 0)
        historicInterest[year]["start"] = row[0][0].date()
        historicInterest[year].setdefault("end", 0)
        historicInterest[year]["end"] = row[0][1].date()
        historicInterest[year].setdefault("rate", 0)
        historicInterest[year]["rate"] = float(row[1][:-1])/100

def find_interest_rate(paymentDate):
    '''
    Finds interest rate for a date which falls in 
    a given academic year using a lookup dictionary.
    '''
    try:
        year = paymentDate.year
        sdate = historicInterest[str(year)]["start"]
        edate = historicInterest[str(year)]["end"]
        delta = edate - sdate
    
        allDates = [sdate + timedelta(days=i) for i in range(delta.days+1)] # create list of all dates in date range sdate to edate
        
        # Dates in the second semester are in the next calendar year but same academic year
        # in this case, take the rate of the previous calendar year
        if paymentDate in allDates:
            rate = historicInterest[str(year)]["rate"]
        else:
            rate = historicInterest[str(year-1)]["rate"]
    except KeyError: # error for dates in next calendar year but in an academic year which exceeds the last year of the dictionary
        rate = historicInterest[str(year-1)]["rate"]
    return rate

To calculate how much I owed after university I simulated each passing day’s interest plus any new instalments arriving from Student Finance England throughout university, using a Pandas dataframe of payments (digitised from my paper statements).
def graduate_amount(simEnd, employmentStart, myPayments=None):     '''
    calculate total student debt owed at employment, 
    end of graduation year or at final instalment manually (using simEnd)
    Alternatively can take manually input total
    '''
    
    cumulativeTotal = 0
    interestRate = 0
    if myPayments is not None:
        startDate = myPayments.index.min()
        if simEnd == "yearEnd":
            graduationYear = myPayments.index.max().year # assumes that final payment occurs during graduation year
            yearEnd = str(graduationYear)+"-08-31"
            endDate = pd.Timestamp(yearEnd) # simulation ends at end of academic year of final payment
        elif simEnd == "employment":
            endDate = pd.Timestamp(employmentStart)
        else:
            endDate = myPayments.index.max() # simulation ends at final payment

        delta = timedelta(days=1)
        
        ## Simulate through dates in date period, 
        ## compounding interest each day and adding installments
        
        while startDate <= endDate: # simulate interest compounding up to and including last day
            interestRate = find_interest_rate(startDate)
            cumulativeTotal *= (1+(interestRate/365)) # apply interest on previous payments before new payment
            if startDate in myPayments.index: # check if there was a loan instalment on this day
                cumulativeTotal += myPayments.loc[startDate]["Gross"]
            startDate += delta                
            
    else:
        print("Please enter your net total of Student Debt at graduation")
        cumulativeTotal = input()
    return cumulativeTotal

Using the above functions, the value owed in Student Finance loans at the start of employment can be calculated. After the April following graduation, you begin paying back towards your loan in the style of a monthly tax. In this simulation interest accrues on the loan daily and on the last working day of the month (BMonthEnd) your repayment comes out of your salary, as in reality.
Monte Carlo methods are a class of algorithms that rely on repeated random sampling to obtain numerical results — by the law of large numbers, the expected value of a random variable can be approximated by taking the sample mean of independent samples. In plain English: “while we don’t know what the correct answer or strategy is, we can simulate many attempts and the average will approximate the right answer”. Monte Carlo can be used for many problems with a probabilistic element or “risk”, such as gambling, or stock market and portfolio performance in finance. Here is a great example.
Since the amount of student finance I will pay across my working life (through monthly payments) is based on what I earn at time t, and I don’t know what I will earn, I can simulate my career earnings using Monte Carlo. In the simulation:
The starting salary (£29,000) is the median graduate starting salary, based on graduate schemes of employment — reported by the Institute of Student Employers (ISE).
I divide the 30-year payment period of the loan into different salary bands for my career.
I chose 6 separate bands, each 5 years long (but this can be varied).
Each salary band represents a salary increase at time t — the increase is taken from a Gaussian distribution centred around a mean which is a percentage of my gross salary at time t-1.
This percentage decreases the further the simulation runs into my career i.e., most salary growth occurs in early years (high % increase), then it slows (low % increase). e.g., in the below table (0,1) = 37.49% salary increase.
I simulate my career according to these salary bands 100,000 times.
The loan’s interest rate is set at 5.5% — RPI of 2.5% plus 3% (government method). To inform this I used a 5-year moving average of historic UK RPI values, which I downloaded from the Office for National Statistics (ONS). Whilst predicted RPI estimates are available, the current COVID-19 crisis and its economic implications will likely affect these predictions, thus I took the pre-COVID19 value which has remained around 2.5% in recent years.
I calculate what the average loan value and cumulative sum of repayments (lifetime contribution) are across all salary trajectories after the 30-year payment period.
Translation:
As a graduate earner, most salary growth occurs in the early years (high % increase) before levelling off (low % increase) — see this incredibly thorough new report The impact of undergraduate degree on lifetime earnings by the Institute for Fiscal Studies.
A pay-rise of x% in 5 years is not certain —it could be slightly less than or greater than x%, or you could have a series of smaller or larger pay-rises (the aggregate of which are represented in the 5-year jump). Monte Carlo helps to mitigate this by drawing many salary values (k = 100,000) from a normal distribution for each band. These average x%, but can be less than or greater than x%. I simulate all these trajectories and the monthly payments towards my loan and work out in how many of the simulations I pay off my entire loan.
As you can see in the top plot, only a small proportion of loans are ever paid off via monthly deductions. These loans are identifiable as the trajectories which cross the zero-line (marked in red) and correspond to the largest salaries. The lowest salaries across all years result in loans which continue to grow in value.
For 100,000 simulations, after the 30 year payment period:
the average loan value is: £60,600.74
only in 3.54% of salary trajectories was the loan completely paid off i.e., crossed the red zero line in the plot (3,543/100,000)
the average total amount of money paid towards the loan is: £99,691.01
DISCLAIMER: I am not a financial adviser — any ideas here are purely hypothetical based off simulations with a suite of assumptions & caveats. These are simply my thoughts on potentially effective strategies, as part of a conceptual exercise. If you are unsure about your own personal financial situation, seek the advice of a qualified financial adviser.
This simulation, of course, contains several caveats:
Salary bands: I assume 6 x 5-year salary bands — there is no guarantee that graduate earnings will follow this format. There are not adequate data on regular salary progressions for a particular field in the UK, as salary increases and promotions are subject to many variables, including academic qualifications (e.g. BSc vs MSc vs PhD), field, company, and the performance of the individual themselves. Whilst there are data on average graduate earnings per subject, these data do not capture the many routes/fields that a graduate with a particular degree can take. After conversations with senior roles in my network, I determined that approximate 5-year frequencies for salary increases and the percentages chosen are close to reality, on average, for a STEM graduate.Interest rate: This simulation assumes that recent RPI values will remain constant in future years, however the real interest rate on the loan changes every academic year because of changing RPI, which will affect how quickly the interest of the loan compounds.Starting salary: I used the average starting salary based on graduate schemes, but this is not representative of all graduate salaries — which affects repayment.Other compensation: The simulation only considers base salary, without bonuses, company shares or other forms of renumeration.
Salary bands: I assume 6 x 5-year salary bands — there is no guarantee that graduate earnings will follow this format. There are not adequate data on regular salary progressions for a particular field in the UK, as salary increases and promotions are subject to many variables, including academic qualifications (e.g. BSc vs MSc vs PhD), field, company, and the performance of the individual themselves. Whilst there are data on average graduate earnings per subject, these data do not capture the many routes/fields that a graduate with a particular degree can take. After conversations with senior roles in my network, I determined that approximate 5-year frequencies for salary increases and the percentages chosen are close to reality, on average, for a STEM graduate.
Interest rate: This simulation assumes that recent RPI values will remain constant in future years, however the real interest rate on the loan changes every academic year because of changing RPI, which will affect how quickly the interest of the loan compounds.
Starting salary: I used the average starting salary based on graduate schemes, but this is not representative of all graduate salaries — which affects repayment.
Other compensation: The simulation only considers base salary, without bonuses, company shares or other forms of renumeration.
So what is the conclusion here? What strategy should you take with regard to paying off your student loan?
Firstly, it should be highlighted that debt repayment is a blend of arithmetic and also psychology, because as complex creatures, our emotional welfare with regard to debt is affected by multiple factors. There are different debt consolidation strategies if you have multiple debt repayments to make e.g. Snowball or Avalanche methods.
Secondly, in a purely mathematical sense, the optimum strategy for paying the minimum amount on the student loan would be to remain at a salary below the repayment threshold for the entire 30-year payment period, thereby receiving the degree for free, as you never pay a penny for it. However, this is only when considering the loan in isolation from other factors, and obviously does not reflect the real life ambitions of a typical graduate. With this in mind I consider strategies that assume progressive career growth which includes repaying your loan.
Practically and in isolation, yes, you should try and pay it off with any extra money you encounter, because the Results show, on average, you will pay for the loan more than twice over across your working life time (99,691.01/42,000 = 2.37).
Crucially, the major factor affecting amortisation in this problem is the dynamics between the interest and the monthly repayments. If the interest on the loan accrued in a given month is £20, you need to pay more than £20 in repayments at the end of the month to decrease the principal amount — this is basic mathematics.
The key factor is the rate at which your salary increases, because of the powers of compound growth. Your repayments need to chip off the interest plus more to start decreasing the principal amount. But, if your salary means you don’t manage to overcome the interest early on, even if your salary rises to a substantial amount later in life, the loan will have grown to an amount which demands a disproportionately higher salary to conquer the later monthly interest, which will be much greater due to the non-linearity of compound growth. Therefore, to successfully pay off your loan only through monthly tax repayments, the salary must grow fast enough in the early years such that repayments quickly overcome the interest and the debt is not “allowed” to grow. The other option is that if your salary is too low to achieve this, you make voluntary repayments each month to make up the difference.
Of course in reality, your loan repayment is not in isolation of other factors. It’s a multi-dimensional problem! It comes down to what else you can invest any extra money in for the long term, because of the time-value of money and opportunity cost. Time-value of money is the concept that the same sum of money is worth more now than later on in life because of its earning potential and inflation.
If you come across a sum of money that affords you the ability to pay off the loan (either from a savings account, inheritance etc.), you could invest it and grow it, utilising compound growth rather than only being a victim of it.
I did a post-hoc analysis to show this. Suppose instead of paying off the loan, you use a long term, sit-and-hold strategy in an investment with a higher average return than the amount you pay towards the loan through monthly salary deductions — either with a lump sum equivalent to the value of the loan (£42,000), or — since this situation will be very rare for the typical graduate — with an initial investment of £1,000 and monthly deposits of any savings (£200).
3 scenarios:
You encounter £42,000 and pay off the loan immediately. Monthly repayments (blue line) would cost you approx. £100,000 over your lifetime, which you’ve avoided. £100,000 — £42,000 = £58,000 “profit”.You encounter £42,000 and invest it at a 5.0% return (after inflation) and leave it to grow for the 30-years instead (orange line). After 30 years this is worth approx £187,000. £187,000 — £100,000 = £87,000 profit.You invest £1,000 and use money you save each month (e.g. £200) to top up the investment monthly (green line). After 30 years this is worth approx £170,000. £170,000–£100,000 = £70,000 profit.
You encounter £42,000 and pay off the loan immediately. Monthly repayments (blue line) would cost you approx. £100,000 over your lifetime, which you’ve avoided. £100,000 — £42,000 = £58,000 “profit”.
You encounter £42,000 and invest it at a 5.0% return (after inflation) and leave it to grow for the 30-years instead (orange line). After 30 years this is worth approx £187,000. £187,000 — £100,000 = £87,000 profit.
You invest £1,000 and use money you save each month (e.g. £200) to top up the investment monthly (green line). After 30 years this is worth approx £170,000. £170,000–£100,000 = £70,000 profit.
As these results show, even if the simulated graduate doesn’t have a large lump sum available and uses a much more modest amount to begin investing their monthly savings, they could still end up in greater profit than if they paid off the loan completely. In most cases, graduates are unlikely to encounter this kind of lump sum, and to attempt to save money after your living costs to then pay towards the student loan could leave you forever chasing your own tail as the loan interest simultaneously compounds more than you can save — you would be better off investing it.
This opportunity cost applies to other investments, like purchasing a house and leveraging its appreciation in value and even to investment in yourself, such as courses, seminars and conferences, which develop your skills and grow your network. Whilst this is hard to capture in monetary terms, it will generate more opportunity, and likely greater profit.
It’s not a crystal-clear conclusion— there are a lot of “‘ifs”:
If the interest on the loan were much lower, it would be clear to simply pay through monthly deductions with less concern for added investment as you would be a lot less likely to overpay.
If you encounter a sum of money that approximates the value of your student debt or if you save money each month, it could be more profitable to invest it, as paying off the loan would incur huge opportunity cost. As a young graduate you are in a strong position— the time/effort/money invested in your first few years can affect the course of your career, and years of delayed investment for the future could drastically reduce your ROI later in life.
If you have the money but don’t invest it, then you would be better off paying off the loan with this money, otherwise you could pay several times over through monthly repayments, plus this liquid money will lose value each year due to inflation.
These results will undoubtedly inform my personal finance decisions in the near future.
What is also reassuring is that the report mentioned above found that even after accounting for taxes and Student Finance repayments, UK graduates are still at least £100,000 better off, on average, for getting a degree, because of the additional, net take-home salary that they earn.
This project has certainly shown me that the notion of “don’t pay off the loan in full as it gets cancelled later on” is misguided in its lack of elaboration — it completely depends on salary, because this determines if you under- or over-pay for your degree. If lifetime salary is low enough, then you could underpay for the degree via monthly repayments, in which case you should not pay extra or worry about investing. However, these simulations suggest that if you end up earning in the average (densest) region (see salary step plot in Results) then you should invest any extra money and pay the minimum on your loan. This is because you will need investments later on to counterbalance the over-payment of your degree. Of course, these conclusions are hypothetical and are drawn from the predicted interest rate and simulated salaries, which could be different.
Apart from the greater understanding of the student loans system I have gained, this exercise did highlight something important. We do not have enough publicly available and consumable data tracking graduate lifetime earnings for different fields or careers. The report mentioned analyses longitudinal data for graduates and non-graduates from a particular cohort, and was very recently published — research like this needs to be made available and digestible to prospective undergraduates. Undergraduate university courses in the UK now cost up to £9,250 per year, which you may pay for several times over as we have seen. We need data on what graduates of a particular course at a particular university go on to earn so candidates can judge for themselves what the ROI for their course and university would be, in light of the huge loan they would be taking on, rather than simply being dazzled by universities on Open Days.
I hope this article has been insightful! Onto the next project...