To quantify Buffet's #1 rule of investing, "Don't lose money", I take the assumption that % returns of an investment follow a Normal distribution.
Now a high return high risk investment might follow N(mu=50%, sigma=70%) while low return low risk investment follow N(mu=20%, sigma=10%).
from operator import mul from functools import reduce from random import gauss from statistics import median from typing import List def avg_cagr(percents: List[int]) -> float: '''Given (successive) % annual growth rates, returns average Compound Annual Growth Rate''' amount = reduce(mul, [1+p/100 for p in percents]) amount = amount if amount > 0 else 0 # at worst, complete amount can be lost but can't go negative return (amount**(1/len(percents)) - 1)*100 def normal_returns(mu: float, sigma: float, years: int = 20, simulations: int = 1000) -> float: '''Returns net CAGR assuming annual percentage returns follow a Normal distribution''' return median(avg_cagr([gauss(mu=mu, sigma=sigma) for _ in range(years)]) for _ in range(simulations))
I have simulated
normal_returns for various values of
sigma (for 20 consecutive years) and plotted a contour plot. We can see here that N(25, 20) handily beats N(60, 80). Plotting code
My query is does this formulation of problem (beyond just the code) seem alright? Could I model/design it better? What are other approaches?