Portfolio optimization 投资组合优化 cvx #112
Replies: 7 comments 2 replies
-
In the following code we compute and plot the optimal risk-return trade-off for 10 assets, restricting ourselves to a long only portfolio. # Generate data for long only portfolio optimization.
import numpy as np
import scipy.sparse as sp
np.random.seed(1)
n = 10
mu = np.abs(np.random.randn(n, 1))
Sigma = np.random.randn(n, n)
Sigma = Sigma.T.dot(Sigma) # Long only portfolio optimization.
import cvxpy as cp
w = cp.Variable(n)
gamma = cp.Parameter(nonneg=True)
ret = mu.T @ w
risk = cp.quad_form(w, Sigma)
prob = cp.Problem(cp.Maximize(ret - gamma * risk), [cp.sum(w) == 1, w >= 0]) # Compute trade-off curve.
SAMPLES = 100
risk_data = np.zeros(SAMPLES)
ret_data = np.zeros(SAMPLES)
gamma_vals = np.logspace(-2, 3, num=SAMPLES)
for i in range(SAMPLES):
gamma.value = gamma_vals[i]
prob.solve()
risk_data[i] = cp.sqrt(risk).value
ret_data[i] = ret.value # Plot long only trade-off curve.
import matplotlib.pyplot as plt
%matplotlib inline
%config InlineBackend.figure_format = 'svg'
markers_on = [29, 40]
fig = plt.figure()
ax = fig.add_subplot(111)
plt.plot(risk_data, ret_data, "g-")
for marker in markers_on:
plt.plot(risk_data[marker], ret_data[marker], "bs")
ax.annotate(
r"$\gamma = %.2f$" % gamma_vals[marker],
xy=(risk_data[marker] + 0.08, ret_data[marker] - 0.03),
)
for i in range(n):
plt.plot(cp.sqrt(Sigma[i, i]).value, mu[i], "ro")
plt.xlabel("Standard deviation")
plt.ylabel("Return")
plt.show() |
Beta Was this translation helpful? Give feedback.
-
We plot below the return distributions for the two risk aversion values marked on the trade-off curve. Notice that the probability of a loss is near 0 for the low risk value and far above 0 for the high risk value. # Plot return distributions for two points on the trade-off curve.
import scipy.stats as spstats
plt.figure()
for midx, idx in enumerate(markers_on):
gamma.value = gamma_vals[idx]
prob.solve()
x = np.linspace(-2, 5, 1000)
plt.plot(
x,
spstats.norm.pdf(x, ret.value, risk.value),
label=r"$\gamma = %.2f$" % gamma.value,
)
plt.xlabel("Return")
plt.ylabel("Density")
plt.legend(loc="upper right")
plt.show() |
Beta Was this translation helpful? Give feedback.
-
# Portfolio optimization with leverage limit.
Lmax = cp.Parameter()
prob = cp.Problem(
cp.Maximize(ret - gamma * risk), [cp.sum(w) == 1, cp.norm(w, 1) <= Lmax]
) # Compute trade-off curve for each leverage limit.
L_vals = [1, 2, 4]
SAMPLES = 100
risk_data = np.zeros((len(L_vals), SAMPLES))
ret_data = np.zeros((len(L_vals), SAMPLES))
gamma_vals = np.logspace(-2, 3, num=SAMPLES)
w_vals = []
for k, L_val in enumerate(L_vals):
for i in range(SAMPLES):
Lmax.value = L_val
gamma.value = gamma_vals[i]
prob.solve(solver=cp.SCS)
risk_data[k, i] = cp.sqrt(risk).value
ret_data[k, i] = ret.value # Plot trade-off curves for each leverage limit.
for idx, L_val in enumerate(L_vals):
plt.plot(risk_data[idx, :], ret_data[idx, :], label=r"$L^{\max}$ = %d" % L_val)
for w_val in w_vals:
w.value = w_val
plt.plot(cp.sqrt(risk).value, ret.value, "bs")
plt.xlabel("Standard deviation")
plt.ylabel("Return")
plt.legend(loc="lower right")
plt.show() |
Beta Was this translation helpful? Give feedback.
-
# Portfolio optimization with a leverage limit and a bound on risk.
prob = cp.Problem(cp.Maximize(ret), [cp.sum(w) == 1, cp.norm(w, 1) <= Lmax, risk <= 2]) # Compute solution for different leverage limits.
for k, L_val in enumerate(L_vals):
Lmax.value = L_val
prob.solve()
w_vals.append(w.value) # Plot bar graph of holdings for different leverage limits.
colors = ["b", "g", "r"]
indices = np.argsort(mu.flatten())
for idx, L_val in enumerate(L_vals):
plt.bar(
np.arange(1, n + 1) + 0.25 * idx - 0.375,
w_vals[idx][indices],
color=colors[idx],
label=r"$L^{\max}$ = %d" % L_val,
width=0.25,
)
plt.ylabel(r"$w_i$", fontsize=16)
plt.xlabel(r"$i$", fontsize=16)
plt.xlim([1 - 0.375, 10 + 0.375])
plt.xticks(np.arange(1, n + 1))
plt.show() |
Beta Was this translation helpful? Give feedback.
-
# Generate data for factor model.
n = 600
m = 30
np.random.seed(1)
mu = np.abs(np.random.randn(n, 1))
Sigma_tilde = np.random.randn(m, m)
Sigma_tilde = Sigma_tilde.T.dot(Sigma_tilde)
D = sp.diags(np.random.uniform(0, 0.9, size=n))
F = np.random.randn(n, m) # Factor model portfolio optimization.
w = cp.Variable(n)
f = cp.Variable(m)
gamma = cp.Parameter(nonneg=True)
Lmax = cp.Parameter()
ret = mu.T @ w
risk = cp.quad_form(f, Sigma_tilde) + cp.sum_squares(np.sqrt(D) @ w)
prob_factor = cp.Problem(
cp.Maximize(ret - gamma * risk),
[cp.sum(w) == 1, f == F.T @ w, cp.norm(w, 1) <= Lmax],
)
# Solve the factor model problem.
Lmax.value = 2
gamma.value = 0.1
prob_factor.solve(verbose=True) from cvxpy.atoms.affine.wraps import psd_wrap
# Standard portfolio optimization with data from factor model.
risk = cp.quad_form(w, psd_wrap(F.dot(Sigma_tilde).dot(F.T) + D))
prob = cp.Problem(
cp.Maximize(ret - gamma * risk), [cp.sum(w) == 1, cp.norm(w, 1) <= Lmax]
)
prob.solve(verbose=True, max_iter=100_000) print("Factor model solve time = {}".format(prob_factor.solver_stats.solve_time))
print("Single model solve time = {}".format(prob.solver_stats.solve_time)) |
Beta Was this translation helpful? Give feedback.
-
Portfolio optimization
https://github.com/cvxgrp/cvx_short_course/blob/master/book/docs/applications/notebooks/portfolio_optimization.ipynb
https://github.com/mathnovel/DayCollection/blob/main/cvx/portfolio_potimization.ipynb
Beta Was this translation helpful? Give feedback.
All reactions