首页 > 解决方案 > 均值方差优化 + Python + 调整约束

问题描述

我正在尝试使用 scipi 中的内置 SLSQP 优化器进行平均方差投资组合优化,并且难以理解如何使用 10% 的恒定投资组合方差的约束来定义求解投资组合权重的约束。只能合并所有权重之和应为 0 的约束

我已经能够使用这个优化器来找到最大化投资组合夏普比率的投资组合,并找到最小化投资组合方差的权重。现在需要添加额外的约束,使投资组合的方差始终保持在 10%,优化器求解使投资组合收益最大化的权重


def portfolio_annualised_performance(weights, mean_returns, carry_cov):
    returns = np.sum(mean_returns*weights) *12
    std = np.sqrt(np.dot(weights.T, np.dot(carry_cov, weights))) * np.sqrt(12)
    return std, returns

def neg_sharpe_ratio(weights, mean_returns, carry_cov, risk_free_rate):
    p_var, p_ret = portfolio_annualised_performance(weights, mean_returns, carry_cov)
    return -(p_ret - risk_free_rate) / p_var

def max_sharpe_ratio(mean_returns, carry_cov, risk_free_rate):
    args = (mean_returns, carry_cov, risk_free_rate)
    no = int(len(mean_returns))
    constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 0})
    bound1 = (-1.0,0.0)
    bound2 = (0.0,1.0)
    bounds = tuple(bound2 for asset in range(int(no/2)))+tuple(bound1 for asset in range(int(no/2)))
    result = sco.minimize(neg_sharpe_ratio, no*[1./no,], args=args,method='SLSQP', bounds=bounds, constraints=constraints)
    return result

######## NEED HELP WITH THE FOLLOWING SNIPPET OF CODE

def neg_return(weights, mean_returns, carry_cov, risk_free_rate):
    p_var, p_ret = portfolio_annualised_performance(weights, mean_returns, carry_cov)
    return -(p_ret)

def max_carry(mean_returns, carry_cov, risk_free_rate):
    args = (mean_returns, carry_cov, risk_free_rate)
    no = int(len(mean_returns))
    constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 0})
    bound1 = (-1.0,0.0)
    bound2 = (0.0,1.0)
    bounds = tuple(bound2 for asset in range(int(no/2)))+tuple(bound1 for asset in range(int(no/2)))
    result = sco.minimize(neg_return, no*[1./no,], args=args,method='SLSQP', bounds=bounds, constraints=constraints)
    return result

我猜我必须更新它以确保优化器查看的所有 portfgolio 空间的 p_var =10% 但是如何修改下面的约束字典?

constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 0})

我也尝试了以下方法,但似乎根本没有帮助(如果方差高于或低于 10.5% 或 9.5%,则尝试返回较大的正回报值,这应该会增加优化器的成本函数):

def neg_return(weights, mean_returns, carry_cov, risk_free_rate):
    p_var, p_ret = portfolio_annualised_performance(weights, mean_returns, carry_cov)
    if p_var > 0.105 or p_var< 0.095:
        p_ret = -p_ret*1000 
    return -(p_ret)

标签: pythonoptimizationscipymeanvariance

解决方案


您需要将约束更新为:

constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 0},
{'type':'eq','fun': const_vol,'args':[mean_return, carry_cov]})

def const_vol(weights, *args):
        curr_vol = portfolio_annualised_performance(weights, args[0], args[1])[0]
        return 0.1 - curr_vol

推荐阅读