欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答、求职一站式搞定!

对商业智能BI、大数据分析挖掘、机器学习,python,R等数据领域感兴趣的同学加微信:tstoutiao,邀请你进入数据爱好者交流群,数据爱好者们都在这儿。

作者:量化小白H

个人公众号:量化小白上分记

本文是对报告《20100210-华泰证券-数量化策略:大小盘轮动》、《20161218-中金公司-价量视角下的市值风格轮动策略》部分内容的复制,文章为个人理解,不保证正确性,请理性看待,欢迎指正。

大小盘轮动

A股市场上存在着明显的大小盘轮动的现象,一段时间大盘表现强势,一段时间小盘表现强势,所谓八轮动。这种现象提供了构建大小盘轮动策略的可能,目前常见的两种构建大小盘轮动策略的方式分别为

宏观层面出发,分析影响市场价格变动的政策、利率、GDP、供需数据等,以此构建模型分析市场当前的大小盘风格;

技术角度出发,通过量价数据构建指标,分析市场当前的大小盘风格。

两种方式各有优劣,本文复制的两篇报告均属于第二种方式。

左侧交易&右侧交易

以交易时点划分,可以将市场上的交易行为划分为两类:左侧交易与右侧交易。

左侧交易:在价格即将达到某个支撑点时逆向进入市场,做反转。

右侧交易:在价格走出趋势之后进入市场,做动量,也就是常说的追涨杀跌。

本文选取的两种策略分别属于这两种策略,比较说明在同一指标下,这两种交易行为的优劣,但不具有普遍性。

数据提取

大盘指数:HS300

小盘指数:ZZ500

回测区间2015年1月1日 2018年12月2日

数据来源:WIND

注:后台回复“代码”可获取代码文件和研报

import pandas as pdimport numpy as npfrom matplotlib import pyplot as pltfrom matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r'c:\windows\fonts\simsun.ttc',size = 20) from WindPy import *w.start()

dateStart =  date(2005,1,1)dateEnd = date(2018,12,2)

IndexClose = w.wsd("000300.SH,000905.SH", "close", "{}".format(dateStart), "{}".format(dateEnd), "")Indexprice = pd.DataFrame(np.array(IndexClose.Data).T,columns=['hs300','ZZ500'],index = IndexClose.Times)

相对强弱指标

通过大小盘指数收盘价格构造相对强弱指数:

其中P1是中证500点位,P2是沪深300点位,回测区间内的相对强弱指标如图所示

代码(全文作图代码基本相同,之后不再列出)

Indexprice['P'] = np.log(Indexprice.ZZ500) - np.log(Indexprice.hs300)X = np.arange(Indexprice.shape[0])xticklabel = Indexprice.indexxticks = np.arange(0,Indexprice.shape[0]+1,np.int((Indexprice.shape[0]+1)/5))

plt.figure(figsize = [20,4])SP = plt.axes()      P1 = SP.plot(X,Indexprice.hs300,linewidth = 2,label = 'HS300',color = 'darkred')P2 = SP.plot(X,Indexprice.ZZ500,linewidth = 2,label = 'ZZ500',color = 'cornflowerblue')SP1 = SP.twinx()P3 = SP1.plot(X,Indexprice['P'],color = 'orange',linewidth = 2,label = u'相对强弱指数')   SP.set_xticks(xticks)SP.set_xticklabels(xticklabel[xticks],size = 20)p = P1+P2+P3lns = [l.get_label() for l in p]

plt.legend(p,lns,prop=font)plt.show()

相对强弱指标的值大小没有意义,并不是说大于0就倾向于小盘,小于0就倾向于大盘,两个指数的点数之间数量上有差异,因此要关注指标的变化趋势。

指标呈上升趋势,说明当前市场为小盘风格,应该投资小盘指数,反之应投资大盘指数

策略1:参见华泰研报

策略1为左侧交易,首先计算指标的MA10对数据进行平滑,通过函数updownbound计算MA10布林带,若MA10上穿下轨,做多小盘股,若MA10下穿上轨,做多大盘。

布林带定义

def updownbound(data,n,c):      data['upbound'] = data['P'].rolling(window = n, center = False).mean() + c * data['P'].rolling(window = n, center = False).std()   data['upbound'] = data['upbound'].shift(1)   data['downbound'] = data['P'].rolling(window = n, center = False).mean() - c * data['P'].rolling(window = n, center = False).std()   data['downbound'] = data['downbound'].shift(1)   for i in range(2,n):       data.loc[i,'upbound'] = data.loc[0:i - 1,'P'].mean() + c * data.loc[0:i - 1,'P'].std()       data.loc[i,'downbound'] = data.loc[0:i - 1,'P'].mean() - c * data.loc[0:i - 1,'P'].std()   data.loc[0,'upbound'] = 0   data.loc[0,'downbound'] = 0    data.loc[1,'upbound'] = data.loc[0,'P']   data.loc[1,'downbound'] = data.loc[0,'P']   return(data)

