Last active
January 2, 2020 12:13
-
-
Save DBremen/b72b71275df72ec6c581d992a52e0619 to your computer and use it in GitHub Desktop.
Intro to Monte Carlo https://nbviewer.jupyter.org/gist/DBremen/b72b71275df72ec6c581d992a52e0619
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
{ | |
"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