Skip to content

Instantly share code, notes, and snippets.

@st1vms
Last active June 24, 2025 20:05
Show Gist options
  • Save st1vms/2c6abb8c17aeab9a42ae5c23ed1a3ae2 to your computer and use it in GitHub Desktop.
Save st1vms/2c6abb8c17aeab9a42ae5c23ed1a3ae2 to your computer and use it in GitHub Desktop.
Fund calculator
# Requirements: pandas matplotlib
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import ticker
# Parameters
monthly_investment = 50
simulation_monthly_rates = [0.00, 0.0137, 0.0359] # All the monthly rates to simulate
total_simulation_years = 20 # Total number of years to simulate future value
# List of (loss_probability, [loss_percentage1, loss_perc2, ...])
monthly_loss_map = [
(0.1, [0.1, 0.6]),
(0.01, [0.1, 0.6]),
]
monthly_loss_map = sorted(monthly_loss_map, key=lambda v: v[0])
# Set a seed for reproducibility
np.random.seed(42) # TODO Run simulations on multiple seed and pick best and worst
# Simulate the future values
results = {}
# Simulate each monthly rate
for r in simulation_monthly_rates:
fv = []
# We start the first month with a base investment
monthly_fv = monthly_investment
for y in range(total_simulation_years):
for m in range(12):
# Simulate probability of loss
prob = np.random.rand()
for entry in monthly_loss_map:
if prob < entry[0]:
# Monthly loss
monthly_fv -= monthly_fv * np.random.choice(entry[1])
break
# Monthly win + new investement
monthly_fv += monthly_fv * r + monthly_investment
fv.append(monthly_fv)
results[f"Monthly return, price rate: {int(r * 100)}%"] = fv
tot = []
total_invested = 0
for y in range(total_simulation_years):
for m in range(12):
total_invested += monthly_investment
tot.append(total_invested)
results["Total Invested"] = tot
pd.options.display.float_format = "{:,.2f}".format
df = pd.DataFrame(results)
df.index.name = "Months"
print(df.round(2))
ax = df.plot()
ax.set_xlabel("Months")
ax.set_ylabel("Monthly Future Value (€)")
ax.set_title(
f"""€{monthly_investment}/Month, Total Invested : {results["Total Invested"][-1]} in {total_simulation_years} years."""
)
ax.grid(True)
ax.yaxis.set_major_formatter(
ticker.StrMethodFormatter("{x:,.0f}")
) # Adds commas and no decimals
plt.tight_layout()
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment