『运筹OR帷幄』原创
0 简介
昨天实习摸鱼的时候开始看《Quantitative Equity Portfolio Management:Modern Techniques and Applications》,第一章讲到了经典的几个组合优化模型,于是乎干脆顺便在聚宽的策略环境里实现了一下,并选取了一个多因子选股进行了对比测试,初步证明了经典组合优化的一定有效性。个人觉得在实际交易场景中使用优化模型的主要难点在于如何较好的估计不同资产间的协方差矩阵以及各自的期望收益率。实证分析显示带有依赖资产预期收益率约束的优化问题,强行使用过去某段时间区间内的收益率替代预期收益率会产生严重的估计偏误从而严重影响优化结果。我觉得在实际使用这类模型以下两个问题需要被考虑:
1 如何有效的估计约束依赖的指标,如资产的预期收益率向量,资产的 向量,资产的协方差矩阵等等。关于这一块应该也已经有不少的工作,我了解比较少,但所知道的比如BL模型通过将投资者观点和先验收益率结合产生后验收益率输入均值方差优化模型,或者通过Compression Matrix的方法优化协方差矩阵都能较好的改进通过历史波动率来估计协方差矩阵而带来的种种弊端:比如,随着资产数目二次增加的估计时间复杂度,优化结果对权重的初始化高度敏感等等,这里不再展开。
2 如何考虑资产之间的序列相关性,通过简单的实证分析,对于大类资产间的配比如权益国债黄金,资产之间的相关性较低,我们更希望协方差是一个对角矩阵,通过一些诸如masking或者shrinkage的trick可以较好的实现,而如果是纯股票组合,有时候考虑序列相关性的优化结果更好(我未做深入研究)。回到正题,我大致实现了以下几种常见优化。首先设置我们的原始股票列表,以及定义一个函数返回该组资产过去 天的日收盘价序列。
import numpy as np
import pandas as pd
import scipy.optimize as sco
universe = get_index_stocks('000300.XSHG')
stock_list = universe[0:5]#为了方便演示这里只选取五只股票构建投资组合
'''给定股票列表得到过去245个交易日的收盘价面板'''
def get_closedata(stock_list):
close_dict = {}
for i in range(len(stock_list)):
code_name = stock_list[i]
close_seq = attribute_history(stock_list[i],245,'1d', ('close'))
close_seq = list(close_seq['close'])
close_dict[code_name] = close_seq
#transofrm to dataframe
df_stock = pd.DataFrame(close_dict,columns = list(close_dict.keys()))
return df_stock #255*N的DataFrame,每列对应一只股票过去245个交易日股价
1 以最大化期望收益率建立优化问题
优化问题:
代码:
'''全局最大化期望收益率组合'''
def cal_expret(weights:list,df_stock):
risk_free_rate = 0.03
if len(weights) != df_stock.shape[1]: