A while back, I looked into a very simple toy model for living off savings. The main idea was to:

  1. set aside a yearly budget at the end of the year
  2. cover all expenses for the upcoming year using the yearly budget
  3. invest the lion share of your salary every month
  4. refill the budget a little bit every month

The first time around, I looked at a single year. This time around, I tried to imagine what would happen if we extend the horizon of this strategy and tweak a few parameters.

import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import pandas as pd


def simulate(startdate, enddate, m_salary, m_expenses, m_refill, y_return):
    dates = pd.date_range(startdate, enddate, freq="MS")
    dataset = pd.DataFrame(index=dates)

    budget = float(m_expenses * 12)

    dataset["costs"] = float(m_expenses)
    dataset["income"] = float(m_salary)

    dataset["refill"] = np.where(
        dataset.index.month_name() == "January", budget, m_refill
    )

    for i, r in dataset.iterrows():
        dataset.loc[i, "_diff"] = r["refill"] - r["costs"]

    dataset["budget"] = dataset["_diff"].cumsum()
    dataset["investment"] = float(m_salary - m_refill)
    dataset["return"] = round(float(y_return / 12), 1)

    dataset["_appreciation"] = (dataset["investment"] * dataset["return"]) + dataset[
        "investment"
    ]

    dataset["_detraction"] = np.where(
        dataset.index.month_name() == "January", budget, 0
    )

    for i, r in dataset.iterrows():
        if i == pd.Timestamp(startdate):
            dataset.loc[i, "_capital_diff"] = r["_appreciation"]
        else:
            dataset.loc[i, "_capital_diff"] = r["_appreciation"] - r["_detraction"]

    dataset["capital"] = dataset["_capital_diff"].cumsum()

    columns = [c for c in dataset if not c.startswith("_")]
    dataset = dataset[columns]

    return dataset

If the numbers hold, we can plug in:

  • a start date
  • an end date
  • a monthly salary (Swedish Kronor)
  • monthly expenses (Swedish Kronor)
  • monthly budget refill amount (Swedish Kronor)
  • an estimated annually return rate for invested capital
r = simulate("1/1/2022", "12/31/2026", 31_000, 15_200, 4_000, 3)
plt.plot(r.index, r["budget"], label="budget", c="red")
plt.plot(r.index, r["capital"], label="capital", c="green")
plt.ticklabel_format(axis="y", style="plain")

ax = plt.gca()
ax.get_yaxis().set_major_formatter(
  plt.FuncFormatter(lambda x, loc: "{:,}".format(int(x)))
  )
plt.legend(frameon=False)

Some interesting outcomes:

  • you never run out of money as long as you spend less than your budget
  • because you constantly refill your budget, you end up with slightly more in it at the end every year; assuming expenses and salary stay fixed over the years
  • your capital grows very fast
  • you could live off your capital after the first year already; assuming you can achieve the annual rate of return you specified
  • as the gap between capital and budget widens, the less you need a salary