我正在尝试使用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%,但是如何修改下面的constrasint词典?
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)
答案 0 :(得分:0)
您需要将约束更新为:
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