国信投资时钟策略研究(一)代码

策略分享
标签: #<Tag:0x00007fc835163190>

(iQuant) #1
克隆策略

国信投资时钟策略研究(一)

美林投资时钟其主要原理是根据经济增长和通货膨胀趋势,将经济周期划分为4 个阶段:复苏、过热、滞涨、衰退。复苏周期配置股票,过热周期配置大宗商品,滞涨周期持有现金,衰退周期配置债券。
国信金工在《海外量化技术本土化系列报告之十一:美林投资时钟A 股市场探讨》中分析了美林投资时钟直接用于A股市场的效果较差,进而做了进一步详尽的研究:
行业增长稳定性分析方面:考察指标1)主营收入增长稳定性;2)主营成本增长稳定性;3)毛利增长稳定性,实证结果显示:医药生物、食品饮料、零售、农林牧渔的稳定性较好,而建筑建材、煤炭、有色、电力、汽车、钢铁的稳定性较差。
通胀传导能力分析:通过分析主营业务收入对主营业务成本的弹性中值进行通胀传导能力区分,实证结果显示:医药生物、零售、房地产、食品饮料等行业抗通胀能力较强,电力、钢铁、农林牧渔等行业抗通胀能力较弱。
根据美林投资时钟,寻找股票属性最强的行业构建周期成长指数,大宗商品属性最强的行业构建周期价值指数,现金属性最强的行业构建防御价值指数,债券属性最强的行业构建防御成长指数。
国信投资时钟策略指数分两个系列:行业集群系列指数、经济周期系列指数,两个系列指数均具有良好的代表性和可投资性。

一、行业集群系列指数
行业集群系列指数是根据《逆向思考的浪花—国信投资时钟》报告中,首先对股票市场行业指数进行相关性分析,然后利用最小生成树算法刻画行业关联图,最终将A股市场划分为四个行业集群:
1. 强周期指数:采掘、房地产、交运设备、有色金属、金融服务、黑色金属。
2. 中周期集群:交通运输、化工、公用事业、建筑建材、机械设备。
3. 消费类集群:医药生物、商业贸易、家用电器、农林牧渔、信息服务、食品饮料。
4. 轻工业集群:轻工制造、纺织服装、综合、电子元器件、信息设备、餐饮旅游。

二、经济周期系列指数
经济周期系列指数是根据行业的经济周期属性,挑选出每个经济周期最具代表性的行业分别构建复苏指数、过热指数、滞胀指数、衰退指数。根据《逆向思考的浪花—国信投资时钟》报告中提出的模型,选择方案如下:
1、复苏指数(周期成长指数):房地产、汽车,对应投资期为复苏期;消费结构升级是中国经济中场周期走势的决定性力,从国外经验看,房地产和汽车仍将是未来长期主导中国消费结构升级和中长经济周期走势的核心力。
2、过热指数(周期价值指数):有色、煤炭,对应投资期为过热期;在过热周期,经济增长超过潜在经济增长率,呈加速趋势,市场需求旺盛,经济活动的加速使通胀进一步上升。央行加息以求降温,加息使债券收益率曲线上行并变得平缓,债券表现非常糟糕。经济活动过热以及较高的通货膨胀使得大宗商品成为收益率最高的资产。在股市中,与大宗商品相关的股票是较好的选择,矿业股(煤炭和有色)表现最好。有色金属和CRB工业原材料指数之间的相关系数高达0.8473,煤
炭和CRB工业原料指数之间的相关系数亦达0.5095,在25 个行业中分别排名第1 和第6。其他相关性较高的行业有:零售、食品饮料、建筑机械、房地产;负相关性较高的行业有:信息服务、电力、信息设备、电子元器件、纺织服装、轻工制造、高速公路、铁路运输、农林牧渔。
3、滞涨指数(防御价值指数):医药生物、零售,对应投资期为滞涨期,滞涨前期经济增长率依然超过潜在增长率,但呈现减速趋势,产出正缺口正逐渐减小,通胀由于资源价格高企,利率由于通胀也处于高位,企业成本日益上升,为保持盈利而提高产品价格,导致成本、工资、价格螺旋上涨,但业绩开始出现停滞甚至下滑的趋势。央行紧缩银根,现金最佳的选择。股票中需求弹性小的公用事业、医药等是较好的选择。
4、衰退指数(防御成长指数):高速公路、机场,对应投资期为衰退期。在衰退周期,经济增长率低于潜在增长率,继续呈减速趋势,产出负缺口继续扩大,超额生产能力和下跌的大宗商品价格使得通货膨胀率更加低。市场需求不足,企业盈利微弱,并且实际收益率下降。央行采用宽松的货币政策(减息)和积极的财政政策(减税)以刺激经济增长。减息导致收益率曲线急剧下行,债券是最佳选择。
周期指数VS 防御指数:如果将周期成长指数和周期价值指数简单相加合成周期指数,防御价值指数和防御成长指数简单相加合成防御指数,可以看到两类指数轮动明显,同时这两类指数的相对强弱变化也反映出投资者对于经济增长的预期。
价值指数VS 成长指数:如果将周期价值指数和防御价值指数简单相加合成价值指数,周期成长指数和防御成长指数简单相加合成成长指数,亦可以看到两类指数明显的轮动,这两类指数之间的相对强弱变化则反映出投资者对于通货膨胀的预期

