English Русский Español Deutsch 日本語 Português
组合趋势和盘整策略

组合趋势和盘整策略

MetaTrader 5交易系统 | 4 十月 2018, 09:34
11 786 7
Dmitriy Gizlyk
Dmitriy Gizlyk

目录

简介

有多种多样的交易策略,它们中的一些要寻找趋势,而其它的一些会定义价格波动的范围而在其中进行交易。市场是动荡的,趋势之后永远是盘整,这对跟随趋势的交易者和在范围内低买高卖的人来说都有获利的机会。当两组中的一组人获利的时候,另一组或者在亏损或者在等待时机。

有没有可能把这两种方法组合到一起来增加获利呢?这两种策略能否相互补充呢?让我们试试把这看起来不同的交易模型组合起来,看看这样的组合有什么结果。

1. 组合策略的原则

从价格图表上可以看到不断变化的趋势,大的变化后通常是盘整的阶段,这时价格会开始在一个狭窄的范围内变化。交易者通常根据当前市场的条件来选择他们的交易策略,但是我们怎样才能确定这个时候应该选择哪个策略呢?是趋势策略还是盘整策略呢? 

图表

有一些文章 [1] 和 [2] 是探讨在不同的趋势和盘整阶段的交易策略的,很容易就会发现,在评估市场条件后可以使用某种策略,这两种策略类型都使用了不同的趋势指标来确定市场的状态,只是,当在市场上有趋势时使用趋势策略入场,当市场平静时使用盘整策略建仓。因而,我们的第一种把两种策略组合到一个 EA 交易中的方法就是: 如果有趋势,就使用跟随趋势的算法,如果没有趋势,就使用盘整算法。

在更加详细地检查了价格图表之后,我们可以看到,不论趋势还是盘整,价格的变化都是没有方向性的,所有的变化都伴随着价格的波动。如果是盘整时期的变化,它们有一个很近的范围,而在有趋势时,有些变化会超过其它。这种特性可以在组合趋势和盘整策略的时候使用,思路是跟随一个趋势,尽管入场点应当是使用盘整交易的振荡指标来确认。这种方法有助于捕捉修正的结束,而减少回撤并增加价格向期望方向变化的潜在可能。

2. 开发 EA 交易

为了演示组合策略的原则,我已经从文章[1]中的策略1和文章[2]中的策略6,这两个选定的策略都是使用 ADX 指标来判断趋势的。EA 的优化是预先在从 01.01.2017 到 8.01.2018 的时间段进行的。根据这些策略的优化结果,选择了下面的参数。

趋势策略 1.

趋势策略的参数

盘整策略 6.

盘整策略的参数

在屏幕截图中提供了单个 EA 在优化参数后的交易结果。

趋势策略 1.

趋势策略的测试结果趋势策略的测试结果

盘整策略 6.

盘整策略的测试结果盘整策略的测试结果

这两个 EA 都是根据指标信号,在信号出现时没有开启的仓位,就会开启订单。根据预先定义的获利和止损值关闭仓位。

这种方法可以把仓位跟踪模块排除在外,而大幅度地简化了 EA 的逻辑。当组合 EA 时,我将会保持 EA 的运行逻辑不变,来演示组合方法(而不是改变 EA 的逻辑)是如何影响结果的。

2.1. 方法一

第一种方法是按顺序检查两种策略的信号,而当它们中的任意一个出现时就开启仓位。每个策略都有它自己的指标参数,以及止损和获利水平。使用这种方法,如果有一种策略开启的仓位会阻止另一个策略开启仓位,所以,在市场上永远最多只有一个开启的仓位,这样可以减少风险。

这种方法的缺点是可能会丧失获利交易的机会,这在一个策略有信号而存在另一个策略所开启的仓位时可能会出现。但是,根据这种方法,所应用的策略应当在不同的市场阶段来交易,也就意味着这个缺点造成的影响应当比较小。

为了实现这个方法,把两个 EA 的代码复制到一个文件中,根据相同的函数来把它们组合在一起,为了防止名称的重复,在跟随趋势策略的函数中加上"Trend"变量,而在盘整策略的函数中加入"Flat"类的变量。

