Backtesting: Pitfalls and Solutions

策略回测:陷阱和解决方案


在交易策略的调试中,狭义的回测指的是对某一历史区间的模拟,从而得到一个假设结果:如果这个策略在过去的某个时间区间运行,会得到怎样的结果。

这样的回测提供的信息是有限的,它提供了一个完整性检测,即在某种市场场景下,策略的收益,成本,仓位,换手率等等评估。即使回测系统设计得非常完整,研究人员非常专业,因为选择的偏差和过度拟合的原因,仍然不可避免地落入误区。Luo Yin和他的小组在文章Seven sins of quantitative investing中提到7点:
  • 回测使用的股票池可能不完整,在运行策略回测的时刻,历史上的有些股票可能已经退市
  • 使用的信息有可能是超前的,比如一些宏观信息,往往是滞后的,而且会不断修正。因此在某时刻获得的数据,在历史上是超前的
  • 研究人员会对回测的结果做出主观的解释,而信息的随机性往往难以判断
  • 对数据的过度挖掘,以及过度拟合的产生,使得样本内和样本外性能有大的偏差
  • 交易费用估算的复杂性。交易费用包含多个组成部分,精确的估算常需要在order book,trade book级别进行计算
  • 离群值对回测结果造成的影响,许多模型对离群值是敏感的,而离群值的检测没有最佳的答案
  • 策略需要做空时,借贷导致的费用常常难以预先估算
许多人将回测作为一个研究工具,而事实上,回测的目的是通过模拟历史场景,剔除坏的模型,而不是通过调整参数来改进坏的模型。因而,一些研究人员常用的方法,比如通过回测来选择特征值并不可取。正确的方法应该实在回测之前,采用其他的方法来决定特征值的重要性。

以下是Marcos Lopez De Prado对回测的几点建议
  • 尽量使用大的股票池(或者其他投资产品),避免在小的股票集合运行回测来获得策略的评估。其背后的原理,是寻找符合多数股票特性的规律,而不是过度拟合在少数的股票上
  • 为了减低过度拟合的风险,同时降低策略预测信号的variance,建议使用bagging等方法加入随机性。
  • 将策略研究和回测工具严格区分,即,在回测策略之前使用其他方法决定策略的参数,决定最优策略然后使用回测工具。而不是依赖回测工具来选取策略的最佳参数,避免人为地对回测结果做出主观的解释
  • 记录所有的回测结果,利用PBO(probability of backtest overfitting)等工具来估算过度拟合的程度
  • 模拟历史场景而不是单一的重复历史。狭义的回测围绕着给定的一段历史数据,这一段历史数据往往是所有可能性中的一个场景,带有一定随机性,在未来未必重复出现。因此需要根据所有可能出现的历史场景,构造相应的数据。
  • 如果回测结果并不满意,则回到策略研发阶段,改进或者重新研发策略,避免围绕回测结果过度解读,或者利用回测的结果优化策略的参数。
PBO probability of backtesting overfitting

PBO是在回测中衡量一个策略的过度拟合程度的度量,通过CSCV(combinatorial symmetric cross validation)算法实现。

1. 假设一个交易策略对历史样本进行回测,时间点为1,2,…,T,通过调整参数和策略模型等方法得到N个收益时间序列。组建一个矩阵M,M的每一行代表时间t=1,2,…,T,每一列为回测n的收益时间序列,这里n=1,2,…,N。

2. 首先将M按行分割成S个子矩阵,每一个子矩阵Ms含有相同的行数,和N列。从S个子矩阵中随机抽取S/2个,将每一个子矩阵记为J。重复这样的随机抽取,并进行以下步骤计算:

3. 将子矩阵J的行和列作为样本内数据,子矩阵J在M中的补集作为样本外数据,记为Jtest。对J中的每一列计算策略效益,这里假设为Sharpe Ratio。之前提过,M的每一列都是某个回测样本的收益序列,因此这里我们计算的是J矩阵也就是某个样本内的收益序列的收益。这样得到一个Sharpe ratio的序列,记为R=r1,r2,…,rN。

4. 在R中找到sharpe ratio最高的一列,将其序号记为n*。

5. 接下来计算样本外数据,即Jtest的每一列的收益,同样得到一个sharpe ratio序列,记为Rtest。然后找到之前的n*在Rtest中的相对排序,记为omega。Omega代表了在样本内数据中收益最好的回测序列在样本外数据中的相对排序。

6. 计算lambda_c = log(|omega /(1-omega)|)

对S的所有子矩阵重复以上步骤3-6的计算,我们得到一系列的lambda_c,可以画出一个分布曲线,而这个分布从负无穷到0的积分(即<0的立即密度函数)就是回测方法的过度拟合的度量。

以上取<0部分做积分,其意义在于计算样本内的收益小于样本为收益的累计概率。

值得注意的是,这个算法保持了时间的相对连贯性,因为在构造S的时候是将时间t=1,2,…,T做分块的切割,而不是按照每个t来做随机整合。也就是说,随机抽取是在相互不关联的子集之间进行的。

除了计算过度拟合指标,在以上的计算过程中,在每一步R和Rtest的计算中,可以计算得到R中收益最好的列的指标,和Rtest中收益最好的列的指标,将其画出散点图以后可以看出样本内和样本外的最佳收益的关系,一般来说,这个散点图显示下降的趋势,即样本内和样本外的收益是负相关的。