【量化交易入门】简单市值轮动策略 简单市值轮动策略 学习内容: 学会使用run
简单市值轮动策略
学习内容:
学会使用run_daily进行周期循环
学会取用市值数据、持仓数据、指数成分股数据
学会写小市值策略
这一次我们要学写一个小市值轮动策略。
1 确定策略内容
简单小市值轮动策略内容是这样的:
> 每隔若干个交易日,等金额持有市值排名最小的前几只股票,卖出其他股票。
进一步明确下,把量确定,例如这样:
> 每隔10个交易日,等金额持有市值排名最小的前5只股票,卖出其他股票。
接下来按之前讲的套路出牌就好了,即初始化加周期循环。(想想之前的内容,这次具体该怎么做)
2 初始化
确定轮动频率,即每隔多少个交易日进行买卖。比如就是10个交易日。
确定持有最小市值股票数,即持有市值排名最小的前多少只股票。比如就是前5只。
则初始化部分代码为:
> 答疑与延伸:
- 这也是多股票策略,怎么不确定股票范围了?股票范围我们希望是能在全市场,但它是变化的,有新股上市,也有退市的,所以股票范围不能事先确定好不变,所以要在周期循环的部分不断更新并确定股票范围。
3 周期循环的另一种写法--run_daily
那么用run_daily的我们的初始化-周期循环的策略框架怎么写呢?
我们的新套路如下:
首先,可以看出run_daily要写在initialize里。
其次,需要知道的是,你把什么函数替换掉daily,谁就会像原来的handle_data一样进行周期循环。虽然名字不一定是daily,可以自己改,但不能很聚宽回测引擎已经有的函数重名,比如不能叫handle_data、initialize。
> 答疑与延伸:
- time='every_bar'是什么意思?time这个参数控制循环行为的,当time=’every_bar‘时,循环的行为就和handle_data一样,按天回测时就每天开盘时运行,按分钟回测时就每分钟开始时运行。当然time还可以为别的,从而循环的行为会有所不同,从而实现一些handle_data做不到的事,具体见API原文:定时运行
4 开始写周期循环部分
按之前的设定,我们希望策略每十天进行一次循环,进行判断,买入卖出等,即轮动频率为10天。但策略回测只提供了基本的每分钟循环和每日循环,要做到每10天进行一次循环需要写代码编程解决。
怎么编呢?想法很简单,就每日循环好了,第一天正常进行判断买入卖出,之后九天什么都不做,然后,第十一天再正常判断买入卖出,再闲九天,这不就搞定了。
因此,我们需要一个变量,记着现在是策略进行第几天了,如果能被轮动频率10整除余1就干活,进行买卖。否则,就闲着,什么都不做。
所以,至此我们的代码应当是这样写的:
> 答疑与延伸:
- g.days=1为什么要写到initialize里?因为g.days需要独立在周期循环之外来记录策略运行天数,而且还要在周期循环中使用,所以需要在initialize里设置为全局变量并赋予初值1。如果写在周期循环里,每次循环都将被重置为1,无法记录运行天数。
- g.days % g.period什么意思? 意为求g.days整除g.period后的余数,“%”是取余运算。例如,那么12%10就是等于2,因为12整除10得1余2,更多的,3%10等于3,3%5等于3。
- pass什么意思? 在python里就是什么也不做的意思。
接下来,我们关注点将在“写进行选股、判断、买入卖出等代码”这个关键代码,其余代码暂时放到视野外。
5 找出全市场上市值最小的5只股票
用context结构获取策略回测数据中的当前时间;用get_index_stocks获取指数成分股,从而确定股票范围;用get_fundamentals来使用财务数据中的市值数据,同时也能获取到相应股票代码。
代码如下:
> 答疑与延伸:
- `这些数据都是怎么取用的?请到前文中查阅。
- list(df['code'][:g.stocksnum])什么意思? df是取出的按市值从小到大排好序的股票代码,是个dataframe,df['code']就是选取df中的code列,即股票代码。df['code'][:g.stocksnum]就是取df中的code列中的前g.stocksnum个。最后list()是把df['code'][:g.stocksnum]转成将会用到的list的数据类型。dataframe的用法详情请见:pandas库之数据查看、选择
6 分配资金进行买卖交易
要买的股票已经选好放在buylist里了,只要将资金分好,相应的买入就好了,如果看过之前那篇多股票策略的话,应该很好理解。
特别的是,存在这样的情况,某股票市值是最小前五的而被选入buylist,而且也买入持有了,但过了一段时间,其股票市值不是最小前五了,从而不再当下的buylist里,这时我们应当卖出这个股票。因为我们的策略就是10天为周期地持有市场上市值最小的五只股票。
代码如下:
> 答疑与延伸:
- context.portfolio.positions什么意思? 是当前策略的持有股票数据是个dict,不妨自己输出看看,更多相关内容请在水水水水撒中查阅。
7 策略完成,进行回测
至此,我们的策略都已经用代码实现好了,完整代码如下:
进行回测,回测结果如图:
自测与自学
1、是否学会使用run_daily进行周期循环
2、是否学会取用市值数据、持仓数据、指数成分股数据
3、是否学会编写简单小市值轮动策略
4、调整下策略,比如轮动频率,持仓股票数,回测看看效果如何?
5、思考此文中,虽然每次都等资金的买入,为何5只股票的持仓量其实还是不同,而且可能差很大?
到JoinQuant查看策略源码,并与作者交流讨论:【新手入门教程】简单市值轮动策略