三、轮动规律
A 股市场存在明显的经济周期轮动:周期成长指数-->周期价值指数-->防御价值指数-->防御成长指数-->周期成长指数。
1、复苏-过热:周期成长指数(复苏指数)高位下跌,周期价值(过热指数)指数触底后快速上涨。
2、过热-滞涨:周期价值指数(过热指数)高位快速下跌,防御价值指数(滞涨指数)触底快速上涨;这里也是牛市到熊市的切换点。
3、滞涨-衰退:防御价值指数(滞涨指数)高位盘整或者下跌,防御成长指数(衰退指数)快速上涨。
4、衰退-复苏:防御成长指数(衰退指数)高位下跌,周期成长(复苏指数)快速上涨;这里也是股市熊市到牛市的切换点。
市场见顶:周期价值指数见顶回落,防御价值指数见底上涨。
市场见底:防御成长指数见顶回落,周期成长指数见底上涨。
牛市中各行业集群出现普涨,其中强周期集群领涨,采掘涨势仅次于有色金属。

四、样本股选择
按行业将样本空间中最近一年(新股为上市以来)的日均成交金额处于后50%的股票剔除,然后将剩余股票按照最近一年日均总市值由高到低进行排名,每行业选择排名在前20名的股票进入指数的样本股。
这里简单处理,直接采用板块行业指数计算。

五、指数基准日与基准点位
指数以2006年1月4日为基准日期,基准点位1000点。
In [1]:
# 210000 采掘 220000 化工 230000 钢铁 240000 有色金属 610000 建筑材料/建筑建材 620000 建筑装饰
#630000 电气设备 640000 机械设备 650000 国防军工 280000 汽车/交运设备 330000 家用电器 360000 轻工制造
#110000 农林牧渔 340000 食品饮料 350000 纺织服装 370000 医药生物 450000 商业贸易 460000 休闲服务
#270000 电子  710000 计算机 720000 传媒/信息服务 730000 通信 410000 公用事业 420000 交通运输
#430000 房地产 480000 银行 490000 非银金融 510000 综合
sw_level1 = [430000,280000,240000,210000,370000,450000,420000]
adjusted_sw_level1 = ['SW'+str(i)+'.SHA' for i in sw_level1]
price_df = D.history_data(instruments=adjusted_sw_level1, start_date='2006-01-04', end_date='2018-05-12',
               fields=['close']) 
