美文网首页量化交易我爱编程量化交易&宽客
【量化课堂】简单市值轮动策略

【量化课堂】简单市值轮动策略

作者: 城2021 | 来源:发表于2018-01-26 15:51 被阅读175次

> 学习内容:

> - 学会使用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原文:定时运行

>-推荐以后都用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可用来获取财务数据,用法复杂而强大,但常用的基本可以套用这个公式:(可对比上文代码理解)

其中,数据表.数据项怎么找呢?到导航栏-数据-财务数据中找,比如数据表valuation,数据项market_cap,如下图:

get_index_stocks的用法就比较简单,就是在导航栏-数据-指数数据中找到要用的指数,之后放到括号里。返回的是指数成分股list,所以获取多个指数成分股list后用“+”连接起来。具体看文档API文档 get_index_stocks

> 答疑与延伸:

>- 使用更复杂的条件筛选财务数据?get_fundamentals中的与或非

>-get_fundamentals的更多介绍API文档 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的用法详情请见:dataframe 专题指南,pandas库之数据查看、选择

6 分配资金进行买卖交易

要买的股票已经选好放在buylist里了,只要将资金分好,相应的买入就好了,如果看过之前那篇多股票策略的话,应该很好理解。

特别的是,存在这样的情况,某股票市值是最小前五的而被选入buylist,而且也买入持有了,但过了一段时间,其股票市值不是最小前五了,从而不再当下的buylist里,这时我们应当卖出这个股票。因为我们的策略就是10天为周期地持有市场上市值最小的五只股票。

代码如下:

> 答疑与延伸:

>- context.portfolio.positions什么意思? 是当前策略的持有股票数据是个dict,不妨自己输出看看,参考内容: 回测账户数据——contextPython入门- 数据类型之字典

7 策略完成,进行回测

至此,我们的策略都已经用代码实现好了,完整代码如下:

进行回测,回测结果如图:

自测与自学

1、是否学会使用run_daily进行周期循环

2、是否学会取用市值数据、持仓数据、指数成分股数据

3、是否学会编写简单小市值轮动策略

4、调整下策略,比如轮动频率,持仓股票数,回测看看效果如何?

5、思考此文中,虽然每次都等资金的买入,为何5只股票的持仓总价值其实还是不同,而且可能越差越大?

相关文章

网友评论

    本文标题:【量化课堂】简单市值轮动策略

    本文链接:https://www.haomeiwen.com/subject/mqiiaxtx.html