//--- 公用参数
input double               Inp_Lot=0.01;                          //手数
input MarginMode           Inp_MMode=LOT;                         //资金管理
input int                  Inp_MagicNum=1111;                     //幻数
input int                  Inp_Deviation = 2;                     //偏差(点数)
//---
input string               Trend_EaComment="Trend Strategy";      //策略的注释
input int                  Trend_StopLoss=25;                     //止损(点数)
input int                  Trend_TakeProfit=90;                   //获利(点数)
//--- RSI_Color 指标参数
input int                  Trend_RSIPeriod=28;                    //RSI 周期数
input double               Trend_Overbuying=70;                   //超买区域
input double               Trend_Overselling=30;                  //超卖区域
//--- ADX_Cloud 指标参数
input int                  Trend_ADXPeriod=11;                    //ADX 周期数
input double               Trend_alpha1 = 0.25;                   //alpha1
input double               Trend_alpha2 = 0.25;                   //alpha2
//---
input string               Flat_EaComment="Flat Strategy";        //策略注释
input int                  Flat_StopLoss=50;                      //止损(点数)
input int                  Flat_TakeProfit=50;                    //获利(点数)
//--- WPR 指标参数
input int                  Flat_WPRPeriod=7;                      //WPR 周期数
//--- ADX 指标参数
input int                  Flat_ADXPeriod=11;                     //ADX 周期数
input int                  Flat_FlatLevel=40;                     //ADX 平盘水平

OnTick 函数的开始, 检查是否有开启的仓位。如果没有开启的仓位,就更新指标数据并按顺序检查趋势和盘整策略的入场信号。如果有任何信号出现,就根据对应的策略开启一个仓位。

void OnTick()
  {
//--- 检查由 EA 在早前开启的仓位
   if(!Trade.IsOpenedBySymbol(_Symbol,Inp_MagicNum))
     {
      //--- 取得用于计算的数据
      if(!GetIndValue())
         return;
      //--- 根据趋势算法开启订单
      //--- 如果有买入信号,开启订单
      if(TrendBuySignal())
         Trade.BuyPositionOpen(Symbol(),Inp_Lot,Trend_StopLoss,Trend_TakeProfit,Inp_MagicNum,Trend_EaComment);
      else
      //--- 如果有卖出信号,开启订单
      if(TrendSellSignal())
         Trade.SellPositionOpen(Symbol(),Inp_Lot,Trend_StopLoss,Trend_TakeProfit,Inp_MagicNum,Trend_EaComment);
      else
      //--- 根据盘整算法开启订单
      //--- 如果有买入信号,开启订单
      if(FlatBuySignal())
         Trade.BuyPositionOpen(Symbol(),Inp_Lot,Flat_StopLoss,Flat_TakeProfit,Inp_MagicNum,Flat_EaComment);
      else
      //--- 如果有卖出信号,开启订单
      if(FlatSellSignal())
         Trade.SellPositionOpen(Symbol(),Inp_Lot,Flat_StopLoss,Flat_TakeProfit,Inp_MagicNum,Flat_EaComment);
     }
  }

完整的 EA 代码在附件中 (Combination1 项目)。

2.2. 方法二

第二种方法的组合过程稍微复杂一些,除了第一种方法之外,还创建了两种策略相结合的信号。

在提供的趋势策略实例中,使用 ADX 云指标来定义趋势,这个指标显示了在 DI+ 和 DI- 线之间的差距,而没有检验趋势的强弱。同时,盘整策略在开启仓位之前会使用 ADX 阈值来检验趋势的强弱,这样,我们就能在交易中引入另一个过滤器,在趋势策略之后根据趋势的强弱来进行交易。

bool TrendBuySignal()
  {
   return(trend_adx[0]>trend_adx[1] && trend_rsi1[0]==1 && trend_rsi1[1]==1 &&  flat_adx[0]>=Flat_FlatLevel)?true:false;
  }

在趋势策略中,交易是根据 RSI 指标排序的,这样我们就能够通过排除与 RSI 信号相反的方向开启仓位来减少在盘整策略之后亏损交易的数量。

bool FlatBuySignal()
  {
   return(flat_wpr[0]<-80 && flat_adx[0]<Flat_FlatLevel && trend_rsi2[0]!=1)?true:false;
  }

完整的 EA 代码可以在附件中找到 (Combination2 项目)。

2.3. 方法三

第三个方法是用于锁仓账户的,在单个EA中独立使用两种策略。每种策略的订单都赋予了特定的幻数,根据到来信号开启仓位,不管是否有其他策略所开启的仓位。

这种方法精确地模拟了在一个相同账户中使用两个 EA 的情况,同时保留了这种方法的所有优点和缺点,特别是因为会根据不同的策略同时开启两个仓位,可能会增加风险。

