Examples
In [1]:
Copied!
import numpy as np
import pandas as pd
import cvxpy as cp
import numpy as np
import pandas as pd
import cvxpy as cp
2021 Final¶
In [6]:
Copied!
def get_mu_V(N):
a = np.ones(N)
b = np.concatenate([np.ones(int(N/2)),-np.ones(int(N/2))])
c = np.concatenate([np.ones(int(N/4)),-np.ones(int(N/4)), np.ones(int(N/4)),-np.ones(int(N/4))])
Beta = np.vstack([a, b, c]).T
mu = a + b + c
V = Beta@Beta.T + np.identity(N)
return mu, V
def get_mu_V(N):
a = np.ones(N)
b = np.concatenate([np.ones(int(N/2)),-np.ones(int(N/2))])
c = np.concatenate([np.ones(int(N/4)),-np.ones(int(N/4)), np.ones(int(N/4)),-np.ones(int(N/4))])
Beta = np.vstack([a, b, c]).T
mu = a + b + c
V = Beta@Beta.T + np.identity(N)
return mu, V
Equally weighted portfolio, variance
In [7]:
Copied!
N = 12
mu, V = get_mu_V(N)
x = np.ones(N) * (1/N)
x.T@V@x
N = 12
mu, V = get_mu_V(N)
x = np.ones(N) * (1/N)
x.T@V@x
Out[7]:
1.0833333333333333
In [8]:
Copied!
for N in [20, 100, 200, 400, 1000]:
mu, V = get_mu_V(N)
x = np.ones(N) * (1/N)
print(x.T@V@x)
for N in [20, 100, 200, 400, 1000]:
mu, V = get_mu_V(N)
x = np.ones(N) * (1/N)
print(x.T@V@x)
1.05 1.01 1.0050000000000006 1.0024999999999948 1.000999999999988
Characteristic Portfolio
$$ \begin{array}{cl} \min & \mathbf{x}^{\mathrm{T}} \mathbf{V} \mathbf{x} \\ \text { s.t. } & \mathbf{b}^{\mathrm{T}} \mathbf{x}=1 \end{array} $$In [9]:
Copied!
N = 12
x = cp.Variable(N)
b = np.concatenate([np.ones(int(N/2)),-np.ones(int(N/2))])
mu, V = get_mu_V(N)
constraints = [b.T@x == 1]
objective = cp.Minimize(cp.quad_form(x, V))
prob = cp.Problem(objective,constraints)
prob.solve()
print(x.value)
print(prob.value)
N = 12
x = cp.Variable(N)
b = np.concatenate([np.ones(int(N/2)),-np.ones(int(N/2))])
mu, V = get_mu_V(N)
constraints = [b.T@x == 1]
objective = cp.Minimize(cp.quad_form(x, V))
prob = cp.Problem(objective,constraints)
prob.solve()
print(x.value)
print(prob.value)
[ 0.08333333 0.08333333 0.08333333 0.08333333 0.08333333 0.08333333 -0.08333333 -0.08333333 -0.08333333 -0.08333333 -0.08333333 -0.08333333] 1.083333333333333
In [10]:
Copied!
a = np.ones(N)
a.T@x.value
a = np.ones(N)
a.T@x.value
Out[10]:
-8.326672684688674e-17
In [11]:
Copied!
c = np.concatenate([np.ones(int(N/4)),-np.ones(int(N/4)), np.ones(int(N/4)),-np.ones(int(N/4))])
c.T@x.value
c = np.concatenate([np.ones(int(N/4)),-np.ones(int(N/4)), np.ones(int(N/4)),-np.ones(int(N/4))])
c.T@x.value
Out[11]:
4.163336342344337e-17
Maximize Sharpe
$$
\frac{\mathbb{E}\left(\mathbf{r}^{\top} \mathbf{x}\right)}{\sigma\left(\mathbf{r}^{\top} \mathbf{x}\right)}=\frac{\boldsymbol{\mu}^{\top} \mathbf{x}}{\sqrt{\mathbf{x}^{\top} \mathbf{V} \mathbf{x}}}
$$
In [12]:
Copied!
def maxSharpe(mu,V,long_only = True):
# Compute the fully-invested portfolio with maximum Sharpe ratio
# Use homogenization trick.
n=len(mu)
z = cp.Variable(n)
kappa = cp.Variable(1)
if long_only:
constraints = [mu.T@z == 1, np.ones(n)@z - kappa == 0, z >= 0, kappa >= 0]
else:
constraints = [mu.T@z == 1, np.ones(n)@z - kappa == 0, kappa >= 0]
prob = cp.Problem(cp.Minimize(cp.quad_form(z,V)),constraints)
prob.solve()
return z.value/kappa.value
def maxSharpe(mu,V,long_only = True):
# Compute the fully-invested portfolio with maximum Sharpe ratio
# Use homogenization trick.
n=len(mu)
z = cp.Variable(n)
kappa = cp.Variable(1)
if long_only:
constraints = [mu.T@z == 1, np.ones(n)@z - kappa == 0, z >= 0, kappa >= 0]
else:
constraints = [mu.T@z == 1, np.ones(n)@z - kappa == 0, kappa >= 0]
prob = cp.Problem(cp.Minimize(cp.quad_form(z,V)),constraints)
prob.solve()
return z.value/kappa.value
In [13]:
Copied!
def get_sharpe(mu, V, x):
return mu.T@x / np.sqrt(x.T@V@x)
def get_sharpe(mu, V, x):
return mu.T@x / np.sqrt(x.T@V@x)
In [14]:
Copied!
for N in [12, 20, 100, 200, 400, 1000]:
mu, V = get_mu_V(N)
x = maxSharpe(mu, V, False)
print(get_sharpe(mu, V, x))
for N in [12, 20, 100, 200, 400, 1000]:
mu, V = get_mu_V(N)
x = maxSharpe(mu, V, False)
print(get_sharpe(mu, V, x))
1.6641005886756877 1.690308509457033 1.7234549688642784 1.72773685116272 1.7298897951146746 1.7311854311433579