Skip to content

Instantly share code, notes, and snippets.

@DBremen
Last active January 2, 2020 12:13
Show Gist options
  • Save DBremen/b72b71275df72ec6c581d992a52e0619 to your computer and use it in GitHub Desktop.
Save DBremen/b72b71275df72ec6c581d992a52e0619 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "# Intro to Monte Carlo"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "<h1 id=\"tocheading\">Table of Contents</h1>\n<div id=\"toc\"></div>"
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "%%javascript\n$.getScript('https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js')",
"execution_count": 1,
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": "<IPython.core.display.Javascript object>",
"application/javascript": "$.getScript('https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js')\n"
},
"metadata": {}
}
]
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "import numpy as np\nimport pandas as pd\nimport pandas_datareader as pdr\nimport matplotlib.pyplot as plt\nimport matplotlib.ticker as mtick\nfrom pandas.plotting import register_matplotlib_converters\nregister_matplotlib_converters()\n#ax.yaxis.set_major_formatter(mtick.PercentFormatter())\npd.options.display.float_format = '${:,.2f}'.format\n%matplotlib inline\n#format DataFrame example\n#formatted = df.style.format({'EPS': '${:,.2f}', 'PE':'{:,.2f}', 'Exp_Ret': '{:,.2%}', 'Price': '${:,.2f}'})",
"execution_count": 2,
"outputs": []
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "# Suppose you have an IRA currently valued at $100,000 invested in the S&P500 ETF. \n# You plan to retire in 30 years.\n# How much should you expect to have in your retirement account\n\npresentValue = 100000\nexpectedReturn = .095\ntimeInYears = 30\nending_balance = 0",
"execution_count": 3,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Deterministic approach with fixed expected return"
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "presentValue = 100000\nexpectedReturn = .095\ntimeInYears = 30\nending_balance = 0\ndata = pd.DataFrame({'Year':range(1, timeInYears + 1),'Ending Balance': np.zeros(timeInYears)})\nfor index, row in data.iterrows():\n if index == 0:\n data.loc[index,'Ending Balance'] = presentValue * (1+ expectedReturn)\n else:\n data.loc[index,'Ending Balance'] = data['Ending Balance'][index-1] * (1+ expectedReturn)\ndata",
"execution_count": 34,
"outputs": [
{
"output_type": "execute_result",
"execution_count": 34,
"data": {
"text/plain": " Year Ending Balance\n0 1 $109,500.00\n1 2 $119,902.50\n2 3 $131,293.24\n3 4 $143,766.10\n4 5 $157,423.87\n5 6 $172,379.14\n6 7 $188,755.16\n7 8 $206,686.90\n8 9 $226,322.16\n9 10 $247,822.76\n10 11 $271,365.92\n11 12 $297,145.69\n12 13 $325,374.53\n13 14 $356,285.11\n14 15 $390,132.19\n15 16 $427,194.75\n16 17 $467,778.25\n17 18 $512,217.19\n18 19 $560,877.82\n19 20 $614,161.21\n20 21 $672,506.53\n21 22 $736,394.65\n22 23 $806,352.14\n23 24 $882,955.59\n24 25 $966,836.37\n25 26 $1,058,685.83\n26 27 $1,159,260.98\n27 28 $1,269,390.77\n28 29 $1,389,982.90\n29 30 $1,522,031.27",
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Year</th>\n <th>Ending Balance</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>0</td>\n <td>1</td>\n <td>$109,500.00</td>\n </tr>\n <tr>\n <td>1</td>\n <td>2</td>\n <td>$119,902.50</td>\n </tr>\n <tr>\n <td>2</td>\n <td>3</td>\n <td>$131,293.24</td>\n </tr>\n <tr>\n <td>3</td>\n <td>4</td>\n <td>$143,766.10</td>\n </tr>\n <tr>\n <td>4</td>\n <td>5</td>\n <td>$157,423.87</td>\n </tr>\n <tr>\n <td>5</td>\n <td>6</td>\n <td>$172,379.14</td>\n </tr>\n <tr>\n <td>6</td>\n <td>7</td>\n <td>$188,755.16</td>\n </tr>\n <tr>\n <td>7</td>\n <td>8</td>\n <td>$206,686.90</td>\n </tr>\n <tr>\n <td>8</td>\n <td>9</td>\n <td>$226,322.16</td>\n </tr>\n <tr>\n <td>9</td>\n <td>10</td>\n <td>$247,822.76</td>\n </tr>\n <tr>\n <td>10</td>\n <td>11</td>\n <td>$271,365.92</td>\n </tr>\n <tr>\n <td>11</td>\n <td>12</td>\n <td>$297,145.69</td>\n </tr>\n <tr>\n <td>12</td>\n <td>13</td>\n <td>$325,374.53</td>\n </tr>\n <tr>\n <td>13</td>\n <td>14</td>\n <td>$356,285.11</td>\n </tr>\n <tr>\n <td>14</td>\n <td>15</td>\n <td>$390,132.19</td>\n </tr>\n <tr>\n <td>15</td>\n <td>16</td>\n <td>$427,194.75</td>\n </tr>\n <tr>\n <td>16</td>\n <td>17</td>\n <td>$467,778.25</td>\n </tr>\n <tr>\n <td>17</td>\n <td>18</td>\n <td>$512,217.19</td>\n </tr>\n <tr>\n <td>18</td>\n <td>19</td>\n <td>$560,877.82</td>\n </tr>\n <tr>\n <td>19</td>\n <td>20</td>\n <td>$614,161.21</td>\n </tr>\n <tr>\n <td>20</td>\n <td>21</td>\n <td>$672,506.53</td>\n </tr>\n <tr>\n <td>21</td>\n <td>22</td>\n <td>$736,394.65</td>\n </tr>\n <tr>\n <td>22</td>\n <td>23</td>\n <td>$806,352.14</td>\n </tr>\n <tr>\n <td>23</td>\n <td>24</td>\n <td>$882,955.59</td>\n </tr>\n <tr>\n <td>24</td>\n <td>25</td>\n <td>$966,836.37</td>\n </tr>\n <tr>\n <td>25</td>\n <td>26</td>\n <td>$1,058,685.83</td>\n </tr>\n <tr>\n <td>26</td>\n <td>27</td>\n <td>$1,159,260.98</td>\n </tr>\n <tr>\n <td>27</td>\n <td>28</td>\n <td>$1,269,390.77</td>\n </tr>\n <tr>\n <td>28</td>\n <td>29</td>\n <td>$1,389,982.90</td>\n </tr>\n <tr>\n <td>29</td>\n <td>30</td>\n <td>$1,522,031.27</td>\n </tr>\n </tbody>\n</table>\n</div>"
},
"metadata": {}
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Incorporating volatile rate of return"
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "# instead of a guaranteed return there will be a distribution of possible returns\n# assume a normal distribution\n# But can we reliably earn 9.5% every year?\n# We need to incorporate volatility\nvolatility = .185\nimport numpy.random as npr\npv = 100000\ner = .095\ntime_horizon = 30\nending_balance = 0\n\nprint(\"{:10s} {:15s}\".format(\"Year\", \"Ending Balance\"))\nprint(\"-\" * 26)\nfor year in range(1,time_horizon + 1):\n year_return = npr.normal(er,volatility)\n ending_balance = pv * (1 + year_return)\n print(\"{:<10d} {:>15,.0f}\".format(year, ending_balance))\n pv = ending_balance",
"execution_count": 35,
"outputs": [
{
"output_type": "stream",
"text": "Year Ending Balance \n--------------------------\n1 94,379\n2 44,016\n3 46,420\n4 46,603\n5 57,057\n6 74,356\n7 64,585\n8 58,505\n9 69,584\n10 91,668\n11 114,435\n12 146,743\n13 108,014\n14 106,605\n15 135,347\n16 132,782\n17 119,679\n18 113,605\n19 154,929\n20 153,161\n21 139,243\n22 146,742\n23 225,351\n24 283,669\n25 332,662\n26 348,899\n27 297,747\n28 389,702\n29 305,516\n30 381,830\n",
"name": "stdout"
}
]
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "# instead of a guaranteed return there will be a distribution of possible returns\n# assume a normal distribution\n# But can we reliably earn 9.5% every year?\n# We need to incorporate volatility\n# this is a conservative value incorparting inflation, too.\nstddev = .185\nimport numpy.random as npr\npv = 100000\ner = .095\ntime_horizon = 30\nending_balance = 0\ndata = pd.DataFrame({'Year':range(1, timeInYears + 1),'Ending Balance': np.zeros(timeInYears)})\nfor index, row in data.iterrows():\n # get the current year's return based on a normal distribution with mean of expected return\n # and stddev of 18.5%\n year_return = npr.normal(er,stddev)\n if index == 0:\n data.loc[index,'Ending Balance'] = presentValue * (1+ year_return)\n else:\n data.loc[index,'Ending Balance'] = data['Ending Balance'][index-1] * (1+ year_return)\ndata",
"execution_count": 38,
"outputs": [
{
"output_type": "execute_result",
"execution_count": 38,
"data": {
"text/plain": " Year Ending Balance\n0 1 $104,045.29\n1 2 $84,159.82\n2 3 $112,840.65\n3 4 $132,269.04\n4 5 $172,723.84\n5 6 $191,791.20\n6 7 $252,896.71\n7 8 $273,441.81\n8 9 $315,665.40\n9 10 $380,839.68\n10 11 $492,011.39\n11 12 $468,710.67\n12 13 $424,575.03\n13 14 $398,408.77\n14 15 $406,800.07\n15 16 $516,665.24\n16 17 $594,145.43\n17 18 $666,060.10\n18 19 $861,120.10\n19 20 $1,022,812.85\n20 21 $1,455,400.73\n21 22 $1,400,135.15\n22 23 $1,727,054.08\n23 24 $1,906,663.11\n24 25 $2,037,939.14\n25 26 $1,925,371.73\n26 27 $1,426,560.52\n27 28 $1,484,375.46\n28 29 $1,322,579.35\n29 30 $1,593,705.87",
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Year</th>\n <th>Ending Balance</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>0</td>\n <td>1</td>\n <td>$104,045.29</td>\n </tr>\n <tr>\n <td>1</td>\n <td>2</td>\n <td>$84,159.82</td>\n </tr>\n <tr>\n <td>2</td>\n <td>3</td>\n <td>$112,840.65</td>\n </tr>\n <tr>\n <td>3</td>\n <td>4</td>\n <td>$132,269.04</td>\n </tr>\n <tr>\n <td>4</td>\n <td>5</td>\n <td>$172,723.84</td>\n </tr>\n <tr>\n <td>5</td>\n <td>6</td>\n <td>$191,791.20</td>\n </tr>\n <tr>\n <td>6</td>\n <td>7</td>\n <td>$252,896.71</td>\n </tr>\n <tr>\n <td>7</td>\n <td>8</td>\n <td>$273,441.81</td>\n </tr>\n <tr>\n <td>8</td>\n <td>9</td>\n <td>$315,665.40</td>\n </tr>\n <tr>\n <td>9</td>\n <td>10</td>\n <td>$380,839.68</td>\n </tr>\n <tr>\n <td>10</td>\n <td>11</td>\n <td>$492,011.39</td>\n </tr>\n <tr>\n <td>11</td>\n <td>12</td>\n <td>$468,710.67</td>\n </tr>\n <tr>\n <td>12</td>\n <td>13</td>\n <td>$424,575.03</td>\n </tr>\n <tr>\n <td>13</td>\n <td>14</td>\n <td>$398,408.77</td>\n </tr>\n <tr>\n <td>14</td>\n <td>15</td>\n <td>$406,800.07</td>\n </tr>\n <tr>\n <td>15</td>\n <td>16</td>\n <td>$516,665.24</td>\n </tr>\n <tr>\n <td>16</td>\n <td>17</td>\n <td>$594,145.43</td>\n </tr>\n <tr>\n <td>17</td>\n <td>18</td>\n <td>$666,060.10</td>\n </tr>\n <tr>\n <td>18</td>\n <td>19</td>\n <td>$861,120.10</td>\n </tr>\n <tr>\n <td>19</td>\n <td>20</td>\n <td>$1,022,812.85</td>\n </tr>\n <tr>\n <td>20</td>\n <td>21</td>\n <td>$1,455,400.73</td>\n </tr>\n <tr>\n <td>21</td>\n <td>22</td>\n <td>$1,400,135.15</td>\n </tr>\n <tr>\n <td>22</td>\n <td>23</td>\n <td>$1,727,054.08</td>\n </tr>\n <tr>\n <td>23</td>\n <td>24</td>\n <td>$1,906,663.11</td>\n </tr>\n <tr>\n <td>24</td>\n <td>25</td>\n <td>$2,037,939.14</td>\n </tr>\n <tr>\n <td>25</td>\n <td>26</td>\n <td>$1,925,371.73</td>\n </tr>\n <tr>\n <td>26</td>\n <td>27</td>\n <td>$1,426,560.52</td>\n </tr>\n <tr>\n <td>27</td>\n <td>28</td>\n <td>$1,484,375.46</td>\n </tr>\n <tr>\n <td>28</td>\n <td>29</td>\n <td>$1,322,579.35</td>\n </tr>\n <tr>\n <td>29</td>\n <td>30</td>\n <td>$1,593,705.87</td>\n </tr>\n </tbody>\n</table>\n</div>"
},
"metadata": {}
}
]
}
],
"metadata": {
"kernelspec": {
"name": "python3",
"display_name": "Python 3",
"language": "python"
},
"toc": {
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": false,
"base_numbering": 1,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": false
},
"language_info": {
"name": "python",
"version": "3.7.4",
"mimetype": "text/x-python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"nbconvert_exporter": "python",
"file_extension": ".py"
},
"gist": {
"id": "b72b71275df72ec6c581d992a52e0619",
"data": {
"description": "Intro to Monte Carlo https://nbviewer.jupyter.org/gist/DBremen/b72b71275df72ec6c581d992a52e0619",
"public": true
}
},
"_draft": {
"nbviewer_url": "https://gist.github.com/b72b71275df72ec6c581d992a52e0619"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment