{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Riskfolio-Lib Tutorial: \n",
"\n",
"\n",
"
\n",
"
\n",
" \n",
"\n",
" \n",
" \n",
" __[Financionerioncios](https://financioneroncios.wordpress.com)__\n",
" __[Orenji](https://www.linkedin.com/company/orenj-i)__\n",
" __[Riskfolio-Lib](https://riskfolio-lib.readthedocs.io/en/latest/)__\n",
" __[Dany Cajas](https://www.linkedin.com/in/dany-cajas/)__\n",
"\n",
"## Tutorial 20: Black Litterman with Factors Models Mean Risk Optimization\n",
"\n",
"## 1. Downloading the data:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"
\n",
" \n",
" \n",
" \n",
" 0 \n",
" 90 \n",
" 180 \n",
" 360 \n",
" 720 \n",
" 1800 \n",
" 3600 \n",
" 7200 \n",
" 10800 \n",
" \n",
" \n",
" Date \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" 2017-11-16 00:00:00 \n",
" 0.0000% \n",
" 0.0059% \n",
" 0.0108% \n",
" 0.0178% \n",
" 0.0246% \n",
" 0.0213% \n",
" 0.0075% \n",
" -0.0048% \n",
" -0.0093% \n",
" \n",
" \n",
" 2017-11-15 00:00:00 \n",
" 0.0180% \n",
" 0.0247% \n",
" 0.0303% \n",
" 0.0391% \n",
" 0.0495% \n",
" 0.0558% \n",
" 0.0512% \n",
" 0.0450% \n",
" 0.0417% \n",
" \n",
" \n",
" 2017-11-14 00:00:00 \n",
" -0.1800% \n",
" -0.1710% \n",
" -0.1624% \n",
" -0.1460% \n",
" -0.1167% \n",
" -0.0506% \n",
" 0.0140% \n",
" 0.0676% \n",
" 0.0861% \n",
" \n",
" \n",
" 2017-11-13 00:00:00 \n",
" 0.0000% \n",
" 0.0013% \n",
" 0.0025% \n",
" 0.0048% \n",
" 0.0088% \n",
" 0.0174% \n",
" 0.0258% \n",
" 0.0334% \n",
" 0.0364% \n",
" \n",
" \n",
" 2017-11-10 00:00:00 \n",
" 0.0000% \n",
" 0.0026% \n",
" 0.0043% \n",
" 0.0054% \n",
" 0.0017% \n",
" -0.0248% \n",
" -0.0615% \n",
" -0.0936% \n",
" -0.1054% \n",
" \n",
" \n",
"
\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\n",
"\n",
" \n",
" \n",
" \n",
" APA \n",
" CMCSA \n",
" CNP \n",
" HPQ \n",
" PSA \n",
" SEE \n",
" ZION \n",
" PEP11900D031 \n",
" PEP13000D012 \n",
" PEP13000M088 \n",
" PEP23900M103 \n",
" PEP70101M530 \n",
" PEP70101M571 \n",
" PEP70310M156 \n",
" \n",
" \n",
" Date \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" 2017-11-16 00:00:00 \n",
" -1.3161% \n",
" -0.2958% \n",
" -1.0903% \n",
" 0.9831% \n",
" 1.7234% \n",
" 1.4016% \n",
" -0.8387% \n",
" -0.0411% \n",
" -0.0380% \n",
" -0.0597% \n",
" -0.0737% \n",
" -0.0116% \n",
" 0.0076% \n",
" -0.0633% \n",
" \n",
" \n",
" 2017-11-15 00:00:00 \n",
" -2.0296% \n",
" 0.8682% \n",
" -1.1202% \n",
" 0.0000% \n",
" -1.3479% \n",
" -0.3326% \n",
" 0.0215% \n",
" -0.1626% \n",
" -0.3076% \n",
" -0.3041% \n",
" -0.2286% \n",
" -0.4459% \n",
" -0.4651% \n",
" -0.2146% \n",
" \n",
" \n",
" 2017-11-14 00:00:00 \n",
" -3.7020% \n",
" -1.0470% \n",
" 1.0800% \n",
" 0.8975% \n",
" -0.1548% \n",
" 0.2668% \n",
" 2.6950% \n",
" 0.2320% \n",
" 0.0236% \n",
" 0.1040% \n",
" 0.2373% \n",
" -0.2741% \n",
" -0.3932% \n",
" 0.2151% \n",
" \n",
" \n",
" 2017-11-13 00:00:00 \n",
" -1.4503% \n",
" 1.0855% \n",
" 0.7480% \n",
" -0.2826% \n",
" 0.8179% \n",
" 1.4205% \n",
" 3.4145% \n",
" 0.0906% \n",
" 0.0064% \n",
" -0.0767% \n",
" 0.0354% \n",
" -0.0835% \n",
" -0.1114% \n",
" -0.0081% \n",
" \n",
" \n",
" 2017-11-10 00:00:00 \n",
" -2.4536% \n",
" 0.7932% \n",
" -1.3418% \n",
" -0.5155% \n",
" 0.0710% \n",
" -0.9381% \n",
" -0.0910% \n",
" 0.1194% \n",
" 0.3792% \n",
" 0.3047% \n",
" 0.1355% \n",
" 0.7118% \n",
" 0.8207% \n",
" -0.0090% \n",
" \n",
" \n",
"
\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Uploading Data\n",
"########################################################################\n",
"\n",
"import pandas as pd\n",
"import numpy as np\n",
"import warnings\n",
"\n",
"warnings.filterwarnings(\"ignore\")\n",
"\n",
"# Interest Rates Data\n",
"kr = pd.read_excel('KeyRates.xlsx', engine='openpyxl', index_col=0, header=0)/100\n",
"\n",
"# Prices Data\n",
"assets = pd.read_excel('Assets.xlsx', engine='openpyxl', index_col=0, header=0)\n",
"\n",
"# Find common dates\n",
"a = pd.merge(left=assets, right=kr, how='inner', on='Date')\n",
"dates = a.index\n",
"\n",
"# Calculate interest rates returns\n",
"kr_returns = kr.loc[dates,:].sort_index().diff().dropna()\n",
"kr_returns.sort_index(ascending=False, inplace=True)\n",
"\n",
"# List of instruments\n",
"equity = ['APA','CMCSA','CNP','HPQ','PSA','SEE','ZION']\n",
"bonds = ['PEP11900D031', 'PEP13000D012', 'PEP13000M088',\n",
" 'PEP23900M103','PEP70101M530','PEP70101M571',\n",
" 'PEP70310M156']\n",
"factors = ['MTUM','QUAL','SIZE','USMV','VLUE']\n",
"\n",
"# Calculate assets returns\n",
"assets_returns = assets.loc[dates, equity + bonds]\n",
"assets_returns = assets_returns.sort_index().pct_change().dropna()\n",
"assets_returns.sort_index(ascending=False, inplace=True)\n",
"\n",
"# Calculate factors returns\n",
"factors_returns = assets.loc[dates, factors]\n",
"factors_returns = factors_returns.sort_index().pct_change().dropna()\n",
"factors_returns.sort_index(ascending=False, inplace=True)\n",
"\n",
"# Show tables\n",
"display(kr_returns.head().style.format(\"{:.4%}\"))\n",
"display(assets_returns.head().style.format(\"{:.4%}\"))"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Durations Matrix\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
" \n",
" \n",
" \n",
" R 0 \n",
" R 90 \n",
" R 180 \n",
" R 360 \n",
" R 720 \n",
" R 1800 \n",
" R 3600 \n",
" R 7200 \n",
" R 10800 \n",
" \n",
" \n",
" \n",
" \n",
" PEP11900D031 \n",
" 0.0012 \n",
" 0.0057 \n",
" 0.0192 \n",
" 0.0730 \n",
" 0.3685 \n",
" 3.0416 \n",
" 0.0030 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP13000D012 \n",
" 0.0000 \n",
" 0.0078 \n",
" 0.0142 \n",
" 0.0617 \n",
" 0.3327 \n",
" 1.0902 \n",
" 4.8055 \n",
" 0.2074 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP13000M088 \n",
" 0.0013 \n",
" 0.0004 \n",
" 0.0147 \n",
" 0.0501 \n",
" 0.2770 \n",
" 2.4626 \n",
" 3.0764 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP23900M103 \n",
" 0.0000 \n",
" 0.0005 \n",
" 0.0117 \n",
" 0.0405 \n",
" 0.2274 \n",
" 3.9726 \n",
" 0.0381 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP70101M530 \n",
" 0.0000 \n",
" 0.0052 \n",
" 0.0101 \n",
" 0.0442 \n",
" 0.2488 \n",
" 0.8826 \n",
" 4.9147 \n",
" 3.5537 \n",
" 0.0000 \n",
" \n",
" \n",
"
\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Convexities Matrix\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
" \n",
" \n",
" \n",
" R^2 0 \n",
" R^2 90 \n",
" R^2 180 \n",
" R^2 360 \n",
" R^2 720 \n",
" R^2 1800 \n",
" R^2 3600 \n",
" R^2 7200 \n",
" R^2 10800 \n",
" \n",
" \n",
" \n",
" \n",
" PEP11900D031 \n",
" 0.0004 \n",
" 0.0032 \n",
" 0.0167 \n",
" 0.0928 \n",
" 0.7741 \n",
" 15.5617 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP13000D012 \n",
" 0.0000 \n",
" 0.0057 \n",
" 0.0070 \n",
" 0.0756 \n",
" 0.7210 \n",
" 4.4984 \n",
" 45.2159 \n",
" 0.1105 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP13000M088 \n",
" 0.0010 \n",
" 0.0001 \n",
" 0.0192 \n",
" 0.0736 \n",
" 0.6161 \n",
" 8.8479 \n",
" 16.2880 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP23900M103 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0156 \n",
" 0.0644 \n",
" 0.5161 \n",
" 22.1272 \n",
" 0.0022 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP70101M530 \n",
" 0.0000 \n",
" 0.0038 \n",
" 0.0052 \n",
" 0.0561 \n",
" 0.5530 \n",
" 3.7373 \n",
" 38.2315 \n",
" 26.1464 \n",
" 0.0000 \n",
" \n",
" \n",
"
\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Uploading Duration and Convexity Matrixes\n",
"########################################################################\n",
"\n",
"durations = pd.read_excel('durations.xlsx', index_col=0, header=0)\n",
"convexity = pd.read_excel('convexity.xlsx', index_col=0, header=0)\n",
"\n",
"print('Durations Matrix')\n",
"display(durations.head().style.format(\"{:.4f}\").background_gradient(cmap='YlGn'))\n",
"print('')\n",
"print('Convexities Matrix')\n",
"display(convexity.head().style.format(\"{:.4f}\").background_gradient(cmap='YlGn'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Estimating Black Litterman with Factors for Fixed Income Portfolios\n",
"\n",
"### 2.1 Building the loadings matrix and risk factors returns\n",
"\n",
"This part shows how to build a personalized loadings matrix that will be used by Riskfolio-Lib to calculate the expected returns and covariance matrix."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
" \n",
" \n",
" \n",
" R 0 \n",
" R 90 \n",
" R 180 \n",
" R 360 \n",
" R 720 \n",
" R 1800 \n",
" R 3600 \n",
" R 7200 \n",
" R 10800 \n",
" R^2 0 \n",
" R^2 90 \n",
" R^2 180 \n",
" R^2 360 \n",
" R^2 720 \n",
" R^2 1800 \n",
" R^2 3600 \n",
" R^2 7200 \n",
" R^2 10800 \n",
" \n",
" \n",
" \n",
" \n",
" PEP11900D031 \n",
" -0.0012 \n",
" -0.0057 \n",
" -0.0192 \n",
" -0.0730 \n",
" -0.3685 \n",
" -3.0416 \n",
" -0.0030 \n",
" -0.0000 \n",
" -0.0000 \n",
" 0.0002 \n",
" 0.0016 \n",
" 0.0083 \n",
" 0.0464 \n",
" 0.3871 \n",
" 7.7809 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP13000D012 \n",
" -0.0000 \n",
" -0.0078 \n",
" -0.0142 \n",
" -0.0617 \n",
" -0.3327 \n",
" -1.0902 \n",
" -4.8055 \n",
" -0.2074 \n",
" -0.0000 \n",
" 0.0000 \n",
" 0.0029 \n",
" 0.0035 \n",
" 0.0378 \n",
" 0.3605 \n",
" 2.2492 \n",
" 22.6080 \n",
" 0.0553 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP13000M088 \n",
" -0.0013 \n",
" -0.0004 \n",
" -0.0147 \n",
" -0.0501 \n",
" -0.2770 \n",
" -2.4626 \n",
" -3.0764 \n",
" -0.0000 \n",
" -0.0000 \n",
" 0.0005 \n",
" 0.0000 \n",
" 0.0096 \n",
" 0.0368 \n",
" 0.3081 \n",
" 4.4240 \n",
" 8.1440 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP23900M103 \n",
" -0.0000 \n",
" -0.0005 \n",
" -0.0117 \n",
" -0.0405 \n",
" -0.2274 \n",
" -3.9726 \n",
" -0.0381 \n",
" -0.0000 \n",
" -0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0078 \n",
" 0.0322 \n",
" 0.2581 \n",
" 11.0636 \n",
" 0.0011 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP70101M530 \n",
" -0.0000 \n",
" -0.0052 \n",
" -0.0101 \n",
" -0.0442 \n",
" -0.2488 \n",
" -0.8826 \n",
" -4.9147 \n",
" -3.5537 \n",
" -0.0000 \n",
" 0.0000 \n",
" 0.0019 \n",
" 0.0026 \n",
" 0.0280 \n",
" 0.2765 \n",
" 1.8686 \n",
" 19.1157 \n",
" 13.0732 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP70101M571 \n",
" -0.0015 \n",
" -0.0039 \n",
" -0.0126 \n",
" -0.0501 \n",
" -0.2829 \n",
" -1.0108 \n",
" -2.5878 \n",
" -6.0312 \n",
" -0.4501 \n",
" 0.0002 \n",
" 0.0016 \n",
" 0.0064 \n",
" 0.0319 \n",
" 0.3123 \n",
" 2.1336 \n",
" 10.1632 \n",
" 49.9021 \n",
" 0.4523 \n",
" \n",
" \n",
" PEP70310M156 \n",
" -0.0000 \n",
" -0.0039 \n",
" -0.0097 \n",
" -0.0403 \n",
" -0.2614 \n",
" -3.8920 \n",
" -0.0000 \n",
" -0.0000 \n",
" -0.0000 \n",
" 0.0000 \n",
" 0.0010 \n",
" 0.0030 \n",
" 0.0268 \n",
" 0.2508 \n",
" 10.6813 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
"
\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Building The Loadings Matrix\n",
"########################################################################\n",
"\n",
"loadings = pd.concat([-1.0 * durations, 0.5 * convexity], axis = 1)\n",
"\n",
"display(loadings.style.format(\"{:.4f}\").background_gradient(cmap='YlGn'))"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
" \n",
" \n",
" \n",
" R 0 \n",
" R 90 \n",
" R 180 \n",
" R 360 \n",
" R 720 \n",
" R 1800 \n",
" R 3600 \n",
" R 7200 \n",
" R 10800 \n",
" R^2 0 \n",
" R^2 90 \n",
" R^2 180 \n",
" R^2 360 \n",
" R^2 720 \n",
" R^2 1800 \n",
" R^2 3600 \n",
" R^2 7200 \n",
" R^2 10800 \n",
" \n",
" \n",
" Date \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" 2017-11-16 00:00:00 \n",
" 0.0000% \n",
" 0.0059% \n",
" 0.0108% \n",
" 0.0178% \n",
" 0.0246% \n",
" 0.0213% \n",
" 0.0075% \n",
" -0.0048% \n",
" -0.0093% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" \n",
" \n",
" 2017-11-15 00:00:00 \n",
" 0.0180% \n",
" 0.0247% \n",
" 0.0303% \n",
" 0.0391% \n",
" 0.0495% \n",
" 0.0558% \n",
" 0.0512% \n",
" 0.0450% \n",
" 0.0417% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" \n",
" \n",
" 2017-11-14 00:00:00 \n",
" -0.1800% \n",
" -0.1710% \n",
" -0.1624% \n",
" -0.1460% \n",
" -0.1167% \n",
" -0.0506% \n",
" 0.0140% \n",
" 0.0676% \n",
" 0.0861% \n",
" 0.0003% \n",
" 0.0003% \n",
" 0.0003% \n",
" 0.0002% \n",
" 0.0001% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0001% \n",
" \n",
" \n",
" 2017-11-13 00:00:00 \n",
" 0.0000% \n",
" 0.0013% \n",
" 0.0025% \n",
" 0.0048% \n",
" 0.0088% \n",
" 0.0174% \n",
" 0.0258% \n",
" 0.0334% \n",
" 0.0364% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" \n",
" \n",
" 2017-11-10 00:00:00 \n",
" 0.0000% \n",
" 0.0026% \n",
" 0.0043% \n",
" 0.0054% \n",
" 0.0017% \n",
" -0.0248% \n",
" -0.0615% \n",
" -0.0936% \n",
" -0.1054% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0001% \n",
" 0.0001% \n",
" \n",
" \n",
"
\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Building the risk factors returns matrix\n",
"########################################################################\n",
"\n",
"kr_returns_2 = kr_returns ** 2\n",
"cols = loadings.columns\n",
"\n",
"X = pd.concat([kr_returns, kr_returns_2], axis=1)\n",
"X.columns = cols\n",
"\n",
"display(X.head().style.format(\"{:.4%}\"))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" PEP11900D031 \n",
" PEP13000D012 \n",
" PEP13000M088 \n",
" PEP23900M103 \n",
" PEP70101M530 \n",
" PEP70101M571 \n",
" PEP70310M156 \n",
" \n",
" \n",
" Date \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" 2017-11-16 \n",
" -0.000411 \n",
" -0.000380 \n",
" -0.000597 \n",
" -0.000737 \n",
" -0.000116 \n",
" 0.000076 \n",
" -0.000633 \n",
" \n",
" \n",
" 2017-11-15 \n",
" -0.001626 \n",
" -0.003076 \n",
" -0.003041 \n",
" -0.002286 \n",
" -0.004459 \n",
" -0.004651 \n",
" -0.002146 \n",
" \n",
" \n",
" 2017-11-14 \n",
" 0.002320 \n",
" 0.000236 \n",
" 0.001040 \n",
" 0.002373 \n",
" -0.002741 \n",
" -0.003932 \n",
" 0.002151 \n",
" \n",
" \n",
" 2017-11-13 \n",
" 0.000906 \n",
" 0.000064 \n",
" -0.000767 \n",
" 0.000354 \n",
" -0.000835 \n",
" -0.001114 \n",
" -0.000081 \n",
" \n",
" \n",
" 2017-11-10 \n",
" 0.001194 \n",
" 0.003792 \n",
" 0.003047 \n",
" 0.001355 \n",
" 0.007118 \n",
" 0.008207 \n",
" -0.000090 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" PEP11900D031 PEP13000D012 PEP13000M088 PEP23900M103 \\\n",
"Date \n",
"2017-11-16 -0.000411 -0.000380 -0.000597 -0.000737 \n",
"2017-11-15 -0.001626 -0.003076 -0.003041 -0.002286 \n",
"2017-11-14 0.002320 0.000236 0.001040 0.002373 \n",
"2017-11-13 0.000906 0.000064 -0.000767 0.000354 \n",
"2017-11-10 0.001194 0.003792 0.003047 0.001355 \n",
"\n",
" PEP70101M530 PEP70101M571 PEP70310M156 \n",
"Date \n",
"2017-11-16 -0.000116 0.000076 -0.000633 \n",
"2017-11-15 -0.004459 -0.004651 -0.002146 \n",
"2017-11-14 -0.002741 -0.003932 0.002151 \n",
"2017-11-13 -0.000835 -0.001114 -0.000081 \n",
"2017-11-10 0.007118 0.008207 -0.000090 "
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Building the asset returns matrix\n",
"########################################################################\n",
"\n",
"Y = assets_returns[bonds]\n",
"\n",
"display(Y.head())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.2 Building views on risk factors"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"R 0 -0.002028\n",
"R 90 -0.001955\n",
"R 180 -0.001819\n",
"R 360 -0.001463\n",
"R 720 -0.000791\n",
"R 1800 -0.000530\n",
"R 3600 -0.002041\n",
"R 7200 -0.003312\n",
"R 10800 -0.003533\n",
"R^2 0 0.000173\n",
"R^2 90 0.000080\n",
"R^2 180 0.000049\n",
"R^2 360 0.000038\n",
"R^2 720 0.000046\n",
"R^2 1800 0.000050\n",
"R^2 3600 0.000057\n",
"R^2 7200 0.000069\n",
"R^2 10800 0.000091\n",
"dtype: float64"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Showing annualized returns of Fixed Income Risk Factors\n",
"########################################################################\n",
"\n",
"display(X.mean()*252)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" Disabled \n",
" Factor \n",
" Sign \n",
" Value \n",
" Relative Factor \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" False \n",
" R 10800 \n",
" >= \n",
" 0.001 \n",
" R 7200 \n",
" \n",
" \n",
" 1 \n",
" False \n",
" R 1800 \n",
" <= \n",
" -0.001 \n",
" \n",
" \n",
" \n",
" 2 \n",
" False \n",
" R 3600 \n",
" <= \n",
" -0.003 \n",
" \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Disabled Factor Sign Value Relative Factor\n",
"0 False R 10800 >= 0.001 R 7200\n",
"1 False R 1800 <= -0.001 \n",
"2 False R 3600 <= -0.003 "
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Building views on some Risk Factors\n",
"########################################################################\n",
"\n",
"views = {'Disabled': [False, False, False],\n",
" 'Factor': ['R 10800','R 1800','R 3600'],\n",
" 'Sign': ['>=', '<=', '<='],\n",
" 'Value': [0.001, -0.001, -0.003],\n",
" 'Relative Factor': ['R 7200', '', '']}\n",
"\n",
"views = pd.DataFrame(views)\n",
"\n",
"display(views)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Matrix of factors views P_f\n",
"[[ 0. 0. 0. 0. 0. 0. 0. -1. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 0. 0. -1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 0. 0. 0. -1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]\n",
"\n",
"Matrix of returns of factors views Q_f\n",
"[[0.001]\n",
" [0.001]\n",
" [0.003]]\n"
]
}
],
"source": [
"########################################################################\n",
"# Building views matrixes P_f and Q_f\n",
"########################################################################\n",
"\n",
"import riskfolio as rp\n",
"\n",
"P_f, Q_f = rp.factors_views(views, loadings, const=False)\n",
"\n",
"print('Matrix of factors views P_f')\n",
"print(P_f)\n",
"print('\\nMatrix of returns of factors views Q_f')\n",
"print(Q_f)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.3 Building Portfolios with mean vector and covariance matrix from Black Litterman with Factors."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"########################################################################\n",
"# Building the Portfolio Object\n",
"########################################################################\n",
"\n",
"# Building the portfolio object\n",
"port = rp.Portfolio(returns=Y)\n",
"\n",
"# Select method and estimate input parameters:\n",
"method_mu='hist' # Method to estimate expected returns based on historical data.\n",
"method_cov='hist' # Method to estimate covariance matrix based on historical data.\n",
"\n",
"port.assets_stats(method_mu=method_mu,\n",
" method_cov=method_cov)\n",
"\n",
"port.factors = X\n",
"port.factors_stats(method_mu=method_mu,\n",
" method_cov=method_cov,\n",
" B=loadings,\n",
" const=False)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"You must convert self.cov_bl_fm to a positive definite matrix\n",
"You must convert self.cov_bl_fm to a positive definite matrix\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
" \n",
" \n",
" \n",
" Pure Factors \n",
" Bayesian BL \n",
" Augmented BL \n",
" \n",
" \n",
" \n",
" \n",
" PEP11900D031 \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" \n",
" \n",
" PEP13000D012 \n",
" 6.6680% \n",
" 33.1060% \n",
" 85.2406% \n",
" \n",
" \n",
" PEP13000M088 \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" \n",
" \n",
" PEP23900M103 \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" \n",
" \n",
" PEP70101M530 \n",
" 32.3833% \n",
" 0.0001% \n",
" 14.7594% \n",
" \n",
" \n",
" PEP70101M571 \n",
" 60.9486% \n",
" 66.8939% \n",
" 0.0000% \n",
" \n",
" \n",
" PEP70310M156 \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" \n",
" \n",
"
\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Calculating optimum portfolios using Mean Vector and\n",
"# Covariance Matrix of Black Litterman with Factors\n",
"########################################################################\n",
"\n",
"port.alpha = 0.05\n",
"rm = 'MV' # Risk measure used, this time will be variance\n",
"obj = 'Sharpe' # Objective function, could be MinRisk, MaxRet, Utility or Sharpe\n",
"hist = False # False: BL covariance and risk factors scenarios\n",
" # True: historical covariance and scenarios\n",
" # 2: risk factors covariance and scenarios\n",
"rf = 0 # Risk free rate\n",
"l = 0 # Risk aversion factor, only useful when obj is 'Utility'\n",
"\n",
"w_fm = port.optimization(model='FM', rm=rm, obj=obj, rf=rf, l=l, hist=hist) \n",
"\n",
"# Estimate Portfolio weights using Black Litterman Bayesian Model:\n",
"port.blfactors_stats(flavor='BLB',\n",
" B=loadings,\n",
" P_f=P_f,\n",
" Q_f=Q_f/252,\n",
" rf=0,\n",
" delta=None,\n",
" eq=True,\n",
" const=False,\n",
" diag=False,\n",
" method_mu=method_mu,\n",
" method_cov=method_cov)\n",
"\n",
"w_blb = port.optimization(model='BL_FM', rm=rm, obj=obj, rf=rf, l=l, hist=hist)\n",
"\n",
"# Estimate Portfolio weights using Augmented Black Litterman Model:\n",
"port.blfactors_stats(flavor='ABL',\n",
" B=loadings,\n",
" P_f=P_f,\n",
" Q_f=Q_f/252,\n",
" rf=0,\n",
" delta=None,\n",
" eq=True,\n",
" const=False,\n",
" diag=False,\n",
" method_mu=method_mu,\n",
" method_cov=method_cov)\n",
"\n",
"w_abl = port.optimization(model='BL_FM', rm=rm, obj=obj, rf=rf, l=l, hist=hist)\n",
"\n",
"ws = pd.concat([w_fm, w_blb, w_abl], axis=1)\n",
"ws.columns = ['Pure Factors', 'Bayesian BL', 'Augmented BL']\n",
"\n",
"display(ws.style.format(\"{:.4%}\").background_gradient(cmap='YlGn'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can see that the we got a messsage that the covariance matrix is not a positive definite matrix, this is common when we work with views on assets or risk factors. In this case, Riskfolio-Lib replace the negative eigenvalues of covariance matrix with zeros and reconstruct the covariance matrix. The problem with this approach is common that the weights that we will get are highly concetrated in few assets.\n",
"\n",
"Other approach is using the mean vector estimated with Black Litterman with Factors and the covariance matrix that we get from historical returns or a factor model. An example with this approach follows:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.4 Building Portfolios with mean vector from Black Litterman with Factors."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"You must convert self.cov_bl_fm to a positive definite matrix\n",
"You must convert self.cov_bl_fm to a positive definite matrix\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
" \n",
" \n",
" \n",
" Pure Factors \n",
" Bayesian BL \n",
" Augmented BL \n",
" \n",
" \n",
" \n",
" \n",
" PEP11900D031 \n",
" 0.0000% \n",
" 0.0000% \n",
" 6.1662% \n",
" \n",
" \n",
" PEP13000D012 \n",
" 6.6680% \n",
" 16.6281% \n",
" 16.4519% \n",
" \n",
" \n",
" PEP13000M088 \n",
" 0.0000% \n",
" 2.2781% \n",
" 5.2878% \n",
" \n",
" \n",
" PEP23900M103 \n",
" 0.0000% \n",
" 0.0000% \n",
" 11.2163% \n",
" \n",
" \n",
" PEP70101M530 \n",
" 32.3833% \n",
" 35.1625% \n",
" 26.2773% \n",
" \n",
" \n",
" PEP70101M571 \n",
" 60.9486% \n",
" 45.9313% \n",
" 23.8393% \n",
" \n",
" \n",
" PEP70310M156 \n",
" 0.0000% \n",
" 0.0000% \n",
" 10.7612% \n",
" \n",
" \n",
"
\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Calculating optimum portfolios using only Mean Vector\n",
"# of Black Litterman with Factors and Factor Covariance Matrix\n",
"########################################################################\n",
"\n",
"hist = 2 # False: BL covariance and risk factors scenarios\n",
" # True: historical covariance and scenarios\n",
" # 2: risk factors covariance and scenarios (Only in BL_FM)\n",
"\n",
"# Estimate Portfolio weights using Black Litterman Bayesian Model:\n",
"port.blfactors_stats(flavor='BLB',\n",
" B=loadings,\n",
" P_f=P_f,\n",
" Q_f=Q_f/252,\n",
" rf=0,\n",
" delta=None,\n",
" eq=True,\n",
" const=False,\n",
" diag=False,\n",
" method_mu=method_mu,\n",
" method_cov=method_cov)\n",
"\n",
"w_blb = port.optimization(model='BL_FM', rm=rm, obj=obj, rf=rf, l=l, hist=hist)\n",
"\n",
"# Estimate Portfolio weights using Augmented Black Litterman Model:\n",
"port.blfactors_stats(flavor='ABL',\n",
" B=loadings,\n",
" P_f=P_f,\n",
" Q_f=Q_f/252,\n",
" rf=0,\n",
" delta=None,\n",
" eq=True,\n",
" const=False,\n",
" diag=False,\n",
" method_mu=method_mu,\n",
" method_cov=method_cov)\n",
"\n",
"w_abl = port.optimization(model='BL_FM', rm=rm, obj=obj, rf=rf, l=l, hist=hist)\n",
"\n",
"ws = pd.concat([w_fm, w_blb, w_abl], axis=1)\n",
"ws.columns = ['Pure Factors', 'Bayesian BL', 'Augmented BL']\n",
"\n",
"display(ws.style.format(\"{:.4%}\").background_gradient(cmap='YlGn'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can see that when we only use the mean vector of Black Litterman with Factors, the weights that we get are more diversified. Also, we can see that the Augmented Black Litterman creates more diversified portfolios than the Bayesian Black Litterman."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Estimating Mean Variance Portfolio for Equity and Fixed Income Portfolio\n",
"\n",
"### 3.1 Building the loadings matrix and risk factors returns.\n",
"\n",
"This part shows how to build a personalized loadings matrix that will be used by Riskfolio-Lib to calculate the expected returns and covariance matrix."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
" \n",
" \n",
" \n",
" const \n",
" MTUM \n",
" QUAL \n",
" SIZE \n",
" USMV \n",
" VLUE \n",
" \n",
" \n",
" \n",
" \n",
" APA \n",
" -0.0008 \n",
" -0.8999 \n",
" 1.2674 \n",
" 0.0000 \n",
" -0.5750 \n",
" 1.4874 \n",
" \n",
" \n",
" CMCSA \n",
" -0.0000 \n",
" 0.2426 \n",
" 0.0000 \n",
" -0.1569 \n",
" 0.5483 \n",
" 0.3623 \n",
" \n",
" \n",
" CNP \n",
" -0.0001 \n",
" -0.3827 \n",
" -0.3579 \n",
" 0.0000 \n",
" 1.9556 \n",
" 0.0000 \n",
" \n",
" \n",
" HPQ \n",
" 0.0003 \n",
" 0.0000 \n",
" 0.5164 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.7550 \n",
" \n",
" \n",
" PSA \n",
" -0.0000 \n",
" 0.0000 \n",
" -0.4623 \n",
" 0.0000 \n",
" 1.8071 \n",
" -0.3115 \n",
" \n",
" \n",
" SEE \n",
" -0.0001 \n",
" 0.0000 \n",
" 0.4915 \n",
" 0.0000 \n",
" 0.5043 \n",
" 0.2535 \n",
" \n",
" \n",
" ZION \n",
" 0.0002 \n",
" 0.0000 \n",
" 1.1589 \n",
" 0.0000 \n",
" -1.3203 \n",
" 1.2202 \n",
" \n",
" \n",
"
\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"B = rp.loadings_matrix(factors_returns, assets_returns[equity])\n",
"\n",
"display(B.style.format(\"{:.4f}\").background_gradient(cmap='YlGn'))"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" APA \n",
" CMCSA \n",
" CNP \n",
" HPQ \n",
" PSA \n",
" SEE \n",
" ZION \n",
" PEP11900D031 \n",
" PEP13000D012 \n",
" PEP13000M088 \n",
" PEP23900M103 \n",
" PEP70101M530 \n",
" PEP70101M571 \n",
" PEP70310M156 \n",
" \n",
" \n",
" Date \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" 2017-11-16 \n",
" -0.013161 \n",
" -0.002958 \n",
" -0.010903 \n",
" 0.009831 \n",
" 0.017234 \n",
" 0.014016 \n",
" -0.008387 \n",
" -0.000411 \n",
" -0.000380 \n",
" -0.000597 \n",
" -0.000737 \n",
" -0.000116 \n",
" 0.000076 \n",
" -0.000633 \n",
" \n",
" \n",
" 2017-11-15 \n",
" -0.020296 \n",
" 0.008682 \n",
" -0.011202 \n",
" 0.000000 \n",
" -0.013479 \n",
" -0.003326 \n",
" 0.000215 \n",
" -0.001626 \n",
" -0.003076 \n",
" -0.003041 \n",
" -0.002286 \n",
" -0.004459 \n",
" -0.004651 \n",
" -0.002146 \n",
" \n",
" \n",
" 2017-11-14 \n",
" -0.037020 \n",
" -0.010470 \n",
" 0.010800 \n",
" 0.008975 \n",
" -0.001548 \n",
" 0.002668 \n",
" 0.026950 \n",
" 0.002320 \n",
" 0.000236 \n",
" 0.001040 \n",
" 0.002373 \n",
" -0.002741 \n",
" -0.003932 \n",
" 0.002151 \n",
" \n",
" \n",
" 2017-11-13 \n",
" -0.014503 \n",
" 0.010855 \n",
" 0.007480 \n",
" -0.002826 \n",
" 0.008179 \n",
" 0.014205 \n",
" 0.034145 \n",
" 0.000906 \n",
" 0.000064 \n",
" -0.000767 \n",
" 0.000354 \n",
" -0.000835 \n",
" -0.001114 \n",
" -0.000081 \n",
" \n",
" \n",
" 2017-11-10 \n",
" -0.024536 \n",
" 0.007932 \n",
" -0.013418 \n",
" -0.005155 \n",
" 0.000710 \n",
" -0.009381 \n",
" -0.000910 \n",
" 0.001194 \n",
" 0.003792 \n",
" 0.003047 \n",
" 0.001355 \n",
" 0.007118 \n",
" 0.008207 \n",
" -0.000090 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" APA CMCSA CNP HPQ PSA SEE \\\n",
"Date \n",
"2017-11-16 -0.013161 -0.002958 -0.010903 0.009831 0.017234 0.014016 \n",
"2017-11-15 -0.020296 0.008682 -0.011202 0.000000 -0.013479 -0.003326 \n",
"2017-11-14 -0.037020 -0.010470 0.010800 0.008975 -0.001548 0.002668 \n",
"2017-11-13 -0.014503 0.010855 0.007480 -0.002826 0.008179 0.014205 \n",
"2017-11-10 -0.024536 0.007932 -0.013418 -0.005155 0.000710 -0.009381 \n",
"\n",
" ZION PEP11900D031 PEP13000D012 PEP13000M088 PEP23900M103 \\\n",
"Date \n",
"2017-11-16 -0.008387 -0.000411 -0.000380 -0.000597 -0.000737 \n",
"2017-11-15 0.000215 -0.001626 -0.003076 -0.003041 -0.002286 \n",
"2017-11-14 0.026950 0.002320 0.000236 0.001040 0.002373 \n",
"2017-11-13 0.034145 0.000906 0.000064 -0.000767 0.000354 \n",
"2017-11-10 -0.000910 0.001194 0.003792 0.003047 0.001355 \n",
"\n",
" PEP70101M530 PEP70101M571 PEP70310M156 \n",
"Date \n",
"2017-11-16 -0.000116 0.000076 -0.000633 \n",
"2017-11-15 -0.004459 -0.004651 -0.002146 \n",
"2017-11-14 -0.002741 -0.003932 0.002151 \n",
"2017-11-13 -0.000835 -0.001114 -0.000081 \n",
"2017-11-10 0.007118 0.008207 -0.000090 "
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Building the asset returns matrix\n",
"########################################################################\n",
"\n",
"Y = pd.concat([assets_returns[equity], Y], axis=1)\n",
"\n",
"display(Y.head())"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" MTUM \n",
" QUAL \n",
" SIZE \n",
" USMV \n",
" VLUE \n",
" R 0 \n",
" R 90 \n",
" R 180 \n",
" R 360 \n",
" R 720 \n",
" ... \n",
" R 10800 \n",
" R^2 0 \n",
" R^2 90 \n",
" R^2 180 \n",
" R^2 360 \n",
" R^2 720 \n",
" R^2 1800 \n",
" R^2 3600 \n",
" R^2 7200 \n",
" R^2 10800 \n",
" \n",
" \n",
" Date \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" \n",
" 2017-11-16 \n",
" 0.009478 \n",
" 0.007556 \n",
" 0.006675 \n",
" 0.006408 \n",
" 0.014509 \n",
" 0.00000 \n",
" 0.000059 \n",
" 0.000108 \n",
" 0.000178 \n",
" 0.000246 \n",
" ... \n",
" -0.000093 \n",
" 0.000000e+00 \n",
" 3.527647e-09 \n",
" 1.163831e-08 \n",
" 3.181621e-08 \n",
" 6.048648e-08 \n",
" 4.552420e-08 \n",
" 5.573518e-09 \n",
" 2.314283e-09 \n",
" 8.695936e-09 \n",
" \n",
" \n",
" 2017-11-15 \n",
" -0.003381 \n",
" -0.005884 \n",
" -0.001974 \n",
" -0.006750 \n",
" -0.003771 \n",
" 0.00018 \n",
" 0.000247 \n",
" 0.000303 \n",
" 0.000391 \n",
" 0.000495 \n",
" ... \n",
" 0.000417 \n",
" 3.225005e-08 \n",
" 6.082093e-08 \n",
" 9.197391e-08 \n",
" 1.529780e-07 \n",
" 2.448864e-07 \n",
" 3.108575e-07 \n",
" 2.620815e-07 \n",
" 2.025117e-07 \n",
" 1.736147e-07 \n",
" \n",
" \n",
" 2017-11-14 \n",
" -0.001687 \n",
" 0.000375 \n",
" -0.000370 \n",
" 0.001932 \n",
" -0.004380 \n",
" -0.00180 \n",
" -0.001710 \n",
" -0.001624 \n",
" -0.001460 \n",
" -0.001167 \n",
" ... \n",
" 0.000861 \n",
" 3.241235e-06 \n",
" 2.925701e-06 \n",
" 2.636999e-06 \n",
" 2.131988e-06 \n",
" 1.362113e-06 \n",
" 2.555747e-07 \n",
" 1.966922e-08 \n",
" 4.572289e-07 \n",
" 7.417774e-07 \n",
" \n",
" \n",
" 2017-11-13 \n",
" 0.002488 \n",
" 0.000877 \n",
" 0.003589 \n",
" 0.003296 \n",
" 0.000751 \n",
" 0.00000 \n",
" 0.000013 \n",
" 0.000025 \n",
" 0.000048 \n",
" 0.000088 \n",
" ... \n",
" 0.000364 \n",
" 0.000000e+00 \n",
" 1.681950e-10 \n",
" 6.400900e-10 \n",
" 2.324301e-09 \n",
" 7.748577e-09 \n",
" 3.033345e-08 \n",
" 6.657174e-08 \n",
" 1.116368e-07 \n",
" 1.328391e-07 \n",
" \n",
" \n",
" 2017-11-10 \n",
" 0.002894 \n",
" 0.001255 \n",
" -0.001730 \n",
" -0.000968 \n",
" 0.001254 \n",
" 0.00000 \n",
" 0.000026 \n",
" 0.000043 \n",
" 0.000054 \n",
" 0.000017 \n",
" ... \n",
" -0.001054 \n",
" 0.000000e+00 \n",
" 6.770924e-10 \n",
" 1.820644e-09 \n",
" 2.881542e-09 \n",
" 2.791573e-10 \n",
" 6.131368e-08 \n",
" 3.779975e-07 \n",
" 8.759856e-07 \n",
" 1.110697e-06 \n",
" \n",
" \n",
"
\n",
"
5 rows × 23 columns
\n",
"
"
],
"text/plain": [
" MTUM QUAL SIZE USMV VLUE R 0 \\\n",
"Date \n",
"2017-11-16 0.009478 0.007556 0.006675 0.006408 0.014509 0.00000 \n",
"2017-11-15 -0.003381 -0.005884 -0.001974 -0.006750 -0.003771 0.00018 \n",
"2017-11-14 -0.001687 0.000375 -0.000370 0.001932 -0.004380 -0.00180 \n",
"2017-11-13 0.002488 0.000877 0.003589 0.003296 0.000751 0.00000 \n",
"2017-11-10 0.002894 0.001255 -0.001730 -0.000968 0.001254 0.00000 \n",
"\n",
" R 90 R 180 R 360 R 720 ... R 10800 \\\n",
"Date ... \n",
"2017-11-16 0.000059 0.000108 0.000178 0.000246 ... -0.000093 \n",
"2017-11-15 0.000247 0.000303 0.000391 0.000495 ... 0.000417 \n",
"2017-11-14 -0.001710 -0.001624 -0.001460 -0.001167 ... 0.000861 \n",
"2017-11-13 0.000013 0.000025 0.000048 0.000088 ... 0.000364 \n",
"2017-11-10 0.000026 0.000043 0.000054 0.000017 ... -0.001054 \n",
"\n",
" R^2 0 R^2 90 R^2 180 R^2 360 \\\n",
"Date \n",
"2017-11-16 0.000000e+00 3.527647e-09 1.163831e-08 3.181621e-08 \n",
"2017-11-15 3.225005e-08 6.082093e-08 9.197391e-08 1.529780e-07 \n",
"2017-11-14 3.241235e-06 2.925701e-06 2.636999e-06 2.131988e-06 \n",
"2017-11-13 0.000000e+00 1.681950e-10 6.400900e-10 2.324301e-09 \n",
"2017-11-10 0.000000e+00 6.770924e-10 1.820644e-09 2.881542e-09 \n",
"\n",
" R^2 720 R^2 1800 R^2 3600 R^2 7200 \\\n",
"Date \n",
"2017-11-16 6.048648e-08 4.552420e-08 5.573518e-09 2.314283e-09 \n",
"2017-11-15 2.448864e-07 3.108575e-07 2.620815e-07 2.025117e-07 \n",
"2017-11-14 1.362113e-06 2.555747e-07 1.966922e-08 4.572289e-07 \n",
"2017-11-13 7.748577e-09 3.033345e-08 6.657174e-08 1.116368e-07 \n",
"2017-11-10 2.791573e-10 6.131368e-08 3.779975e-07 8.759856e-07 \n",
"\n",
" R^2 10800 \n",
"Date \n",
"2017-11-16 8.695936e-09 \n",
"2017-11-15 1.736147e-07 \n",
"2017-11-14 7.417774e-07 \n",
"2017-11-13 1.328391e-07 \n",
"2017-11-10 1.110697e-06 \n",
"\n",
"[5 rows x 23 columns]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Building the asset returns matrix\n",
"########################################################################\n",
"\n",
"X = pd.concat([factors_returns, X], axis=1)\n",
"\n",
"display(X.head())"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
" \n",
" \n",
" \n",
" const \n",
" MTUM \n",
" QUAL \n",
" SIZE \n",
" USMV \n",
" VLUE \n",
" R 0 \n",
" R 90 \n",
" R 180 \n",
" R 360 \n",
" R 720 \n",
" R 1800 \n",
" R 3600 \n",
" R 7200 \n",
" R 10800 \n",
" R^2 0 \n",
" R^2 90 \n",
" R^2 180 \n",
" R^2 360 \n",
" R^2 720 \n",
" R^2 1800 \n",
" R^2 3600 \n",
" R^2 7200 \n",
" R^2 10800 \n",
" \n",
" \n",
" \n",
" \n",
" APA \n",
" -0.0008 \n",
" -0.8999 \n",
" 1.2674 \n",
" 0.0000 \n",
" -0.5750 \n",
" 1.4874 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" CMCSA \n",
" -0.0000 \n",
" 0.2426 \n",
" 0.0000 \n",
" -0.1569 \n",
" 0.5483 \n",
" 0.3623 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" CNP \n",
" -0.0001 \n",
" -0.3827 \n",
" -0.3579 \n",
" 0.0000 \n",
" 1.9556 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" HPQ \n",
" 0.0003 \n",
" 0.0000 \n",
" 0.5164 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.7550 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" PSA \n",
" -0.0000 \n",
" 0.0000 \n",
" -0.4623 \n",
" 0.0000 \n",
" 1.8071 \n",
" -0.3115 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" SEE \n",
" -0.0001 \n",
" 0.0000 \n",
" 0.4915 \n",
" 0.0000 \n",
" 0.5043 \n",
" 0.2535 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" ZION \n",
" 0.0002 \n",
" 0.0000 \n",
" 1.1589 \n",
" 0.0000 \n",
" -1.3203 \n",
" 1.2202 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP11900D031 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" -0.0012 \n",
" -0.0057 \n",
" -0.0192 \n",
" -0.0730 \n",
" -0.3685 \n",
" -3.0416 \n",
" -0.0030 \n",
" -0.0000 \n",
" -0.0000 \n",
" 0.0002 \n",
" 0.0016 \n",
" 0.0083 \n",
" 0.0464 \n",
" 0.3871 \n",
" 7.7809 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP13000D012 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" -0.0000 \n",
" -0.0078 \n",
" -0.0142 \n",
" -0.0617 \n",
" -0.3327 \n",
" -1.0902 \n",
" -4.8055 \n",
" -0.2074 \n",
" -0.0000 \n",
" 0.0000 \n",
" 0.0029 \n",
" 0.0035 \n",
" 0.0378 \n",
" 0.3605 \n",
" 2.2492 \n",
" 22.6080 \n",
" 0.0553 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP13000M088 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" -0.0013 \n",
" -0.0004 \n",
" -0.0147 \n",
" -0.0501 \n",
" -0.2770 \n",
" -2.4626 \n",
" -3.0764 \n",
" -0.0000 \n",
" -0.0000 \n",
" 0.0005 \n",
" 0.0000 \n",
" 0.0096 \n",
" 0.0368 \n",
" 0.3081 \n",
" 4.4240 \n",
" 8.1440 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP23900M103 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" -0.0000 \n",
" -0.0005 \n",
" -0.0117 \n",
" -0.0405 \n",
" -0.2274 \n",
" -3.9726 \n",
" -0.0381 \n",
" -0.0000 \n",
" -0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0078 \n",
" 0.0322 \n",
" 0.2581 \n",
" 11.0636 \n",
" 0.0011 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP70101M530 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" -0.0000 \n",
" -0.0052 \n",
" -0.0101 \n",
" -0.0442 \n",
" -0.2488 \n",
" -0.8826 \n",
" -4.9147 \n",
" -3.5537 \n",
" -0.0000 \n",
" 0.0000 \n",
" 0.0019 \n",
" 0.0026 \n",
" 0.0280 \n",
" 0.2765 \n",
" 1.8686 \n",
" 19.1157 \n",
" 13.0732 \n",
" 0.0000 \n",
" \n",
" \n",
" PEP70101M571 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" -0.0015 \n",
" -0.0039 \n",
" -0.0126 \n",
" -0.0501 \n",
" -0.2829 \n",
" -1.0108 \n",
" -2.5878 \n",
" -6.0312 \n",
" -0.4501 \n",
" 0.0002 \n",
" 0.0016 \n",
" 0.0064 \n",
" 0.0319 \n",
" 0.3123 \n",
" 2.1336 \n",
" 10.1632 \n",
" 49.9021 \n",
" 0.4523 \n",
" \n",
" \n",
" PEP70310M156 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" -0.0000 \n",
" -0.0039 \n",
" -0.0097 \n",
" -0.0403 \n",
" -0.2614 \n",
" -3.8920 \n",
" -0.0000 \n",
" -0.0000 \n",
" -0.0000 \n",
" 0.0000 \n",
" 0.0010 \n",
" 0.0030 \n",
" 0.0268 \n",
" 0.2508 \n",
" 10.6813 \n",
" 0.0000 \n",
" 0.0000 \n",
" 0.0000 \n",
" \n",
" \n",
"
\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Building The Loadings Matrix\n",
"########################################################################\n",
"\n",
"loadings = pd.concat([B, loadings], axis = 1)\n",
"loadings.fillna(0, inplace=True)\n",
"\n",
"display(loadings.style.format(\"{:.4f}\").background_gradient(cmap='YlGn'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.2 Building views on risk factors"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"MTUM 0.154379\n",
"QUAL 0.113842\n",
"SIZE 0.115915\n",
"USMV 0.124555\n",
"VLUE 0.106612\n",
"dtype: float64"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Showing annualized returns of Equity Risk Factors\n",
"########################################################################\n",
"\n",
"display(factors_returns.mean()*252)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" Disabled \n",
" Factor \n",
" Sign \n",
" Value \n",
" Relative Factor \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" False \n",
" MTUM \n",
" >= \n",
" 0.020 \n",
" VLUE \n",
" \n",
" \n",
" 1 \n",
" False \n",
" USMV \n",
" >= \n",
" 0.090 \n",
" \n",
" \n",
" \n",
" 2 \n",
" False \n",
" SIZE \n",
" >= \n",
" 0.120 \n",
" \n",
" \n",
" \n",
" 3 \n",
" False \n",
" R 10800 \n",
" >= \n",
" 0.001 \n",
" R 90 \n",
" \n",
" \n",
" 4 \n",
" False \n",
" R 1800 \n",
" <= \n",
" -0.001 \n",
" \n",
" \n",
" \n",
" 5 \n",
" False \n",
" R 3600 \n",
" <= \n",
" -0.003 \n",
" \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Disabled Factor Sign Value Relative Factor\n",
"0 False MTUM >= 0.020 VLUE\n",
"1 False USMV >= 0.090 \n",
"2 False SIZE >= 0.120 \n",
"3 False R 10800 >= 0.001 R 90\n",
"4 False R 1800 <= -0.001 \n",
"5 False R 3600 <= -0.003 "
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Building views on some Risk Factors\n",
"########################################################################\n",
"\n",
"views = {'Disabled': [False, False, False, False, False, False],\n",
" 'Factor': ['MTUM','USMV','SIZE','R 10800','R 1800','R 3600'],\n",
" 'Sign': ['>=', '>=', '>=', '>=', '<=', '<='],\n",
" 'Value': [0.02, 0.09, 0.12, 0.001, -0.001, -0.003],\n",
" 'Relative Factor': ['VLUE', '', '','R 90', '', '']}\n",
"views = pd.DataFrame(views)\n",
"\n",
"display(views)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Matrix of factors views P_f\n",
"[[ 1. 0. 0. 0. -1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n",
" 0. 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n",
" 0. 0. 0. 0. 0.]\n",
" [ 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n",
" 0. 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 0. 0. 0. -1. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0.\n",
" 0. 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. -1. 0. 0. 0. 0. 0. 0. 0.\n",
" 0. 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. -1. 0. 0. 0. 0. 0. 0.\n",
" 0. 0. 0. 0. 0.]]\n",
"\n",
"Matrix of returns of factors views Q_f\n",
"[[0.02 ]\n",
" [0.09 ]\n",
" [0.12 ]\n",
" [0.001]\n",
" [0.001]\n",
" [0.003]]\n"
]
}
],
"source": [
"########################################################################\n",
"# Building views matrixes P_f and Q_f\n",
"########################################################################\n",
"\n",
"P_f, Q_f = rp.factors_views(views, loadings, const=True)\n",
"\n",
"print('Matrix of factors views P_f')\n",
"print(P_f)\n",
"print('\\nMatrix of returns of factors views Q_f')\n",
"print(Q_f)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.3 Building Portfolios with mean vector and covariance matrix from Black Litterman with Factors."
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"########################################################################\n",
"# Building Portfolio Object\n",
"########################################################################\n",
"\n",
"# Building the portfolio object\n",
"port = rp.Portfolio(returns=Y)\n",
"\n",
"# Calculating optimum portfolio\n",
"\n",
"# Select method and estimate input parameters:\n",
"\n",
"method_mu='hist' # Method to estimate expected returns based on historical data.\n",
"method_cov='hist' # Method to estimate covariance matrix based on historical data.\n",
"\n",
"port.assets_stats(method_mu=method_mu,\n",
" method_cov=method_cov)\n",
"\n",
"port.factors = X\n",
"port.factors_stats(method_mu=method_mu,\n",
" method_cov=method_cov,\n",
" B=loadings,\n",
" const=True)"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"You must convert self.cov_bl_fm to a positive definite matrix\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
" \n",
" \n",
" \n",
" Pure Factors \n",
" Bayesian BL \n",
" Augmented BL \n",
" \n",
" \n",
" \n",
" \n",
" APA \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" \n",
" \n",
" CMCSA \n",
" 10.6669% \n",
" 4.4927% \n",
" 0.0000% \n",
" \n",
" \n",
" CNP \n",
" 12.2572% \n",
" 7.6298% \n",
" 0.0000% \n",
" \n",
" \n",
" HPQ \n",
" 16.3690% \n",
" 17.0336% \n",
" 72.8372% \n",
" \n",
" \n",
" PSA \n",
" 26.0444% \n",
" 19.6223% \n",
" 0.0000% \n",
" \n",
" \n",
" SEE \n",
" 0.0758% \n",
" 0.0000% \n",
" 0.0000% \n",
" \n",
" \n",
" ZION \n",
" 7.9950% \n",
" 9.8279% \n",
" 0.0000% \n",
" \n",
" \n",
" PEP11900D031 \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" \n",
" \n",
" PEP13000D012 \n",
" 0.0001% \n",
" 6.9747% \n",
" 27.1628% \n",
" \n",
" \n",
" PEP13000M088 \n",
" 0.0000% \n",
" 0.4876% \n",
" 0.0000% \n",
" \n",
" \n",
" PEP23900M103 \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" \n",
" \n",
" PEP70101M530 \n",
" 7.8241% \n",
" 14.5620% \n",
" 0.0000% \n",
" \n",
" \n",
" PEP70101M571 \n",
" 18.7674% \n",
" 19.3695% \n",
" 0.0000% \n",
" \n",
" \n",
" PEP70310M156 \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" \n",
" \n",
"
\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Calculating optimum portfolios\n",
"########################################################################\n",
"\n",
"port.alpha = 0.05\n",
"rm = 'MV' # Risk measure used, this time will be variance\n",
"obj = 'Sharpe' # Objective function, could be MinRisk, MaxRet, Utility or Sharpe\n",
"hist = False # False: BL covariance and risk factors scenarios\n",
" # True: historical covariance and scenarios\n",
" # 2: risk factors covariance and scenarios\n",
"rf = 0 # Risk free rate\n",
"l = 0 # Risk aversion factor, only useful when obj is 'Utility'\n",
"\n",
"w_fm = port.optimization(model='FM', rm=rm, obj=obj, rf=rf, l=l, hist=hist) \n",
"\n",
"# Estimate Portfolio weights using Black Litterman Bayesian Model:\n",
"port.blfactors_stats(flavor='BLB',\n",
" B=loadings,\n",
" P_f=P_f,\n",
" Q_f=Q_f/252,\n",
" rf=0,\n",
" delta=None,\n",
" eq=True,\n",
" const=True,\n",
" diag=True,\n",
" method_mu=method_mu,\n",
" method_cov=method_cov)\n",
"\n",
"w_blb = port.optimization(model='BL_FM', rm=rm, obj=obj, rf=rf, l=l, hist=hist)\n",
"\n",
"# Estimate Portfolio weights using Augmented Black Litterman Model:\n",
"port.blfactors_stats(flavor='ABL',\n",
" B=loadings,\n",
" P_f=P_f,\n",
" Q_f=Q_f/252,\n",
" rf=0,\n",
" delta=None,\n",
" eq=True,\n",
" const=True,\n",
" diag=True,\n",
" method_mu=method_mu,\n",
" method_cov=method_cov)\n",
"\n",
"w_abl = port.optimization(model='BL_FM', rm=rm, obj=obj, rf=rf, l=l, hist=hist)\n",
"\n",
"ws = pd.concat([w_fm, w_blb, w_abl], axis=1)\n",
"ws.columns = ['Pure Factors', 'Bayesian BL', 'Augmented BL']\n",
"\n",
"display(ws.style.format(\"{:.4%}\").background_gradient(cmap='YlGn'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can see that the we got a messsage that the covariance matrix is not a positive definite matrix, this is common when we work with views on assets or risk factors. In this case, Riskfolio-Lib replace the negative eigenvalues of covariance matrix with zeros and reconstruct the covariance matrix. The problem with this approach is common that the weights that we will get are highly concetrated in few assets. \n",
"\n",
"We can see that in this case the Black Litterman Bayesian model creates a more diversified portfolio than the Augmented Black Litterman model.\n",
"\n",
"Other approach is using the mean vector estimated with Black Litterman with Factors and the covariance matrix that we get from historical returns or a factor model."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.4 Building Portfolios with mean vector from Black Litterman with Factors."
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"You must convert self.cov_bl_fm to a positive definite matrix\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
" \n",
" \n",
" \n",
" Pure Factors \n",
" Bayesian BL \n",
" Augmented BL \n",
" \n",
" \n",
" \n",
" \n",
" APA \n",
" 0.0000% \n",
" 0.0000% \n",
" 0.0000% \n",
" \n",
" \n",
" CMCSA \n",
" 10.6669% \n",
" 5.2672% \n",
" 7.3134% \n",
" \n",
" \n",
" CNP \n",
" 12.2572% \n",
" 5.9762% \n",
" 1.6711% \n",
" \n",
" \n",
" HPQ \n",
" 16.3690% \n",
" 17.3220% \n",
" 21.2692% \n",
" \n",
" \n",
" PSA \n",
" 26.0444% \n",
" 18.0273% \n",
" 12.0783% \n",
" \n",
" \n",
" SEE \n",
" 0.0758% \n",
" 0.0000% \n",
" 0.0000% \n",
" \n",
" \n",
" ZION \n",
" 7.9950% \n",
" 11.3383% \n",
" 20.9051% \n",
" \n",
" \n",
" PEP11900D031 \n",
" 0.0000% \n",
" 0.0000% \n",
" 2.3440% \n",
" \n",
" \n",
" PEP13000D012 \n",
" 0.0001% \n",
" 6.2308% \n",
" 6.3664% \n",
" \n",
" \n",
" PEP13000M088 \n",
" 0.0000% \n",
" 0.2338% \n",
" 2.0322% \n",
" \n",
" \n",
" PEP23900M103 \n",
" 0.0000% \n",
" 0.0000% \n",
" 4.1502% \n",
" \n",
" \n",
" PEP70101M530 \n",
" 7.8241% \n",
" 14.6896% \n",
" 9.6157% \n",
" \n",
" \n",
" PEP70101M571 \n",
" 18.7674% \n",
" 20.9148% \n",
" 8.2701% \n",
" \n",
" \n",
" PEP70310M156 \n",
" 0.0000% \n",
" 0.0000% \n",
" 3.9845% \n",
" \n",
" \n",
"
\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"########################################################################\n",
"# Calculating optimum portfolios\n",
"########################################################################\n",
"\n",
"hist = 2 # False: BL covariance and risk factors scenarios\n",
" # True: historical covariance and scenarios\n",
" # 2: risk factors covariance and scenarios (Only in BL_FM)\n",
"\n",
"# Estimate Portfolio weights using Black Litterman Bayesian Model:\n",
"port.blfactors_stats(flavor='BLB',\n",
" B=loadings,\n",
" P_f=P_f,\n",
" Q_f=Q_f/252,\n",
" rf=0,\n",
" delta=None,\n",
" eq=True,\n",
" const=True,\n",
" diag=True,\n",
" method_mu=method_mu,\n",
" method_cov=method_cov)\n",
"\n",
"w_blb = port.optimization(model='BL_FM', rm=rm, obj=obj, rf=rf, l=l, hist=hist)\n",
"\n",
"# Estimate Portfolio weights using Augmented Black Litterman Model:\n",
"port.blfactors_stats(flavor='ABL',\n",
" B=loadings,\n",
" P_f=P_f,\n",
" Q_f=Q_f/252,\n",
" rf=0,\n",
" delta=None,\n",
" eq=True,\n",
" const=True,\n",
" diag=True,\n",
" method_mu=method_mu,\n",
" method_cov=method_cov)\n",
"\n",
"w_abl = port.optimization(model='BL_FM', rm=rm, obj=obj, rf=rf, l=l, hist=hist)\n",
"\n",
"ws = pd.concat([w_fm, w_blb, w_abl], axis=1)\n",
"ws.columns = ['Pure Factors', 'Bayesian BL', 'Augmented BL']\n",
"\n",
"display(ws.style.format(\"{:.4%}\").background_gradient(cmap='YlGn'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can see that when we only use the mean vector of Black Litterman with Factors, the weights that we get are more diversified. Also, we can see that the Augmented Black Litterman creates a more diversified portfolio than the Bayesian Black Litterman."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Estimating Black Litterman with Factors Mean Risk Portfolios\n",
"\n",
"When we use risk measures different than Standard Deviation, Riskfolio-Lib only considers the vector of expected returns, and use historical returns to calculate risk measures.\n",
"\n",
"### 4.1 Calculate Black Litterman Bayesian Portfolios for Several Risk Measures"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [],
"source": [
"# Risk Measures available:\n",
"#\n",
"# 'MV': Standard Deviation.\n",
"# 'MAD': Mean Absolute Deviation.\n",
"# 'MSV': Semi Standard Deviation.\n",
"# 'FLPM': First Lower Partial Moment (Omega Ratio).\n",
"# 'SLPM': Second Lower Partial Moment (Sortino Ratio).\n",
"# 'CVaR': Conditional Value at Risk.\n",
"# 'EVaR': Entropic Value at Risk.\n",
"# 'WR': Worst Realization (Minimax)\n",
"# 'MDD': Maximum Drawdown of uncompounded cumulative returns (Calmar Ratio).\n",
"# 'ADD': Average Drawdown of uncompounded cumulative returns.\n",
"# 'CDaR': Conditional Drawdown at Risk of uncompounded cumulative returns.\n",
"# 'EDaR': Entropic Drawdown at Risk of uncompounded cumulative returns.\n",
"# 'UCI': Ulcer Index of uncompounded cumulative returns.\n",
"\n",
"rms = ['MV', 'MAD', 'MSV', 'FLPM', 'SLPM', 'CVaR',\n",
" 'EVaR', 'WR', 'MDD', 'ADD', 'CDaR', 'UCI', 'EDaR']\n",
"\n",
"w_s = pd.DataFrame([])\n",
"port.alpha = 0.05\n",
"\n",
"port.blfactors_stats(flavor='BLB',\n",
" B=loadings,\n",
" P_f=P_f,\n",
" Q_f=Q_f/252,\n",
" rf=0,\n",
" delta=None,\n",
" eq=True,\n",
" const=True,\n",
" diag=True,\n",
" method_mu=method_mu,\n",
" method_cov=method_cov)\n",
"\n",
"model = 'BL_FM'\n",
"obj = 'Sharpe'\n",
"\n",
"for i in rms:\n",
" if i == 'MV':\n",
" hist = 2\n",
" else:\n",
" hist = True\n",
" w = port.optimization(model=model, rm=i, obj=obj, rf=rf, l=l, hist=hist)\n",
" w_s = pd.concat([w_s, w], axis=1)\n",
" \n",
"w_s.columns = rms"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
" \n",
" \n",
" \n",
" MV \n",
" MAD \n",
" MSV \n",
" FLPM \n",
" SLPM \n",
" CVaR \n",
" EVaR \n",
" WR \n",
" MDD \n",
" ADD \n",
" CDaR \n",
" UCI \n",
" EDaR \n",
" \n",
" \n",
" \n",
" \n",
" APA \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" \n",
" \n",
" CMCSA \n",
" 5.27% \n",
" 6.48% \n",
" 8.28% \n",
" 6.69% \n",
" 8.34% \n",
" 11.76% \n",
" 4.02% \n",
" 0.00% \n",
" 8.15% \n",
" 10.28% \n",
" 2.03% \n",
" 10.10% \n",
" 5.55% \n",
" \n",
" \n",
" CNP \n",
" 5.98% \n",
" 6.22% \n",
" 2.27% \n",
" 7.88% \n",
" 2.13% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 7.08% \n",
" 5.60% \n",
" 23.19% \n",
" 11.26% \n",
" 18.31% \n",
" \n",
" \n",
" HPQ \n",
" 17.32% \n",
" 19.10% \n",
" 15.45% \n",
" 18.15% \n",
" 15.33% \n",
" 15.79% \n",
" 15.73% \n",
" 15.78% \n",
" 8.45% \n",
" 0.00% \n",
" 1.99% \n",
" 0.00% \n",
" 6.33% \n",
" \n",
" \n",
" PSA \n",
" 18.03% \n",
" 19.43% \n",
" 18.60% \n",
" 18.69% \n",
" 18.55% \n",
" 18.59% \n",
" 12.37% \n",
" 3.43% \n",
" 43.61% \n",
" 34.45% \n",
" 39.36% \n",
" 34.46% \n",
" 38.65% \n",
" \n",
" \n",
" SEE \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 3.03% \n",
" 4.16% \n",
" 10.15% \n",
" 6.27% \n",
" 9.26% \n",
" 7.64% \n",
" \n",
" \n",
" ZION \n",
" 11.34% \n",
" 10.70% \n",
" 10.67% \n",
" 10.02% \n",
" 10.67% \n",
" 9.50% \n",
" 12.81% \n",
" 14.88% \n",
" 7.76% \n",
" 11.92% \n",
" 13.28% \n",
" 12.52% \n",
" 9.74% \n",
" \n",
" \n",
" PEP11900D031 \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" \n",
" \n",
" PEP13000D012 \n",
" 6.23% \n",
" 12.34% \n",
" 14.33% \n",
" 12.51% \n",
" 14.52% \n",
" 23.34% \n",
" 16.79% \n",
" 5.21% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" \n",
" \n",
" PEP13000M088 \n",
" 0.23% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" \n",
" \n",
" PEP23900M103 \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" \n",
" \n",
" PEP70101M530 \n",
" 14.69% \n",
" 0.00% \n",
" 5.41% \n",
" 0.00% \n",
" 5.61% \n",
" 4.35% \n",
" 3.99% \n",
" 10.37% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" \n",
" \n",
" PEP70101M571 \n",
" 20.91% \n",
" 25.72% \n",
" 24.98% \n",
" 26.06% \n",
" 24.84% \n",
" 16.66% \n",
" 34.29% \n",
" 47.30% \n",
" 20.80% \n",
" 27.60% \n",
" 13.88% \n",
" 22.40% \n",
" 13.78% \n",
" \n",
" \n",
" PEP70310M156 \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" \n",
" \n",
"
\n"
],
"text/plain": [
""
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"w_s.style.format(\"{:.2%}\").background_gradient(cmap='YlGn')"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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9dVXDh99IxHgAAAAAAAAJ1emTBm1bdtWcXFxiomJUdu2bVWmTBmbc5588kkdOnRI3377rVq1aqXVq1erTp06io2NtZ7TuXNnZWVlKT4+XpIUHx8vwzDUqVOngrydHBHgAAAAAAAApxcREWEdZXP19KmreXp6qkWLFho9erQ2bNignj17asyYMdZ2X19fdejQwTqNKiYmRh06dJCPj0+B3ENeCHAAAAAAAIDTa926tTIyMpSRkaFWrVrd0DX33nuv0tLSbI5FRkZq/fr1WrRokdavX2+K6VMST6ECAAAAAACFgKurqxITE637Vzt+/LieeuopRUREqGbNmipevLi2bNmid955R+3bt7c5t3HjxgoLC1P37t0VFhamRx55pMDuIS8EOAAAAAAAoFDIbaqTt7e36tevrw8//FB79+7VxYsXFRQUpOeee04jR47Mdn5ERIRGjhypYcOG3e6Sb5jFMAzD0UVcz+nTp+Xr66tTp06ZYt4ZANxpVq6qYN1v1nSvAysBAADAFVFRUTnu2+vChQvat2+fQkND5enpefOFIZu8+vhGMw/WwAEAAAAAADA5AhwAAAAAAACTI8ABAAAAAAAwOQIcAAAAAAAAkyPAAQAAAAAAMDkCHAAAAAAAAJMjwAEAAAAAADA5AhwAAAAAAACTI8ABAAAAAAAwOQIcAAAAAAAAk3NzdAEAAAAAAMCcEqtULbDPqror0e5revbsqbi4uGzH9+zZozfffFMnT57UggULcry2XLlySk5OliR5eXmpfPnyGjBggHr37i1Jio2N1bPPPqsqVaooMdG2trlz56pjx44KCQlRUlKS3XXnByNwAAAAAACA02rdurVSUlJsttDQ0Bu6duzYsUpJSdGvv/6qJ554Qn369FF8fLy1vVixYjpy5Ig2btxoc110dLSCg4Nv6X1cDwEOAAAAAABwWh4eHgoICLDZXF1db+ja4sWLKyAgQGFhYXrzzTdVsWJFmxE7bm5ueuaZZxQdHW099vfff2v16tV65plnbvWt5IkABwAAAAAAQJKnp6cuXrxocywyMlLx8fE6d+6cpMtTq1q3bi1/f/8CrY0ABwAAAAAAOK1FixbJ29vbuj311FN2v8elS5cUGxurHTt2qFmzZjZttWrVUoUKFfS///1PhmEoNjZWERERt6r8G8YixgAAAAAAwGmFh4dr2rRp1tfFihW7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i/X777+rTZs2Cg0NtbYvWbJE9erVc2CF5hMcHCyLxaKvv/4613MsFgsBTg4sFovOnDkjT09PSZef3nLl2OnTp63n+fj4OKpE0yFktV9SUpKjS3A61apV0zfffJPrU/YWLFhg80MVLmvevLl27dqlhx56SJLUt29fm/bly5fzhLgcPPPMMzp//nyu7QEBARozZkwBVmR+r7/+ury8vLRp0yb17t1bw4cPV82aNfXyyy/r3Llzeuyxx/TGG284ukzT6devn0qXLq0PP/xQM2bMsP4e4Orqqrp162r27Nl6+umnHVylufTt29fm96UrD4i54rvvvmMB4xyEhITI1dU113aLxaIWLVoUYEXmd+2/80WLFrV5vXDhQqd8qhdPocqnVatWKTo6WvPnz1dISIiefPJJPfnkkzyqOAfff/+9Fi9erICAAA0YMMDmm+f1119X48aN1aRJE8cViELjygr9V7sS4ly9T9D6r3nz5qlz5856+OGH9dtvv+mBBx7QokWLrO3Dhw/Xvn37NHfuXAdWaS4//fST/vnnHz366KPWY7Nnz9aYMWOUlpamJ554Qh999JE8PDwcWKW5xMXFqW/fvnrvvff0/PPPWx9FfOnSJc2YMUPDhg3T1KlT1bNnT8cW6mT27dsnT09P/loNmMDFixd17NgxSVKZMmXyHHUIAPlFgGOHv//+W7GxsYqOjlZaWpqefvppTZ8+Xdu3b7dZQwK4GatWrdILL7ygTZs2ZRspcurUKTVs2FDTp093ysT4dluzZs0NnZfbsPo71cqVK7Vo0SIFBgZqwIAB8vLysrYRsmbXunVrhYeHa/jw4ZKkHTt2qE6dOurZs6eqVq2qd999V71791ZUVJRjCzWZoUOH6oMPPlDx4sVVoUIFSdLevXt19uxZDRw4UB9++KGDKwQAADA3Apwb1KZNG61bt07t2rVTly5d1Lp1a7m6usrd3Z0AJw979uzR6NGjNWPGjBzDiL59++rNN99U+fLlHVSh+Tz++OMKDw/PdarB5MmT9cMPP+Q5xepOdfU0qbwwhepf58+f19ChQ7VgwQJdvHhRzZs31+TJk51yTnBBCQwM1MKFC62LZY8aNUpr1qzRunXrJElfffWVxowZo507dzqyTFPatGmT5syZoz179kiSKlWqpE6dOunBBx90cGXmlZaWpi+++EIbNmxQamqqLBaL/P391ahRI3Xu3FnFihVzdImmRL/Zb/PmzZo4cWK2PmvYsKFefPFF6795uHF79+7Vc889p1WrVjm6FNPIyMhQkSJFrK/37t2rjz76SHv27FFgYKD69u2runXrOrBCc6Lfbj1n/f4kwLlBbm5uGjhwoPr27auKFStajxPg5O35559XiRIl9M477+TYPnz4cJ0+fVrTpk0r4MrMKyQkREuXLlXVqlVzbN+1a5datmyp/fv3F3Bl5pfTFKqcMIXqX1emrnTp0kVeXl764osv1KRJE3311VeOLs20PD09tWfPHgUFBUmSHnroIbVu3VqvvvqqpMtr5NSoUYOnUeGm7dy5Uy1atNC5c+fUuHFj+fv7yzAMHTlyRGvWrFGxYsW0fPlyfga5Bv1mvwULFujpp59Ws2bN1KpVK5s+W758uVauXKm5c+eqffv2ji7VqWzfvl116tTh546ruLq6KiUlRX5+fkpISFCjRo1UqVIlPfDAA0pISND27du1du1a1si8Bv126znr9ycBzg3auHGjoqOjNXfuXFWpUkXdunVTx44dVbZsWQKcPFSpUkWffvqpHnjggRzbt27dqmeeeUa7d+8u4MrMy9PTU7/99pt1df5r/fnnn6pRo0aeCzTeqa6eQmUYhtq0aaNPPvlEd999t815TKH6V4UKFTRu3Dh16tRJ0uXH2Ddq1EgXLlzIc7G8O1lISIg+/fRTPfLII8rIyFCJEiW0cOFCNWvWTNLlKVWNGzfWP//84+BKzePXX3+9ofNq1qx5mytxLuHh4QoICFBcXJzNX16ly3+N7dmzp1JSUvTDDz84qEJzot/sV716dXXt2lUjRozIsf3tt9/W7Nmz9fvvvxdwZeY2efLkPNsPHjyo9957z+l+QbydXFxclJqaKj8/Pz322GPy9PTU3LlzrX+Ai4iIUEpKir777jsHV2ou9Jv9Cuv3JwGOnc6dO6cvv/xS0dHR+vnnn5WZmakPPvhAERERKl68uKPLMx0vLy/t2rUr16d4JScnq2rVqjp37lwBV2ZeFSpU0Hvvvaf/+7//y7F9/vz5Gjp0qP76668Crsz5FC9eXNu3b2eKXh6KFCmiffv22YRcXl5e+uOPP6wjTGCrd+/e2rFjh95++20tWLBAcXFxOnTokPUXxc8//1wTJ07U5s2bHVypeVwZHZfXjxwsMJ5d0aJFtWXLllz/SPTbb7+pXr16/D/0GvSb/Tw9PfXrr7+qUqVKObbv3r1b9913ny5cuFDAlZmbi4uLAgMDswWFV2RkZCg1NZV/265ydRARFBSkL7/8Uo0aNbK2b9++Xa1atVJqaqoDqzQf+s1+hfX708XRBTibokWLKiIiQuvWrdOOHTv00ksvacKECfLz89Pjjz/u6PJMx9fXV3v37s21/c8//2Q9kmu0adNGo0ePzvGHpPPnz2vMmDFq166dAypDYZSZmZntf2xubm66dOmSgyoyvzfffFOurq5q3LixPv74Y3388cc2fRgdHa2WLVs6sELz2bdvn/766y/t27cv141QOruSJUta1wvKyZ9//qmSJUsWYEXOgX6zX4UKFbRgwYJc27/55hv+GJKDkJAQffjhh7n+u7Z48WJHl2g6FovFOmrE1dU12+8BPj4+OnXqlCNKMzX6zX6F9fvTzdEFOLPKlSvrnXfe0fjx47Vw4UJFR0c7uiTTeeSRR/TRRx+padOmObZPnjyZpyld49VXX9X8+fNVqVIlvfDCC6pcubIsFosSExM1ZcoUZWZmatSoUY4uE4WEYRjq2bOnzSOvL1y4oD59+tgs8jl//nxHlGdKd911l9auXatTp07J29s721Szr776St7e3g6qzpwiIiLUv39//ec//8mx/dixY6pXrx4hzjWee+459ejRQ6+++qpatGghf39/WSwWpaamasWKFXrrrbc0ePBgR5dpOvSb/caOHatOnTppzZo1atmyZbY+W758ub788ktHl2k6devW1datW/X000/n2H69kYd3IsMwVKlSJVksFp09e1Y7duxQjRo1rO179uxRQECAAys0J/rNfoX1+5MpVLitfvnlFzVo0EDt2rXTyy+/rMqVK0u6vBDvO++8o8WLF2vDhg2qU6eOgys1l+TkZPXt21fLli2z/sNisVjUqlUrTZ06VeXKlXNsgU6iePHi+vXXXxUaGuroUkzr2WefvaHzYmJibnMlKMxcXFzk4uKiUaNG6fXXX8/WfvjwYZUtW9bphjEXhLfffluTJk2yPhVIuvyDfEBAgAYPHqyXX37ZwRWaE/1mv40bN2rSpEnauHGjdRpGQECAGjRooEGDBqlBgwYOrtB8du7cqXPnzuX6hK6LFy/q0KFDuS4lcCeKi4uzeV2lShXVr1/f+nrs2LE6efKkPvjgg4IuzdToN/sV1u9PAhzc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WLFC1apVc3SppkK/2a9Jkya65557FBsbKzc32xUWLl26pB49eujgwYNavXq1Ywo0KfrNfvRZ/tBv9qtZs6YGDRqkyMjIHNsTEhJUt25dpxuBQ4ADAABgUmfOnNFnn32mTZs2KTU1VZIUEBCgBg0a6JlnnpGPj4+DKzQn+s0+hF75Q7/Zjz7LH/rNfs8++6yKFi2qKVOm5NiemJioNm3aaN++fQVc2c0hwAEAAADucIRe+UO/2Y8+yx/6zT7p6enKzMxU0aJFHV3KLUWAAwAAYGJpaWnaunWrUlJS5OrqqvLly6t27dqyWCyOLs3Uzp49q61btyo1NVUWi0UBAQGqU6eO0657AAAAjxEHAAAwoaysLI0YMUL//e9/lZ6eLunfR54GBwfro48+0mOPPebIEk3p0qVLeumll/Txxx/rwoULKlKkiAzD0MWLF+Xp6annn39e7777rtzd3R1dqukQeuUPIeutc/HiRaWkpCg4ONjRpTgV+u3GHT58WOnp6U7bVzyFCgAAwIRGjhypRYsWac6cOVqyZIkaNWqkCRMmaOfOnerevbueeuopLV++3NFlms5LL72kefPmKSYmRv/8848uXLig9PR0/fPPP4qJidH8+fM1bNgwR5dpKpcuXdKgQYPk5+en8PBw9ejRQ926dVOTJk3k5+enwYMH6+LFi44u03SysrL08ssv66677lJ4eLieeeYZPf3007r//vsVGhqqhQsXOrpEp7Nz506FhoY6ugynQ79ld+bMGXXt2lUhISHq0aOHMjIy1L9/fwUGBio0NFSNGzfW6dOnHV2m3ZhCBQAAYEJ33323vvzySz388MOSpIMHD6pKlSo6duyYPDw89MYbb+i7777Thg0bHFypudx1112Kj49X06ZNc2xfuXKlOnXqpKNHjxZwZeY1aNAgzZs3T++//75atWqlEiVKSJJOnjypZcuWadiwYfrPf/6jiRMnOrROsxkxYoS+/fZbjR8/Xp6enho3bpzatWunxx9/XF988YXeeecdffvtt2rZsqWjS3Ua27dvV506dZzuyUCORr9lN2DAAH3//ffq16+f5s+fL19fX+3du1fTp09XVlaW+vXrp8cff1zjxo1zdKl2IcABAAAwIR8fHyUkJKh8+fKSLv+138PDQwcOHFBAQIB27typBx54QGlpaQ6u1Fy8vb21YcMG1axZM8f2hIQE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",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"# Plotting a comparison of assets weights for each portfolio\n",
"\n",
"fig = plt.gcf()\n",
"fig.set_figwidth(14)\n",
"fig.set_figheight(6)\n",
"ax = fig.subplots(nrows=1, ncols=1)\n",
"\n",
"w_s.plot.bar(ax=ax)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.2 Calculate Augmented Black Litterman Portfolios for Several Risk Measures"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"You must convert self.cov_bl_fm to a positive definite matrix\n"
]
}
],
"source": [
"# Risk Measures available:\n",
"#\n",
"# 'MV': Standard Deviation.\n",
"# 'MAD': Mean Absolute Deviation.\n",
"# 'MSV': Semi Standard Deviation.\n",
"# 'FLPM': First Lower Partial Moment (Omega Ratio).\n",
"# 'SLPM': Second Lower Partial Moment (Sortino Ratio).\n",
"# 'CVaR': Conditional Value at Risk.\n",
"# 'EVaR': Entropic Value at Risk.\n",
"# 'WR': Worst Realization (Minimax)\n",
"# 'MDD': Maximum Drawdown of uncompounded cumulative returns (Calmar Ratio).\n",
"# 'ADD': Average Drawdown of uncompounded cumulative returns.\n",
"# 'CDaR': Conditional Drawdown at Risk of uncompounded cumulative returns.\n",
"# 'EDaR': Entropic Drawdown at Risk of uncompounded cumulative returns.\n",
"# 'UCI': Ulcer Index of uncompounded cumulative returns.\n",
"\n",
"rms = ['MV', 'MAD', 'MSV', 'FLPM', 'SLPM', 'CVaR',\n",
" 'EVaR', 'WR', 'MDD', 'ADD', 'CDaR', 'UCI', 'EDaR']\n",
"\n",
"w_s = pd.DataFrame([])\n",
"port.alpha = 0.05\n",
"\n",
"port.blfactors_stats(flavor='ABL',\n",
" B=loadings,\n",
" P_f=P_f,\n",
" Q_f=Q_f/252,\n",
" rf=0,\n",
" delta=None,\n",
" eq=True,\n",
" const=True,\n",
" diag=True,\n",
" method_mu=method_mu,\n",
" method_cov=method_cov)\n",
"\n",
"model = 'BL_FM'\n",
"obj = 'Sharpe'\n",
"\n",
"for i in rms:\n",
" if i == 'MV':\n",
" hist = 2\n",
" else:\n",
" hist = True\n",
" w = port.optimization(model=model, rm=i, obj=obj, rf=rf, l=l, hist=hist)\n",
" w_s = pd.concat([w_s, w], axis=1)\n",
" \n",
"w_s.columns = rms"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
" \n",
" \n",
" \n",
" MV \n",
" MAD \n",
" MSV \n",
" FLPM \n",
" SLPM \n",
" CVaR \n",
" EVaR \n",
" WR \n",
" MDD \n",
" ADD \n",
" CDaR \n",
" UCI \n",
" EDaR \n",
" \n",
" \n",
" \n",
" \n",
" APA \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" \n",
" \n",
" CMCSA \n",
" 7.31% \n",
" 7.34% \n",
" 8.79% \n",
" 6.38% \n",
" 8.88% \n",
" 8.36% \n",
" 8.79% \n",
" 5.47% \n",
" 6.11% \n",
" 15.07% \n",
" 5.27% \n",
" 11.85% \n",
" 7.29% \n",
" \n",
" \n",
" CNP \n",
" 1.67% \n",
" 3.53% \n",
" 0.00% \n",
" 2.67% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 18.42% \n",
" 4.20% \n",
" 25.33% \n",
" 10.06% \n",
" 20.55% \n",
" \n",
" \n",
" HPQ \n",
" 21.27% \n",
" 22.38% \n",
" 19.00% \n",
" 24.95% \n",
" 18.78% \n",
" 16.58% \n",
" 15.88% \n",
" 14.88% \n",
" 13.48% \n",
" 3.41% \n",
" 6.93% \n",
" 1.57% \n",
" 10.91% \n",
" \n",
" \n",
" PSA \n",
" 12.08% \n",
" 15.68% \n",
" 15.84% \n",
" 15.57% \n",
" 15.77% \n",
" 15.63% \n",
" 7.81% \n",
" 0.00% \n",
" 38.43% \n",
" 31.22% \n",
" 41.50% \n",
" 34.67% \n",
" 41.70% \n",
" \n",
" \n",
" SEE \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 7.49% \n",
" 12.88% \n",
" 4.78% \n",
" 11.08% \n",
" 7.65% \n",
" \n",
" \n",
" ZION \n",
" 20.91% \n",
" 17.88% \n",
" 18.28% \n",
" 18.92% \n",
" 18.22% \n",
" 17.27% \n",
" 15.12% \n",
" 14.63% \n",
" 6.48% \n",
" 13.10% \n",
" 13.29% \n",
" 14.57% \n",
" 10.48% \n",
" \n",
" \n",
" PEP11900D031 \n",
" 2.34% \n",
" 6.29% \n",
" 0.00% \n",
" 3.83% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" \n",
" \n",
" PEP13000D012 \n",
" 6.37% \n",
" 15.62% \n",
" 19.18% \n",
" 15.37% \n",
" 19.39% \n",
" 25.39% \n",
" 24.55% \n",
" 18.52% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" \n",
" \n",
" PEP13000M088 \n",
" 2.03% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 9.59% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" \n",
" \n",
" PEP23900M103 \n",
" 4.15% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 2.27% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" \n",
" \n",
" PEP70101M530 \n",
" 9.62% \n",
" 5.86% \n",
" 4.04% \n",
" 4.75% \n",
" 4.03% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" \n",
" \n",
" PEP70101M571 \n",
" 8.27% \n",
" 5.43% \n",
" 14.87% \n",
" 7.56% \n",
" 14.93% \n",
" 16.77% \n",
" 27.86% \n",
" 46.51% \n",
" 0.00% \n",
" 17.84% \n",
" 2.90% \n",
" 16.20% \n",
" 1.41% \n",
" \n",
" \n",
" PEP70310M156 \n",
" 3.98% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" 0.00% \n",
" \n",
" \n",
"
\n"
],
"text/plain": [
""
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"w_s.style.format(\"{:.2%}\").background_gradient(cmap='YlGn')"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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7zVkViu7zzl69Kheeuklff311zpy5IhKly6tu+++W1FRUWrcuLEqVqyoESNGaMSIEdnOTUpKUmhoqHW7VKlSql27tl599VW1aNFCktSvXz/FxcVpwIABmjVrls35gwcP1syZM9W3b1/Fxsband1ejMABAFzXqtWVrQsAAABgFo888oi2b9+uuLg47dmzR19++aVatmypv/7664Zf49tvv1VKSorWrl0rHx8fdezYUfv377e2BwUF6dNPP9WFCxes+y5evKj58+crODi4QK8nL4zAAQAAAAAATufUqVNav3691qxZYx0xExISooYNG9r1OmXLllVAQIACAgI0e/ZsVahQQStWrNCAAQMkSfXr19cff/yhRYsWqWfPnpKkRYsWKSgoSJUqVSrYi8oDI3AAAAAAAIDT8fb2lre3txYvXqz09PQCec3ixYtLki5dumSz/4knnlBMTIx1Ozo6WhEREQXynjeKAg4AAAAAAHA6bm5uio2NVVxcnEqVKqWmTZtq7Nix+uWXX/L1emlpaRozZoxcXV2tI3qu6t27t9avX6+kpCQlJydrw4YN6tWrV0Fcxg2jgAMAAAAAAJzSI488osOHD+vLL79U+/bttWbNGtWvX9+uSYWbNGkib29vlSxZUkuWLFFsbKxq165tc0y5cuXUqVMnxcXFKSYmRp06dVK5cuUK+Gryxhw4AAAAAADAaXl6eqpt27Zq27atxo8fr/79++vll19Wv379buj8+Ph43XXXXSpVqpTKli2b63ERERF6+umnJUnTp08viOh2YQQOAAAAAAAoMu666y6lpaXd8PFBQUGqXLlynsUbSerQoYMyMjKUkZGh9u3b32xMuzECBwAAAAAAOJ0TJ07o0UcfVUREhOrUqaOSJUtqy5YteuONN9SlSxfrcYcOHVJCQoLNufl5/Lerq6sSExOt64WNAg4AAAAAAHA63t7eatSokd59913t27dPly5dUlBQkJ588kmNHTvWetxbb72lt956y+bcmJgYtWzZ0u739PHxudnY+UYBBwAAAAAA5GjIrFaOjpArDw8PTZo0SZMmTcr1mKSkpDxfwzCMPNuvNxny4sWL82wvSMyBAwAAAAAAYHIUcAAAAAAAAEyOAg4AAAAAAIDJUcABAAAAAAAwOQo4AAAAAAAAJkcBBwAAAAAAwOQo4AAAAAAAAJgcBRwAAAAAAACT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8/eLHTt2GF5eXoWYyDlYLBbDxcXFsFgs2Zar+/l3zZavr6/1S10/P79sX/D+/vvvTvnvGpMY36D9+/crNjZWgwYN0oULF9SjRw/17NmT+TSuo1WrVpo7d66OHj2q3r17q3379vTZdRiGodatW8vN7e+P5/nz5/Xggw+qWLFi1n3btm1zRDxTO3DggBo2bJhr+3333SeLxaK5c+cWYipza9KkiYYOHaqffvpJ1apVc3Qcp7Fz506lpqZKuvKZ3bVrl86dOyfpykTksGUYhubNm6fx48fr8uXLev311xUZGWmdCBo5S09P16BBg1S7du0c25OTk/XKK68UcirzO3TokGrVqmXdrly5stasWaNWrVqpd+/eeuONNxyYzpzKli2r5ORkBQcH6/Dhw7p8+bIOHDhg7cfk5GSVKVPGwSnNJyMjQ15eXpIkd3d3FS9e3GY+zLJly+rEiROOimdKpUuX1t69e3XXXXfl2P7777/nOW/a7aps2bL6z3/+o9atW+fY/ttvv+nBBx8s5FTm1qJFC82fP1916tRRvXr1tGbNGtWpU8fa/t133+nOO+90YML8oYBzg+68806NGzdO48aN0+rVqxUdHa2mTZvq8uXLio2NVf/+/VW1alVHxzSdFStW6ODBg4qJibEWv7p16yZJFHJy8fLLL2fb16VLFwckcT4+Pj46evSogoKCcmxPTU3lF9B/oMiaP61bt5ZxzTMAOnfuLOnKv2vGP55KBenuu+/Wvn37NHToUI0YMULFixdXWlpatuN8fHwckM686tatq6CgIPXt2zfH9u3bt1PAyUFAQID27dunihUrWveVL19eq1evVnh4eK79eTvr0qWLIiMj1bdvX3355Zfq06ePnnvuObm4uMhisWjUqFFq166do2OaTlBQkP744w/rz9qnn36qwMBAa3tKSgoPOPmHJ598Un379tWLL76otm3byt/fXxaLRampqVq5cqVef/11jRgxwtExTadBgwY6fPiwQkJCcmw/deqUze8lkCZPnqxmzZrp8OHDuv/++zVu3Dht3rxZNWrU0O7duxUfH69Zs2Y5OqbdeArVTTh9+rQ+/vhjRUdHa9u2bapVq5Z++eUXR8cytZUrVyo6OlqLFy9WUFCQunbtqq5du6p+/fqOjoYioFu3brp8+bIWLlyYY/sjjzwiV1dXLViwoJCTmdvVImtMTIy1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HqToZYfg4GBFRUXp5Zdf1rfffuvoOKbTunVrubm56cyZM9qzZ4+1KC1d+RLTGb8kp4Bzg65+G/1Pp0+f1scff6y5c+cqISGBquc/jBo1Sj169NDSpUv122+/qWPHjgoNDbW2L1u2TA0bNnRgQvMJDg6WxWLR559/nusxFouFAk4OLBaLzp49K09PT0lXnt5ydd+ZM2esx/n4+DgqoulQZLVfUlKSoyM4nZo1a+qLL77I9Sl7ixcvtvmlCle0adNGu3bt0v333y9JGjRokE37ihUreEJcDh5//HFduHAh1/aAgAC9/PLLhZjI/F555RV5eXlp06ZNGjBggF544QXVqVNHzz//vM6fP68HH3xQr776qqNjms7gwYNVtmxZvfvuu5o9e7b17wBXV1c1aNBA8+bN02OPPebglOYyaNAgm7+Xrj4g5qqvv/6aCYxzEBISIldX11zbLRaL2rZtW4iJzO+f/84XL17cZnvJkiVO+VQvnkKVT6tXr1Z0dLQWLVqkkJAQPfLII3rkkUd4VHEOvv32Wy1dulQBAQEaOnSozYfnlVdeUYsWLdSyZUvHBUSRcXWG/mtdLeJcu06h9W8LFy5Ujx491KxZM/3666+699579dVXX1nbX3jhBe3fv18LFixwYEpz+fHHH/XXX3/pgQcesO6bN2+eXn75ZaWlpenhhx/We++9Jw8PDwemNJe4uDgNGjRIb731lp566inro4gvX76s2bNna9SoUZoxY4b69evn2KBOZv/+/fL09OTbasAELl26pOPHj0uSypUrl+eoQwDILwo4dvjzzz8VGxur6OhopaWl6bHHHtOsWbO0fft2mzkkgJuxevVqPf3009q0aVO2kSKnT59WkyZNNGvWLKesGN9qa9euvaHjchtWf7tatWqVvvrqKwUGBmro0KHy8vKytlFkza5Dhw4KDw/XCy+8IEnasWOH6tevr379+qlGjRp68803NWDAAEVFRTk2qMmMHDlS77zzjkqWLKnKlStLkvbt26dz585p2LBhevfddx2cEAAAwNwo4Nygjh07av369ercubN69uypDh06yNXVVe7u7hRw8rB3716NHz9es2fPzrEYMWjQIL322muqVKmSgxKaz0MPPaTw8PBcbzWYNm2avvvuuzxvsbpdXXubVF64hepvFy5c0MiRI7V48WJdunRJbdq00bRp05zynuDCEhgYqCVLllgnyx43bpzWrl2r9evXS5I+++wzvfzyy9q5c6cjY5rSpk2bNH/+fO3du1eSVLVqVXXv3l333Xefg5OZV1pamj755BNt3LhRqampslgs8vf3V9OmTdWjRw+VKFHC0RFNiX6z3+bNmzVlypRsfdakSRM988wz1n/zcOP27dunJ598UqtXr3Z0FNPIyMhQsWLFrNv79u3Te++9p7179yowMFCDBg1SgwYNHJjQnOi3guesn08KODfIzc1Nw4YN06BBg1SlShXrfgo4eXvqqadUqlQpvfHGGzm2v/DCCzpz5oxmzpxZyMnMKyQkRMuXL1eNGjVybN+1a5fatWunAwcOFHIy88vpFqqccAvV367eutKzZ095eXnpk08+UcuWLfXZZ585OpppeXp6au/evQoKCpIk3X///erQoYNefPFFSVfmyKlduzZPo8JN27lzp9q2bavz58+rRYsW8vf3l2EYOnr0qNauXasSJUpoxYoV/A7yD/Sb/RYvXqzHHntMrVu3Vvv27W36bMWKFVq1apUWLFigLl26ODqqU9m+fbvq16/P7x3XcHV1VUpKivz8/JSQkKCmTZuqatWquvfee5WQkKDt27dr3bp1zJH5D/RbwXPWzycFnBv0ww8/KDo6WgsWLFD16tXVu3dvdevWTeXLl6eAk4fq1avrww8/1L333ptj+9atW/X4449r9+7dhZzMvDw9PfXrr79aZ+f/p99//121a9fOc4LG29W1t1AZhqGOHTvqgw8+0J133mlzHLdQ/a1y5cqaOHGiunfvLunKY+ybNm2qixcv5jlZ3u0sJCREH374oZo3b66MjAyVKlVKS5YsUevWrSVduaWqRYsW+uuvvxyc1Dx++eWXGzquTp06tziJcwkPD1dAQIDi4uJsvnmVrnwb269fP6WkpOi7775zUEJzot/sV6tWLfXq1UujR4/Osf0///mP5s2bp99++62Qk5nbtGnT8mw/dOiQ3nrrLaf7A/FWcnFxUWpqqvz8/PTggw/K09NTCxYssH4BFxERoZSUFH399dcOTmou9Jv9iurnkwKOnc6fP69PP/1U0dHR+umnn5SZmal33nlHERERKlmypKPjmY6Xl5d27dqV61O8kpOTVaNGDZ0/f76Qk5lX5cqV9dZbb+lf//pXju2LFi3SyJEj9ccffxRyMudTsmRJbd++nVv08lCs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q5Zre9WqVXXy5MlCTOQc6Df70Wf5Q7/Zb8mSJbp48aJ8fX1zXLy9vR0dMV8YgQMAAGBCO3bsULt27ZSenq4WLVrI399fFotFqamp+v777+Xh4aGVK1eqZs2ajo5qKvSb/Vq2bKkKFSooNjZWbm62MyxcvnxZffv21aFDh7RmzRrHBDQp+s1+9Fn+0G/2q1OnjoYPH67IyMgc2xMSEtSgQQOnG4FDAQcAAMCkzp49q48++kibNm1SamqqJCkgIECNGzfW448/Lh8fHwcnNCf6zT4UvfKHfrMffZY/9Jv9nnjiCRUvXlzTp0/PsT0xMVEdO3bU/v37CznZzaGAAwAAANzmKHrlD/1mP/osf+g3+6SnpyszM1PFixd3dJQCRQEHAADAxNLS0rR161alpKTI1dVVlSpVUr169WSxWBwdzdTOnTunrVu3KjU1VRaLRQEBAapfv77TznsAAACPEQcAADChrKwsjR49Wv/973+Vnp4u6e9HngYHB+u9997Tgw8+6MiIpnT58mU999xzev/993Xx4kUVK1ZMhmHo0qVL8vT01FNPPaU333xT7u7ujo5qOhS98ocia8G5dOmSUlJSFBwc7OgoToV+u3FHjhxRenq60/YVT6ECAAAwobFjx+qrr77S/PnztWzZMjVt2lSTJ0/Wzp071adPHz366KNasWKFo2OaznPPPaeFCxcqJiZGf/31ly5evKj09HT99ddfiomJ0aJFizRq1ChHxzSVy5cva/jw4fLz81N4eLj69u2r3r17q2XLlvLz89OIESN06dIlR8c0naysLD3//PO64447FB4erscff1yPPfaY7rnnHoWGhmrJkiWOjuh0du7cqdDQUEfHcDr0W3Znz55Vr169FBISor59+yojI0NDhgxRYGCgQkND1aJFC505c8bRMe3GLVQAAAAmdOedd+rTTz9Vs2bNJEmHDh1S9erVdfz4cXl4eOjVV1/V119/rY0bNzo4qbnccccdio+PV6tWrXJsX7Vqlbp3765jx44VcjLzGj58uBYuXKi3335b7du3V6lSpSRJp06d0jfffKNRo0bp3//+t6ZMmeLQnGYzevRoffnll5o0aZI8PT01ceJEde7cWQ899JA++eQTvfHGG/ryyy/Vrl07R0d1Gtu3b1f9+vWd7slAjka/ZTd06FB9++23Gjx4sBYtWiRfX1/t27dPs2bN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",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"# Plotting a comparison of assets weights for each portfolio\n",
"\n",
"fig = plt.gcf()\n",
"fig.set_figwidth(14)\n",
"fig.set_figheight(6)\n",
"ax = fig.subplots(nrows=1, ncols=1)\n",
"\n",
"w_s.plot.bar(ax=ax)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can see that in the examples the Augmented Black Litterman model and the Bayesian Black Litterman model increase the diversification when we only consider the mean vector obtained through these methods and we use the covariance and scenarios from the factor model."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.11.7"
}
},
"nbformat": 4,
"nbformat_minor": 4
}