您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 咨询培训 > 《程序化交易实战》连载5周规则交易系统
1.策略思想理查德•唐迁(RichardDonchian)发明的周规则交易系统是一种经典的趋势跟踪交易系统,它尝试跟踪市场趋势从而获利,其最明显的特点是顺势而为。该交易系统并不追求能够在市场的底部买进而在顶部卖出,而是希望能够在涨势时做多、跌势时做空,通过抓住大趋势并跟随大趋势获取收益。从趋势的长度来看,周规则交易系统属于对中期趋势的跟踪。由于周规则是追随趋势的,所以它可以让交易者在重要趋势出现时站在正确的一方。尽管该交易系统在震荡中会出现一定亏损,但是由于其合理使用移动止盈止损技术,整体风险可控。正如一句交易名言——“斩断亏损,让利润奔跑”所说的那样,从长期来看,周规则交易系统具备在震荡中控制亏损、在趋势中获取大幅受益的能力,在很多品种中都有着不错的表现。量邦科技总结此外,该交易系统的另外一个特点是,单笔交易平均利润较高,而交易频率较低,因此它受到交易手续费和滑点的影响都比较小。值得注意的是,从单次交易来看,交易成本似乎对总利润的影响或许并不大,但是从长期来看,交易成本的影响是绝对不可以忽视的。这也正是周规则交易系统长期以来受到青睐的重要原因。当然,与很多趋势跟踪类型的交易策略一样,周规则交易系统也经常因为其无法捕捉到趋势的形成点而受到责难,但我们需要清楚的是,趋势交易一般不会主动去预测趋势是否会形成,而是确认趋势的形成然后顺势而为,因为预测趋势的形成本身是一项艰难而且风险极高的工作。周规则交易系统在趋势刚开始形成的时候并不急于入场,而是耐心观察,确认趋势是否真正形成。等到市场突破之前几周的最高最低点之后,才认定趋势已经形成,并且立即入场,跟随趋势。虽然周规则无法享受到从趋势形成到系统发出入场信号这段时间的利润,但是也规避了在趋势尚未真正形成就入场的风险。2.交易规则A.原始周规则交易系统原始的周规则交易系统的交易规则非常简单易行:在最初的n周进行观察,判断价格的最高和最低点。判断完成之后,如果价格突破之前高点就开多,如果价格突破之前低点就开空。如果持有仓位,但价格朝着与所持仓位相反的方向运动,并且突破了关键点位就及时止损。最初,该交易系统以四周的形式出现,后人又根据交易品种的不同做了相应的调整。B.改良周规则交易系统周规则尝试追踪长期和中期趋势,它在长线上涨或者下跌、矩形形态被突破时非常有效,但是长期无趋势的状态和一些假突破会导致亏损。原始的周规则是一种连续持仓的策略,也就是说,或者持有多仓,或者持有空仓,不存在空仓状态。这样可以更加有效地利用资金,提高资金的使用效率,但是也会产生一个缺陷:在市场无趋势的时候仍然滞留在市场中持有仓位。事实上,在市场横盘时期和无趋势时期,趋势跟随类策略的效果都不是很好。为了减少由于对趋势误判导致的亏损,我们可以对周规则系统进行修正,使该策略的持仓时间不具备连续性。⑴.根据持仓时间优化对于周规则的修正,可以在不改变开仓条件的情况下,通过缩短平仓条件的时间跨度来实现。换言之,开仓信号还是由突破之前n周最高最低点来发出,平仓信号由反向突破n/2周的最高最低点来发出。之后,离开市场等待观望,直到新的n周突破信号出现之后再开仓入场。具体调整方法如下:①.当价格突破前n周的最高价,做多;②.当价格突破前n周的最低价,做空;③.持有多头时,当价格跌破前n/2周的最低价,平仓;④.持有空头时,当价格冲破前n/2周的最高价,平仓。⑵.根据品种的需求优化对于任何市场都机械性地使用四周规则是行不通的,周规则交易系统还可以针对不用品种进行进一步的优化。具体来说,周规则交易系统应该根据不同金融产品的特性,来设置不同的策略参数。在《美林公司商品研究报告》中称,由于不同的商品具备不同的特点,因此对于不同的市场,都应该对周规则进行相应的周数优化。此外,通过改变每周结束的日期,从历史后验来看,该交易系统的表现可以得到进一步地提高。例如,糖期货市场采用五周规则有较好表现,并且可以将周四人为地设置成每周的最后一天;在大豆市场最佳选择是两周规则,并且将每周的最后一天人为地设置成周一,可以收到更好的效果。如果没有很好的研究报告来借鉴,可以先采用四周规则,再根据实际操作情况来不断调整。⑶.根据灵敏度的需求优化周规则交易系统还可以根据风险管理和灵敏度的具体需求,来相应地扩大或者缩短周规则的时间跨度。一方面,当我们需要更加有效的突破信号的时候,我们可以扩大时间跨度。比如说之前很长时间内市场都一直处于横盘整理的状态,那么这时候纵使突破了四周的高低点,也未必能够说明趋势的形成。这时候,我们需要耐心等待重要趋势信号的出现。在此之前,较为最合理的选择是不做任何事情,而不是贸然进场。因为这时候并没有趋势形成,可以将价格的走势视为随机,这时候进场的话,是否盈利更多的依靠的是运气因素。因此,在这种情况下,我们可以将时间跨度调整为八周,以避免时机不成熟的趋势信号。另一方面,当我们需要系统更加灵敏的时候,缩短时间跨度则会非常必要。具体来说,当市场急剧上升或者下降的时候,我们可以缩短周规则的时间跨度,使系统更加灵敏。比如说,我们根据四周规则发出的向下突破的信号,开了空仓。这时市场果真按照我们的预期,大幅下跌。此时无论是使用四周规则还是两周规则来判断平仓信号都无法有效地保护我们的利润。一旦市场在短时间内出现反弹,之前积累的利润会一点点被蚕食掉。为了防止大量的获利回吐,我们可以使用更加严格的止损条件,如一周规则,来发出止损信号,这在很多时候能很好地保护我们获取的利润。但是,在另一种情况下,如果我们开空仓入场之后,价格只是缓慢下落,那我们就不必改变止损条件。因为,我们的利润本身并没有多少,我们不需要为了刻意提升灵敏度来保护利润,使用两周规则来发出止损信号就可以了,而且这还能防止我们被小幅的震荡“震出来”。这种优化周规则交易系统的思想也被称为分级移动止盈止损交易思想——在利润较少时,使用较为宽松的止损条件,以应付小幅的震荡;在利润较多时,使用更加严格的止损条件,以保护我们的利润。这项技术不仅可以用来改善周规则的表现,在其他交易系统中也有着非常广泛的应用。至此我们介绍了三种改良方式:根据在市时长的需求优化,根据品种的需求优化,根据灵敏度的需求优化。它们不仅使得经典周规则交易系统的适应性更加广泛,也保证了该交易系统的长期有效性。接下来我们介绍一下该交易系统的构造过程以及如何用Q语言编写该交易系统的程序化代码。3.系统构造由于Q语言对日的判断和识别比对周的判断和识别更方便,因此在构造交易系统的时候,需要先将周转化成日。假设我们使用的是四周规则,那么这里需要首先将n=4周转换成n=20日,以便于后面Q语言代码的编写。A.原始版本所需变量:Open[t]:当个交易日之前第t个交易日的开盘价Close[t]:当个交易日之前第t个交易日的收盘价High[t]:当个交易日之前第t个交易日的最高价Low[t]:当个交易日之前第t个交易日的最低价UpBand:上一个交易日之前n个交易日的最高价DnBand:上一个交易日之前n个交易日的最低价实施:1)无头寸时:IfClose[1]=UpBand,开多仓;IfClose[1]=DnBand,开空仓。2)持有多头时:IfClose[1]=DnBand,平多仓。3)持有空头时:IfClose[1]=UpBand,平空仓。B.改良版本将周规则交易系统的原始版本根据持仓时间的需求进行优化,把止损价位设置为上一个交易日之前n/2个交易日的最高价和最低价,我们就可以得到下面这个改良版本。所需变量:Open[t]:当个交易日之前第t个交易日的开盘价Close[t]:当个交易日之前第t个交易日的收盘价High[t]:当个交易日之前第t个交易日的最高价Low[t]:当个交易日之前第t个交易日的最低价UpBand:上一个交易日之前n个交易日的最高价DnBand:上一个交易日之前n个交易日的最低价StopLossUp:上一个交易日之前n/2个交易日的最高价StopLossDn:上一个交易日之前n/2个交易日的最低价实施:1)无头寸时:IfClose[1]=UpBand,开多仓;IfClose[1]=DnBand,开空仓。2)持有多头时:IfClose[1]=StopLossDn,平多仓。3)持有空头时:IfClose[1]=StopLossUp,平空仓。4.Q语言代码基于上文所述内容,这里以Q语言为例,详细讲解如何实现这一经典交易策略。A.原始版本⑴.源代码⑵.代码解释整个代码非常简单,只有一个外部参数n,整体不到50行。下面我们来逐行解释一下这些代码的作用。①.第2-4行:由于周规则交易系统没有引用声明任何库函数,在这里对外部参数进行定义和初始化。在经典周规则交易系统的原始版本中,只有一个外部参数n,表示天数,我们将它初始化为22。之所以没有将它初始化为上文中说到的20,是为了后面判定上下限的需要。具体原因会在后面进行解释。②.第6-10行:这是程序的Init()部分,进行初始化操作。在这里,我们进行初始条件的设置、全局变量的声明以及指标对象的实例化。注意,这个部分仅在程序的开始时执行一次。UpBand和DnBand是我们设定的上下边界,只要价格突破UpBand和DnBand,我们就会进场。其初始化值为0。③.第12-44行:这是主程序Start()部分,由行情驱动循环调用。在实时交易中,每来一个新的行情Tick,就对这部分调用一次。在历史后验中,行情每驱动一次,就调用一次。I.第13-15行:跳过前n-1天,也就是前21天。由于历史数据不足,无法判断之前四周的最高和最低价。因此这段时间什么都不做,直接跳过后面的代码。II.第17-19行:到了第22天,才会第一次运行第17行之后的代码。将UpBand定义为max(High[2:int(Ex.n)]),意思是从High[2]到High[21]这20个数据的最大值,也就是上一个交易日之前的20个交易日内最高价的最大值。首先需要说明的是,int(Ex.n)指的是将外部参数n取整,这里就是指22。同时,特别需要注意的是,High[2:22]代表一个从High[2]到High[21]的序列,其中High[22]是不包含在内的。这正是我们将外部参数n初始化为22的原因。只有令n=22,我们才可以保证High[2:int(Ex.n)]中一共有20个数据,才可以满足四周规则通过之前20天最高最低点判断入场和出场条件的需要。同理,将DnBand定义为min(Low[2:int(Ex.n)]),意思是从Low[2]到Low[21]这20个数据的最小值,也就是上一个交易日之前的20个交易日内最低价的最小值。III.第21-23行:将UpBand和DnBand以辅助线的形式在K线图中画出来。这个步骤并不影响程序的运行,只是为我们观察K线时看开平仓的点位以及进行相关分析提供方便。IV.第25-32行:这是我们首次开仓时运行的代码。如果这根Bar的序号大于上次平仓时的Bar序号,如果现在没有仓位,如果昨天的收盘价大于UpBand,那么我们就在今天开盘的时候以今天的开盘价做多。如果这根Bar的序号大于上次平仓时的Bar序号,如果现在没有仓位,如果昨天的收盘价小于DnBand,那么我们就在今天开盘的时候以今天的开盘价做空。其中Bar.CountPos.LastExitBar这行代码是为了确保本次开仓与上一次平仓不出现在同一根Bar上,以防止极端行情下的信号闪烁问题。V.第34-43行:这是我们有仓位之后,触发平仓并反手条件时运行的代码。如果这根Bar的序号大于上次开仓时的Bar序号,如果现在有空仓,如果昨天的收盘价大于UpBand,那么我们就在今天开盘的时候以今天的开盘价平空仓,然后以今天的开盘价做多。如果这根Bar的序号大于上次开仓时的Bar序号,如果现在有多仓,如果昨天的收盘价小于DnBand,那么我们就在今天开盘的时候以今天的开盘价平多仓,然后以今天的开盘价做空。④.第46-47行:这是程序的Unit()部分,在程序全部执行完成结束后调用,一般我们不需要在这个模块中写代码。至此,周规则交易系统原始
本文标题:《程序化交易实战》连载5周规则交易系统
链接地址:https://www.777doc.com/doc-2801025 .html