Last active
June 24, 2025 20:05
-
-
Save st1vms/2c6abb8c17aeab9a42ae5c23ed1a3ae2 to your computer and use it in GitHub Desktop.
Fund calculator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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