相对强弱指数、MA10及布林带如下

策略规则

当 10 日均线从下方上穿下轨,则做多小盘股,卖出大盘股,第二天开始算收益率。

当 10 日均线从上方下穿上轨,则做空小盘股,做多大盘股,第二天开始算收益率。

其他的情形,不需要做什么操作,任何时候都是满仓大盘股或者小盘股。

def strategy(data):   data['flag_hs'] = 0   data['flag_zz'] = 0   data['ret_strategy'] = 0   data['ret_zz'] = data['ZZ500'].pct_change(1)   data['ret_hs'] = data['hs300'].pct_change(1)   data.loc[0,'ret_zz'] = 0   data.loc[0,'ret_hs'] = 0   for i in range(1,data.shape[0] - 1):       # 上穿下轨,做多小盘,卖出大盘       if data.ma10[i - 1] < data.downbound[i - 1] and data.ma10[i] > data.downbound[i]:           data.loc[i + 1 ,'flag_zz'] = 1           data.loc[i + 1 ,'flag_hs'] = 0#           data.loc[i + 1,'net_zz'] = data.loc[i ,'net_zz']*(1 + data.loc[i + 1,'ret_zz'])#           data.loc[i + 1,'net_hs'] = data.loc[i ,'net_hs']*(1 - data.loc[i + 1,'ret_hs'])       # 下穿上轨,做多大盘,卖出小盘       elif data.ma10[i - 1] > data.upbound[i - 1] and data.ma10[i] < data.upbound[i]:           data.loc[i + 1 ,'flag_zz'] = 0           data.loc[i + 1 ,'flag_hs'] = 1#           data.loc[i + 1,'net_zz'] = data.loc[i ,'net_zz']*(1 - data.loc[i + 1,'ret_zz'])#           data.loc[i + 1,'net_hs'] = data.loc[i ,'net_hs']*(1 + data.loc[i + 1,'ret_hs'])       else:           data.loc[i + 1 ,'flag_zz'] = data.loc[i ,'flag_zz']           data.loc[i + 1 ,'flag_hs'] = data.loc[i ,'flag_hs']

   data.loc[data['flag_zz'] ==1,'ret_strategy'] = data.loc[data['flag_zz'] ==1,'ret_zz']   data.loc[data['flag_hs'] ==1,'ret_strategy'] = data.loc[data['flag_hs'] ==1,'ret_hs']

   data['net_strategy_zz'] = (1 + data['flag_zz']*data['ret_zz']).cumprod()   data['net_strategy_hs'] = (1 + data['flag_hs']*data['ret_hs']).cumprod()   data['net_strategy'] = (1 + data['ret_strategy']).cumprod()   return data

回测结果如下,蓝色为策略收益,浅蓝色为小盘指数的净值,红色为大盘指数的净值,绿色为持仓情况,值为1表示持有的是大盘,值为2表示持有的是小盘。

策略净值为4.96,整体来看,这种策略的优势仅在于交易次数很小,但基本没有超额收益。

再从其他方面考察策略:

上图为策略相对于大盘和小盘指数的表现,可以看出策略在16年之前优于大盘,而在整个区间内与小盘指数基本持平。

分年统计来看,策略并没有表现出持续优于大盘指数或者优于小盘指数。

整体来看,策略效果不尽人意。分析原因,主要在于市场在2008-2015年之间出现了长期的震荡行情,16年之后至今也是震荡下行,没有出现明显的趋势性,因此很难触发策略条件。

策略2:参见中金研报

策略2采取趋势突破的方法,创新高时买入小盘指数,创新低时买入大盘指数

报告中相对强弱指数定义如下

与前文定义的指标相差一个常数,对结果没有影响,仍采用前文定义。

策略规则:

相对强弱指数创新N1日新高,持有小盘

相对强弱指数创N2日新低,持有大盘

def strategy1(data,N1,N2,fee_ratio = 0):   data['flag_hs'] = 0   data['flag_zz'] = 0   data['ret_strategy'] = 0   data['buysell'] = 0   data['ret_zz'] = data['ZZ500'].pct_change(1).fillna(0)   data['ret_hs'] = data['hs300'].pct_change(1).fillna(0)

   for i in range(max(N1,N2),data.shape[0] - 1):       # 创新高,做多小盘       if data.P[i] >= np.max(data.P[i - N1:i]):           data.loc[i + 1 ,'flag_zz'] = 1           data.loc[i + 1 ,'flag_hs'] = 0

