答应我,在量化策略回测里,避开未来函数这4个坑
由于社群的原因,看过不少策略,今天就腆着脸唠唠,量化新手期经常碰到未来函数的4个坑,希望量化萌新们少掉点儿头发。新手向文章,大神请绕行~
情景1:使用前复权价格数据。
由于股票会存在分红送股的情形,价格会出现非交易回落,导致股票价格序列的不连续性,假设个股“10送10”,股价就腰斩了,双均线什么的马上就会出现“死叉”,所以为了指标计算的连续性和方便性,就会使用复权价格数据。
一些量化萌新入门之前,在行情软件上一般是看前复权行情(很多股民都有这个习惯),因为前复权行情是保证现在的价格不变,根据分红送股的信息对之前的股票价格进行调整,看到现在K线的数值比较“正常”,如果是看后复权价格行情的话,很多上市时间比较长、分红送股比较多的股票后复权价格都是“成千上万”的了,不太“人性化”。
酱香型科技公司的前复权价格比较符合股民习惯。
后复权价格已然上万,很多人一开始不习惯也不喜欢。
所以有一部分新手就会使用前复权价格数据,刚才已经说了,过去的股价数据是按照现在价格,根据分红送配的信息往过去推的,换句话来说,历史的价格数据包含了现在的信息,也就有了“未来信息”。
如果是使用前复权价格数据,那最简单且收益高的量化策略就是,买上市时间早且前复权价格低的股票,回测收益率曲线保证不差。
情景2:当前K线出信号,当前K线成交。
这里特指的是:使用K线收盘价序列计算指标,出现信号后,以收盘价成交。
其实这种情况已经比“最低价买入,最高价卖出”的偷价情形好很多了,除非是恶意设置,不然一般萌新凭直觉都会避免。
但有时候看一些萌新的策略源码,会出现类似于“IF Crossover(MA5, MA20) THEN Buy(Close,...)”(当前MA5均线上穿MA20均线时,按收盘价买入)的情形,其实这挺符合日常看盘的习惯,看到金叉死叉的时候,都会在脑子里面从当前时点开始判断之后的行情。
但在量化里面,这其实也是包含了未来信息的,因为量化交易实盘是实时进行的,至少会出现以下两种不利的情况。
(1)当前K线没走完,最高价就触发了金叉信号,按照最高价就买入了,可能收盘价和最高价之间就存在不小的滑点。
(2)当前K线最高价可以触发金叉信号,但按照收盘价计算却触发不了金叉信号,这就造成了实盘当中能成交、回测当中无法成交的不对应情况。
因此有经验的宽客一般都会设置为“当前K线出信号,下一根K线开盘价/限价成交”,例如上面的例子可以改为“IF Crossover(MA5[1], MA20[1]) THEN Buy(Open,...)”(根据上一根K线计算的MA5均线上穿MA20均线时,按照开盘价买入)。
其实这样的设置还可能不够严谨,不过已经比之前的情形好很多了。更为严谨的是,买入价可以设为“Max(Open,LimitPrice)”(开盘价和心里目标价位的最大值),量化想做好就是要扣很多细节,路漫漫其修远兮,吾将上下而求索~
情景3:无法判断最低价和最高价的出现顺序。
这种情况相对少见,造成的后果也比较薛定谔,举个例子来说明吧。
假设一个股票/品种出现了天地板(大幅震荡同理),涨停会触发止盈,跌停会触发止损。
如果是按照K线来回测的,用高低价判断是否触发止盈止损,这就要看在策略源码中,你把止损写在前头,还是把止盈写在前头,因为在这根K线上,止盈止损的条件同时都满足,谁写在前头谁就会被执行。
但是在实盘当中,最高价和最低价必然有先后出场的顺序,假设先出现跌停,再出现涨停,而在代码当中是把止盈写在前头。
这个时候就变相出现了未来信息,在回测当中出现了“苦尽甘来”的情况,在实盘当中要亏损10%的情况,在回测当中却盈利了10%。
这个就有点儿类似于“幸存者偏差”,如同很多经典量化书籍都提到过的例子:在米国,买入困境当中的股票博反转,回测效果非常好,实盘效果却可能大相径庭,因为在早期,个股退市后数据就“消失”了,能回测到的股票都是从困境当中挺过来的幸存者,股价自然会迎来大涨,但如果在现实当中买到的是没有挺过来的不幸者,那就GG了。
情景4:财报数据当中的未来信息。
这个财报当中的未来信息非常隐蔽,我初始做量化的时候也掉进过这个坑,不是自己"粗心大意",而是没有经验、特别是没有财务相关知识的萌新容易掉坑。
众所周知,A股上市公司的一季报、半年报、三季报和年报的披露截止时间分别在当年的4月底、8月底、10月底和次年4月底公布,一般很少有人在2021年1月就直接调用2020年报的,这个错误对普通股民都太过明显,今天要说的是比较"隐蔽的"。
举个例子,有的童鞋就考虑到财报的延后披露,但各家上市公司的披露日期又没有规律,于是乎,在构建量化基本面模型时,就在披露截止日期的次月第一个交易日调取财报数据,比方说在2021年5月6日才调用2020年报数据。
的确,这种方式能剔除绝大部分的未来信息,但是还是有些隐蔽的瑕疵,这个瑕疵的根源就是:部分公司会对之前的财报数据进行修正,最新值会替换掉旧值。
举个真实的例子,某扇贝跑来跑去的上市公司XX岛由于2014、2015连续两年亏损被*ST,如果2016年再亏损就要进入退市流程了。2017年3月21日,XX岛公布了2016年的年报,净利润为7571个w,扭亏为盈,保壳成功。但在2019年7月被证监会最终查出虚增利润1.3个小目标,追溯调整后净利润为-5543个w。
如果今天来回测,取到XX岛2016年的净利润就是-5543w,可以避开这个大雷,而实际上,2017年5月第一个交易日取到的净利润却是7571w,老老实实挨锤。
XX岛2016年的年报原始数据。
2022年今天查询到的XX岛财务数据。
这种回测历史当中能取到、现实当中无法取到的财报数据,就是做基本面量化的萌新很容易掉进的坑,特别还是早期的时候。
不过现在萌新们不用担心了,很多量化平台都做了非常贴心的设置,除了设定报告期外,还可以设定取数日期,只能取到在实际当中取数日期之前可见的财报数据,在取数日期之后的修正是取不到的,或者是其他落地的金融数据库,会同时存储原始财报数据和修改后的财报数据,并且有每条记录的公告日期,可以按照公告日期进行数据选择。
在回测当中,要有效避免掉这些未来函数/未来信息,除了多听前人的掉坑经验外,就是彻底了解自己所用的指标、变量、模型、算法的计算流程和细节,在哪个环节上会拿到这个时点之外的未知信息,慢慢地打磨细节,这样会比较快。
END
如果对本文有疑惑,或是想聊聊
亦或是围观朋友圈当点赞之交
点我,让我们一路同行
吃瓜吐槽写代码
(微信号:iquantman)
添加好友后,私信『666』
送你一些量化小福利