算法交易策略的成功回测
介绍
本来来自英文网站 QuantStart 中对于算法交易策略回测描述的一篇文章,原文可以参见脚注。[ Successful Backtesting of Algorithmic Trading Strategies - Part I] 市面上介绍算法交易的文章虽然不算多,但也不少,很多量化爱好者也会在各大论坛对自己的策略进行分享, 一般的流程就是策略描述,策略代码,策略回测表现。但是,就笔者所看到的,很多类似的量化研究还停留 在比较初级的阶段,很多回测中的问题,策略实现者并没有意识到,最后回测出来一条貌似很牛逼的曲线, 就认为他的策略差不多可用了,印钞机哪里这么容易去造成。当然,对于这些热心分享的网友们,笔者表示 由衷感谢,正是从他们无私分享中,笔者也从一个普通菜鸟,渐渐成熟到能够去独立开发一些实盘策略,但 是,对于其中的一些坑坑洼洼,尤其是笔者也踩过了不少的坑,也不想后来人再去走一次这样的弯路,因此, 去对回测中可能遇到的坑进行一些总结和分享,还是挺有必要的。
之前的文章中,笔者曾经提到过一些回测的坑,包括未来函数、偷价等常见的易犯的错误,不过经验与能力 所限,笔者所言,在广度与深度上也没有那么尽如人意。
恰巧,最近在 QuantStart 网站上看到了关于回测的一系列文章,很多论述,哪怕看过几次都值得回味, 因此,笔者这里斗胆,对这篇文章进行翻译与二次加工,以飨读者,希望读者们能够仔细阅读这篇文章,如果 觉得笔者翻译与注解的不行,完全可以去参照英文原文,多次品读与回味。
什么是回测
算法交易和其他投资门类差别很大,相比其他投资方式,在提供了足够丰富的数据后,算法交易可以根据历史 数据,对未来收益有一个更好的估计。通过历史数据去估计未来收益,这样的回程称之为回测 (backtesting).
简单而言,回测就是将你的独特的策略应用到历史金融数据上,得到一系列交易信号,每次交易 (这里的一次 包含买入和卖出) 都会有相应的利润或者损失。将回测时间区间内的收益与损失进行累加,可以得到总盈亏。 这些就是回测的精华部分。当然,实际中还是会有各种问题,所谓 “魔鬼藏在细节中” (devil is always in the details),后续会提到.
那么,为什么要回测呢,下面是一些关键原因:
1.过滤
策略的研发过程,一般包括建模、研究、回测、模拟、实盘等阶段,在研究过程中,对于我们去考虑策略 中设置的一些条件是否合适,回测可以提供一个比较好的评价标准,对于拖累回测结果的过滤条件,我们可 以评估需要加入这样的过滤条件所有合适。
2.建模
回测允许我们 (安全地) 去测试对于市场建立的模型,譬如交易损失,买卖盘传递,延迟,流动性以及其 他市场微观结构方面的问题。
3.优化
尽管策略优化很容易引入过拟合,回测不失为策略参数优化的有效手段。
4.验证
策略通常是在外部进行编码实现的,并仅通过策略自己的管道。但是,我们依然可以通过 对一个策略进行回测,看策略是否被正确地实现。尽管我们很难去观察外部策略的信号,但是通过 回测表现,譬如夏普、最大回撤等绩效指标,我们可以大体评估我们写下的代码是否达到我们所计划 的那样.
尽管回测对于算法交易有着巨大的帮助,但是,对一个策略直接进行回测很多时候还是不可能的。通常而言, 随着策略的时间频率提升,回测的难度随之加大。因为此时通过回测去正常衡量市场和交易的微观结构 会变得非常困难,回测的可靠性也随着急剧缩减。在超高频算法中,交易系统对于策略表现更为关键。
很不幸,尽管回测有着各种优点,但是它也会引入各种类型的偏差,下面,我们会深入讨论这些偏差。
影响策略回测的偏差
对于策略回测,有很多因素会影响回测效果。而且更不幸的是,这些因素大部分都会造成回测效果比实际 交易效果更好。因此,在根据回测结果去评估策略效果的时候,最好将回测结果作为策略能达到效果的上 界。将影响回测的所有因素都消除是不可能的,我们能做到的就是尽量去减少会影响回测的因素,使其尽 量贴近实盘。
这里,我们希望讨论四种主要影响回测偏差的因素:过度优化、未来偏差、幸存者偏差以及心理承受偏差。
过度优化
过度优化可能是所有回测偏差中出现的最多的。优化和引入额外的交易参数,一般而言,在回测数据集上 策略回测绩效表现非常吸引人的时候,往往都是过度优化,一旦实盘,策略表现就会表现的和回测差异 非常大。
由于策略中包含了很多参数,包括进出场条件,回溯周期,平均值周期 (譬如移动均线周期) 等, 消除过度优化往往很难。一种避免过度优化的方式是,减少参数的数量同时增加训练集中的数据点。 但是,增加数据点也可能导致问题,由于回测周期过长,很久之前的数据与当前环境可能差异已经很大。 (譬如以牛市的历史数据去评估熊市中策略的表现,很显然是不合理的。)
有一种缓解过度优化的方式,称之为 'sensitivity analysis'. 通过渐进地改变参数的数值 并画出回测绩效表现 “超曲面”。这样子,选择的合理的参数应该是一个参数域内表现比较平稳,且回测 结果不错的参数组合,而对于回测绩效曲面产生跃变的参数组合,显然应该被排除。
未来偏差
当回测系统中不小心用到了未来的数据,也就是引入了实际在历史中这个时刻应该没有的数据,就产生未来偏 差。譬如我们按照时序来进行回测,当我们回测到了第 个数据点的时候,但是假如我们用到了第 个数据点, , 未来偏差就发生了。未来偏差的引入很微妙,这里列出了三种可能引入未来偏差的 情况。
1.技术漏洞
代码中的数组或者向量往往需要迭代或者进行索引,这些指标的不正确的偏移,可能导致原本我们想要取 的数据点,结果取到了 的数据点,这里 .
2.参数计算
另外一种未来偏差可能在进行参数优化的时候出现,譬如对两个时间序列进行线性回归,假如整个数据集 都被用来计算回归系数,并用来优化交易策略的时候,此时未来偏差就引入进来了,因为回测的时间点, 我们并不知道之后的数据点是什么样的,如果用这样的参数去实盘,效果与回测就会偏差很大。
3.极值点
很多交易策略会用到一段时间内的极值点,譬如利用 OHLC (开高低收) 数据中的 high 和 low 的价格 序列。但是,这些极值点之后在相应的 bar 结束后才可以用来计算,如果在对应的 bar 还没有走完就采 用极值点,往往就会引入未来偏差。无论在哪个交易策略中,如果要用到 high/low 的信息,等上一个 bar 走完再进行计算,都是有必要的。
未来偏差往往是导致我们回测效果很好但是实盘却很失败的主要原因。
幸存者偏差
幸存者偏差对于策略而言,非常危险,往往会导致策略表现比实际好很多。通常这样的偏差出现在我们当前所用 的数据集不包括一些历史上原本应该存在的标的的时候,我们只考虑了当前仍然可以交易的标的,而历史上的有 些退市或者 ST 股等并没有加入到我们的初始股票池中。
经常会看到一些选股策略,只考虑当前的沪深 300的成分股,或者当前 A 股中没有被 ST或停牌的股票组合, 这样是不合理的,笔者曾经开发一个策略,在历史上某个时刻,海南椰岛被选入了模拟盘,但是第二天,海南椰岛 被 ST, 如果回测时候刨除这样的股票,无疑是引入了未来信息。 (笔者注)
为了避免这样的问题,可行的方式有两种,
1.包含所有非幸存者的全量数据集
当然,这会引入其他问题,譬如,回测的时候,为了尽量避免出现幸存者偏差,笔者的选股程序会在每个历史 交易日重置初始股票池,但这样,无法一次缓存历史上所有历史数据,导致回测速度变得很慢,所需数据量也 变得很大。(笔者注)
2.使用离当前时间更近的数据集
离当前更近的时间意味着挑出的股票池和当前应该更接近,但是没有足够长的回测时间,可能我们回测的数据 会比较少,不具有统计意义。(笔者注)
心理承受偏差
这种特殊的现象往往在量化交易中鲜被提及,但是,考虑到更自由的交易方式的时候,这种现象值得被展开讲 一讲。这种现象有很多名字,这里,我决定称之为 “心理承受偏差”,因为它揭示了问题的本质。
当我们开发一个策略,并对过去 5 年或者更长时间进行回测的时候,很容易看到一条向上的净值曲线,回测 绩效,包括综合年化收益率,夏普,甚至是最大回测等都足以让我们满意。但是,假如这样的策略最大回撤为 25%,回撤时间持续了 4 个月,对于动量策略,这样的例子应该是常见的。通过回测结果,让我们去接受这 样的回撤周期和这样的回撤值似乎是合理的,但是,真到实盘的时候,这远比我们想象中的要难得多。
如果回测的时候看到了最大回撤有 25%,在实盘中,几乎肯定会出现类似的甚至比回测的历史回撤更大的回撤 以及回撤周期。这些回撤时期,心理上会非常难熬。之所以这里将这样的现象作为回测偏差,是因为策略如果 在回撤的时候就停止运行,策略当然还是一个成功的策略,但是这样一来的话,相比回测,实际表现往往又会 远远不如回测结果。这样,即使策略在客观上是算法式的,心理因素仍然对策略有着非常大的影响。应对方式 上,当你看到历史回测中有这样大的回撤和回撤市场,就需要对实盘时遇到类似的回撤,有足够的坚持去继续 运行自己的策略。
总结
开发一个属于自己的策略往往需要在很多细节上花费非常多的心思,当回测出现一个很好的策略的时候,不必 先欣喜若狂,先仔细回顾自己的交易逻辑,然后再仔细调整自己在回测代码中的逻辑漏洞,尽量去做到尽善尽美, 同样的策略交易逻辑,不同的人来写,可能会有不同的结果,而往往,成败就在逻辑的细节处,希望大家能够 在开发自己的策略的时候,能够小心小心再小心!!!
来源:QuantStart Team 翻译:胡琛
------------------------------------------------------------------------------------------
相关阅读: