python - 均值方差优化 + 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)
解决方案
您需要将约束更新为:
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
推荐阅读
- regex - 如何在数组公式中进行多次搜索?
- verilog - 如何在 Synopsys VCS 中将比特爆破信号转储到 vcd
- python - 带有装饰器的 Python 客户端身份验证
- mysql - 提高此查询的效率:使用联接和子查询进行更新
- python - 数据库表不是 JSON 可序列化的
- java - 我们如何通过不完整的名称找到产品或类别?
- php - 试图获取非对象 WordPress 的属性“ID”
- arrays - 循环将数组打印到多个单元格,“对象 _Global 的范围失败”错误
- javascript - Phonegap:资源文件夹,内容在应用程序 /www/ 文件夹中不可见,但在 APK /www/ 文件夹中可用
- r - 有没有办法只将某些点与 ggplot2 中的一条线连接起来?