Last active
December 12, 2020 14:52
-
-
Save Financioneroncios/2bc449962757fe868848c450bf759128 to your computer and use it in GitHub Desktop.
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": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Equity Risk Factors Models with Python\n", | |
"### Portfolio Optimization Part III\n", | |
"<br>__[Financionerioncios](https://financioneroncios.wordpress.com)__\n", | |
"<br>__[Dany Cajas](https://www.linkedin.com/in/dany-cajas/)__\n", | |
"<br>__[Riskfolio-Lib](http://riskfolio-lib.readthedocs.io/)__\n", | |
"<br>__[Practical Econometrics with Python](https://www.amazon.com/-/es/Marlon-Saito-ebook/dp/B08KJ1322G/ref=sr_1_1?dchild=1&qid=1603904149&refinements=p_27%3AMarlon+Saito&s=digital-text&sr=1-1&text=Marlon+Saito)__ \n", | |
"<br>__[Econometría Práctica con Python](https://www.amazon.com/-/es/Marlon-Saito-ebook/dp/B08KHZKV9R/ref=sr_1_2?dchild=1&qid=1603903646&refinements=p_27%3AMarlon+Saito&s=digital-text&sr=1-2&text=Marlon+Saito)__ \n", | |
"\n", | |
"<br>Hola gente, espero les guste este post que es de mis temas favoritos =D. No se olviden que para Python les recomiendo que usen __[winpython](https://winpython.github.io/)__ (solo windows, pero es portable) o __[anaconda](https://www.anaconda.com/download/)__ (es multiplataforma, pero requiere de instalación). Al instalar cualquiera de estas distribuciones encontraran los ejecutables Jupyter Notebook (el formato del post, los archivos tienen extensión es .ipynb) y Spyder (IDE que recomiendo para trabajar porque permite visualizar las variables y su tipo, los archivos tienen extensión es .py)\n", | |
"\n", | |
"En la página del blog dejaré los notebooks (se abren con jupyter notebook), los scripts de python (recomiendo que usen spyder para trabajar con estos archivos) y los archivos en excel con la data usada en los ejemplos.\n", | |
"\n", | |
"Los temas que trataremos en este post son:\n", | |
"1. Modelo de Capital Asset Princing Model (CAPM).\n", | |
" 1. Formulación del Modelo.\n", | |
" 1. Estimación de los parámetros del modelo de media varianza.\n", | |
"2. Modelo de Factores de Riesgo.\n", | |
" 1. Formulación del Modelo.\n", | |
" 1. Estimación de los parámetros del modelo de media varianza.\n", | |
"\n", | |
"## 1. Modelo CAPM\n", | |
"\n", | |
"### 1. Formulación del Modelo\n", | |
"\n", | |
"El modelo CAPM propuesto por Sharpe, busca explicar el retorno de los activos como una función del activo libre de riesgo, un coeficiente $\\beta_a$ y la prima de riesgo de mercado.\n", | |
"<br>\n", | |
"<br>$$ r_a = r_f + \\beta_a (r_m - r_f) + \\epsilon $$\n", | |
"<br> \n", | |
"Donde:\n", | |
"<br>$r_a:$ es el retorno del activo a.\n", | |
"<br>$r_f:$ es la tasa libre de riesgo.\n", | |
"<br>$r_m:$ es el retorno del mercado.\n", | |
"<br>$r_m-r_f:$ es la prima de riesgo del mercado.\n", | |
"<br>$\\epsilon:$ es el error de estimación del modelo.\n", | |
"\n", | |
"El termino $\\beta_a$ es calculado mediante una regresión entre el rendimiento del activo y el rendimiento de un indice de mercado (usualmente el S&P500), por lo que la formula para calcular el $\\beta_a$ es la siguiente:\n", | |
"<br>\n", | |
"<br>$$ \\beta_a= \\frac{cov(r_a,r_m)}{\\sigma_m^2} = \\rho_{a,m}\\frac{\\sigma_a}{\\sigma_m}$$\n", | |
"<br> \n", | |
"Donde:\n", | |
"<br>$cov(r_a,r_m):$ es la covarianza entre los retornos del activo y los retornos del mercado.\n", | |
"<br>$\\rho_{a,m}:$ es la correlación entre los retornos del activo y los retornos del mercado.\n", | |
"<br>$\\sigma_m:$ es la desviación estándar de los retornos del mercado o la volatilidad del mercado.\n", | |
"<br>$\\sigma_a:$ es la desviación estándar de los retornos del activo o la volatilidad del activo.\n", | |
"\n", | |
"### 2. Estimación de los parámetros del modelo de media varianza.\n", | |
"\n", | |
"A partir del modelo CAPM podemos estimar los inputs del modelo de media varianza o modelo de Markowitz.\n", | |
"\n", | |
"El vector de medias de medias y la matriz de covarianzas pueden estimarse con las siguientes formulas:\n", | |
"<br>\n", | |
"\n", | |
"$$\n", | |
"\\begin{equation*}\n", | |
"\\begin{gathered}\n", | |
"E(r) = r_f + B E(r_m - r_f) \\\\\n", | |
"\\\\\n", | |
"\\Sigma = B \\sigma_{r_m - r_f} B^T + \\Sigma_{\\epsilon} \\\\\n", | |
"\\\\\n", | |
"E(r) = \\begin{bmatrix} E(r_{1}) \\\\ E(r_{2}) \\\\ \\vdots \\\\ E(r_{N}) \\end{bmatrix} \\; \\; , \\; \\;\n", | |
"\\alpha = \\begin{bmatrix} \\alpha_{1} \\\\ \\alpha_{2} \\\\ \\vdots \\\\ \\alpha_{N} \\end{bmatrix} \\; \\; , \\; \\;\n", | |
"B = \\begin{bmatrix} \\beta_{1,1} \\\\ \\beta_{2,1} \\\\ \\vdots \\\\ \\beta_{N,1} \\end{bmatrix} \\; \\; , \\; \\;\n", | |
"\\epsilon = \\begin{bmatrix} \\epsilon_{1} \\\\ \\epsilon_{2} \\\\ \\vdots \\\\ \\epsilon_{N} \\end{bmatrix}\n", | |
"\\end{gathered}\n", | |
"\\end{equation*}\n", | |
"$$\n", | |
"\n", | |
"Donde:\n", | |
"<br>$E(r):$ es el vector de retornos esperados de los activos.\n", | |
"<br>$B:$ es el vector de betas de los activos.\n", | |
"<br>$\\Sigma:$ es la matriz de covarianzas de los activos.\n", | |
"<br>$\\sigma_{r_m - r_f}:$ es la varianza de la prima de mercado.\n", | |
"<br>$\\Sigma_{\\epsilon}:$ es una matriz diagonal de las varianzas de los errores de cada activo.\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"########################################################################\n", | |
"# Importando la Data\n", | |
"########################################################################\n", | |
"\n", | |
"import pandas as pd\n", | |
"import numpy as np\n", | |
"\n", | |
"sp500 = pd.read_excel('SP500.xlsx', index_col=0, header=0)\n", | |
"sp500_ret = sp500.pct_change().dropna()\n", | |
"\n", | |
"precios = pd.read_excel('Prices.xlsx', index_col=0, header=0)\n", | |
"precios = precios.sample(n = 10, random_state = 1, axis = 1)\n", | |
"retornos = precios.pct_change().dropna()\n", | |
"\n", | |
"assets = precios.columns.tolist()\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"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>Beta_1</th>\n", | |
" <th>Beta_2</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>NTRS</th>\n", | |
" <td>0.995139</td>\n", | |
" <td>0.995139</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>O</th>\n", | |
" <td>0.431426</td>\n", | |
" <td>0.431426</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>SBUX</th>\n", | |
" <td>0.902596</td>\n", | |
" <td>0.902596</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>SWK</th>\n", | |
" <td>1.188754</td>\n", | |
" <td>1.188754</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>COF</th>\n", | |
" <td>1.552629</td>\n", | |
" <td>1.552629</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>M</th>\n", | |
" <td>1.313719</td>\n", | |
" <td>1.313719</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>ECL</th>\n", | |
" <td>0.650029</td>\n", | |
" <td>0.650029</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>EXC</th>\n", | |
" <td>0.338666</td>\n", | |
" <td>0.338666</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>HRB</th>\n", | |
" <td>0.455073</td>\n", | |
" <td>0.455073</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>ALXN</th>\n", | |
" <td>1.088635</td>\n", | |
" <td>1.088635</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" Beta_1 Beta_2\n", | |
"NTRS 0.995139 0.995139\n", | |
"O 0.431426 0.431426\n", | |
"SBUX 0.902596 0.902596\n", | |
"SWK 1.188754 1.188754\n", | |
"COF 1.552629 1.552629\n", | |
"M 1.313719 1.313719\n", | |
"ECL 0.650029 0.650029\n", | |
"EXC 0.338666 0.338666\n", | |
"HRB 0.455073 0.455073\n", | |
"ALXN 1.088635 1.088635" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"########################################################################\n", | |
"# Calculando los Betas\n", | |
"########################################################################\n", | |
"import statsmodels.api as sm\n", | |
"from sklearn.linear_model import LinearRegression\n", | |
"\n", | |
"# Usando statsmodels\n", | |
"x = sp500_ret.values\n", | |
"x = sm.add_constant(x)\n", | |
"\n", | |
"Beta_1 = []\n", | |
"for i in assets:\n", | |
" y_i = retornos[i].values\n", | |
" mod = sm.OLS(y_i, x)\n", | |
" res = mod.fit()\n", | |
" Beta_1.append(res.params[1])\n", | |
"\n", | |
"Beta_1 = np.matrix(Beta_1)\n", | |
"\n", | |
"# Usando scikit learn\n", | |
"y = retornos.values\n", | |
"x = sp500_ret.values\n", | |
"\n", | |
"reg = LinearRegression().fit(x, y)\n", | |
"Beta_2 = np.matrix(reg.coef_).T\n", | |
"\n", | |
"# Combinando ambos betas para mostrarlos\n", | |
"B1 = pd.DataFrame(Beta_1.T, index = assets, columns = ['Beta_1'])\n", | |
"B2 = pd.DataFrame(Beta_2.T, index = assets, columns = ['Beta_2'])\n", | |
"\n", | |
"display(pd.concat([B1, B2], axis = 1))\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"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>NTRS</th>\n", | |
" <th>O</th>\n", | |
" <th>SBUX</th>\n", | |
" <th>SWK</th>\n", | |
" <th>COF</th>\n", | |
" <th>M</th>\n", | |
" <th>ECL</th>\n", | |
" <th>EXC</th>\n", | |
" <th>HRB</th>\n", | |
" <th>ALXN</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>0</th>\n", | |
" <td>0.004512</td>\n", | |
" <td>0.009679</td>\n", | |
" <td>0.016238</td>\n", | |
" <td>0.010317</td>\n", | |
" <td>0.009858</td>\n", | |
" <td>0.008295</td>\n", | |
" <td>0.011343</td>\n", | |
" <td>0.005316</td>\n", | |
" <td>0.007505</td>\n", | |
" <td>0.021858</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" NTRS O SBUX SWK COF M ECL \\\n", | |
"0 0.004512 0.009679 0.016238 0.010317 0.009858 0.008295 0.011343 \n", | |
"\n", | |
" EXC HRB ALXN \n", | |
"0 0.005316 0.007505 0.021858 " | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
}, | |
{ | |
"data": { | |
"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>NTRS</th>\n", | |
" <th>O</th>\n", | |
" <th>SBUX</th>\n", | |
" <th>SWK</th>\n", | |
" <th>COF</th>\n", | |
" <th>M</th>\n", | |
" <th>ECL</th>\n", | |
" <th>EXC</th>\n", | |
" <th>HRB</th>\n", | |
" <th>ALXN</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>NTRS</th>\n", | |
" <td>0.004613</td>\n", | |
" <td>0.000739</td>\n", | |
" <td>0.001546</td>\n", | |
" <td>0.002036</td>\n", | |
" <td>0.002659</td>\n", | |
" <td>0.002250</td>\n", | |
" <td>0.001113</td>\n", | |
" <td>0.000580</td>\n", | |
" <td>0.000779</td>\n", | |
" <td>0.001864</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>O</th>\n", | |
" <td>0.000739</td>\n", | |
" <td>0.003413</td>\n", | |
" <td>0.000670</td>\n", | |
" <td>0.000883</td>\n", | |
" <td>0.001153</td>\n", | |
" <td>0.000975</td>\n", | |
" <td>0.000483</td>\n", | |
" <td>0.000251</td>\n", | |
" <td>0.000338</td>\n", | |
" <td>0.000808</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>SBUX</th>\n", | |
" <td>0.001546</td>\n", | |
" <td>0.000670</td>\n", | |
" <td>0.007343</td>\n", | |
" <td>0.001847</td>\n", | |
" <td>0.002412</td>\n", | |
" <td>0.002041</td>\n", | |
" <td>0.001010</td>\n", | |
" <td>0.000526</td>\n", | |
" <td>0.000707</td>\n", | |
" <td>0.001691</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>SWK</th>\n", | |
" <td>0.002036</td>\n", | |
" <td>0.000883</td>\n", | |
" <td>0.001847</td>\n", | |
" <td>0.006047</td>\n", | |
" <td>0.003177</td>\n", | |
" <td>0.002688</td>\n", | |
" <td>0.001330</td>\n", | |
" <td>0.000693</td>\n", | |
" <td>0.000931</td>\n", | |
" <td>0.002227</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>COF</th>\n", | |
" <td>0.002659</td>\n", | |
" <td>0.001153</td>\n", | |
" <td>0.002412</td>\n", | |
" <td>0.003177</td>\n", | |
" <td>0.012339</td>\n", | |
" <td>0.003510</td>\n", | |
" <td>0.001737</td>\n", | |
" <td>0.000905</td>\n", | |
" <td>0.001216</td>\n", | |
" <td>0.002909</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>M</th>\n", | |
" <td>0.002250</td>\n", | |
" <td>0.000975</td>\n", | |
" <td>0.002041</td>\n", | |
" <td>0.002688</td>\n", | |
" <td>0.003510</td>\n", | |
" <td>0.012216</td>\n", | |
" <td>0.001470</td>\n", | |
" <td>0.000766</td>\n", | |
" <td>0.001029</td>\n", | |
" <td>0.002461</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>ECL</th>\n", | |
" <td>0.001113</td>\n", | |
" <td>0.000483</td>\n", | |
" <td>0.001010</td>\n", | |
" <td>0.001330</td>\n", | |
" <td>0.001737</td>\n", | |
" <td>0.001470</td>\n", | |
" <td>0.003057</td>\n", | |
" <td>0.000379</td>\n", | |
" <td>0.000509</td>\n", | |
" <td>0.001218</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>EXC</th>\n", | |
" <td>0.000580</td>\n", | |
" <td>0.000251</td>\n", | |
" <td>0.000526</td>\n", | |
" <td>0.000693</td>\n", | |
" <td>0.000905</td>\n", | |
" <td>0.000766</td>\n", | |
" <td>0.000379</td>\n", | |
" <td>0.003506</td>\n", | |
" <td>0.000265</td>\n", | |
" <td>0.000635</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>HRB</th>\n", | |
" <td>0.000779</td>\n", | |
" <td>0.000338</td>\n", | |
" <td>0.000707</td>\n", | |
" <td>0.000931</td>\n", | |
" <td>0.001216</td>\n", | |
" <td>0.001029</td>\n", | |
" <td>0.000509</td>\n", | |
" <td>0.000265</td>\n", | |
" <td>0.006797</td>\n", | |
" <td>0.000853</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>ALXN</th>\n", | |
" <td>0.001864</td>\n", | |
" <td>0.000808</td>\n", | |
" <td>0.001691</td>\n", | |
" <td>0.002227</td>\n", | |
" <td>0.002909</td>\n", | |
" <td>0.002461</td>\n", | |
" <td>0.001218</td>\n", | |
" <td>0.000635</td>\n", | |
" <td>0.000853</td>\n", | |
" <td>0.025560</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" NTRS O SBUX SWK COF M ECL \\\n", | |
"NTRS 0.004613 0.000739 0.001546 0.002036 0.002659 0.002250 0.001113 \n", | |
"O 0.000739 0.003413 0.000670 0.000883 0.001153 0.000975 0.000483 \n", | |
"SBUX 0.001546 0.000670 0.007343 0.001847 0.002412 0.002041 0.001010 \n", | |
"SWK 0.002036 0.000883 0.001847 0.006047 0.003177 0.002688 0.001330 \n", | |
"COF 0.002659 0.001153 0.002412 0.003177 0.012339 0.003510 0.001737 \n", | |
"M 0.002250 0.000975 0.002041 0.002688 0.003510 0.012216 0.001470 \n", | |
"ECL 0.001113 0.000483 0.001010 0.001330 0.001737 0.001470 0.003057 \n", | |
"EXC 0.000580 0.000251 0.000526 0.000693 0.000905 0.000766 0.000379 \n", | |
"HRB 0.000779 0.000338 0.000707 0.000931 0.001216 0.001029 0.000509 \n", | |
"ALXN 0.001864 0.000808 0.001691 0.002227 0.002909 0.002461 0.001218 \n", | |
"\n", | |
" EXC HRB ALXN \n", | |
"NTRS 0.000580 0.000779 0.001864 \n", | |
"O 0.000251 0.000338 0.000808 \n", | |
"SBUX 0.000526 0.000707 0.001691 \n", | |
"SWK 0.000693 0.000931 0.002227 \n", | |
"COF 0.000905 0.001216 0.002909 \n", | |
"M 0.000766 0.001029 0.002461 \n", | |
"ECL 0.000379 0.000509 0.001218 \n", | |
"EXC 0.003506 0.000265 0.000635 \n", | |
"HRB 0.000265 0.006797 0.000853 \n", | |
"ALXN 0.000635 0.000853 0.025560 " | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"########################################################################\n", | |
"# Calculando el vector de medias y la matriz de covarianzas a partir\n", | |
"# del modelo CAPM\n", | |
"########################################################################\n", | |
"\n", | |
"Sigma_rm = np.matrix(np.var(sp500_ret, ddof = 1))\n", | |
"\n", | |
"# Usando statsmodels\n", | |
"x = sp500_ret.values\n", | |
"x = sm.add_constant(x)\n", | |
"\n", | |
"mu_F_1 = []\n", | |
"Sigma_e_1 = []\n", | |
"for i in assets:\n", | |
" y_i = retornos[i].values\n", | |
" mod = sm.OLS(y_i, x)\n", | |
" res = mod.fit()\n", | |
" error = np.matrix(y_i) - np.matrix(res.predict(x))\n", | |
" mu_F_1.append(np.mean(res.predict(x), axis = 0))\n", | |
" Sigma_e_1.append(np.asscalar(np.var(error.T, ddof = 1, axis = 0)))\n", | |
"\n", | |
"mu_F_1 = np.matrix(mu_F_1)\n", | |
"Sigma_e_1 = np.diag(Sigma_e_1)\n", | |
"Sigma_F_1 = Beta_2.T * Sigma_rm * Beta_2 + Sigma_e_1\n", | |
"\n", | |
"display(pd.DataFrame(mu_F_1, columns = assets))\n", | |
"display(pd.DataFrame(Sigma_F_1, index = assets, columns = assets))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"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>NTRS</th>\n", | |
" <th>O</th>\n", | |
" <th>SBUX</th>\n", | |
" <th>SWK</th>\n", | |
" <th>COF</th>\n", | |
" <th>M</th>\n", | |
" <th>ECL</th>\n", | |
" <th>EXC</th>\n", | |
" <th>HRB</th>\n", | |
" <th>ALXN</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>0</th>\n", | |
" <td>0.004512</td>\n", | |
" <td>0.009679</td>\n", | |
" <td>0.016238</td>\n", | |
" <td>0.010317</td>\n", | |
" <td>0.009858</td>\n", | |
" <td>0.008295</td>\n", | |
" <td>0.011343</td>\n", | |
" <td>0.005316</td>\n", | |
" <td>0.007505</td>\n", | |
" <td>0.021858</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" NTRS O SBUX SWK COF M ECL \\\n", | |
"0 0.004512 0.009679 0.016238 0.010317 0.009858 0.008295 0.011343 \n", | |
"\n", | |
" EXC HRB ALXN \n", | |
"0 0.005316 0.007505 0.021858 " | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
}, | |
{ | |
"data": { | |
"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>NTRS</th>\n", | |
" <th>O</th>\n", | |
" <th>SBUX</th>\n", | |
" <th>SWK</th>\n", | |
" <th>COF</th>\n", | |
" <th>M</th>\n", | |
" <th>ECL</th>\n", | |
" <th>EXC</th>\n", | |
" <th>HRB</th>\n", | |
" <th>ALXN</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>NTRS</th>\n", | |
" <td>0.004613</td>\n", | |
" <td>0.000739</td>\n", | |
" <td>0.001546</td>\n", | |
" <td>0.002036</td>\n", | |
" <td>0.002659</td>\n", | |
" <td>0.002250</td>\n", | |
" <td>0.001113</td>\n", | |
" <td>0.000580</td>\n", | |
" <td>0.000779</td>\n", | |
" <td>0.001864</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>O</th>\n", | |
" <td>0.000739</td>\n", | |
" <td>0.003413</td>\n", | |
" <td>0.000670</td>\n", | |
" <td>0.000883</td>\n", | |
" <td>0.001153</td>\n", | |
" <td>0.000975</td>\n", | |
" <td>0.000483</td>\n", | |
" <td>0.000251</td>\n", | |
" <td>0.000338</td>\n", | |
" <td>0.000808</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>SBUX</th>\n", | |
" <td>0.001546</td>\n", | |
" <td>0.000670</td>\n", | |
" <td>0.007343</td>\n", | |
" <td>0.001847</td>\n", | |
" <td>0.002412</td>\n", | |
" <td>0.002041</td>\n", | |
" <td>0.001010</td>\n", | |
" <td>0.000526</td>\n", | |
" <td>0.000707</td>\n", | |
" <td>0.001691</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>SWK</th>\n", | |
" <td>0.002036</td>\n", | |
" <td>0.000883</td>\n", | |
" <td>0.001847</td>\n", | |
" <td>0.006047</td>\n", | |
" <td>0.003177</td>\n", | |
" <td>0.002688</td>\n", | |
" <td>0.001330</td>\n", | |
" <td>0.000693</td>\n", | |
" <td>0.000931</td>\n", | |
" <td>0.002227</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>COF</th>\n", | |
" <td>0.002659</td>\n", | |
" <td>0.001153</td>\n", | |
" <td>0.002412</td>\n", | |
" <td>0.003177</td>\n", | |
" <td>0.012339</td>\n", | |
" <td>0.003510</td>\n", | |
" <td>0.001737</td>\n", | |
" <td>0.000905</td>\n", | |
" <td>0.001216</td>\n", | |
" <td>0.002909</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>M</th>\n", | |
" <td>0.002250</td>\n", | |
" <td>0.000975</td>\n", | |
" <td>0.002041</td>\n", | |
" <td>0.002688</td>\n", | |
" <td>0.003510</td>\n", | |
" <td>0.012216</td>\n", | |
" <td>0.001470</td>\n", | |
" <td>0.000766</td>\n", | |
" <td>0.001029</td>\n", | |
" <td>0.002461</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>ECL</th>\n", | |
" <td>0.001113</td>\n", | |
" <td>0.000483</td>\n", | |
" <td>0.001010</td>\n", | |
" <td>0.001330</td>\n", | |
" <td>0.001737</td>\n", | |
" <td>0.001470</td>\n", | |
" <td>0.003057</td>\n", | |
" <td>0.000379</td>\n", | |
" <td>0.000509</td>\n", | |
" <td>0.001218</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>EXC</th>\n", | |
" <td>0.000580</td>\n", | |
" <td>0.000251</td>\n", | |
" <td>0.000526</td>\n", | |
" <td>0.000693</td>\n", | |
" <td>0.000905</td>\n", | |
" <td>0.000766</td>\n", | |
" <td>0.000379</td>\n", | |
" <td>0.003506</td>\n", | |
" <td>0.000265</td>\n", | |
" <td>0.000635</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>HRB</th>\n", | |
" <td>0.000779</td>\n", | |
" <td>0.000338</td>\n", | |
" <td>0.000707</td>\n", | |
" <td>0.000931</td>\n", | |
" <td>0.001216</td>\n", | |
" <td>0.001029</td>\n", | |
" <td>0.000509</td>\n", | |
" <td>0.000265</td>\n", | |
" <td>0.006797</td>\n", | |
" <td>0.000853</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>ALXN</th>\n", | |
" <td>0.001864</td>\n", | |
" <td>0.000808</td>\n", | |
" <td>0.001691</td>\n", | |
" <td>0.002227</td>\n", | |
" <td>0.002909</td>\n", | |
" <td>0.002461</td>\n", | |
" <td>0.001218</td>\n", | |
" <td>0.000635</td>\n", | |
" <td>0.000853</td>\n", | |
" <td>0.025560</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" NTRS O SBUX SWK COF M ECL \\\n", | |
"NTRS 0.004613 0.000739 0.001546 0.002036 0.002659 0.002250 0.001113 \n", | |
"O 0.000739 0.003413 0.000670 0.000883 0.001153 0.000975 0.000483 \n", | |
"SBUX 0.001546 0.000670 0.007343 0.001847 0.002412 0.002041 0.001010 \n", | |
"SWK 0.002036 0.000883 0.001847 0.006047 0.003177 0.002688 0.001330 \n", | |
"COF 0.002659 0.001153 0.002412 0.003177 0.012339 0.003510 0.001737 \n", | |
"M 0.002250 0.000975 0.002041 0.002688 0.003510 0.012216 0.001470 \n", | |
"ECL 0.001113 0.000483 0.001010 0.001330 0.001737 0.001470 0.003057 \n", | |
"EXC 0.000580 0.000251 0.000526 0.000693 0.000905 0.000766 0.000379 \n", | |
"HRB 0.000779 0.000338 0.000707 0.000931 0.001216 0.001029 0.000509 \n", | |
"ALXN 0.001864 0.000808 0.001691 0.002227 0.002909 0.002461 0.001218 \n", | |
"\n", | |
" EXC HRB ALXN \n", | |
"NTRS 0.000580 0.000779 0.001864 \n", | |
"O 0.000251 0.000338 0.000808 \n", | |
"SBUX 0.000526 0.000707 0.001691 \n", | |
"SWK 0.000693 0.000931 0.002227 \n", | |
"COF 0.000905 0.001216 0.002909 \n", | |
"M 0.000766 0.001029 0.002461 \n", | |
"ECL 0.000379 0.000509 0.001218 \n", | |
"EXC 0.003506 0.000265 0.000635 \n", | |
"HRB 0.000265 0.006797 0.000853 \n", | |
"ALXN 0.000635 0.000853 0.025560 " | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"# Usando scikit learn\n", | |
"x = sp500_ret.values\n", | |
"\n", | |
"error_2 = y - reg.predict(x)\n", | |
"\n", | |
"mu_F_2 = np.matrix(np.mean(reg.predict(x), axis = 0))\n", | |
"Sigma_e_2 = np.diag(np.var(error_2, ddof = 1, axis = 0))\n", | |
"Sigma_F_2 = Beta_2.T * Sigma_rm * Beta_2 + Sigma_e_2\n", | |
"\n", | |
"display(pd.DataFrame(mu_F_2, columns = assets))\n", | |
"display(pd.DataFrame(Sigma_F_2, index = assets, columns = assets))\n", | |
"\n", | |
"#display(pd.DataFrame(np.cov(y.T), index = assets, columns = assets))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Ahora vamos a comparar el resultado de optimizar un portafolio usando las estimaciones del CAPM versus el modelo historico." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"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>Historico</th>\n", | |
" <th>CAPM</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>NTRS</th>\n", | |
" <td>0.00%</td>\n", | |
" <td>0.00%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>O</th>\n", | |
" <td>21.91%</td>\n", | |
" <td>24.97%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>SBUX</th>\n", | |
" <td>15.77%</td>\n", | |
" <td>18.53%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>SWK</th>\n", | |
" <td>0.11%</td>\n", | |
" <td>0.80%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>COF</th>\n", | |
" <td>0.00%</td>\n", | |
" <td>0.00%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>M</th>\n", | |
" <td>0.00%</td>\n", | |
" <td>0.00%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>ECL</th>\n", | |
" <td>37.73%</td>\n", | |
" <td>32.09%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>EXC</th>\n", | |
" <td>8.72%</td>\n", | |
" <td>9.47%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>HRB</th>\n", | |
" <td>5.15%</td>\n", | |
" <td>7.26%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>ALXN</th>\n", | |
" <td>10.62%</td>\n", | |
" <td>6.88%</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" Historico CAPM\n", | |
"NTRS 0.00% 0.00%\n", | |
"O 21.91% 24.97%\n", | |
"SBUX 15.77% 18.53%\n", | |
"SWK 0.11% 0.80%\n", | |
"COF 0.00% 0.00%\n", | |
"M 0.00% 0.00%\n", | |
"ECL 37.73% 32.09%\n", | |
"EXC 8.72% 9.47%\n", | |
"HRB 5.15% 7.26%\n", | |
"ALXN 10.62% 6.88%" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"########################################################################\n", | |
"# Calculando los portafolios optimos con las estimaciones historicas \n", | |
"# y las estimaciones del CAPM\n", | |
"########################################################################\n", | |
"\n", | |
"import cvxpy as cv\n", | |
"\n", | |
"# Definiendo la funcion de optimización\n", | |
"def Max_Sharpe(mu, Sigma):\n", | |
" w = cv.Variable((mu.shape[1], 1))\n", | |
" k = cv.Variable(1)\n", | |
" rf = cv.Parameter(nonneg=True)\n", | |
" rf.value=0\n", | |
" #definiendo el problema, funcion objetivo y reestricciones \n", | |
" constraints = [(mu - rf)*w == 1,\n", | |
" w >= 1e-10,\n", | |
" k >= 1e-10,\n", | |
" cv.sum(w) == k]\n", | |
" prob = cv.Problem(cv.Minimize(cv.quad_form(w, Sigma)), constraints)\n", | |
" #resolviendo el problema\n", | |
" prob.solve(solver=cv.ECOS)\n", | |
"\n", | |
" return np.matrix(w.value/k.value)\n", | |
"\n", | |
"# Definiendo los inputs del modelo historico\n", | |
"mu = np.matrix(np.mean(retornos.values, axis = 0))\n", | |
"Sigma = np.cov(retornos.values.T)\n", | |
"\n", | |
"w1 = Max_Sharpe(mu, Sigma)\n", | |
"w2 = Max_Sharpe(mu_F_2, Sigma_F_2)\n", | |
"\n", | |
"# Combinando los portafolios para mostrarlos\n", | |
"W1 = pd.DataFrame(w1, index = assets, columns = ['Historico'])\n", | |
"W2 = pd.DataFrame(w2, index = assets, columns = ['CAPM'])\n", | |
"\n", | |
"display(pd.concat([W1, W2], axis = 1).applymap(\"{0:.2%}\".format))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### 2. Risk Factors\n", | |
"\n", | |
"Como una alternativa al Capital Asset Pricing Model (CAPM), Stephen Ross derivó un modelo de precios de activos basado en argumentos de arbitraje denominado Arbitrage Price Theory (APT). La APT establece que el rendimiento esperado de un activo está linealmente relacionado con varios factores de riesgo, a diferencia del CAPM que sugiere que solo esta relacionado con el rendimiento de mercado. Sin embargo, la APT no especifica cuáles son estos factores de riesgo, esta es una ventaja ya que permite modelar el riesgo de forma mas libre que el CAPM, además que este enfoque permite eliminar el riesgo no sistemático para que un inversionista solo sea compensado por aceptar los factores de riesgo sistemáticos. \n", | |
"\n", | |
"### A. Formulación\n", | |
"Un modelo de múltiples factores de riesgo comienza suponiendo que tenemos $N$ activos y que el retorno de cada activo puede expresarse de la forma:\n", | |
"\n", | |
"$$\n", | |
"\\begin{gathered}\n", | |
"R_{i} = \\alpha_{i} + \\sum^{K}_{i = 1}\\beta_{i,k}F_{k} + \\epsilon_{i}\n", | |
"\\end{gathered}\n", | |
"$$\n", | |
"\n", | |
"Además se asume:\n", | |
"\n", | |
"$$\n", | |
"\\begin{gathered}\n", | |
"E(\\epsilon_{i})=0 \\\\\n", | |
"\\\\\n", | |
"E(\\epsilon_{i}\\epsilon_{j}) = E(\\epsilon_{i}F_{j})= 0 \\\\\n", | |
"\\\\\n", | |
"E(\\epsilon_{i}\\epsilon_{i}) = \\sigma_{i}^{2} \\; ; \\; \\forall \\; i \\neq j \\in N\n", | |
"\\end{gathered}\n", | |
"$$\n", | |
"\n", | |
"Aquí $F_{k} \\; \\forall \\; k = 1,2,\\cdots,K$ son $K$ factores de riesgo comunes a todos los activos, $\\beta_{ik}$ es la sensibilidad del activo $i$ al factor $k$, y $\\epsilon_{i}$ es el retorno no sistemático (idiosincrásico) para el activo $i$. Podemos escribir la relación anterior en forma matricial para todos los activos de la siguientes forma:\n", | |
"\n", | |
"$$\n", | |
"\\begin{equation*}\n", | |
"\\begin{gathered}\n", | |
"R = \\alpha + B F + \\epsilon \\\\\n", | |
"\\\\\n", | |
"R = \\begin{bmatrix} R_{1} \\\\ R_{2} \\\\ \\vdots \\\\ R_{N} \\end{bmatrix} \\; \\; , \\; \\;\n", | |
"\\alpha = \\begin{bmatrix} \\alpha_{1} \\\\ \\alpha_{2} \\\\ \\vdots \\\\ \\alpha_{N} \\end{bmatrix} \\; \\; , \\; \\;\n", | |
"B = \\begin{bmatrix} \\beta_{1,1} & \\beta_{1,2} & \\cdots &\\beta_{1,k}\\\\ \\beta_{2,1} & \\beta_{2,2} & \\cdots &\\beta_{2,k} \\\\ \\vdots & \\vdots & \\ddots & \\vdots \\\\ \\beta_{N,1} & \\beta_{N,2} & \\cdots &\\beta_{N,k} \\end{bmatrix} \\; \\; , \\; \\;\n", | |
"F = \\begin{bmatrix} F_{1} \\\\ F_{2} \\\\ \\vdots \\\\ F_{k} \\end{bmatrix} \\; \\; , \\; \\; \n", | |
"\\epsilon = \\begin{bmatrix} \\epsilon_{1} \\\\ \\epsilon_{2} \\\\ \\vdots \\\\ \\epsilon_{N} \\end{bmatrix}\n", | |
"\\end{gathered}\n", | |
"\\end{equation*}\n", | |
"$$\n", | |
"\n", | |
"Donde a la matriz $B$ se le conoce como matriz de mapeo de factores o loadings matrix. Si tomamos valor esperado a la ecuación anterior, obtenemos el vector de retornos esperados de los activos $\\mu$, expresado en términos de los retornos esperados de los factores de riesgo:\n", | |
"\n", | |
"$$\n", | |
"\\begin{gathered}\n", | |
"\\mu = \\alpha +BE(F)\n", | |
"\\end{gathered}\n", | |
"$$\n", | |
"\n", | |
"Para calcular la matriz de covarianzas $\\Sigma_{f}$ siguiendo usando el modelo de factores, utilizamos la siguiente ecuación:\n", | |
"\n", | |
"$$\n", | |
"\\begin{gathered}\n", | |
"\\Sigma_{f} = B \\Sigma_{F} B^{T} + \\Sigma_{\\epsilon}\n", | |
"\\end{gathered}\n", | |
"$$\n", | |
"\n", | |
"Donde $\\Sigma_{F}$ es la matriz de covarianzas de los factores de riesgo y $\\Sigma_{\\epsilon}$ es la matriz de covarianzas de los retornos no sistemáticos $\\epsilon$, la cual por los supuestos iniciales es una matriz diagonal, donde cada elemento de la diagonal es $\\sigma_{i}^{2}$. En la practica se puede aproximar la matriz de covarianzas $\\Sigma_{f}$ con la ecuación $ \\Sigma_{f} \\approx B \\Sigma_{F} B^{T}$, en caso no se tengan valores observados de los retornos de los activos para estimar $\\epsilon_{i}$. Finalmente este método nos permite estimar parámetros de entrada más robustos que luego se utilizan en el modelo de media varianza.\n", | |
"\n", | |
"Un problema de este método es que se puede generar una matriz de covarianzas $\\Sigma_{f}$ que no sea definida positiva, lo que hace imposible la solución del problema de optimización; en este caso se puede optar por dos alternativas: hallar la matriz definida positiva mas cercana a $\\Sigma_{f}$ o utilizar la matriz de covarianzas original de los activos $\\Sigma$. \n", | |
"\n", | |
"### B. Modelo de Fama French\n", | |
"\n", | |
"Un modelo de factores de riesgos muy conocido es el modelo de tres factores de Fama French, el cual usaremos en este post y tiene la siguiente forma:\n", | |
"\n", | |
"$$\n", | |
"\\begin{gathered}\n", | |
"r_{i} - r_{f} = \\beta_{0} + \\beta_{1} (r_{m} - r_{f}) + \\beta_{2}SMB + \\beta_{3}HML + \\epsilon\n", | |
"\\end{gathered}\n", | |
"$$\n", | |
"\n", | |
"<br>Donde:\n", | |
"<br>$r - r_{f}:$ es el retorno en exceso del activo.\n", | |
"<br>$r_{m} - r_{f}:$ es la prima de riesgo de mercado.\n", | |
"<br>$SMB:$ es el factor tamaño o small minus big market cap, este factor nos dice que las empresas de menor <br>capitalización de mercado tienen un rendimiento superior que las empresas de mayor capitalización.\n", | |
"<br>$HML:$ es el factor valor o high minus low price to book, este factor nos dice que las empresas con un alto ratio price to book tienen un rendimiento superior que las empresas de bajo ratio price to book.\n", | |
"\n", | |
"La ecuación anterior puede ser expresada en la forma matricial del modelo de factores de la sección anterior para un número de activos $N$, usando los siguientes arreglos:\n", | |
"\n", | |
"$$\n", | |
"\\begin{equation*}\n", | |
"\\begin{gathered}\n", | |
"R = \\alpha + B F + \\epsilon \\\\\n", | |
"\\\\\n", | |
"R = \\begin{bmatrix} r_{1} \\\\ r_{2} \\\\ \\vdots \\\\ r_{N} \\end{bmatrix} \\; \\; , \\; \\;\n", | |
"\\alpha = \\begin{bmatrix} r_{f} + \\beta_{1,0} \\\\ r_{f} + \\beta_{2,0} \\\\ \\vdots \\\\ r_{f} + \\beta_{N,0} \\end{bmatrix} \\; \\; , \\; \\;\n", | |
"B = \\begin{bmatrix} \\beta_{1,1} & \\beta_{1,2} & \\beta_{1,3}\\\\ \\beta_{2,1} & \\beta_{2,2} &\\beta_{2,3} \\\\ \\vdots & \\vdots & \\vdots \\\\ \\beta_{N,1} & \\beta_{N,2} &\\beta_{N,3} \\end{bmatrix} \\; \\; , \\; \\;\n", | |
"F = \\begin{bmatrix} r_{m} - r_{f} \\\\ SMB \\\\ HML \\end{bmatrix}\n", | |
"\\end{gathered}\n", | |
"\\end{equation*}\n", | |
"$$\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"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>NTRS</th>\n", | |
" <th>O</th>\n", | |
" <th>SBUX</th>\n", | |
" <th>SWK</th>\n", | |
" <th>COF</th>\n", | |
" <th>M</th>\n", | |
" <th>ECL</th>\n", | |
" <th>EXC</th>\n", | |
" <th>HRB</th>\n", | |
" <th>ALXN</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>0</th>\n", | |
" <td>0.004512</td>\n", | |
" <td>0.009679</td>\n", | |
" <td>0.016238</td>\n", | |
" <td>0.010317</td>\n", | |
" <td>0.009858</td>\n", | |
" <td>0.008295</td>\n", | |
" <td>0.011343</td>\n", | |
" <td>0.005316</td>\n", | |
" <td>0.007505</td>\n", | |
" <td>0.021858</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" NTRS O SBUX SWK COF M ECL \\\n", | |
"0 0.004512 0.009679 0.016238 0.010317 0.009858 0.008295 0.011343 \n", | |
"\n", | |
" EXC HRB ALXN \n", | |
"0 0.005316 0.007505 0.021858 " | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
}, | |
{ | |
"data": { | |
"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>NTRS</th>\n", | |
" <th>O</th>\n", | |
" <th>SBUX</th>\n", | |
" <th>SWK</th>\n", | |
" <th>COF</th>\n", | |
" <th>M</th>\n", | |
" <th>ECL</th>\n", | |
" <th>EXC</th>\n", | |
" <th>HRB</th>\n", | |
" <th>ALXN</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>NTRS</th>\n", | |
" <td>0.004814</td>\n", | |
" <td>0.000780</td>\n", | |
" <td>0.001544</td>\n", | |
" <td>0.002230</td>\n", | |
" <td>0.003265</td>\n", | |
" <td>0.002501</td>\n", | |
" <td>0.001253</td>\n", | |
" <td>0.000709</td>\n", | |
" <td>0.000874</td>\n", | |
" <td>0.001157</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>O</th>\n", | |
" <td>0.000780</td>\n", | |
" <td>0.003525</td>\n", | |
" <td>0.000783</td>\n", | |
" <td>0.001016</td>\n", | |
" <td>0.001519</td>\n", | |
" <td>0.001225</td>\n", | |
" <td>0.000424</td>\n", | |
" <td>0.000249</td>\n", | |
" <td>0.000454</td>\n", | |
" <td>0.000778</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>SBUX</th>\n", | |
" <td>0.001544</td>\n", | |
" <td>0.000783</td>\n", | |
" <td>0.007595</td>\n", | |
" <td>0.001948</td>\n", | |
" <td>0.002587</td>\n", | |
" <td>0.002343</td>\n", | |
" <td>0.000803</td>\n", | |
" <td>0.000411</td>\n", | |
" <td>0.000874</td>\n", | |
" <td>0.002507</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>SWK</th>\n", | |
" <td>0.002230</td>\n", | |
" <td>0.001016</td>\n", | |
" <td>0.001948</td>\n", | |
" <td>0.006318</td>\n", | |
" <td>0.003980</td>\n", | |
" <td>0.003111</td>\n", | |
" <td>0.001384</td>\n", | |
" <td>0.000789</td>\n", | |
" <td>0.001111</td>\n", | |
" <td>0.001654</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>COF</th>\n", | |
" <td>0.003265</td>\n", | |
" <td>0.001519</td>\n", | |
" <td>0.002587</td>\n", | |
" <td>0.003980</td>\n", | |
" <td>0.014527</td>\n", | |
" <td>0.004538</td>\n", | |
" <td>0.002143</td>\n", | |
" <td>0.001307</td>\n", | |
" <td>0.001597</td>\n", | |
" <td>0.000740</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>M</th>\n", | |
" <td>0.002501</td>\n", | |
" <td>0.001225</td>\n", | |
" <td>0.002343</td>\n", | |
" <td>0.003111</td>\n", | |
" <td>0.004538</td>\n", | |
" <td>0.012897</td>\n", | |
" <td>0.001464</td>\n", | |
" <td>0.000831</td>\n", | |
" <td>0.001327</td>\n", | |
" <td>0.002335</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>ECL</th>\n", | |
" <td>0.001253</td>\n", | |
" <td>0.000424</td>\n", | |
" <td>0.000803</td>\n", | |
" <td>0.001384</td>\n", | |
" <td>0.002143</td>\n", | |
" <td>0.001464</td>\n", | |
" <td>0.003268</td>\n", | |
" <td>0.000549</td>\n", | |
" <td>0.000482</td>\n", | |
" <td>-0.000018</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>EXC</th>\n", | |
" <td>0.000709</td>\n", | |
" <td>0.000249</td>\n", | |
" <td>0.000411</td>\n", | |
" <td>0.000789</td>\n", | |
" <td>0.001307</td>\n", | |
" <td>0.000831</td>\n", | |
" <td>0.000549</td>\n", | |
" <td>0.003645</td>\n", | |
" <td>0.000270</td>\n", | |
" <td>-0.000301</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>HRB</th>\n", | |
" <td>0.000874</td>\n", | |
" <td>0.000454</td>\n", | |
" <td>0.000874</td>\n", | |
" <td>0.001111</td>\n", | |
" <td>0.001597</td>\n", | |
" <td>0.001327</td>\n", | |
" <td>0.000482</td>\n", | |
" <td>0.000270</td>\n", | |
" <td>0.006930</td>\n", | |
" <td>0.001004</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>ALXN</th>\n", | |
" <td>0.001157</td>\n", | |
" <td>0.000778</td>\n", | |
" <td>0.002507</td>\n", | |
" <td>0.001654</td>\n", | |
" <td>0.000740</td>\n", | |
" <td>0.002335</td>\n", | |
" <td>-0.000018</td>\n", | |
" <td>-0.000301</td>\n", | |
" <td>0.001004</td>\n", | |
" <td>0.031738</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" NTRS O SBUX SWK COF M ECL \\\n", | |
"NTRS 0.004814 0.000780 0.001544 0.002230 0.003265 0.002501 0.001253 \n", | |
"O 0.000780 0.003525 0.000783 0.001016 0.001519 0.001225 0.000424 \n", | |
"SBUX 0.001544 0.000783 0.007595 0.001948 0.002587 0.002343 0.000803 \n", | |
"SWK 0.002230 0.001016 0.001948 0.006318 0.003980 0.003111 0.001384 \n", | |
"COF 0.003265 0.001519 0.002587 0.003980 0.014527 0.004538 0.002143 \n", | |
"M 0.002501 0.001225 0.002343 0.003111 0.004538 0.012897 0.001464 \n", | |
"ECL 0.001253 0.000424 0.000803 0.001384 0.002143 0.001464 0.003268 \n", | |
"EXC 0.000709 0.000249 0.000411 0.000789 0.001307 0.000831 0.000549 \n", | |
"HRB 0.000874 0.000454 0.000874 0.001111 0.001597 0.001327 0.000482 \n", | |
"ALXN 0.001157 0.000778 0.002507 0.001654 0.000740 0.002335 -0.000018 \n", | |
"\n", | |
" EXC HRB ALXN \n", | |
"NTRS 0.000709 0.000874 0.001157 \n", | |
"O 0.000249 0.000454 0.000778 \n", | |
"SBUX 0.000411 0.000874 0.002507 \n", | |
"SWK 0.000789 0.001111 0.001654 \n", | |
"COF 0.001307 0.001597 0.000740 \n", | |
"M 0.000831 0.001327 0.002335 \n", | |
"ECL 0.000549 0.000482 -0.000018 \n", | |
"EXC 0.003645 0.000270 -0.000301 \n", | |
"HRB 0.000270 0.006930 0.001004 \n", | |
"ALXN -0.000301 0.001004 0.031738 " | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"########################################################################\n", | |
"# Calculando el vector de medias y la matriz de covarianzas a partir\n", | |
"# del modelo CAPM\n", | |
"########################################################################\n", | |
"\n", | |
"# Cargando la informacion de los factores\n", | |
"Factores = pd.read_excel('FamaFrench.xlsx', index_col=0, header=0)/100\n", | |
"\n", | |
"# Calculando los betas del modelo\n", | |
"x = Factores[['Mkt-RF', 'SMB', 'HML']].values\n", | |
"reg = LinearRegression().fit(x, y)\n", | |
"B = np.matrix(reg.coef_).T\n", | |
"\n", | |
"# Calculando los inputs del modelo\n", | |
"Sigma_F = np.cov(x.T)\n", | |
"error = y - reg.predict(x)\n", | |
"Sigma_e = np.diag(np.var(error, ddof = 1, axis = 0))\n", | |
"\n", | |
"mu_fama = np.matrix(np.mean(reg.predict(x), axis = 0))\n", | |
"Sigma_fama = B.T * Sigma_F * B + Sigma_e_2\n", | |
"\n", | |
"display(pd.DataFrame(mu_fama, columns = assets))\n", | |
"display(pd.DataFrame(Sigma_fama, index = assets, columns = assets))\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"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>Historico</th>\n", | |
" <th>CAPM</th>\n", | |
" <th>Factores</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>NTRS</th>\n", | |
" <td>0.00%</td>\n", | |
" <td>0.00%</td>\n", | |
" <td>0.00%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>O</th>\n", | |
" <td>21.91%</td>\n", | |
" <td>24.97%</td>\n", | |
" <td>24.27%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>SBUX</th>\n", | |
" <td>15.77%</td>\n", | |
" <td>18.53%</td>\n", | |
" <td>17.91%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>SWK</th>\n", | |
" <td>0.11%</td>\n", | |
" <td>0.80%</td>\n", | |
" <td>0.00%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>COF</th>\n", | |
" <td>0.00%</td>\n", | |
" <td>0.00%</td>\n", | |
" <td>0.00%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>M</th>\n", | |
" <td>0.00%</td>\n", | |
" <td>0.00%</td>\n", | |
" <td>0.00%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>ECL</th>\n", | |
" <td>37.73%</td>\n", | |
" <td>32.09%</td>\n", | |
" <td>34.67%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>EXC</th>\n", | |
" <td>8.72%</td>\n", | |
" <td>9.47%</td>\n", | |
" <td>10.02%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>HRB</th>\n", | |
" <td>5.15%</td>\n", | |
" <td>7.26%</td>\n", | |
" <td>6.34%</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>ALXN</th>\n", | |
" <td>10.62%</td>\n", | |
" <td>6.88%</td>\n", | |
" <td>6.79%</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" Historico CAPM Factores\n", | |
"NTRS 0.00% 0.00% 0.00%\n", | |
"O 21.91% 24.97% 24.27%\n", | |
"SBUX 15.77% 18.53% 17.91%\n", | |
"SWK 0.11% 0.80% 0.00%\n", | |
"COF 0.00% 0.00% 0.00%\n", | |
"M 0.00% 0.00% 0.00%\n", | |
"ECL 37.73% 32.09% 34.67%\n", | |
"EXC 8.72% 9.47% 10.02%\n", | |
"HRB 5.15% 7.26% 6.34%\n", | |
"ALXN 10.62% 6.88% 6.79%" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"########################################################################\n", | |
"# Calculando los portafolios optimos con las estimaciones del modelo de \n", | |
"# factores de riesgo de Fama French\n", | |
"########################################################################\n", | |
"\n", | |
"w3 = Max_Sharpe(mu_fama, Sigma_fama)\n", | |
"\n", | |
"# Combinando los portafolios para mostrarlos\n", | |
"W3 = pd.DataFrame(w3, index = assets, columns = ['Factores'])\n", | |
"\n", | |
"display(pd.concat([W1, W2, W3], axis = 1).applymap(\"{0:.2%}\".format))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.7.7" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment