ml-finance-python
python scripts for finance machine learning
git clone https://9o.is/git/ml-finance-python.git
lab_109.ipynb
(39351B)
1 {
2 "cells": [
3 {
4 "cell_type": "markdown",
5 "metadata": {},
6 "source": [
7 "# Efficient Frontier - Part III - Running the Optimizer\n",
8 "\n",
9 "In order to plot the frontier for portfolios with more than 2 assets, we need to find the weights of the portfolio on the efficient frontier.\n",
10 "\n",
11 "We start by creating the same sort of function that we already created for the 2 asset case:\n",
12 "\n",
13 "```python\n",
14 "\n",
15 "def plot_ef(n_points, er, cov):\n",
16 " \"\"\"\n",
17 " Plots the multi-asset efficient frontier\n",
18 " \"\"\"\n",
19 " weights = ???? # we need to implement: optimal_weights(n_points, er, cov)\n",
20 " rets = [portfolio_return(w, er) for w in weights]\n",
21 " vols = [portfolio_vol(w, cov) for w in weights]\n",
22 " ef = pd.DataFrame({\n",
23 " \"Returns\": rets, \n",
24 " \"Volatility\": vols\n",
25 " })\n",
26 " return ef.plot.line(x=\"Volatility\", y=\"Returns\", style='.-')\n",
27 "```\n",
28 "\n",
29 "But let's start by loading up the data as usual:\n"
30 ]
31 },
32 {
33 "cell_type": "code",
34 "execution_count": 2,
35 "metadata": {},
36 "outputs": [],
37 "source": [
38 "%load_ext autoreload\n",
39 "%autoreload 2\n",
40 "%matplotlib inline\n",
41 "import edhec_risk_kit as erk\n",
42 "\n",
43 "ind = erk.get_ind_returns()\n",
44 "er = erk.annualize_rets(ind[\"1996\":\"2000\"], 12)\n",
45 "cov = ind[\"1996\":\"2000\"].cov()"
46 ]
47 },
48 {
49 "cell_type": "markdown",
50 "metadata": {},
51 "source": [
52 "In order to find the optimal weights, we need a function that will minimize the volatility for a given level of return.\n",
53 "\n",
54 "\n",
55 "```python\n",
56 "from scipy.optimize import minimize\n",
57 "\n",
58 "def minimize_vol(target_return, er, cov):\n",
59 " \"\"\"\n",
60 " Returns the optimal weights that achieve the target return\n",
61 " given a set of expected returns and a covariance matrix\n",
62 " \"\"\"\n",
63 " n = er.shape[0]\n",
64 " init_guess = np.repeat(1/n, n)\n",
65 " bounds = ((0.0, 1.0),) * n # an N-tuple of 2-tuples!\n",
66 " # construct the constraints\n",
67 " weights_sum_to_1 = {'type': 'eq',\n",
68 " 'fun': lambda weights: np.sum(weights) - 1\n",
69 " }\n",
70 " return_is_target = {'type': 'eq',\n",
71 " 'args': (er,),\n",
72 " 'fun': lambda weights, er: target_return - erk.portfolio_return(weights,er)\n",
73 " }\n",
74 " weights = minimize(erk.portfolio_vol, init_guess,\n",
75 " args=(cov,), method='SLSQP',\n",
76 " options={'disp': False},\n",
77 " constraints=(weights_sum_to_1,return_is_target),\n",
78 " bounds=bounds)\n",
79 " return weights.x\n",
80 "```\n",
81 "\n",
82 "Let's use this to recreate the result we got from frontier for the 2-Asset optimization between \"Games\" and \"Fin\". Let's plot that efficient frontier as we did last time:"
83 ]
84 },
85 {
86 "cell_type": "code",
87 "execution_count": 3,
88 "metadata": {},
89 "outputs": [
90 {
91 "data": {
92 "text/plain": [
93 "<matplotlib.axes._subplots.AxesSubplot at 0x1118de470>"
94 ]
95 },
96 "execution_count": 3,
97 "metadata": {},
98 "output_type": "execute_result"
99 },
100 {
101 "data": {
102 "image/png": "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\n",
103 "text/plain": [
104 "<Figure size 432x288 with 1 Axes>"
105 ]
106 },
107 "metadata": {
108 "needs_background": "light"
109 },
110 "output_type": "display_data"
111 }
112 ],
113 "source": [
114 "l = [\"Games\", \"Fin\"]\n",
115 "erk.plot_ef2(20, er[l], cov.loc[l,l])"
116 ]
117 },
118 {
119 "cell_type": "markdown",
120 "metadata": {},
121 "source": [
122 "The Efficient Frontier for the protfolio that has a target return of 0.15 is approx 0.056, so let's see if our optimizer is able to locate it."
123 ]
124 },
125 {
126 "cell_type": "code",
127 "execution_count": 4,
128 "metadata": {},
129 "outputs": [
130 {
131 "data": {
132 "text/plain": [
133 "0.056163669406706564"
134 ]
135 },
136 "execution_count": 4,
137 "metadata": {},
138 "output_type": "execute_result"
139 }
140 ],
141 "source": [
142 "weights_15 = erk.minimize_vol(0.15, er[l], cov.loc[l,l])\n",
143 "vol_15 = erk.portfolio_vol(weights_15, cov.loc[l,l])\n",
144 "vol_15"
145 ]
146 },
147 {
148 "cell_type": "markdown",
149 "metadata": {},
150 "source": [
151 "Perfect!\n",
152 "\n",
153 "Now that we can find the weights to minimize the vol given a target return, we can plot the efficient frontier by dividing up the range from the highest to the lowest possible return into a grid, and finding the portfolio that targets the minimum volatility given a particular targeted rate of return.\n",
154 "\n",
155 "Add these:\n",
156 "\n",
157 "```python\n",
158 "def optimal_weights(n_points, er, cov):\n",
159 " \"\"\"\n",
160 " \"\"\"\n",
161 " target_rs = np.linspace(er.min(), er.max(), n_points)\n",
162 " weights = [minimize_vol(target_return, er, cov) for target_return in target_rs]\n",
163 " return weights\n",
164 "\n",
165 "def plot_ef(n_points, er, cov):\n",
166 " \"\"\"\n",
167 " Plots the multi-asset efficient frontier\n",
168 " \"\"\"\n",
169 " weights = optimal_weights(n_points, er, cov) # not yet implemented!\n",
170 " rets = [portfolio_return(w, er) for w in weights]\n",
171 " vols = [portfolio_vol(w, cov) for w in weights]\n",
172 " ef = pd.DataFrame({\n",
173 " \"Returns\": rets, \n",
174 " \"Volatility\": vols\n",
175 " })\n",
176 " return ef.plot.line(x=\"Volatility\", y=\"Returns\", style='.-')\n",
177 "```\n"
178 ]
179 },
180 {
181 "cell_type": "code",
182 "execution_count": 12,
183 "metadata": {},
184 "outputs": [
185 {
186 "data": {
187 "text/plain": [
188 "<matplotlib.axes._subplots.AxesSubplot at 0x1a25d4a630>"
189 ]
190 },
191 "execution_count": 12,
192 "metadata": {},
193 "output_type": "execute_result"
194 },
195 {
196 "data": {
197 "image/png": "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\n",
198 "text/plain": [
199 "<Figure size 432x288 with 1 Axes>"
200 ]
201 },
202 "metadata": {
203 "needs_background": "light"
204 },
205 "output_type": "display_data"
206 }
207 ],
208 "source": [
209 "l = [\"Smoke\", \"Fin\", \"Games\", \"Coal\"]\n",
210 "erk.plot_ef(50, er[l], cov.loc[l,l])"
211 ]
212 },
213 {
214 "cell_type": "code",
215 "execution_count": null,
216 "metadata": {},
217 "outputs": [],
218 "source": []
219 }
220 ],
221 "metadata": {
222 "kernelspec": {
223 "display_name": "Python 3",
224 "language": "python",
225 "name": "python3"
226 },
227 "language_info": {
228 "codemirror_mode": {
229 "name": "ipython",
230 "version": 3
231 },
232 "file_extension": ".py",
233 "mimetype": "text/x-python",
234 "name": "python",
235 "nbconvert_exporter": "python",
236 "pygments_lexer": "ipython3",
237 "version": "3.8.8"
238 }
239 },
240 "nbformat": 4,
241 "nbformat_minor": 2
242 }