使用CVXOPT进行均值方差优化

时间:2019-02-26 00:05:09

标签: cvxopt

我看到这个问题是4年前问过的,但是我仍然对答案感到困惑,因此重新发布它。代码粘贴在

如果假设我要确保资产1的范围在20%和40%之间,资产2的范围在<30%之间,并且说资产2在10-15%之间,那么我对G和h做了什么更改?即代码中G和h的值是什么。

其余的内容很容易理解,但是在二次优化器上却有些挣扎。感谢任何帮助!

谢谢, PK

import numpy as np
import pandas as pd
from scipy import optimize
import cvxopt as opt
from cvxopt import blas, solvers
import matplotlib.pyplot as plt


np.random.seed(123)

# Turn off progress printing
solvers.options['show_progress'] = False

# Number of assets
n_assets = 4

# Number of observations
n_obs = 2000

## Generating random returns for our 4 securities
return_vec = np.random.randn(n_assets, n_obs)


def rand_weights(n):
    '''
    Produces n random weights that sum to 1
    '''
    k = np.random.rand(n)
    return k / sum(k)


def random_portfolio(returns):
    '''
    Returns the mean and standard deviation of returns for a random portfolio
    '''

    p = np.asmatrix(np.mean(returns, axis=1))
    w = np.asmatrix(rand_weights(returns.shape[0]))
    C = np.asmatrix(np.cov(returns))

    mu = w * p.T
    sigma = np.sqrt(w * C * w.T)

    # This recursion reduces outliers to keep plots pretty
    if sigma > 2:
        return random_portfolio(returns)
    return mu, sigma


def optimal_portfolios(returns):
    n = len(returns)
    returns = np.asmatrix(returns)

    N = 50000

    # Creating a list of returns to optimize the risk for
    mus = [10 ** (5.0 * t / N - 1.0) for t in range(N)]

    # Convert to cvxopt matrices
    S = opt.matrix(np.cov(returns))
    pbar = opt.matrix(np.mean(returns, axis=1))

    # Create constraint matrices
    G = -opt.matrix(np.eye(n))  # negative n x n identity matrix
    h = opt.matrix(0.0, (n, 1))
    A = opt.matrix(1.0, (1, n))
    b = opt.matrix(1.0)

    # Calculate efficient frontier weights using quadratic programming
    portfolios = [solvers.qp(mu * S, -pbar, G, h, A, b)['x']
                  for mu in mus]

    ## Calculate the risk and returns of the frontier
    returns = [blas.dot(pbar, x) for x in portfolios]
    risks = [np.sqrt(blas.dot(x, S * x)) for x in portfolios]

    return returns, risks


n_portfolios = 25000

means, stds = np.column_stack([random_portfolio(return_vec) for x in range(n_portfolios)])

returns, risks = optimal_portfolios(return_vec)

1 个答案:

答案 0 :(得分:0)

约束部分不能那样工作;

在这种情况下,G Mat应该为4 X 4,h应该为1 X 4,如下所示 如果需要最小阈值,在这种情况下,可以像下面的示例一样在“ h”矩阵中输入(20%)。但是,我无法添加最大约束。

G = matrix([[-1.0, 0.0, 0.0, 0.0],
       [0.0, -1.0, 0.0, 0.0],
       [0.0, 0.0, -1.0, 0.0],
       [0.0, 0.0, 0.0, -1.0]])

 h = matrix([-0.2, 0.0, 0.0, 0.0])