> 学习内容:
> - 学会使用run_daily进行周期循环
> - 学会取用市值数据、持仓数据、指数成分股数据
> - 学会写小市值策略
1 确定策略内容
简单小市值轮动策略内容是这样的:
> 每隔若干个交易日,等金额持有市值排名最小的前几只股票,卖出其他股票。
进一步明确下,把量确定,例如这样:
> 每隔10个交易日,等金额持有市值排名最小的前5只股票,卖出其他股票。
接下来,进行初始化和周期循环。
2 初始化
确定轮动频率,即每隔多少个交易日进行买卖。比如就是10个交易日。
确定持有最小市值股票数,即持有市值排名最小的前多少只股票。比如就是前5只。
则初始化部分代码为:
> 答疑与延伸:
>- 这也是多股票策略,怎么不确定股票范围了?股票范围我们希望是能在全市场,但它是变化的,有新股上市,也有退市的,所以股票范围不能事先确定好不变,所以要在周期循环的部分不断更新并确定股票范围。
3 周期循环的另一种写法--run_daily
那么用run_daily的我们的初始化-周期循环的策略框架怎么写呢?
我们的新套路如下:
首先,可以看出run_daily要写在initialize里。
其次,需要知道的是,你把什么函数替换掉daily,谁就会像原来的handle_data一样进行周期循环。虽然名字不一定是daily,可以自己改,但不能很聚宽回测引擎已经有的函数重名,比如不能叫handle_data、initialize。
> 答疑与延伸:
>-推荐以后都用run_daily来进行周期循环,聚宽系统上handle_data将会弃用。
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来使用财务数据中的市值数据,同时也能获取到相应股票代码。
代码如下:
get_fundamentals可用来获取财务数据,用法复杂而强大,但常用的基本可以套用这个公式:(可对比上文代码理解)
> 答疑与延伸:
6 分配资金进行买卖交易
要买的股票已经选好放在buylist里了,只要将资金分好,相应的买入就好了,如果看过之前那篇多股票策略的话,应该很好理解。
特别的是,存在这样的情况,某股票市值是最小前五的而被选入buylist,而且也买入持有了,但过了一段时间,其股票市值不是最小前五了,从而不再当下的buylist里,这时我们应当卖出这个股票。因为我们的策略就是10天为周期地持有市场上市值最小的五只股票。
代码如下:
> 答疑与延伸:
7 策略完成,进行回测
至此,我们的策略都已经用代码实现好了,完整代码如下:
进行回测,回测结果如图:
自测与自学
1、是否学会使用run_daily进行周期循环
2、是否学会取用市值数据、持仓数据、指数成分股数据
3、是否学会编写简单小市值轮动策略
4、调整下策略,比如轮动频率,持仓股票数,回测看看效果如何?
5、思考此文中,虽然每次都等资金的买入,为何5只股票的持仓总价值其实还是不同,而且可能越差越大?