Tuesday, November 03, 2020

The Final Word on the Safe Rate of Withdrawal

This is going to be a rather abstract post on the safe rate of withdrawal because too much ink has been spent on this problem. 

I think the bigger tragedy is that too little code has been written to address this issue.

As of this week, I have been able to inch closer to resolving this for retail investors by combining several programs I wrote on Python. 

Here's how I think the issue can be resolved once and for all:

a) Define a retirement portfolio that generally works and is uncontroversial.

This can be done by any advisor. I did this with a 50/50 portfolio of VT and AGG. A large global equity ETF combined with a US Govt Bond ETF.

Once we have defined this, we can look at historical returns. In such a case, we programmatically find out the statistics of using such a portfolio over the past 10 years. My program output looks like this.


The numbers are not too bad for a 50:50 Stock:Bond fund. Even better, the period coincides with a recovery from the 2009 recession so it's not too different from the current climate. 

b) Generate a probability distribution function with the same statistics as the numbers obtained.

This is the hardest part of solving the problem. 

If we assume that returns are normally distributed, we will not be able to account for the skew and kurtosis (fat-tails) of financial markets. I was googling for an answer and managed to find a function that can do that on Python. 

However, mathematicians are warning that it can be inaccurate, but I'm an engineer and not a mathematician and really don't give a flying fuck.

Source-code is attached. It was a bitch to debug the code done by the original guy. 

import numpy as np
from statsmodels.sandbox.distributions.extras import pdf_mvsk
import scipy.interpolate as interpolate

def generate_normal_four_moments(musigmaskewkurtsize=100sd_wide = 3):
    variance = sigma*sigma
    f = pdf_mvsk([mu, variance, skew, kurt])
    x = np.linspace(mu - sd_wide * sigma, mu + sd_wide * sigma, num=1000)
    y = [f(i) for i in x]
    yy = np.cumsum(y) / np.sum(y)
    inv_cdf = interpolate.interp1d(yy, x, fill_value="extrapolate")
    rr = np.random.random(size)
    return inv_cdf(rr)

The pdf turns out to be really unlike any distribution of a balanced portfolio proving that mathematicians are not really jiak liao bee and are worth listening to, but such are the limits of what can be done using Python at the moment:


c) Build 1000 imaginary portfolios and see how many are successful and how many fail.

Once the pdf is defined, the question comes from generating 1000 portfolios with random returns from the probability distribution function. I start with a capital of $100,000 and I spend the withdrawal rate every year for 40 years but subject the capital to randomly generated VT:AGG market returns.

An example set at 5% withdrawal rate looks really pretty.


From the analysis, in 1000 alternate universes, 982 can sustain a VT:AGG portfolio with 18 fails, failure defined as a portfolio 80% lower than the starting value ( < $20,000 )

Clearly, spending 8% is asking for trouble :


There are a lot of problems employing this approach and I'm not sure whether professional tools actually have a way to resolve it :
  • If you take a 20-year backtest, the return statistics of the retirement portfolio changes too drastically and can impact the number later. 
  • Mathematicians say that it is not straightforward to generate a PDF with four moments of return, variance, skew and kurtosis. So the function call itself is suspect. 
  • No one really withdraws a percentage value. Your cost of living is likely a fixed number. 
I don't know how professional tools do it, looking at some spreadsheets on the web, it may sample from actual historical data. This can be a problem for local folks trying to retire using Netlink Trust and ABF Govt Bond Fund which does not have a historical track record. 

But with whatever I have, I should be able to launch a web app for my community to play with soon. 

But right now my stand does not change, if you don't feel secure, aim for a withdrawal rate of 3.5%. The field of mathematics and computing may not be ready to solve your problem. 









No comments:

Post a Comment