ml-finance-python

python scripts for finance machine learning

git clone https://9o.is/git/ml-finance-python.git

lab_108.ipynb

(35618B)


      1 {
      2  "cells": [
      3   {
      4    "cell_type": "markdown",
      5    "metadata": {},
      6    "source": [
      7     "# The Efficient Frontier - Part II\n",
      8     "\n",
      9     "Let's start by loading the returns and generating the expected returns vector and the covariance matrix"
     10    ]
     11   },
     12   {
     13    "cell_type": "code",
     14    "execution_count": 1,
     15    "metadata": {},
     16    "outputs": [],
     17    "source": [
     18     "%load_ext autoreload\n",
     19     "%autoreload 2\n",
     20     "%matplotlib inline\n",
     21     "import edhec_risk_kit as erk\n",
     22     "\n",
     23     "ind = erk.get_ind_returns()\n",
     24     "er = erk.annualize_rets(ind[\"1996\":\"2000\"], 12)\n",
     25     "cov = ind[\"1996\":\"2000\"].cov()"
     26    ]
     27   },
     28   {
     29    "cell_type": "markdown",
     30    "metadata": {},
     31    "source": [
     32     "As a first exercise, let's assume we have some weights, and let's try and compute the returns and volatility of a portfolio, given a set of weights, returns, and a covariance matrix.\n",
     33     "\n",
     34     "The returns are easy, so let's add this to our toolkit\n",
     35     "\n",
     36     "```python\n",
     37     "\n",
     38     "def portfolio_return(weights, returns):\n",
     39     "    \"\"\"\n",
     40     "    Computes the return on a portfolio from constituent returns and weights\n",
     41     "    weights are a numpy array or Nx1 matrix and returns are a numpy array or Nx1 matrix\n",
     42     "    \"\"\"\n",
     43     "    return weights.T @ returns\n",
     44     "\n",
     45     "```\n",
     46     "\n",
     47     "The volatility is just as easy in matrix form:\n",
     48     "\n",
     49     "```python\n",
     50     "def portfolio_vol(weights, covmat):\n",
     51     "    \"\"\"\n",
     52     "    Computes the vol of a portfolio from a covariance matrix and constituent weights\n",
     53     "    weights are a numpy array or N x 1 maxtrix and covmat is an N x N matrix\n",
     54     "    \"\"\"\n",
     55     "    return (weights.T @ covmat @ weights)**0.5\n",
     56     "```\n",
     57     "\n"
     58    ]
     59   },
     60   {
     61    "cell_type": "code",
     62    "execution_count": 2,
     63    "metadata": {},
     64    "outputs": [],
     65    "source": [
     66     "l = [\"Food\", \"Beer\", \"Smoke\", \"Coal\"]"
     67    ]
     68   },
     69   {
     70    "cell_type": "code",
     71    "execution_count": 3,
     72    "metadata": {},
     73    "outputs": [
     74     {
     75      "data": {
     76       "text/plain": [
     77        "Food     0.116799\n",
     78        "Beer     0.141126\n",
     79        "Smoke    0.107830\n",
     80        "Coal     0.414689\n",
     81        "dtype: float64"
     82       ]
     83      },
     84      "execution_count": 3,
     85      "metadata": {},
     86      "output_type": "execute_result"
     87     }
     88    ],
     89    "source": [
     90     "er[l]"
     91    ]
     92   },
     93   {
     94    "cell_type": "code",
     95    "execution_count": 4,
     96    "metadata": {},
     97    "outputs": [
     98     {
     99      "data": {
    100       "text/html": [
    101        "<div>\n",
    102        "<style scoped>\n",
    103        "    .dataframe tbody tr th:only-of-type {\n",
    104        "        vertical-align: middle;\n",
    105        "    }\n",
    106        "\n",
    107        "    .dataframe tbody tr th {\n",
    108        "        vertical-align: top;\n",
    109        "    }\n",
    110        "\n",
    111        "    .dataframe thead th {\n",
    112        "        text-align: right;\n",
    113        "    }\n",
    114        "</style>\n",
    115        "<table border=\"1\" class=\"dataframe\">\n",
    116        "  <thead>\n",
    117        "    <tr style=\"text-align: right;\">\n",
    118        "      <th></th>\n",
    119        "      <th>Food</th>\n",
    120        "      <th>Beer</th>\n",
    121        "      <th>Smoke</th>\n",
    122        "      <th>Coal</th>\n",
    123        "    </tr>\n",
    124        "  </thead>\n",
    125        "  <tbody>\n",
    126        "    <tr>\n",
    127        "      <th>Food</th>\n",
    128        "      <td>0.002609</td>\n",
    129        "      <td>0.002379</td>\n",
    130        "      <td>0.002061</td>\n",
    131        "      <td>0.000027</td>\n",
    132        "    </tr>\n",
    133        "    <tr>\n",
    134        "      <th>Beer</th>\n",
    135        "      <td>0.002379</td>\n",
    136        "      <td>0.005264</td>\n",
    137        "      <td>0.001359</td>\n",
    138        "      <td>0.001728</td>\n",
    139        "    </tr>\n",
    140        "    <tr>\n",
    141        "      <th>Smoke</th>\n",
    142        "      <td>0.002061</td>\n",
    143        "      <td>0.001359</td>\n",
    144        "      <td>0.008349</td>\n",
    145        "      <td>-0.000733</td>\n",
    146        "    </tr>\n",
    147        "    <tr>\n",
    148        "      <th>Coal</th>\n",
    149        "      <td>0.000027</td>\n",
    150        "      <td>0.001728</td>\n",
    151        "      <td>-0.000733</td>\n",
    152        "      <td>0.018641</td>\n",
    153        "    </tr>\n",
    154        "  </tbody>\n",
    155        "</table>\n",
    156        "</div>"
    157       ],
    158       "text/plain": [
    159        "           Food      Beer     Smoke      Coal\n",
    160        "Food   0.002609  0.002379  0.002061  0.000027\n",
    161        "Beer   0.002379  0.005264  0.001359  0.001728\n",
    162        "Smoke  0.002061  0.001359  0.008349 -0.000733\n",
    163        "Coal   0.000027  0.001728 -0.000733  0.018641"
    164       ]
    165      },
    166      "execution_count": 4,
    167      "metadata": {},
    168      "output_type": "execute_result"
    169     }
    170    ],
    171    "source": [
    172     "cov.loc[l,l]"
    173    ]
    174   },
    175   {
    176    "cell_type": "code",
    177    "execution_count": 5,
    178    "metadata": {},
    179    "outputs": [
    180     {
    181      "data": {
    182       "text/plain": [
    183        "0.19511097196038385"
    184       ]
    185      },
    186      "execution_count": 5,
    187      "metadata": {},
    188      "output_type": "execute_result"
    189     }
    190    ],
    191    "source": [
    192     "import pandas as pd\n",
    193     "import numpy as np\n",
    194     "ew = np.repeat(0.25, 4)\n",
    195     "erk.portfolio_return(ew, er[l])"
    196    ]
    197   },
    198   {
    199    "cell_type": "code",
    200    "execution_count": 6,
    201    "metadata": {},
    202    "outputs": [
    203     {
    204      "data": {
    205       "text/plain": [
    206        "0.055059195776437045"
    207       ]
    208      },
    209      "execution_count": 6,
    210      "metadata": {},
    211      "output_type": "execute_result"
    212     }
    213    ],
    214    "source": [
    215     "erk.portfolio_vol(ew, cov.loc[l,l])"
    216    ]
    217   },
    218   {
    219    "cell_type": "markdown",
    220    "metadata": {},
    221    "source": [
    222     "# The 2-Asset Case\n",
    223     "\n",
    224     "In the case of 2 assets, the problem is somewhat simplified, since the weight of the second asset is 1-the weight of the first asset.\n",
    225     "\n",
    226     "Let's write a function that draws the efficient frontier for a simple 2 asset case.\n",
    227     "\n",
    228     "Start by generating a sequence of weights in a list of tuples. Python makes it easy to generate a list by using something called a _list comprehension_ ... which you can think of as an efficient way to generate a list of values instead of writing a for loop.\n"
    229    ]
    230   },
    231   {
    232    "cell_type": "code",
    233    "execution_count": 7,
    234    "metadata": {},
    235    "outputs": [],
    236    "source": [
    237     "import numpy as np\n",
    238     "\n",
    239     "n_points = 20\n",
    240     "weights = [np.array([w, 1-w]) for w in np.linspace(0, 1, n_points)]\n"
    241    ]
    242   },
    243   {
    244    "cell_type": "code",
    245    "execution_count": 8,
    246    "metadata": {},
    247    "outputs": [
    248     {
    249      "data": {
    250       "text/plain": [
    251        "list"
    252       ]
    253      },
    254      "execution_count": 8,
    255      "metadata": {},
    256      "output_type": "execute_result"
    257     }
    258    ],
    259    "source": [
    260     "type(weights)"
    261    ]
    262   },
    263   {
    264    "cell_type": "code",
    265    "execution_count": 9,
    266    "metadata": {},
    267    "outputs": [
    268     {
    269      "data": {
    270       "text/plain": [
    271        "20"
    272       ]
    273      },
    274      "execution_count": 9,
    275      "metadata": {},
    276      "output_type": "execute_result"
    277     }
    278    ],
    279    "source": [
    280     "len(weights)"
    281    ]
    282   },
    283   {
    284    "cell_type": "code",
    285    "execution_count": 10,
    286    "metadata": {},
    287    "outputs": [
    288     {
    289      "data": {
    290       "text/plain": [
    291        "array([0., 1.])"
    292       ]
    293      },
    294      "execution_count": 10,
    295      "metadata": {},
    296      "output_type": "execute_result"
    297     }
    298    ],
    299    "source": [
    300     "weights[0]"
    301    ]
    302   },
    303   {
    304    "cell_type": "code",
    305    "execution_count": 11,
    306    "metadata": {},
    307    "outputs": [
    308     {
    309      "data": {
    310       "text/plain": [
    311        "array([0.21052632, 0.78947368])"
    312       ]
    313      },
    314      "execution_count": 11,
    315      "metadata": {},
    316      "output_type": "execute_result"
    317     }
    318    ],
    319    "source": [
    320     "weights[4]"
    321    ]
    322   },
    323   {
    324    "cell_type": "code",
    325    "execution_count": 12,
    326    "metadata": {},
    327    "outputs": [
    328     {
    329      "data": {
    330       "text/plain": [
    331        "array([1., 0.])"
    332       ]
    333      },
    334      "execution_count": 12,
    335      "metadata": {},
    336      "output_type": "execute_result"
    337     }
    338    ],
    339    "source": [
    340     "weights[19]"
    341    ]
    342   },
    343   {
    344    "cell_type": "code",
    345    "execution_count": 13,
    346    "metadata": {},
    347    "outputs": [
    348     {
    349      "data": {
    350       "text/plain": [
    351        "<matplotlib.axes._subplots.AxesSubplot at 0x1a1cc43c18>"
    352       ]
    353      },
    354      "execution_count": 13,
    355      "metadata": {},
    356      "output_type": "execute_result"
    357     },
    358     {
    359      "data": {
    360       "image/png": "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\n",
    361       "text/plain": [
    362        "<Figure size 432x288 with 1 Axes>"
    363       ]
    364      },
    365      "metadata": {
    366       "needs_background": "light"
    367      },
    368      "output_type": "display_data"
    369     }
    370    ],
    371    "source": [
    372     "l = [\"Games\", \"Fin\"]\n",
    373     "rets = [erk.portfolio_return(w, er[l]) for w in weights]\n",
    374     "vols = [erk.portfolio_vol(w, cov.loc[l,l]) for w in weights]\n",
    375     "ef = pd.DataFrame({\"R\": rets, \"V\": vols})\n",
    376     "ef.plot.scatter(x=\"V\", y=\"R\")"
    377    ]
    378   },
    379   {
    380    "cell_type": "markdown",
    381    "metadata": {},
    382    "source": [
    383     "We can create function that plots the frontier:\n",
    384     "\n",
    385     "```python\n",
    386     "def plot_ef2(n_points, er, cov):\n",
    387     "    \"\"\"\n",
    388     "    Plots the 2-asset efficient frontier\n",
    389     "    \"\"\"\n",
    390     "    if er.shape[0] != 2 or er.shape[0] != 2:\n",
    391     "        raise ValueError(\"plot_ef2 can only plot 2-asset frontiers\")\n",
    392     "    weights = [np.array([w, 1-w]) for w in np.linspace(0, 1, n_points)]\n",
    393     "    rets = [portfolio_return(w, er) for w in weights]\n",
    394     "    vols = [portfolio_vol(w, cov) for w in weights]\n",
    395     "    ef = pd.DataFrame({\n",
    396     "        \"Returns\": rets, \n",
    397     "        \"Volatility\": vols\n",
    398     "    })\n",
    399     "    return ef.plot.line(x=\"Volatility\", y=\"Returns\", style=\".-\")\n",
    400     "```\n",
    401     "\n",
    402     "A useful summary of the visualization features in pandas is [here](https://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html)\n"
    403    ]
    404   },
    405   {
    406    "cell_type": "code",
    407    "execution_count": 14,
    408    "metadata": {},
    409    "outputs": [
    410     {
    411      "data": {
    412       "text/plain": [
    413        "<matplotlib.axes._subplots.AxesSubplot at 0x1a1cd7bc88>"
    414       ]
    415      },
    416      "execution_count": 14,
    417      "metadata": {},
    418      "output_type": "execute_result"
    419     },
    420     {
    421      "data": {
    422       "image/png": "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\n",
    423       "text/plain": [
    424        "<Figure size 432x288 with 1 Axes>"
    425       ]
    426      },
    427      "metadata": {
    428       "needs_background": "light"
    429      },
    430      "output_type": "display_data"
    431     }
    432    ],
    433    "source": [
    434     "l = [\"Fin\", \"Beer\"]\n",
    435     "erk.plot_ef2(25, er[l].values, cov.loc[l,l])"
    436    ]
    437   },
    438   {
    439    "cell_type": "code",
    440    "execution_count": null,
    441    "metadata": {},
    442    "outputs": [],
    443    "source": []
    444   }
    445  ],
    446  "metadata": {
    447   "kernelspec": {
    448    "display_name": "Python 3",
    449    "language": "python",
    450    "name": "python3"
    451   },
    452   "language_info": {
    453    "codemirror_mode": {
    454     "name": "ipython",
    455     "version": 3
    456    },
    457    "file_extension": ".py",
    458    "mimetype": "text/x-python",
    459    "name": "python",
    460    "nbconvert_exporter": "python",
    461    "pygments_lexer": "ipython3",
    462    "version": "3.8.8"
    463   }
    464  },
    465  "nbformat": 4,
    466  "nbformat_minor": 2
    467 }