#           data.loc[i + 1,'net_zz'] = data.loc[i ,'net_zz']*(1 + data.loc[i + 1,'ret_zz'])#           data.loc[i + 1,'net_hs'] = data.loc[i ,'net_hs']*(1 - data.loc[i + 1,'ret_hs'])       # 创新低,做多大盘       elif data.P[i] <= np.min(data.P[i - N2:i]):           data.loc[i + 1 ,'flag_zz'] = 0           data.loc[i + 1 ,'flag_hs'] = 1

#           data.loc[i + 1,'net_zz'] = data.loc[i ,'net_zz']*(1 - data.loc[i + 1,'ret_zz'])#           data.loc[i + 1,'net_hs'] = data.loc[i ,'net_hs']*(1 + data.loc[i + 1,'ret_hs'])       else:           data.loc[i + 1 ,'flag_zz'] = data.loc[i ,'flag_zz']           data.loc[i + 1 ,'flag_hs'] = data.loc[i ,'flag_hs']

   data.loc[data['flag_zz'] ==1,'ret_strategy'] = data.loc[data['flag_zz'] ==1,'ret_zz']   data.loc[data['flag_hs'] ==1,'ret_strategy'] = data.loc[data['flag_hs'] ==1,'ret_hs']

   data.loc[data['flag_hs'] != data.flag_hs.shift(1),'buysell'] = 1    data.loc[0,'buysell'] = 0   data['ret_strategy'] = data['ret_strategy'] - fee_ratio*data['buysell']   #data['net_strategy_zz'] = (1 + data['flag_zz']*data['ret_zz']).cumprod()   #data['net_strategy_hs'] = (1 + data['flag_hs']*data['ret_hs']).cumprod()   data['net_strategy'] = (1 + data['ret_strategy']).cumprod()   return data

fee_ratio为手续费率,设定为0,取N1 = 20,N2 = 20,回测结果如下

最优参数下,策略净值为7.52,从净值曲线来看,明显优于策略1,有超额回报,但交易次数增多,交易成本也会上升。

此外,今年以来策略出现明显回撤,但整个市场都在下跌,可以通过策略与大小盘指数的相对强弱来说明策略相对于市场的表现

可以看出,策略2持续性优于或持平大小盘指数。

分年统计表明,除了16,17年,策略相对于沪深300每年都有正收益。

总体来看,策略2明显优于策略1(但并不是说右侧交易一定优于左侧交易,只是这一指标下)。

策略2参数优化

中金报告中指数,N1,N2处于15-25时,策略表现都很好。对N1,N2从5到30进行遍历,看看策略在不同参数下的表现情况。

横纵轴分别为N1,N2,竖轴/颜色表示策略累计收益率,颜色越深表明策略累积收益率越大,从图可以看出,最优参数存在于平面左下区域,即N1,N2较小时

取最优参数N1 = 8,N2 = 10做回测结果如下

最优参数下,净值为12.78

相对于市场走势平稳,回测区间内均持平或上升。

分年统计来看,除个别年份,每年对于大小盘指数都有明显超额收益,表现很好。

参考文献

1. 20100210-华泰证券-数量化策略:大小盘轮动

2. 20161218-中金公司-量化策略专题风格轮动研究(1):价量视角下的市值风格轮动策略

Python的爱好者社区历史文章大合集

Python的爱好者社区历史文章列表(每周追加更新一次)

关注后在公众号内回复“ 课程 ”即可获取:

小编的转行入职数据科学(数据分析挖掘/机器学习方向)【最新免费】

小编的Python的入门免费视频课程

小编的Python的快速上手matplotlib可视化库!

崔老师爬虫实战案例免费学习视频。

陈老师数据分析报告扩展制作免费学习视频。

玩转大数据分析!Spark2.X + Python精华实战课程免费学习视频。

研报复制(三):基于相对强弱指标的大小盘轮动相关推荐

  1. RSRS指标择时及大小盘轮动

    RSRS指标择时及大小盘轮动 简介: RSRS指标的构建 1)取前N日的最高价序列与最低价序列. 2)将两列数据,以最高价为因变量,最低价为自变量进行OLS线性回归. 3)取前M日的斜率时间序列,计算 ...

  2. 【每周研报复现】基于阻力支撑相对强度(RSRS)的市场择时

    原创文章第106篇,专注"个人成长与财富自由.世界运作的逻辑, AI量化投资". 今天要复现的研报是:"光大证券_金融工程深度:基于阻力支撑相对强度(RSRS)的市场择时 ...

  3. 2021年CS保研经历(三):清华大学自动化学院大数据专硕预推免

    目录 写在前面 清华自动化大数据(9.14) 1.资格审查(9.10) 2.面试(9.14) 3.收到拒信(9.16) 4.调剂(NULL) 写在前面   这段经历对我来说印象很深刻,所以这里单独记录 ...

  4. 研报复现系列(二):【光大证券】基于阻力支撑相对强度(RSRS)的市场择时

    1.研报概述 本文是券商金工研报复现系列的第二篇,文本复现了[光大证券]的[基于阻力支撑相对强度(RSRS)的市场择时]. 阻力位与支撑位传统的应用方法一般是选取特定的阻力位.支撑位作为阈值来进行突破 ...

  5. 研报复现系列(三):【东莞证券】股吧里说了什么?——基于文本舆情构建股市情绪指标

    1.研报概述 本文是研报复现系列的第三篇,本文复现了[东莞证券]的研报[股吧里说了什么?--基于文本舆情构建股市情绪指标] 该研报试图利用文本情感分析,通过统计情绪词,将股民的评论进行情感分析,联系情 ...

  6. 基于LSTM的研报分类系统

    关于lstm的文本分类可以参考:https://blog.csdn.net/lilong117194/article/details/82217271 下面是基于东方财富中宏观研究的研报分类系统介绍: ...

  7. 基于图数据的研报词关联之聚合分析

    基于图数据的研报词关联之聚合分析 基于图数据的研报关键词聚合分析 一.算法介绍 二.数据模型 三.计算关键词上下文聚合相似性 四.关键词上下文聚合性能测试 五.计算聚合相似性[CYPHER优化] 六. ...

  8. 阻力支撑指标RSRS策略:光大证券研报复现

    昨天我们已经计算好了RSRS指标策略,今天把光大证券的研报复现一下. 由于计算比较耗时,我们会把计算的中间结果的dataframe保存下来. 我们使用hdf5保留数据结果,这里有一个小tip,有点奇怪 ...

  9. 复现东方证券研报--特质波动率因子研究

    最近发现特质波动率因子选股效果不错,于是按照东方证券研报的思路做了一些研究.研究发现该因子确实有显著的选股能力,并且在CAPM.Fama-French三因子.Carhart四因子.Fama-Frenc ...

最新文章

  1. 高考成绩查询2021艺术类6,2021年高考成绩6月26日左右可查!
  2. html grid插件,miniGrid:轻量级流布局JS插件
  3. Appium_pytest fixture的使用
  4. java 重建二叉树_【剑指offer】 Java实现重建二叉树
  5. stm32高级定时器 基础知识
  6. [收藏]孔庆东-为何要唱样板戏
  7. linux shell实现随机数多种方法(date,random,uuid)
  8. TrustToken向Curve上tfTUSD贷款池新投入2400万美元资金
  9. vue获取url中ip_Kubernetes 集群中这样获取客户端真实 IP
  10. 阿里巴巴正式上线全球首个数据中心Open Channel SSD产品
  11. 迭代器模式在 Java 容器中的实现
  12. JupyterHub与OpenLDAP集成
  13. linux终端字体放大_5 个 PowerShell 主题,让你的 Windows 终端更好看
  14. 探究CRM未来趋势:纷享销客的连接型CRM到底是什么?
  15. Python如何开发一款连连看脚本,第一必须是我。
  16. python求解一元二次方程考虑复数_Python学习笔记:求解一元二次方程
  17. 对于分布式消息队列我有话说
  18. composer安装fxp/composer-asset-plugin
  19. 为什么企业要招应届生?
  20. android中的高级组件(三)(ExpandableListView,ImageSwitcher,Gallery)

热门文章

  1. 秘鲁庆祝亚马逊河被评选为世界自然奇观十周年纪念日
  2. linux运维工程师培训课程_Linux系统资深运维工程师的进阶秘籍
  3. Haihong Alison
  4. SpringToolSuite4汉化
  5. ajax获得header信息,关于jquery ajax跨域请求获取response headers问题
  6. 手写一个bind函数
  7. 荣耀有没有鸿蒙os2.0,不是所有华为、荣耀手机都能升级“鸿蒙OS2.0”,只有这48款才行...
  8. java计算机毕业设计在线果蔬团购系统源码+mysql数据库+系统+lw文档+部署
  9. php session的默认保存路径
  10. 中国四大工控与电子调查研究咨询公司信息