上一篇文章市值轮动策略2.0
摘要
- 分钟止损
- 行业与概念股
- 根据大盘调整持仓水平
- 获取行情——history
- 技术指标库
- 带名字的list——dict
- 性能分析
- 归因分析
承接上文,我们继续以市值轮动策略为引,学习新的量化交易知识。
分钟级止损
上篇文章讲了如何每日止损,即每天检查是否满足止损条件判断是否减仓股票。为了更及时的止损,我们将介绍如何每天每分钟地检查止损条件。
首先把策略的时间周期级别改到分钟级。
随着时间级别的改变,默认的循环周期就变成了分钟级,所以我们把原本按日循环的daily
函数变成为按分钟循环,我们要改正为每天循环。
把原本run_daily
中的time参数从'every_bar'改为'before_open','before_open'含义是每天开盘前运行,而'every_bar'是每个循环周期运行一次,原本是日级就每天循环,刚刚改成分钟级就每分钟运行一次。操作如下:
为了每分钟判断止损条件,即增加分钟循环,并把原本的止损函数stop放进去。像daily函数那样,我们建立一个新函数mktopen,像刚刚讲的每分钟循环,time参数就是'every_bar'了。操作如下:
这样我们就把原来的日级策略加入了分钟级止损。
答疑与延伸:
run_daily
中的time参数?请看API 定时运行
- 除了止损外,其他的分钟级操作也可以在mktopen中完成,比如计算分钟级的技术指标等
行业、概念股
原本的策略,是在全A股中选股,那若想只在某个行业或概念中选股怎么办呢?
类似之前获取指数成分股的方法,换个函数名就能获取某行业下的股票或属于某概念的股票了。先在数据页面找到你要获取的行业或概念代码,具体方法如下:
我们这次选聚宽一级行业的金融行业(HY007)、申万一级行业房地产板块(801180)、移动支付概念(GN069)。在数据页面顶部是可以看到get_industry_stocks
与get_concept_stocks
相关使用方法。具体操作如下:
答疑与延伸:
- 概念?不同于行业分类的一种分类方法,按概念分类可以包括多个多个行业,是按某事件、某潮流分类,比如雄安概念、5G概念。更多了解请百度咯。
根据大盘指数行情调整策略
个股是要受到市场整体的好坏的影响的,所以我们考虑根据大盘情况调整持仓水平,大盘不好就少持仓,多就多持仓。具体我们简单而不失代表性的这样设计一个判断大盘函数:
如果沪深300指数大于20日均线,返回满仓操作的信号;
如果沪深300指数小鱼20日均线,返回半仓操作的信号;
我们自定义一个函数mkt_index
,包含三个内容获得大盘指数、获得大盘指数20日均线、判断大盘情况返回信号:
mkt_index
函数还是都是注释,我们接下来一步步会完成它。
这个函数的位置放在每个周期交易下单前,并新增一个全局变量g.holdpct
来接受返回的信号。
获取指数行情数据——history
首先,我们要获取大盘指数的值,之前讲过获取股票的价格,类似的方法也可以指数的值。
我们这次介绍另一种更推荐的history
方法获取行情数据。代码如下:
history默认取出的数据是dataframe格式,是个带行名列名的表格。需进一步选择这个dataframe中的我们想要的大盘指数的值。代码如下:
为了说明数据格式上的差别,我在上图中用print在日志中输出了前后的mktindex
的对比。可以看到前是一个表格(尽管在这个例子中是一行一列的),后是一个值。
此时,mktindex
就是沪深300指数的最新值了。
答疑与延伸:
- history?以后要用history替代用data获取行情,data在系统上有弊端,将逐渐废弃。详情见:API history,
attribute_history
是类似的一个获取行情的函数,推荐阅读 history和attribute_history的区别?
- mktindex.ix[-1,'000300.XSHG']?含义是获取mktindex这个dataframe中的倒数第一行,这列的数据。推荐阅读:pandas.dataframe 专题使用指南
计算均线——技术指标库
获取了指数的值,接下来获取指数的20日均线,当然自己计算也不难(获取最近20日行情求平均),但这里引入下技术指标库来解决这个问题:
使用之前要导入技术指标库,就是写一行代码,如下图:
首先在技术指标库中找到我们要用的MA均线函数:(善用ctrl f搜索功能)
根据文档中的介绍来使用它,代码如下:
带名字的list——字典dict
通过文档介绍可以发现,MA返回的是一个dict,dict 是什么呢?
相比于之前学过的list,dict额外给了其中每个值(value)一个名字(键、key),基本格式为{key:value,...}。
dict取用的时候不必像list[3]
那样通过位置3选择数据,而是通过那个名字(key),在本例中就是ma20['000300.XSHG']
这样来获取dict ma20中key为'000300.XSHG'的值的。
为了说明数据格式上的差别,我在上图中用print在日志中输出了前后的ma20
的对比。上图中,可以看到MA直接获得的是一个dict,内容为“{'000300.XSHG': 3459.5297599999985}”,后面得到的就是一个值3459.52976。
此时,ma20
就是沪深300指数的20日均线值了。
根据大盘改变持仓水平
剩下的工作就简单了,一个if判断句就搞定了。
返回的1或0.5什么意思?接受返回值的是'g.holdpct',之后只要让每次下单量乘上'g.holdpct'就起到调节持仓水平的作用了。大盘在均线上就正常下单,大盘在均线下就只下正常水平的一半。具体改动如下:
答疑与延伸:
- 两个return?一个函数的代码中不一定只有一个return,但是return是函数的终点,执行后就离开函数了,所以一次调用函数只能有一个return执行。
性能分析
分钟级策略计算量容易很大,极端时可能会造成交易延迟,以至于出现策略总是慢半拍的情况,所以我们也要关注下策略的运算耗时情况,而相关函数就是——enable_profile
用法就是把enable_profile()
这行代码复制粘贴放到第一行。然后,你成功回测后可以在回测详情页面查看性能分析的结果,如下图:
如果你觉得你的代码执行过慢,重点看下耗时较长的地方,想办法优化下速度。优化速度的方法往往是算法流程优化、换更高效的库或数据类型等,这里就不展开介绍了。
归因分析
为了评价策略从而进一步改善策略,除了回测界面有的风险指标、持仓详情等,还有一个更深入的归因分析功能,功能按钮在回测详情页如图:
归因分析功能会分析你的回测结果,从多个维度分析你的策略,如收益、持仓、风险、因子、brinson归因等。单说这块就够一篇文章的了,这里不展开了。
另外,这个功能计算量比较大,尤其是brinson归因,所以往往会明显感觉到慢,请耐心等待。
策略完成,源码可在文章最后回测中查看。
自测与自学
- 是否理解并学会使用分钟级回测?
- 是否会取用行业股、概念股?
- 是否会使用history取数据?
- 是否会使用技术指标库?
- 是否会使用dict类型数据?
- 是否会使用性能分析和归因分析?
- 思考并总结目前为止学过的获取数据的方法。