//--- 公用参数
input double               Inp_Lot=0.01;                             //手数
input MarginMode           Inp_MMode=LOT;                            //资金管理
input int                  Inp_Deviation = 2;                        //偏差(点数)
//---
input string               Trend_EaComment="Trend Strategy";         //策略的注释
input int                  Trend_StopLoss=25;                        //止损(点数)
input int                  Trend_TakeProfit=90;                      //获利(点数)
input int                  Trend_MagicNum=1111;                      //幻数
//--- RSI_Color 指标参数
input int                  Trend_RSIPeriod=28;                       //RSI 周期数
input double               Trend_Overbuying=70;                      //超买区域
input double               Trend_Overselling=30;                     //超卖区域
//--- ADX_Cloud 指标参数
input int                  Trend_ADXPeriod=11;                       //ADX 周期数
input double               Trend_alpha1 = 0.25;                      //alpha1
input double               Trend_alpha2 = 0.25;                      //alpha2
//---
input string               Flat_EaComment="Flat Strategy";           //策略注释
input int                  Flat_StopLoss=50;                         //止损(点数)
input int                  Flat_TakeProfit=50;                       //获利(点数)
input int                  Flat_MagicNum=1112;                       //幻数
//--- WPR 指标参数
input int                  Flat_WPRPeriod=7;                         //WPR 周期数
//--- ADX 指标参数
input int                  Flat_ADXPeriod=11;                        //ADX 周期数
input int                  Flat_FlatLevel=40;                        //ADX 平盘水平

在 OnTick 函数中, 独立检查由趋势策略开启的仓位的幻数和使用盘整策略开启仓位的幻数。

void OnTick()
  {
//--- 检查之前由 EA 开启的趋势策略的订单
   if(!Trade.IsOpenedBySymbol(_Symbol,Trend_MagicNum))
     {
      //--- 取得用于计算的数据
      if(!GetIndValue())
         return;
      //--- 如果有买入信号,开启订单
      if(TrendBuySignal())
         Trade.BuyPositionOpen(Symbol(),Inp_Lot,Trend_StopLoss,Trend_TakeProfit,Trend_MagicNum,Trend_EaComment);
      else
      //--- 如果有卖出信号,开启订单
      if(TrendSellSignal())
         Trade.SellPositionOpen(Symbol(),Inp_Lot,Trend_StopLoss,Trend_TakeProfit,Trend_MagicNum,Trend_EaComment);
     }
//--- 检查之前由EA 开启的盘整策略的订单
   if(!Trade.IsOpenedBySymbol(_Symbol,Flat_MagicNum))
     {
      //--- 取得用于计算的数据
      if(!GetIndValue())
         return;
      //--- 如果有买入信号,开启订单
      if(FlatBuySignal())
         Trade.BuyPositionOpen(Symbol(),Inp_Lot,Flat_StopLoss,Flat_TakeProfit,Flat_MagicNum,Flat_EaComment);
      else
      //--- 如果有卖出信号,开启订单
      if(FlatSellSignal())
         Trade.SellPositionOpen(Symbol(),Inp_Lot,Flat_StopLoss,Flat_TakeProfit,Flat_MagicNum,Flat_EaComment);
     }
  }

完整的 EA 代码可以在附件中找到 (Combination3 项目).

3. 测试 EA 交易

在准备了三个由不同的策略组合方法开发的 EA 之后,是时候来测试这些 EA 并比较结果了,为了保证结果的兼容性,测试要在不修改 EA 参数的情况下进行。

3.1. 测试方法一

第一种测试显示有利润。总的利润和恢复系数比任何一个原来的 EA 都更高。与盘整策略相比,余额曲线看起来更平坦,而交易数量上升了,而相对余额和资金的回撤都减少了。同时,获利因子略有下降,而总的利润比最初策略的总利润也少一些。

方法一的测试结果方法一的测试结果

3.2. 测试方法二

使用第二种方法与第一种方法相比可以增加更多的利润,而交易的数量还保持同样,尽管总的利润还是比最初 EA 的利润略少一些。相应地,利润的增长也增加恢复和利润因子 (后者变得与盘整策略相等了), 以及获利交易的比例。同时,最大余额回撤也减少了。

方法二的测试结果方法二的测试结果

3.3. 测试方法三

使用第三种方法可以增加总利润,与初始 EA 的总利润水平相同。利润的增长是可能通过增加交易数量达到的,同时,存款负载和最大余额回撤增加了。

