Last active
December 26, 2023 04:57
-
-
Save rlan/acaec0f61b7bce7bd8b04eb208e0c691 to your computer and use it in GitHub Desktop.
twin-investing
This file contains 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
matplotlib | |
pandas | |
seaborn |
This file contains 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
{ | |
"nbformat": 4, | |
"nbformat_minor": 0, | |
"metadata": { | |
"colab": { | |
"name": "twin-investing.ipynb", | |
"provenance": [], | |
"include_colab_link": true | |
}, | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3" | |
}, | |
"language_info": { | |
"name": "python" | |
} | |
}, | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "view-in-github", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"<a href=\"https://mybinder.org/v2/gist/rlan/acaec0f61b7bce7bd8b04eb208e0c691/HEAD\" target=\"_parent\"><img src=\"https://mybinder.org/badge_logo.svg\" alt=\"Open In Binder\"/></a>", | |
"<a href=\"https://colab.research.google.com/gist/rlan/acaec0f61b7bce7bd8b04eb208e0c691/twin-investing.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "s5Qt1nP0hLy4" | |
}, | |
"source": [ | |
"Suppose you have a twin. Say you start investing USD 10000 per year every year for 10 years and stop adding more. At which point, your twin starts and also USD 10,000 yearly. If no sales occur, who would have more money at 65? How does interest rate per year change the answer?" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "5aRSBb5Vib7l" | |
}, | |
"source": [ | |
"#@title Parameters\n", | |
"\n", | |
"start_age = 30#@param {type: \"number\"}\n", | |
"twin_start_age = 40#@param {type: \"number\"}\n", | |
"end_age = 65 #@param {type: \"number\"}\n", | |
"yearly = 10000 #@param {type: \"number\"}\n", | |
"interest_rate = 0.06 #@param {type: \"number\"}\n", | |
"\n", | |
"#@markdown ---\n", | |
"\n" | |
], | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "uFqzq-8kkNiM" | |
}, | |
"source": [ | |
"import seaborn as sns\n", | |
"import pandas as pd\n", | |
"import matplotlib.pyplot as plt" | |
], | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "JVlbksmFiRV5" | |
}, | |
"source": [ | |
"assert twin_start_age > start_age\n", | |
"age = [x for x in range(start_age, end_age)]" | |
], | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "xNbMiYpDoUHR" | |
}, | |
"source": [ | |
"contrib = [yearly]*(twin_start_age - start_age) + [0]*(end_age-twin_start_age)\n", | |
"contrib_twin = [0]*(twin_start_age - start_age) + [yearly]*(end_age-twin_start_age)" | |
], | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "eGW3QMasjQkf" | |
}, | |
"source": [ | |
"def calc_balance(contrib, interest_rate):\n", | |
" assert interest_rate < 1\n", | |
" assert interest_rate > 0\n", | |
" balance = [0.0]*len(contrib)\n", | |
" for idx in range(len(balance)):\n", | |
" if idx == 0:\n", | |
" balance[idx] = contrib[idx]\n", | |
" else:\n", | |
" balance[idx] = balance[idx-1]*(1 + interest_rate) + contrib[idx]\n", | |
" return balance\n", | |
"balance = calc_balance(contrib, interest_rate)\n", | |
"balance_twin = calc_balance(contrib_twin, interest_rate)" | |
], | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "ordVl3IzkboL" | |
}, | |
"source": [ | |
"# Plot\n", | |
"df = pd.DataFrame.from_dict({'Age':age, 'Contribution':contrib, 'Who':'You'})\n", | |
"df_twin = pd.DataFrame.from_dict({'Age':age, 'Contribution':contrib_twin, 'Who':'Twin'})\n", | |
"both = pd.concat([df, df_twin], ignore_index=True)\n", | |
"sns.relplot(data=both, x='Age', y='Contribution', hue='Who')\n", | |
"plt.show()\n", | |
"df = pd.DataFrame.from_dict({'Age':age, 'Balance':balance, 'Who':'You'})\n", | |
"df_twin = pd.DataFrame.from_dict({'Age':age, 'Balance':balance_twin, 'Who':'Twin'})\n", | |
"both = pd.concat([df, df_twin], ignore_index=True)\n", | |
"ax = sns.lineplot(data=both, x='Age', y='Balance', hue='Who')\n", | |
"ax.set_title(f'Interest rate {interest_rate*100}%')\n", | |
"plt.show()" | |
], | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "6TSdxdOEk-Uz" | |
}, | |
"source": [ | |
"" | |
], | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "Xl1bfYvCuwMB" | |
}, | |
"source": [ | |
"Given that retirement age is far away enough, there will be an interest rate that creates a tie. With a higher one, you will win because money has been in the market longer, due to compound interest. With a lower one, your twin will win because of more contribution total. Which person would you want to be?" | |
] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment