Bootstrap

换了量化平台,重新回测,还是十年10倍

这不是前几天发了篇文章《手把手教你构建与改进轮动策略》嘛,很开心能激发一些小伙伴的动手能力和开发优化能力,但同时也引发了部分小伙伴的疑惑。

比如说就有知友疑惑道“这个回测是默认每天都操作吗?如果是的话,是否有些不妥?” 其实呢,回测当中并不是想模拟每天都要操作,而是发生轮换时才操作,只不过为了计算方便,没有纳入轮换时的交易成本。

关于这点,在之前的文章末尾已经有所提及,除此之外呢,为了计算简单方便,还存在着“收盘价出信号,收盘价成交”的未来函数问题,于是乎,为了回测的严谨性,不再让一些小伙伴们迷糊,决定换一个量化平台,重新确认那个轮动策略在历史当中的表现。

图片

咱以之前那篇文章最后改进出来的轮动策略为准,也就是第4节中的『轮动策略改进2』,先来描述一下策略大致思路,候选池确认为:红利ETF(510880),创业板ETF(159915),纳指ETF(513100),黄金ETF(518880);每日为候选池当中的所有ETF进行动量强弱打分,ETF强弱得分为“斜率和决定系数的乘积”,买入得分最高的那个ETF,若得分持续最高则继续持有,否则卖出旧仓买入新的最强。

从这里就可以看出了,虽然每个交易日都进行打分,但并不是每天都会交易,只有在新旧最强ETF发生交替时,才会先卖出之前最高得分ETF,买入现在最高得分ETF,回顾一下之前的回测绩效。

图片

图片

这次重新回测使用的量化平台是聚宽(JoinQuant),为了能与之前的回测对应,有2个关键的地方要重点注意。

第一个就是回测的时间范围,之前旧回测取数据设置的起始时间是2013年7月29日,由于要计算N日的斜率和对交易信号进行“平移”,旧回测实际的开始时间是2013年9月2日,而JoinQuant在回测过程中会默认往前多取一天,于是乎,JoinQuant的开始时间就要设置为2013年9月3日(在回测详情中会显示为9月2日)。

旧回测当中并没有设置结束日,因为数据API会自动取到最新日期数据,方便后来做试验的小伙伴回测到最新的日期,那次回测是在上周末完成的,能看到的最新交易日是2023年7月28日,为了对应,JoinQuant当中的结束时间也设置为这个日期。

第二个就是交易的时点,旧回测当中是“收盘价出信号,收盘价成交”,这样是带有一定未来函数的,需要进行校正,在JoinQuant当中,咱依旧是收盘价出交易信号,但在第二天的开盘才成交。

先不加费率和滑点,用JoinQuant回测一遍,绩效如下。对了,为了防止带入其他的未来函数,开启了系统的防未来函数(avoid_future_data)功能。

图片

图片

对比前后两版回测绩效图,旧回测当中基准累计收益为460.28%,JoinQuant的为460.77%,十年数据累计误差了千分之五,基本可以看成是一致的。

旧回测的策略累计收益率为1482.79%,JoinQuant的策略累计收益为1345.85%,少收益了136.94%,这就是“收盘价成交”还是“第二日开盘成交”之间的区别引起的,这也在情理之中。

有趣的部分来了,旧回测的策略年化收益(CAGR)显示为21.23%,而JoinQuant的年化收益却是31.95%,累计收益率低的那个,年化收益率却反而高出一大截,这是什么鬼?

遍查网络资料,发现这是由一个非常不人性化的参数默认值引起的,到底是怎么肥事,听我细细道来。

先来说复合年化增长率(Compound Annual Growth Rate,CAGR),也就是咱常说的“年化收益率”,它的通用计算公式如下。

图片

EV是期末值,BV是期初值,n是年数,CAGR的计算就是期末值除以期初值,再开n次方,最后减1再乘100。

这式子不复杂,但是相同净值序列放到不同的量化平台/软件,统计出来的策略年化收益率CAGR却是不尽相同的,特别是时间范围小的,相差可能非常大,这里面最关键的因素就是n值,也就是年数的确定。

如果你每次交易都是从某一年年头交易到后面某一年年尾,那这样的年数很好确定,因为都是整数嘛。但现实是回测的起始时间和结束时间,圈出来的时间范围是不整的,那年数是怎么确定呢?

有两条路子,一个是按照交易日数换算,另一个是按照自然日数换算。

JoinQuant就是按照交易日换算,认为一年是250个交易日,回测当中有多少个交易日,除以250,就是年数。

图片

旧回测用的quantstats库走的就是另外的路子,按照自然日换算,一年是365个自然日,其实按照自然日换算也没有问题,十年范围这么长期的回测,两种方式换算出来的年数差别不大,关键是quantstats的底层计算CAGR时默认参数有大坑。

图片

怎么回事呢?就是旧回测时,quantstats也是会用期末日期减期初日期,算出这之间有多少个自然日,坑爹就坑爹在,它除以的默认参数是252,而不是365,又要按自然日算,除以的却是交易日数,本来年数应该是10,现在一晃却变成15了,同样的累计收益,花更长的时间达成,年化收益可不是就低嘛~~如果把periods设置成365,计算出来的CAGR就正常了,所以JoinQuant的策略年化收益是正确的,之前旧回测的是错的。

图片

填了这个大坑,关注点还是回到策略这边,在原来的基础上,加入费率和滑点。ETF的费率跟股票是差不多的,就看自己开H时定的是多少,这里回测时设置在最高档万分之3,最低5元,没有印花税,实际上从各券商渠道来看,ETF费率最低可以做到万分之0.4。

图片

在滑点上,设置为0.002元,基本上也就是买入往上挂一档,卖出往下挂一档。都设置完毕,重新跑一遍回测,绩效如下。

图片

图片

不出意外地,收益出现了明显的下降,但依然稳在了十年10倍,策略累计收益率为1040.55%,年化收益率为28.74%,夏普率为1.0,最大回测为29.88%,虽然没有了之前文章旧回测时那么亮眼,但胜在把很多实际因素都考虑进去了,从目前的情况来看,还属于是一个不错的入门基础策略。

哦,对了,本次的JoinQuant策略源码原路径自取,相比之前的版本,还有一处改进,就是除了候选池可以加入任意股票/ETF等有连续价格序列的证券外,每次轮动时还可以选入任意个标的,而不是像之前只能选入一个。

原文首发链接:《换了量化平台,重新回测,还是十年10倍》

;