700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 投资组合--最优化求解(Python)

投资组合--最优化求解(Python)

时间:2021-03-07 19:10:04

相关推荐

投资组合--最优化求解(Python)

除了用蒙特卡洛模拟进行投资组合求解外,也可以通过python的scipy.optimize库进行最优化求解。接着上一篇文章,我们继续使用scipy.optimize进行投资组合最优化求解工作。

import scipy.optimize as sco# 定义计算投资组合的状态函数如下def portfolio_status(weights):weights = array(weights)[:,newaxis]port_rets = weights.T @ array(returns.mean() * 250)[:,newaxis]port_vols = sqrt(multi_dot([weights.T, returns.cov()*250, weights]))# 返回组合收益率,组合波动率和夏普比率return array([port_rets, port_vols, port_rets/port_vols]).flatten()

用最优化module求解最大夏普比率对应的组合

# 定义夏普比率(取负号)函数def sharpe_ratio(weights):return -portfolio_status(weights)[2] #取return结果中的第3个数# 设置每一只股票权重范围为0<=x<=1tuple((0,1) for x in range(numofasset))# 明确组合最优化约束条件和股票权重范围cons = ({'type':'eq','fun': lambda x: sum(x)-1})bnds = tuple((0,1) for x in range(numofasset))initial_wts = numofasset*[1./numofasset] #初始化weights的值便于优化算法快速完成计算# 用最优化module求解最大夏普比率,opt_sharpe(目标函数, 入参, 优化方法, 边界条件, 约束条件)opt_sharpe = sco.minimize(sharpe_ratio, initial_wts, method='SLSQP',bounds = bnds, constraints = cons)opt_sharpe# 最大夏普比率组合权重list(zip(symbols, around(opt_sharpe['x']*100, 2))) #两个list对应元素生成一个tuple# 最大夏普比率组合数status = ['Returns', 'Volatility', 'Sharpe Ratio']list(zip(status, around(portfolio_status(opt_sharpe['x']), 4)))

用最优化module求解最小波动率组合

# 定义波动率(方差)函数def variance(weights):return portfolio_status(weights)[1]**2# 用最优化module求解最小方差opt_var = sco.minimize(variance, initial_wts, method='SLSQP',bounds = bnds, constraints = cons)opt_var# 最小方差组合权重list(zip(symbols, around(opt_var['x']*100,2)))# status = ['Returns', 'Volatility', 'Sharp Ratio']list(zip(status, around(portfolio_status(opt_var['x']),4)))

用最优化module求解有效边界(effective frontier)

# 定义波动率(标准差)函数def volatility(weights):return portfolio_status(weights)[1] #portfolio_status(weights)函数返回列表第2个元素为vol# 设定有效边界参数targetrets = linspace(0.04, 0.42, 500) # 将目标收益率进行500等分targetvols_ = []for i in tqdm(targetrets):ef_cons = ({'type':'eq','fun': lambda x: sum(x)-1},{'type':'eq','fun': lambda x: portfolio_status(x)[0]-i}) #两个约束条件opt_ef = sco.minimize(volatility, initial_wts, method='SLSQP',bounds=bnds, constraints=ef_cons)targetvols_.append(opt_ef['fun'])targetvols = array(targetvols_)# 记录有效边界数据到DataFrameef_port = pd.DataFrame({'targetrets': around(targetrets*100, 2),'targetvols': around(targetvols*100, 2),'targetsharpe': around(targetrets/targetvols, 2)})ef_port.head()# 有效边界画图fig = px.scatter(ef_port, x='targetvols', y='targetrets', color='targetsharpe',labels={'targetrets': '预期收益率', 'targetvols': '预期波动率','targetsharpe': '夏普比率'},title='投资组合有效边界').update_traces(mode='markers', marker=dict(symbol='circle'))# 标出最大夏普比率组合(市场组合)fig.add_scatter(mode='markers',x=[100*portfolio_status(opt_sharpe['x'])[1]], #[1]为volsy=[100*portfolio_status(opt_sharpe['x'])[0]], #[0]为retsmarker=dict(color='Blue', size=14, symbol='square'),name = '市场组合').update(layout_showlegend=False)# 标出最小方差(波动率)组合fig.add_scatter(mode='markers',x=[100*portfolio_status(opt_var['x'])[1]], #[1]为volsy=[100*portfolio_status(opt_var['x'])[0]], #[0]为retsmarker=dict(color='Red', size=14, symbol='square'),name = '最小波动率组合').update(layout_showlegend=False)fig.update_xaxes(showspikes=True)fig.update_yaxes(showspikes=True)

最后可视化结果如下其中红色方块和蓝色方块分别为最小波动率组合和最大夏普比率组合所在的位置

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。