方法三的测试结果方法三的测试结果

4. 优化策略

在前一部分测试的 EA 展示了在 EA 中组合策略的优点,所有这三种方法都显示了和最初的策略相比利润有所增加。但是我们不应忘记,最初的策略是为测试的时间短做了优化的,而在测试组合 EA 时我们使用了相同的初始参数。

但是,我们都意识到 EA 逻辑中的任何影响都需要另外修改它的参数,让我们尝试使用最初的两种组合策略的方法优化 EA 来看看结果。

请记住,开发 EA 的最终目的是在市场上赚钱,而不是在历史数据中演示它们的功能。所以,我建议把测试的时间段分成两个部分,之前,我们是在从 1.01.2017 到 8.01.2018 进行测试的,现在,我建议在相同的时间段,即从 1.01.2017 到 6.01.2018 进行优化,而在剩余的时间段进行一次前瞻测试。

优化周期数

4.1. 优化方法一

在选择优化参数的时候,请记住我们的每个 EA 都包含两个部分的策略,在这种情况下,每个策略都使用了两个指标来入场交易,但是我们不要忘记,两个策略都使用 ADX 来判断趋势的强弱和方向,所以,EA 的逻辑使用了三个指标来定义入场点。我建议优化这三个指标的周期数,

ADX 指标周期数的优化显示出,在指标周期数从12到14的范围有最大化的利润和稳定性。下面的图片显示了 EA 利润与 ADX 和 RSI 在优化时间段的周期数变化的相互关联。

进行的前瞻测试确认了在这样的指标值范围时,可能会获利。当 ADX 周期数等于13的时候有最大的稳定性。这样,类似的优化和前瞻测试结果就证明了 EA 在非优化时间段的稳定性。

ADX 前瞻测试

WPR 周期数的优化显示了类似的结果。在优化时间段中,当指标周期数等于7的时候 EA 有最大的稳定性,同时,当 ADX 指标周期数增加时,也可能在3到5的范围会获利。下面的图片显示了 EA 的利润与 WPR 和 ADX 在优化时间段周期数改变的相互关联。

WPR 优化

前瞻测试确认指定的区域,同时,在 WPR 指标周期数为3-4的范围时利润有所增长,如果 WPR 等于7,当 ADX 指标值增加的时候 EA 的获利能力会下降。这可能是因为测试时间比较短以及它的特殊性。

WPR 前瞻测试

RSI 指标周期数的优化确认上面的结论,在优化时间段中,27到32的范围中获利能力和稳定性是最高的,下面的图片显示了 EA 利润与在优化时间段中 RSI 和 ADX 周期数变化之间的相互关联。

RSI 优化

在前瞻测试中, RSI 周期数的获利范围缩窄到30-32。

RSI 前瞻测试

尝试优化获利和止损值并没有增加 EA 的获利能力,也确认了之前选定的参数值。

根据优化结果,最优化的参数为, ADX 周期数等于13,RSI 周期数等于30 而 WPR 周期数等于7。使用这些参数,而其它参数保持不变,EA 在优化时间段内取得了 202.33 USD 的利润,在前瞻测试中取得了 46.10 USD 的利润。这种获利能力超过了根据方法三组合 EA 在此测试时间段的获利。在使用方法三组合的 EA 中使用相同参数得到的也是差一些的结果: 分别是 166.29 USD 和 60.27 USD。

优化方法一优化方法一优化方法一

前瞻测试优化的结果确认了 EA 在非优化时间段的稳定性。

4.2. 优化方法 2

有趣的是,根据方法二组合的 EA 在优化后取得的结果和之前优化的类似,这可以指示出交易系统的稳定性。结果指标周期数就和前一部分中优化的指标周期数类似,其它的方面都是相同的,方法二的 EA 显示出获利较低,因为交易数量有所减少。优化图在下面提供。

方法 2. ADX 优化方法 2. ADX 前瞻测试方法 2. WPR 优化方法 2. WPR 前瞻测试方法 2. RSI 优化方法 2. RSI 前瞻测试

同时,提高了趋势策略的信号质量可以优化止损和获利水平,在优化之后,趋势策略的止损减小为从 25 到 20 个点, 而获利从90 增加到 110 个点。这增加了 EA 工作中的获利能力。止损和获利水平优化图在下面提供。

方法 2. SL 优化方法 2. SL 前瞻测试方法 2. TP 优化方法 2. TP 前瞻测试

