Skip to content

Instantly share code, notes, and snippets.

@FilippoGuerrieri26
Created July 27, 2023 18:00
Show Gist options
  • Save FilippoGuerrieri26/a5bd497480451b971bbba8a35713b3dc to your computer and use it in GitHub Desktop.
Save FilippoGuerrieri26/a5bd497480451b971bbba8a35713b3dc to your computer and use it in GitHub Desktop.
mean_variance
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "269c5f46-b00f-412b-b31c-c6bf4d71eef9",
"metadata": {},
"source": [
"# Mean Variance Optimization"
]
},
{
"cell_type": "markdown",
"id": "c6f44bc4-d674-49e2-be9d-e854538d7289",
"metadata": {},
"source": [
"The modern portfolio theory (MPT) is a practical method for selecting investments in order to maximize their overall returns within an acceptable level of risk. <br>\n",
"This theory was firstly introduced by the American economist Harry Markowitz in his seminal paper \"Portfolio Selection\", published in the journal of Finance in 1952. Harry Markowitz was later awarded a Nobel Prize for his work. <br>\n",
"The mathematical framework developed by Markowitz is used to build a portfolio of investments that maximize the amount of expected (or ex-ante) return given a certain level of risk. <br>"
]
},
{
"cell_type": "markdown",
"id": "b274dd9c-3d90-476f-9faf-1428271c8411",
"metadata": {},
"source": [
"In order to achieve the Mean Variance Optimization Framework, we can go down two possible routes: <br>\n",
"1. The first one is to look at the Ex-Ante Sharpe Ratio of the Portfolio and maximise this ratio. Recall the Sharpe Ratio is defined as <br>\n",
" <br>\n",
" $SR_p = ER(P) / \\sigma_p$ <br>\n",
"<br>\n",
"2. The second option is to minimize the portfolio ex-ante volatility given a target return <br>\n",
"<br>\n",
"\n",
"In this notebook I am going to contruct both ways. The second approach I will use to introduce the concept of Efficient Frontier and show how to plot it."
]
},
{
"cell_type": "markdown",
"id": "97f2c6bb-4a70-47f4-8ece-243426f77371",
"metadata": {},
"source": [
"## 1) Define Functions"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "56cb8076-8745-4669-b099-19522f6a7c9c",
"metadata": {},
"outputs": [],
"source": [
"# Import packages\n",
"import pandas as pd\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from scipy.optimize import minimize, Bounds"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "d3b09213-26d5-48b9-a676-fe31217d317f",
"metadata": {},
"outputs": [],
"source": [
"# Define portfolio return as a function of constituents weights and returns\n",
"def portfolio_return(weights, returns):\n",
" return weights @ returns"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "e879c049-209a-4b35-aa9c-eb185424c4bc",
"metadata": {},
"outputs": [],
"source": [
"# Define portfolio ex-ante volatility as a function of constituent weights and VCV matrix\n",
"def portfolio_volatility(weights, covmat):\n",
" w = np.array(weights)\n",
" covmat = np.asarray(covmat)\n",
" return np.dot(np.dot(w.T, covmat), weights) ** 0.5"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "3bf87f68-2e34-4c54-92e8-22d0f70dddad",
"metadata": {},
"outputs": [],
"source": [
"# Negative Sharpe Ratio Function to be optimized\n",
"def negative_sharpe_ratio(weights, exp_ret, covmat, risk_free=0.0):\n",
" return - ((portfolio_return(weights=weights, returns=exp_ret) - risk_free)\n",
" / portfolio_volatility(weights=weights, covmat=covmat) ** 0.5)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "dc1bad1a-d0f6-47b4-a3e4-0ab09578eded",
"metadata": {},
"outputs": [],
"source": [
"# Portfolio risk to be optimized\n",
"def risk(weights, exp_ret, covmat, risk_free=0.0):\n",
" return portfolio_volatility(weights=weights, covmat=covmat)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "732b7ed2-9b5e-4c39-98bc-6da36c5b72f5",
"metadata": {},
"outputs": [],
"source": [
"# Define Optimization Function\n",
"def optimize(func, exp_ret, covmat, risk_free, target_return=None, allow_short=False):\n",
" \"\"\"\n",
" Optimize the input function and return portfolio weights.\n",
" Can be used either with negative sharpe ratio and no target return, or risk and target return\n",
" If allow short, negative weights allowed. By default, bunds are set (-1, 1)\n",
" \"\"\"\n",
" init_weights = [1 / covmat.shape[0]] * covmat.shape[0]\n",
"\n",
" opt_bounds = Bounds(0, 1) if not allow_short else Bounds(-1, 1)\n",
"\n",
" opt_constraints = {'type': 'eq',\n",
" 'fun': lambda w: 1.0 - np.sum(w)}\n",
" if target_return is not None:\n",
" opt_constraints = ({'type': 'eq',\n",
" 'fun': lambda w: 1.0 - np.sum(w)},\n",
" {'type': 'eq',\n",
" 'fun': lambda w: target_return - w.T @ exp_ret})\n",
"\n",
" optimal_weights = minimize(func,\n",
" init_weights,\n",
" args=(exp_ret, covmat, risk_free),\n",
" method='SLSQP',\n",
" bounds=opt_bounds,\n",
" constraints=opt_constraints)\n",
"\n",
" return optimal_weights.x"
]
},
{
"cell_type": "markdown",
"id": "d01b448e-450f-459f-a58a-4ea0f1c7e188",
"metadata": {},
"source": [
"## 2) Read Sample Data"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "e156d14b-8464-4df6-852b-872b11f93697",
"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>Agric</th>\n",
" <th>Food</th>\n",
" <th>Soda</th>\n",
" <th>Beer</th>\n",
" <th>Smoke</th>\n",
" <th>Toys</th>\n",
" <th>Fun</th>\n",
" <th>Books</th>\n",
" <th>Hshld</th>\n",
" <th>Clths</th>\n",
" <th>...</th>\n",
" <th>Boxes</th>\n",
" <th>Trans</th>\n",
" <th>Whlsl</th>\n",
" <th>Rtail</th>\n",
" <th>Meals</th>\n",
" <th>Banks</th>\n",
" <th>Insur</th>\n",
" <th>RlEst</th>\n",
" <th>Fin</th>\n",
" <th>Other</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Date</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2000-02-29</th>\n",
" <td>0.068472</td>\n",
" <td>-0.071657</td>\n",
" <td>-0.086558</td>\n",
" <td>-0.116859</td>\n",
" <td>-0.039824</td>\n",
" <td>0.004201</td>\n",
" <td>-0.033265</td>\n",
" <td>-0.002529</td>\n",
" <td>-0.116674</td>\n",
" <td>-0.105813</td>\n",
" <td>...</td>\n",
" <td>-0.127882</td>\n",
" <td>-0.052703</td>\n",
" <td>0.016575</td>\n",
" <td>-0.041647</td>\n",
" <td>-0.120569</td>\n",
" <td>-0.113040</td>\n",
" <td>-0.131426</td>\n",
" <td>0.020556</td>\n",
" <td>0.066967</td>\n",
" <td>-0.015026</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2000-03-31</th>\n",
" <td>0.043484</td>\n",
" <td>0.104341</td>\n",
" <td>-0.003911</td>\n",
" <td>0.001821</td>\n",
" <td>0.052309</td>\n",
" <td>0.078418</td>\n",
" <td>0.111058</td>\n",
" <td>0.126672</td>\n",
" <td>-0.147599</td>\n",
" <td>0.250240</td>\n",
" <td>...</td>\n",
" <td>0.127391</td>\n",
" <td>0.127595</td>\n",
" <td>0.069853</td>\n",
" <td>0.144585</td>\n",
" <td>0.160870</td>\n",
" <td>0.150960</td>\n",
" <td>0.233528</td>\n",
" <td>0.042740</td>\n",
" <td>0.149051</td>\n",
" <td>-0.015447</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2000-04-30</th>\n",
" <td>-0.058529</td>\n",
" <td>-0.051005</td>\n",
" <td>-0.005994</td>\n",
" <td>0.036583</td>\n",
" <td>0.038363</td>\n",
" <td>0.001111</td>\n",
" <td>0.044316</td>\n",
" <td>-0.077032</td>\n",
" <td>0.047017</td>\n",
" <td>0.036836</td>\n",
" <td>...</td>\n",
" <td>-0.082692</td>\n",
" <td>0.034616</td>\n",
" <td>-0.030021</td>\n",
" <td>-0.054818</td>\n",
" <td>0.037121</td>\n",
" <td>-0.028531</td>\n",
" <td>0.000034</td>\n",
" <td>-0.025197</td>\n",
" <td>-0.112271</td>\n",
" <td>0.088046</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2000-05-31</th>\n",
" <td>-0.011313</td>\n",
" <td>0.173636</td>\n",
" <td>-0.073239</td>\n",
" <td>0.119248</td>\n",
" <td>0.194693</td>\n",
" <td>0.010906</td>\n",
" <td>0.013244</td>\n",
" <td>-0.064416</td>\n",
" <td>0.029127</td>\n",
" <td>-0.053616</td>\n",
" <td>...</td>\n",
" <td>-0.025352</td>\n",
" <td>-0.036809</td>\n",
" <td>0.013387</td>\n",
" <td>-0.031333</td>\n",
" <td>-0.042611</td>\n",
" <td>0.079685</td>\n",
" <td>0.062347</td>\n",
" <td>-0.032784</td>\n",
" <td>-0.065917</td>\n",
" <td>0.104813</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2000-06-30</th>\n",
" <td>0.002221</td>\n",
" <td>0.017665</td>\n",
" <td>0.013378</td>\n",
" <td>0.060779</td>\n",
" <td>0.030101</td>\n",
" <td>-0.016968</td>\n",
" <td>-0.009577</td>\n",
" <td>-0.003258</td>\n",
" <td>-0.029174</td>\n",
" <td>-0.077753</td>\n",
" <td>...</td>\n",
" <td>-0.030232</td>\n",
" <td>-0.018448</td>\n",
" <td>-0.024008</td>\n",
" <td>-0.019798</td>\n",
" <td>-0.039315</td>\n",
" <td>-0.099044</td>\n",
" <td>-0.027761</td>\n",
" <td>-0.014854</td>\n",
" <td>0.143584</td>\n",
" <td>0.029686</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 49 columns</p>\n",
"</div>"
],
"text/plain": [
" Agric Food Soda Beer Smoke Toys \\\n",
"Date \n",
"2000-02-29 0.068472 -0.071657 -0.086558 -0.116859 -0.039824 0.004201 \n",
"2000-03-31 0.043484 0.104341 -0.003911 0.001821 0.052309 0.078418 \n",
"2000-04-30 -0.058529 -0.051005 -0.005994 0.036583 0.038363 0.001111 \n",
"2000-05-31 -0.011313 0.173636 -0.073239 0.119248 0.194693 0.010906 \n",
"2000-06-30 0.002221 0.017665 0.013378 0.060779 0.030101 -0.016968 \n",
"\n",
" Fun Books Hshld Clths ... Boxes Trans \\\n",
"Date ... \n",
"2000-02-29 -0.033265 -0.002529 -0.116674 -0.105813 ... -0.127882 -0.052703 \n",
"2000-03-31 0.111058 0.126672 -0.147599 0.250240 ... 0.127391 0.127595 \n",
"2000-04-30 0.044316 -0.077032 0.047017 0.036836 ... -0.082692 0.034616 \n",
"2000-05-31 0.013244 -0.064416 0.029127 -0.053616 ... -0.025352 -0.036809 \n",
"2000-06-30 -0.009577 -0.003258 -0.029174 -0.077753 ... -0.030232 -0.018448 \n",
"\n",
" Whlsl Rtail Meals Banks Insur RlEst \\\n",
"Date \n",
"2000-02-29 0.016575 -0.041647 -0.120569 -0.113040 -0.131426 0.020556 \n",
"2000-03-31 0.069853 0.144585 0.160870 0.150960 0.233528 0.042740 \n",
"2000-04-30 -0.030021 -0.054818 0.037121 -0.028531 0.000034 -0.025197 \n",
"2000-05-31 0.013387 -0.031333 -0.042611 0.079685 0.062347 -0.032784 \n",
"2000-06-30 -0.024008 -0.019798 -0.039315 -0.099044 -0.027761 -0.014854 \n",
"\n",
" Fin Other \n",
"Date \n",
"2000-02-29 0.066967 -0.015026 \n",
"2000-03-31 0.149051 -0.015447 \n",
"2000-04-30 -0.112271 0.088046 \n",
"2000-05-31 -0.065917 0.104813 \n",
"2000-06-30 0.143584 0.029686 \n",
"\n",
"[5 rows x 49 columns]"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 49 Industry portfolio data\n",
"returns = pd.read_excel(\"../49_portfolios.xlsx\")\n",
"returns.set_index(\"Date\", inplace=True)\n",
"returns.head()"
]
},
{
"cell_type": "markdown",
"id": "a0a403f9-90a4-4999-b920-c0a77122e864",
"metadata": {},
"source": [
"## 3) Apply Mean Variance Optimization"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "c01bcd8c-ff39-4458-b610-35f3abdd9bae",
"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>Agric</th>\n",
" <th>Food</th>\n",
" <th>Soda</th>\n",
" <th>Beer</th>\n",
" <th>Smoke</th>\n",
" <th>Toys</th>\n",
" <th>Fun</th>\n",
" <th>Books</th>\n",
" <th>Hshld</th>\n",
" <th>Clths</th>\n",
" <th>...</th>\n",
" <th>Boxes</th>\n",
" <th>Trans</th>\n",
" <th>Whlsl</th>\n",
" <th>Rtail</th>\n",
" <th>Meals</th>\n",
" <th>Banks</th>\n",
" <th>Insur</th>\n",
" <th>RlEst</th>\n",
" <th>Fin</th>\n",
" <th>Other</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Agric</th>\n",
" <td>0.065914</td>\n",
" <td>0.013899</td>\n",
" <td>0.012753</td>\n",
" <td>0.011274</td>\n",
" <td>0.016191</td>\n",
" <td>0.026432</td>\n",
" <td>0.036881</td>\n",
" <td>0.031536</td>\n",
" <td>0.011314</td>\n",
" <td>0.025402</td>\n",
" <td>...</td>\n",
" <td>0.030105</td>\n",
" <td>0.026687</td>\n",
" <td>0.027132</td>\n",
" <td>0.020021</td>\n",
" <td>0.020713</td>\n",
" <td>0.028190</td>\n",
" <td>0.022501</td>\n",
" <td>0.036617</td>\n",
" <td>0.036715</td>\n",
" <td>0.020368</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Food</th>\n",
" <td>0.013899</td>\n",
" <td>0.023091</td>\n",
" <td>0.017230</td>\n",
" <td>0.016629</td>\n",
" <td>0.021472</td>\n",
" <td>0.018713</td>\n",
" <td>0.020240</td>\n",
" <td>0.019191</td>\n",
" <td>0.015262</td>\n",
" <td>0.019213</td>\n",
" <td>...</td>\n",
" <td>0.018170</td>\n",
" <td>0.017316</td>\n",
" <td>0.018008</td>\n",
" <td>0.014674</td>\n",
" <td>0.016879</td>\n",
" <td>0.019596</td>\n",
" <td>0.020847</td>\n",
" <td>0.022026</td>\n",
" <td>0.017215</td>\n",
" <td>0.014831</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Soda</th>\n",
" <td>0.012753</td>\n",
" <td>0.017230</td>\n",
" <td>0.055634</td>\n",
" <td>0.021872</td>\n",
" <td>0.020718</td>\n",
" <td>0.026059</td>\n",
" <td>0.035657</td>\n",
" <td>0.027019</td>\n",
" <td>0.019196</td>\n",
" <td>0.029159</td>\n",
" <td>...</td>\n",
" <td>0.024546</td>\n",
" <td>0.023761</td>\n",
" <td>0.023691</td>\n",
" <td>0.018787</td>\n",
" <td>0.023477</td>\n",
" <td>0.024668</td>\n",
" <td>0.025006</td>\n",
" <td>0.040405</td>\n",
" <td>0.025511</td>\n",
" <td>0.020294</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Beer</th>\n",
" <td>0.011274</td>\n",
" <td>0.016629</td>\n",
" <td>0.021872</td>\n",
" <td>0.027925</td>\n",
" <td>0.018788</td>\n",
" <td>0.014748</td>\n",
" <td>0.017299</td>\n",
" <td>0.015025</td>\n",
" <td>0.017701</td>\n",
" <td>0.016847</td>\n",
" <td>...</td>\n",
" <td>0.016030</td>\n",
" <td>0.017024</td>\n",
" <td>0.015123</td>\n",
" <td>0.013297</td>\n",
" <td>0.016885</td>\n",
" <td>0.016415</td>\n",
" <td>0.017740</td>\n",
" <td>0.017660</td>\n",
" <td>0.015226</td>\n",
" <td>0.015074</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Smoke</th>\n",
" <td>0.016191</td>\n",
" <td>0.021472</td>\n",
" <td>0.020718</td>\n",
" <td>0.018788</td>\n",
" <td>0.066761</td>\n",
" <td>0.021389</td>\n",
" <td>0.021845</td>\n",
" <td>0.021957</td>\n",
" <td>0.018814</td>\n",
" <td>0.019604</td>\n",
" <td>...</td>\n",
" <td>0.020588</td>\n",
" <td>0.018642</td>\n",
" <td>0.022201</td>\n",
" <td>0.010000</td>\n",
" <td>0.018174</td>\n",
" <td>0.024592</td>\n",
" <td>0.021807</td>\n",
" <td>0.025591</td>\n",
" <td>0.021368</td>\n",
" <td>0.021720</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 49 columns</p>\n",
"</div>"
],
"text/plain": [
" Agric Food Soda Beer Smoke Toys Fun \\\n",
"Agric 0.065914 0.013899 0.012753 0.011274 0.016191 0.026432 0.036881 \n",
"Food 0.013899 0.023091 0.017230 0.016629 0.021472 0.018713 0.020240 \n",
"Soda 0.012753 0.017230 0.055634 0.021872 0.020718 0.026059 0.035657 \n",
"Beer 0.011274 0.016629 0.021872 0.027925 0.018788 0.014748 0.017299 \n",
"Smoke 0.016191 0.021472 0.020718 0.018788 0.066761 0.021389 0.021845 \n",
"\n",
" Books Hshld Clths ... Boxes Trans Whlsl \\\n",
"Agric 0.031536 0.011314 0.025402 ... 0.030105 0.026687 0.027132 \n",
"Food 0.019191 0.015262 0.019213 ... 0.018170 0.017316 0.018008 \n",
"Soda 0.027019 0.019196 0.029159 ... 0.024546 0.023761 0.023691 \n",
"Beer 0.015025 0.017701 0.016847 ... 0.016030 0.017024 0.015123 \n",
"Smoke 0.021957 0.018814 0.019604 ... 0.020588 0.018642 0.022201 \n",
"\n",
" Rtail Meals Banks Insur RlEst Fin Other \n",
"Agric 0.020021 0.020713 0.028190 0.022501 0.036617 0.036715 0.020368 \n",
"Food 0.014674 0.016879 0.019596 0.020847 0.022026 0.017215 0.014831 \n",
"Soda 0.018787 0.023477 0.024668 0.025006 0.040405 0.025511 0.020294 \n",
"Beer 0.013297 0.016885 0.016415 0.017740 0.017660 0.015226 0.015074 \n",
"Smoke 0.010000 0.018174 0.024592 0.021807 0.025591 0.021368 0.021720 \n",
"\n",
"[5 rows x 49 columns]"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Variance - Covariance Matrix\n",
"vcv = returns.cov()\n",
"vcv = vcv * np.sqrt(252) # Annualized VCV. As frequency is daily, multiply * np.sqrt(252)\n",
"vcv.head()"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "25e08878-960d-421b-8cf4-9ef0b023afbc",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Agric 0.009760\n",
"Food 0.008096\n",
"Soda 0.010208\n",
"Beer 0.008206\n",
"Smoke 0.014435\n",
"dtype: float64"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Expected Returns\n",
"exp_ret = returns.mean()\n",
"exp_ret.head()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "2a3d356b-60e5-4e78-8df0-ef5a7aa3f596",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
" 4.32470397e-01, 4.31562735e-17, 0.00000000e+00, 3.56962191e-17,\n",
" 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
" 0.00000000e+00, 4.99169601e-18, 0.00000000e+00, 1.40894465e-17,\n",
" 0.00000000e+00, 0.00000000e+00, 3.88233874e-17, 1.26301729e-17,\n",
" 0.00000000e+00, 1.91236027e-17, 0.00000000e+00, 0.00000000e+00,\n",
" 0.00000000e+00, 5.67529603e-01, 0.00000000e+00, 0.00000000e+00,\n",
" 3.95422008e-18, 0.00000000e+00, 0.00000000e+00, 2.17585180e-17,\n",
" 1.47975682e-17, 2.51423596e-17, 1.79145500e-17, 1.28973079e-17,\n",
" 0.00000000e+00, 0.00000000e+00, 1.75497834e-17, 0.00000000e+00,\n",
" 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
" 3.26922561e-17, 0.00000000e+00, 2.85441910e-17, 2.08091003e-17,\n",
" 9.51196499e-18])"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Apply Mean Variance function\n",
"mean_variance_weights = optimize(func=negative_sharpe_ratio,\n",
" exp_ret=exp_ret,\n",
" covmat=vcv,\n",
" risk_free=0.0)\n",
"mean_variance_weights"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "ec39cddf-b5cd-4ecb-8769-326cdbb27458",
"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>Weight</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Agric</th>\n",
" <td>0.00000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Food</th>\n",
" <td>0.00000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Soda</th>\n",
" <td>0.00000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Beer</th>\n",
" <td>0.00000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Smoke</th>\n",
" <td>0.43247</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Weight\n",
"Agric 0.00000\n",
"Food 0.00000\n",
"Soda 0.00000\n",
"Beer 0.00000\n",
"Smoke 0.43247"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Transform into DataFrame for ease of visualization\n",
"mean_variance_weights = pd.DataFrame(mean_variance_weights, index=vcv.index, columns=[\"Weight\"])\n",
"mean_variance_weights.head()"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "72ca6fd0-aeee-4fc9-89cc-64ce0f5679f3",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<AxesSubplot:>"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABBEAAAHqCAYAAABSltYWAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABM50lEQVR4nO3dd7htV1kv4N+XE0hAIAqEYhJI0NBLwICUSFMuIEgRELBio0iRqAjIFRD1XlRApBlBUUQEBEQiRZBeApgEQgnlGhAhFA1ICZ3AuH+MuXLW3tnnnLnnmouzk7zv85zn7LX2Wt8eq84xvzHGN6q1FgAAAIB9OWB/NwAAAAA4f5BEAAAAAEaRRAAAAABGkUQAAAAARpFEAAAAAEaRRAAAAABGOXB//eHLXvay7cgjj9xffx4AAADYg1NPPfWzrbVDN1+/35IIRx55ZE455ZT99ecBAACAPaiq/9zqessZAAAAgFEkEQAAAIBRJBEAAACAUfZbTQQAAAD4bvnWt76VM888M1//+tf3d1N2lIMPPjiHH354LnKRi4y6vSQCAAAAF3hnnnlmLnnJS+bII49MVe3v5uwIrbV87nOfy5lnnpmjjjpq1H0sZwAAAOAC7+tf/3ouc5nLSCAsqapc5jKX2dbsDEkEAAAALhQkEM5ru8+JJAIAAACs2fHHH58nP/nJ516+7W1vm1/5lV859/Jv/uZv5klPetKW9330ox+d1772tXuN/9jHPjZPeMITznP9F77whTzjGc+Y1ugtqIkAAADAhc6Rj3jFrPE+9vg77PX3N73pTfOiF70oD33oQ/Od73wnn/3sZ/OlL33p3N+fdNJJG5IMyx73uMdNbtciifBrv/Zrk2MsMxMBAAAA1uxmN7tZTjrppCTJ6aefnmtf+9q55CUvmc9//vP5xje+kQ9+8INJklvc4hb5oR/6odz2trfNpz/96STJfe5zn7z4xS9Okrzyla/M1a9+9Rx33HF5yEMekjve8Y7n/o0PfOADueUtb5mrXOUqecpTnpIkecQjHpGPfOQjOeaYY/Kwhz1s5cdhJgIAAACs2fd///fnwAMPzMc//vGcdNJJuclNbpJPfvKTefvb355DDjkk17jGNXL88cfnZS97WQ499NC88IUvzKMe9ag8+9nPPjfG17/+9dzvfvfLm9/85hx11FG5973vveFvfOhDH8ob3vCGnH322bna1a6WBzzgAXn84x+f97///TnttNNmeRySCAAAAPBdsJiNcNJJJ+U3fuM38slPfjInnXRSDjnkkBx22GF5zWtek9vc5jZJkm9/+9u54hWvuOH+H/rQh3KVq1zl3O0Y733ve+eZz3zmub+/wx3ukIMOOigHHXRQLne5y+W//uu/Zn8MkggAAADwXXDTm940J510Ut73vvfl2te+do444og88YlPzKUudanc+ta3Pndmwp601vYa/6CDDjr35127duWcc86Zre0LaiIAAADAd8HNbnazvPzlL8+lL33p7Nq1K5e+9KXzhS98IW9/+9tzz3veM2eddda5SYRvfetbOf300zfc/+pXv3o++tGP5mMf+1iS5IUvfOE+/+YlL3nJnH322bM9BkkEAAAA+C64znWuk89+9rO58Y1vvOG6Qw45JJe73OXy4he/OA9/+MNzvetdL8ccc8y5hRgXLnaxi+UZz3hGbne72+W4447L5S9/+RxyyCF7/ZuXucxlcrOb3SzXvva1ZymsWPuaDrEuxx57bDvllFP2y98GAADgwuWDH/xgrnGNa+zvZqzsy1/+ci5xiUuktZYHPvCBOfroo3P88cevFHOr56aqTm2tHbv5tmYiAAAAwPnEs571rBxzzDG51rWulS9+8Yu53/3u9139+worAgAAwPnE8ccfv/LMg1VIIgAA+92Rj3jFqNt97PF3WHNLAIC9sZwBAACAC4X9VRNwJ9vucyKJAAAAwAXewQcfnM997nMSCUtaa/nc5z6Xgw8+ePR9LGcAAADgAu/www/PmWeembPOOmt/N2VHOfjgg3P44YePvr0kAgAAABd4F7nIRXLUUUft72ac71nOAAAAAIwiiQAAAACMIokAAAAAjCKJAAAAAIwiiQAAAACMIokAAAAAjCKJAAAAAIwiiQAAAACMIokAAAAAjCKJAAAAAIwiiQAAAACMIokAAAAAjCKJAAAAAIwiiQAAAACMIokAAAAAjCKJAAAAAIwiiQAAAACMIokAAAAAjCKJAAAAAIwiiQAAAACMIokAAAAAjCKJAAAAAIwiiQAAAACMIokAAAAAjCKJAAAAAIwiiQAAAACMIokAAAAAjCKJAAAAAIwiiQAAAACMIokAAAAAjCKJAAAAAIwiiQAAAACMIokAAAAAjCKJAAAAAIwiiQAAAACMIokAAAAAjCKJAAAA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\n",
"text/plain": [
"<Figure size 1296x576 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# Plot optimal weights\n",
"mean_variance_weights.plot(kind=\"bar\", figsize=(18, 8))"
]
},
{
"cell_type": "markdown",
"id": "82e8f1f7-9f90-4277-9443-952b2387d545",
"metadata": {},
"source": [
"## 4) Plot Efficient Frontier"
]
},
{
"cell_type": "markdown",
"id": "b61fd673-caba-4106-bf7a-197d4a85b4d4",
"metadata": {},
"source": [
"The efficient frontier is the set of optimal portfolios that offer the highest expected return for a defined level of risk or the lowest risk for a given level of expected return. <br>\n",
"Portfolios that lie below the efficient frontier are sub-optimal (also called \"dominated portfolios\"), because they do not provide enough return for the given level of risk. <br>"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "8cca8326-7932-4d23-966d-a55ec416f91e",
"metadata": {},
"outputs": [],
"source": [
"# Define a function to produce n sets of optimal weights, associated to n portfolios on the efficient frontier\n",
"def optimal_weights(n_points, er, vcv):\n",
" \"\"\"\n",
" Returns a list of weights that represent a grid of n_points on the efficient frontier\n",
" \"\"\"\n",
" target_rs = np.linspace(er.min(), er.max(), n_points)\n",
" weights = [optimize(func=risk,\n",
" exp_ret=exp_ret,\n",
" covmat=vcv,\n",
" target_return=target_return,\n",
" risk_free=0.0) for target_return in target_rs]\n",
" return weights"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "b79d626a-07b0-48fc-8c9c-d166732b8ba2",
"metadata": {},
"outputs": [],
"source": [
"weights = optimal_weights(1000, exp_ret, vcv) # define a set of target returns equal to the number of portfolios in the Efficient Frontier\n",
"rets = [portfolio_return(w, exp_ret) for w in weights] # portfolio returns\n",
"vols = [portfolio_volatility(w, vcv) for w in weights] # portfolio volatilities\n",
"ef = pd.DataFrame({\n",
" \"Returns\": rets,\n",
" \"Volatility\": vols})"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "ef1273f2-e3f3-4803-a89c-e94127fb3d2b",
"metadata": {},
"outputs": [],
"source": [
"# Find Global Minimum Variance Portfolio : the portfolio associated to the lowest possible level of ex-ante volatility given the constituents\n",
"# To do this, it is enough to simply minimize the ex-ante volatility\n",
"gmv_weights = optimize(func=risk,\n",
" exp_ret=exp_ret,\n",
" covmat=vcv,\n",
" risk_free=0.0)\n",
"gmv_vol=portfolio_volatility(weights=gmv_weights, covmat=vcv)\n",
"gmv_ret=portfolio_return(weights=gmv_weights, returns=exp_ret)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "78368a79-4d82-4a85-9f8e-d1fc476d6b07",
"metadata": {},
"outputs": [],
"source": [
"# Find Maximum Sharpe Ratio Portfolio\n",
"ms_weights = optimize(func=negative_sharpe_ratio,\n",
" exp_ret=exp_ret,\n",
" covmat=vcv,\n",
" risk_free=0.0)\n",
"ms_vol=portfolio_volatility(weights=ms_weights, covmat=vcv)\n",
"ms_ret=portfolio_return(weights=ms_weights, returns=exp_ret)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "d0c7cb8c-66eb-4a01-8389-05a8c438a718",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.collections.PathCollection at 0x7f9c5503fcd0>"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 1296x576 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.figure(figsize=(18, 8))\n",
"plt.scatter(ef.Volatility, ef.Returns, marker=\"o\", linewidths=0.1)\n",
"plt.scatter(gmv_vol, gmv_ret, color=\"red\", marker=\"*\", linewidths=5.0)\n",
"plt.scatter(ms_vol, ms_ret, color=\"green\", marker=\"*\", linewidths=5.0)"
]
},
{
"cell_type": "markdown",
"id": "8301eef4-e032-4312-9479-65375c59af33",
"metadata": {},
"source": [
"To visualize only dominating portfolios (eg portfolios that exhibit higher returns given same level of volatility):"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "46d4bdce-7265-473b-acc8-60963c517e23",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.collections.PathCollection at 0x7f9c552a5be0>"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 1296x576 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"dom_ef = ef[ef.Returns >= gmv_ret]\n",
"plt.figure(figsize=(18, 8))\n",
"plt.scatter(dom_ef.Volatility, dom_ef.Returns, marker=\"o\", linewidths=0.1)\n",
"plt.scatter(gmv_vol, gmv_ret, color=\"red\", marker=\"*\", linewidths=5.0)\n",
"plt.scatter(ms_vol, ms_ret, color=\"green\", marker=\"*\", linewidths=5.0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ea5c8ca4-0702-471a-ad56-408f5432df2e",
"metadata": {},
"outputs": [],
"source": []
}
],
"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.9.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment