克隆成功是否进入此策略?

确定取消

CTA投资与程序化交易:CTA实战——策略编写陷阱:偷价格

发布于2017-07-25 19:48 浏览 1949 评论 1 0 0 分享到:

法律申明:量邦科技原创内容,保留所有版权和知识产权,禁止任何形式的转载。

在程序化交易的学习中,从来都不是一马平川,途中存在着很多隐蔽的陷阱,对初学者会造成很大的困扰。一些经验还不太丰富的策略编写者甚至会在反复检查代码之后,仍然只能对着明显不合理的后验结果无计可施。为了避免这种情况的发生,这里详细介绍几种典型的策略编写陷阱以及它的解决方法供参考。

简介

从表现形式来看,程序化交易策略编写的陷阱大致可以分为两大类。第一类陷阱会导致后验与实盘的表现有着很大的不一致。具体来说就是,后验表现很好的策略在实盘之后丧失了盈利能力,甚至可能一直亏损。第二类陷阱会导致策略发出的交易信号与策略研发者的预期不一致。换句话说,开发者的策略思想并没有真实地通过策略代码得到实现。其中偷价格就是导致陷阱的最典型一类问题。

概念介绍

偷价格陷阱,从字面上大致就能理解其中的意思,指的是偷来一个本不存在的价格去进行成交。一个程序化交易策略如果使用交易信号被触发之前的价格作为成交价的话,那么这个交易策略就存在偷价格的问题。在真实交易中,当交易信号被触发时,你已经失去了用过去的价格来进行交易的机会了。值得注意的是,触发交易信号的价格一般而言也是不能当作成交价格使用的,在简单后验时可以使用该价格加上一定的滑点来当作交易价格。

存在偷价格问题的策略,在每次交易时都会“偷取”一定额度的收益。这相当于在真实的后验曲线之上叠加了一条光滑的正收益曲线,因此很容易导致后验结果获得一个更加漂亮的权益走势,但这在真实交易中是不会发生的。所以,交易者在将策略用于实盘交易之后会发现,之前平滑漂亮的收益曲线消失了,取而代之的是一条波动很大的曲线。如果在后验中价格偷得比较严重的话,交易者最终获得的甚至有可能是向下的负收益曲线。

原因解析

偷价格的形式多张多样,但究其原因都是我们在策略中使用的成交价格不是当前的最新价格,而是过去某个时间的价格或者是根本不存在的价格。接下来我们用例子来展示一下几个偷价格的典型情景。

案例一

我们用前面系列里的Hans123v2为例。以下两幅权益走势图都是Hans123v2,代码也几乎一样,但产生了不同的净值曲线,第一幅图曲线光滑,回撤极小为5.39%,年化收益在43.39%。第二幅图明显的波动就大了许多,年化收益率为22.56%;这就是典型的程序化交易陷阱:每次只偷到一点小小的价格,却能积少成多,产生非常巨大的威力。

偷价格2.png

偷价格1.png

Hans123的交易思想是,当前这根bar的突破上边界UpperBand后,开多仓。问题在于第一幅图直接就使用当前Bar的开盘价Open(0)进行成交,这就犯了偷价格的错误。除非Open(0)直接就突破UpBand,否则实际成交是Open(0)这个价格已经成为了过去时,这个价格在真实交易中无法成交。我们直接给出正确的写法:

self.max(self.open(0), self.UpBand)

我们比较Open(0)和上轨的大小,如果Open(0)较大,那选择它直接突破,否则就是在突破的点位进行成交,这样就接近了实盘情况。如果用Open(0)作为成交价格的话,大部分交易都会偷取一定额度的价格作为利润。所以,后验曲线的形状和收益率、最大回撤、盈亏比等反映策略表现情况的数据都显得非常漂亮。

可能读者会想到,是否可以直接取上边界UpperBand作为成交价呢?事实上,如果每次都取UpperBand作为成交价,也会发生偷价格的问题。

在此需要说明的是,我们假定在一根bar之内价格是连续的,如果价格在bar内突破上边界,那么成交价确实等于UpperBand。但是在两根bar之间,价格可能会不连续。尤其是第二天开盘时的第一根bar和前一天收盘时的最后一根bar相比,价格经常会不连续,甚至会发生跳空高开或者低开等情况。譬如某根Bar跳空高开,在其开盘的一瞬间就早已突破了UpperBand。此时,程序告诉我们需要开多仓,但我们已经无法用UpperBand的价格成交了。下图是出现跳空时仍然用UpperBand作为成交价的情况。可以看出,选取UpperBand作为成交价偷取了一定的价格。在实盘交易中,以这个价格开仓显然是无法成交的。

至此,我们可以看出在该策略中,如果用Open(0)作为成交价,则大部分交易都会偷到价格;而如果取UpperBand作为成交价,真正偷到价格的时候并不多,它只会在发生跳空的情况下才有可能偷到价格,而发生跳空与策略开仓碰到一起的几率并不很大。但是,这仍然是需要极力去避免的问题,不可忽视。

所以我们要记住正确的做法应当是,当High(0)突破UpperBand后,选取Open(0)和UpperBand中较大的一个价格作为成交价格,即max(UpBand, Open(0))。这才是在实盘交易中可以成交的价格,策略的后验结果也能最大限度地接近其实盘的表现。如果出现跳空,价格不连续,这根bar的开仓价格Open(0)直接超过了UpperBand,我们就以Open(0)的价格开仓。

在做空时我们也需要进行类似的处理。当Low(0)突破下边界LowerBand时,我们应当选取Open(0)和LowerBand中较小的那一个。当Open(0)跳空低开,有可能出现开盘价便小于LowerBand的情况,此时触发做空信号,我们已经无法用LowerBand的价格进行交易,而应该以开盘价Open(0)成交。所以,一般而言,只要是价格向下突破触发开平仓条件,我们都应该选取Open(0)和LowerBand中较低者作为成交价,即min(LowerBand, Open(0)),以确保不会发生偷价格的情况。读者在编写突破类策略时,应当多加注意。

案例二

另外,在编写策略开平仓条件的时候,除了成交价格选择不当会造成偷价格的问题以外,还可能仅仅由于一个符号的疏忽而落入偷价格的陷阱。

偷价格4.png

这两行代码仍然是刚刚的策略,当前Bar突破上轨是做多,并用UpBand和Open(0)中较大的那一个作为成交价,但如果开仓条件只是用大于来判定,当这个条件满足时,市场价格已经高于UpBand了,这时候不一定能用UpBand来进行成交,虽然成交价可能只是比较UpBand高一点的价格,但每次都偷来一点点,累计的利润还是可观的,相当于每次交易都给自己加了一个对自己有利的滑点。正确的做法应该是用>=作为判断条件:

偷价格3.png

总结

综上所述,偷价格是一个非常容易导致策略的历史后验与实盘表现不一致的陷阱。虽然偷价格在每次交易中仅仅带来微小的虚假利润,但是聚少成多,累积起来的收益足以呈现出一个策略表现完美的错觉,而且这个问题在交易频率较高的策略中会显得更加突出。如果我们在后验中看到某个策略的收益很高,回撤极小,而且收益曲线非常平滑,请先根据刚才讨论的几种情况检查一下代码,看看是否存在偷价格的问题。我们把案例一的策略也放出来,大家可以同Hans123v2原版进行对比。


回到教程:CTA投资与程序化交易:从经典CTA到现代研究方法

主力连续跳空?指数合约无法交易?8888超级后验,请下载量邦天语(研究免费)

天语是本地专业CTA研究与实盘交易软件,内置大量业务逻辑,大宽网和市场同类产品都是开放式学习研究平台,基本都不具备高级业务逻辑。

1 个评论

学习了!
发表评论