price_df = pd.pivot_table(price_df, values='close', index=['date'], columns=['instrument'])
#指数计算步骤如下:
price_df['Recovery_index']=price_df['SW430000.SHA']+price_df['SW280000.SHA']#计算复苏指数
price_df['Overheate_index']=price_df['SW240000.SHA']+price_df['SW210000.SHA']#计算过热指数
price_df['Stagflation_index']=price_df['SW370000.SHA']+price_df['SW450000.SHA']#计算滞涨指数
price_df['Decline_index']=price_df['SW420000.SHA']#计算衰退指数
#首先计算相对指数 Yit= Xit *1000
Yit=price_df[['Recovery_index','Overheate_index','Stagflation_index','Decline_index']].apply(lambda df:df/df[0])*1000
#计算各自的相对指数
Yit['sum_Yit']=Yit['Recovery_index']+Yit['Overheate_index']+Yit['Stagflation_index']+Yit['Decline_index']
Yit['Recovery_index_relative']=Yit['Recovery_index']/Yit['sum_Yit']
Yit['Overheate_index_relative']=Yit['Overheate_index']/Yit['sum_Yit']
Yit['Stagflation_index_relative']=Yit['Stagflation_index']/Yit['sum_Yit']
Yit['Decline_index_relative']=Yit['Decline_index']/Yit['sum_Yit']
#绘制相对指数走势
T.plot(Yit[['Recovery_index_relative','Overheate_index_relative','Stagflation_index_relative','Decline_index_relative']].apply(lambda df:1000*df/df[0]))

在进行阶段划分时,我们参考研报中的时间段,确认阶段的初步原则为按照复苏、过热、滞涨、衰退的顺序划分,举例如下:

1、复苏期从复苏指数低位上涨开始,延续到复苏指数到达顶峰或下一个阶段即过热指数开始上涨为止。

2、过热期即过热指数开始上涨开始,延续到过热指数达到顶峰或下一阶段即滞涨指数开始上涨为止。

3、滞涨期即滞涨指数开始上涨开始,延续到滞涨指数达到顶峰或下一阶段即衰退指数开始上涨为止。

4、衰退期即衰退指数开始上涨开始,延续到衰退指数达到顶峰或下一阶段即复苏指数开始上涨为止。

In [2]:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.collections as collections
t = Yit.index
s1=np.array(Yit['Recovery_index_relative'].values.tolist())
s2=np.array(Yit['Overheate_index_relative'].values.tolist())
s3=np.array(Yit['Stagflation_index_relative'].values.tolist())
s4=np.array(Yit['Decline_index_relative'].values.tolist())
t1=np.array([int(i) for i in t.strftime('%Y%m%d')])
#字体控制
font1 = {'family' : 'Times New Roman',  
'weight' : 'normal',  
'size'   : 60,  
} 
#条件背景填充
fig, ax = plt.subplots(figsize=(80,30))
ax.tick_params(labelsize=50)  
ax.plot(t, s1, label='Recovery_index_relative',color='blue',linewidth=5.0)
ax.plot(t, s2, label='Overheate_index_relative',color='red',linewidth=5.0)
ax.plot(t, s3, label='Stagflation_index_relative',color='green',linewidth=5.0)
ax.plot(t, s4, label='Decline_index_relative',color='black',linewidth=5.0)
plt.fill_between(t,0.5, where=(t>=pd.to_datetime('2006-07-24')) & (t<=pd.to_datetime('2006-12-25')), facecolor='blue',alpha=0.3)
plt.fill_between(t,0.5, where=(t>=pd.to_datetime('2006-12-26')) & (t<=pd.to_datetime('2007-10-12')), facecolor='red',alpha=0.3)
plt.fill_between(t,0.5, where=(t>=pd.to_datetime('2007-10-13')) & (t<=pd.to_datetime('2008-07-10')), facecolor='green',alpha=0.3)
plt.fill_between(t,0.5, where=(t>=pd.to_datetime('2008-07-11')) & (t<=pd.to_datetime('2008-10-16')), facecolor='black',alpha=0.3)
plt.fill_between(t,0.5, where=(t>=pd.to_datetime('2008-10-17')) & (t<=pd.to_datetime('2009-03-09')), facecolor='blue',alpha=0.3)
plt.fill_between(t,0.5, where=(t>=pd.to_datetime('2009-03-10')) & (t<=pd.to_datetime('2009-07-29')), facecolor='red',alpha=0.3)
plt.fill_between(t,0.5, where=(t>=pd.to_datetime('2009-07-30')) & (t<=pd.to_datetime('2014-02-15')), facecolor='green',alpha=0.3)
plt.fill_between(t,0.5, where=(t>=pd.to_datetime('2014-02-16')) & (t<=pd.to_datetime('2015-09-21')), facecolor='black',alpha=0.3)
plt.fill_between(t,0.5, where=(t>=pd.to_datetime('2015-09-22')) & (t<=pd.to_datetime('2017-06-05')), facecolor='blue',alpha=0.3)
plt.fill_between(t,0.5, where=(t>=pd.to_datetime('2017-06-06')) & (t<=pd.to_datetime('2017-09-11')), facecolor='red',alpha=0.3)
plt.fill_between(t,0.5, where=t>=pd.to_datetime('2017-09-12'), facecolor='green',alpha=0.3)

plt.xlabel('time',font1)
plt.ylabel('relative index',font1)
plt.title("economic cycle relative_index",font1)
plt.legend(prop=font1)
plt.xlim(t.min(), t.max())
plt.show()
In [3]:
#经济增长预期指数:如果将复苏指数和过热指数简单相加合成周期指数
#滞涨指数和衰退指数简单相加合成防御指数,可以看到两类指数轮动明显,同时这两类指数的相对强弱变化也反映出投资者对于经济增长的预期
price_df['Periodic_index']=price_df['Recovery_index']+price_df['Overheate_index']
price_df['Defense_index']=price_df['Stagflation_index']+price_df['Decline_index']
Yit=price_df[['Periodic_index','Defense_index']].apply(lambda df:df/df[0])*1000
Yit['sum_Periodic_Defense']=Yit['Periodic_index']+Yit['Defense_index']
Yit['Periodic_index']=Yit['Periodic_index']/Yit['sum_Periodic_Defense']
Yit['Defense_index']=Yit['Defense_index']/Yit['sum_Periodic_Defense']
T.plot(Yit[['Periodic_index','Defense_index']].apply(lambda df:1000*df/df[0]),title='Periodic_index and Defense_index')
In [4]:
#通货膨胀预期指数:如果将过热指数和滞涨指数简单相加合成价值指数,复苏指数和衰退指数简单相加合成成长指数,亦可以看到两类指数明显的轮动,
#这两类指数之间的相对强弱变化则反映出投资者对于通货膨胀的预期。
price_df['Value_index']=price_df['Stagflation_index']+price_df['Overheate_index']
price_df['Growth_index']=price_df['Recovery_index']+price_df['Decline_index']
Yit=price_df[['Value_index','Growth_index']].apply(lambda df:df/df[0])*1000
Yit['sum_Value_Growth']=Yit['Value_index']+Yit['Growth_index']
Yit['Value_index']=Yit['Value_index']/Yit['sum_Value_Growth']
Yit['Growth_index']=Yit['Growth_index']/Yit['sum_Value_Growth']
T.plot(Yit[['Value_index','Growth_index']].apply(lambda df:df/df[0]),title='Value_index and Growth_index')
六、结论
美林投资时钟指出:复苏周期配置股票,过热周期配置大宗商品,滞涨周期持有现金,衰退周期配置债券。
宏观经济周期和股票市场联动关系如果按照美林时钟所言,似乎只在经济复苏周期才适合投资股市。
但国信这篇文章通过构造与四个经济周期特征相匹配的复苏指数、过热指数、滞涨指数和衰退指数,总结出了即使在股票市场内部,四个指数的相对变化规律依旧能够照应符合宏观经济周期的变化规律。
从周期VS防御、成长vs价值的相对指数表现来看,其几乎完美的对称性走势确实反应了市场具有典型的结构性特征和周期性特征,从一个周期轮动的视角诠释了“股市是经济的晴雨表”这句话。
而由此引申出来的就是,通过掌握这些相对变化规律,即使在熊市大环境下依旧有可能利用周期的轮动,通过指数基金/行业基金的多空组合实现获利。  

参考文献: 20101118-国信证券-《海外量化技术本土化系列报告之十一:美林投资时钟A股市场探讨》

20100712-国信证券-《海外量化技术本土化系列之七:国信投资时钟初探》

20120319-国信证券-《金融工程专题研究:国信投资时钟策略指数》


投资时钟系列研究(一)
(Haley) #4

请问四个周期的时间节点是如何定量划分的?


(达达) #5

粗略定量就是一条曲线下降,另一条开始上升。也就是某条曲线的高点拐头向下和另外一条曲线低点开始回升。根据周期不跳跃可回返的顺序,你可以猜测下一个周期是哪个曲线可能开始下降,哪个曲线可能开始上升。