根据优化的结果,使用方法二组合策略的 EA 获利在三种方法里是最高的,在其它的 EA 中使用这些优化参数则结果是最差的。测试所优化 EA 的屏幕截图如下所示。

优化方法 2

结论

在本文中,我提出了三种在一个 EA 交易中组合两种策略的方法,展示了如何在 EA 中这样处理以及在优化之后不改变参数对 EA 进行测试。

下面的表格总结了所有策略的测试结果。组合 EA 的优化显示了与两个独立 EA 相比,它们有更高的获利能力。

在您的 EA 中,您也可以使用所提出的组合方法来任意组合两种或多种策略,或者加上您自己的方法。无法确定哪种方法才是最好的,在每种情况下,交易者都应当在选择组合策略的方法时有创新的思路,并且要考虑到策略本身和它们的运行逻辑。

参数 趋势
策略
盘整
策略
方法一 方法二 方法三 方法1优化
回溯/前瞻 
方法2优化
回溯/前瞻 
总利润 51.56 158.96 160.52 166.12 210.40  202.33 / 46.10  206.40 / 43,10
获利因子 2.39 1.25 1.24 1.25 1.31  1.25 / 1.58  1.25 /1.54
恢复系数 3.65 3.55 3.73 3.86 4.90 4.08 / 1.94  4.17 / 1.82
最大余额回撤 8.49 41.30 36.41 35.67 39.23 44.98 / 19.75  44.98 /19.75
最大净值回撤 14.14 44.76 43.04 43.04 42.96 49.53 / 23.72  49.53 / 23.72
交易数 24 290 295 295 315
 371 / 41  373 / 40
获利交易比例 41.67% 55.52% 53.22% 53.90% 54.29% 53.64 / 60.98  53.62 / 60

参考

  1. 十个趋势策略的比较分析
  2. 十个盘整策略的比较分析
  3. 趋势会持续多久?

本文中使用的程序

#
 名称
类型 
描述 
1  Trade.mqh  类库  用于交易操作的类
2  Combination1.mq5  EA 交易  基于方法一组合策略的 EA 交易
3  Combination2.mq5  EA 交易  基于方法二组合策略的 EA 交易
4  Combination3.mq5  EA 交易  基于方法三组合策略的 EA 交易

本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/5022

附加的文件 |
MQL5.zip (180.6 KB)
最近评论 | 前往讨论 (7)
Dmitriy Gizlyk
Dmitriy Gizlyk | 9 12月 2018 在 10:16
bigpig :
Можете ли вы дать мне свою контактную информацию? Autoexec.bat меня есть несколько мнений, чтобы обсудить в частном порядке.

你可以给我写私信。

Sheng Qiang Chang
Sheng Qiang Chang | 15 5月 2019 在 08:42
Vary good, Very informative.
h93910
h93910 | 23 5月 2019 在 13:52
mark
xiaokedou
xiaokedou | 6 9月 2019 在 11:06
请问一下mql5每次指标都报错是什么原因呀
Jun Yang Chen
Jun Yang Chen | 25 9月 2022 在 05:53
Good performance for 1 minute OHLC, BUT really BAD performance for the every thick back test.
深度神经网络(第八部分)。 提高袋封融合的分类品质 深度神经网络(第八部分)。 提高袋封融合的分类品质
本文研讨三种可用于提高袋封融合分类品质的方法,并对其效率进行了评估。 评估 ELM 神经网络超参数的优化效果,以及后期处理参数。
在MQL5.com自由职业者服务中已完成50,000个订单 在MQL5.com自由职业者服务中已完成50,000个订单
截至2018年10月,MetaTrader官方自由职业者服务的成员已完成超过50,000个订单。这是全球最大的MQL程序员自由职业网站:超过1000名开发人员,每天几十个新订单以及7种语言本地化。
Elder-Ray (多头力度和空头力度) Elder-Ray (多头力度和空头力度)
本文详述了基于多头力度(Bulls Power),空头力度(Bears Power)和均线指标(EMA - 指数平均)的 Elder-Ray 交易系统。 Alexander Elder 在他的著作“为生活而交易”中描述了这个系统。
基于 CGraphic  用于分析数据数组(时间序列)之间相互关联的 PairPlot  图 基于 CGraphic 用于分析数据数组(时间序列)之间相互关联的 PairPlot 图
在技术分析中比较几个时间序列是一种很常用的任务,需要合适的工具。在本文中,我提出开发一种用于图形化分析的工具,可以侦测两个或者多个时间序列之间的相互关联。