English Русский Español Deutsch 日本語 Português
preview
学习如何基于鳄嘴(Gator)振荡器设计交易系统

学习如何基于鳄嘴(Gator)振荡器设计交易系统

MetaTrader 5交易 | 15 五月 2023, 14:40
1 613 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

概述

    欢迎阅读我们系列中的一篇新文章,介绍如何基于最流行的技术指标设计交易系统,不仅学习如何通过 MQL5 编程语言创建交易系统,我们还会学习每个提到的技术指标。 在本文中,我们将学习关于这些流行的指标其一,即鳄嘴(Gator)振荡器,从而更详细地了解它是什么,如何使用它,以及如何创建一个可以在 MetaTrader5 中使用的交易系统,帮助我们进行交易,或拓展我们的视野,审视可以获得更好结果的新交易方法。 

      我们将贯穿以下主题,尽可能全面地涵盖该指标:

      1. 鳄嘴振荡器定义
      2. 鳄嘴振荡器策略
      3. 鳄嘴振荡器蓝图
      4. 鳄嘴振荡器交易系统
      5. 结束语

      我们将利用 MetaTrader 5 交易终端来测试上述策略,并通过 MetaTrader 5 内置的 MetaQuotes 语言(MQL5 编程语言)构建我们的交易系统。 如果您不知道如何下载和使用 MetaTrader 5,以及 MQL5 的 IDE,您可以阅读我上一篇文章中的主题《在 MetaEditor 中编写 MQL5 代码》,从而学习有关该主题的更多信息。

      我需要在此重申,在使用之前,您必须测试任何提到的策略,确保它对您有用,且可盈利;因为没适合所有人的东西,这里的主要意图是教学,只为学习指标背后的主要概念和根源,还有一条忠言我需要在此提及,那就是如果您想提高编程技能,请尝试自行编写本文和其它文章的代码。

      免责声明:所有信息“按原样”提供仅用于教学目的,并非出于交易目的或建议。 这些信息不能保证任何结果。 如果您选择在您的任何交易账户上使用这些材料,您将自行承担风险,您是唯一的责任人。


      鳄嘴振荡器定义

      在这一部分中,我们将更详细地甄别鳄嘴振荡器指标,从而明白和辨别其背后的主要概念,并以相应有效的方式运用它。 鳄嘴振荡器指标由比尔·威廉姆斯(Bill Williams)创建,帮助我们判定行情是否处于趋势,或范围是否存在倾向,除了给出交易入场或离场的时间外,这种趋势在动量方面可以持续多少。 如我们所知,这两件事在交易中非常重要。 鳄嘴振荡器基于鳄鱼(Alligator)指标,您可以阅读我之前的文章学习如何设计鳄鱼的交易系统中有关该鳄鱼指标的更多详细信息。

      鳄嘴指标的计算与我们将看到的显示鳄鱼指标平衡线的收敛和发散程度相同。 以下是鳄嘴指标的计算:

      • 第一步:我们需要计算中位价格:

      Median Price = (High + Low) /2

      • 第二步:我们需要计算鳄鱼上颚、鳄鱼牙齿和鳄鱼嘴唇:
      鳄鱼上颚 = SMMA (Median Price, 13,8)
      鳄鱼牙齿 = SMMA (Median Price, 8, 5)
      鳄鱼嘴唇 = SMMA (Median Price, 5, 3)
      • 其中:

      Median Price: 价格中位。

      High: 最高价数值。

      Low: 最低价数值。

      SMMA: 平滑移动平均线是一种移动平均线,它是数据、周期和偏移(如果存在)的平滑方式。 如果我们说 SMMA(Median Price, 13, 5),意味着 SMMA 是依据中位价格数据得出的平滑移动平均线,平滑周期为 13,向未来的偏移为 5。 

      鳄鱼上颚:鳄鱼指标的蓝线。

      鳄鱼牙齿:鳄鱼指标的红线。

      鳄鱼嘴唇:鳄鱼指标的绿线。

      以前的计算可生成鳄嘴振荡器指标,但我们不需要手动计算它,因为它已在 MetaTrader 5 中内置,我们所需要的只是从可用的技术指标中选择它,并将其插入图表当中,如下所示。

      打开 MetaTrader 5 时,选择“插入”选项卡 -->指标 --> 比尔·威廉姆斯 --> 鳄嘴振荡器

      鳄嘴插入

      选择鳄嘴振荡器后,我们将找到与以下内容相同的鳄嘴参数窗口:

      鳄嘴参数

      在上图例当中,我们得到鳄嘴振荡器指标的参数,可确定指标的所需设置,它与以下内容相同:

      1. 确定下颌的周期。
      2. 确定下颌的水平偏移。
      3. 确定牙齿的周期。
      4. 确定牙齿的水平偏移。
      5. 确定鳄唇的周期。
      6. 确定鳄唇的水平偏移。
      7. 确定均化的首选方法。
      8. 确定计算鳄嘴时所采用的价格类型。
      9. 确定鳄嘴向上的颜色。
      10. 确定鳄嘴向下的颜色。
      11. 确定鳄嘴线条的宽度。  

      在确定鳄嘴振荡器指标的所有首选参数后,我们会发现该指标附加到图表下部的图表上,如下所示:

      鳄嘴加载

      正如我们在上一张图表中看到的,我们有了带有鳄嘴振荡器上、下值的指标,从中可以清楚地看到,上值高于零,下值低于零。 我们还根据每根柱线与其前一根柱线之间的关系得到绿色和红色柱线。 如果当前柱线大于前一根柱线,我们将看到当前柱线为绿色,反之亦然,如果当前低于前一根柱线,我们将发现当前为红色。 


      鳄嘴振荡器策略

      在本主题中, 我将与您分享一些简单的策略,鳄嘴振荡器指标只是用于学习目的。 在将其用于实盘账户之前,您必须测试任何提到的策略,确保它对您有用。

        策略一:鳄嘴状态策略:

          基于此策略,我们需要根据指标的柱线识别鳄嘴状态。 据此,我们将拥有四个鳄嘴状态。 如果我们的两根柱线都是红色的,则鳄嘴的状态将是一个休眠阶段。 如果我们的两根柱线都是绿色的,则是一个进食阶段。 如果我们的两根柱线在红色之后都是绿色的,则处于觉醒阶段。 如果我们在绿色之后都是红色的柱线,则这是吃饱阶段。

          所以,简言之,

          两根柱线都呈红色 ==> 休眠阶段

          两根柱线都呈绿色 ==> 进食阶段

          柱线先绿后红 ==> 觉醒阶段

          柱线先红后绿 ==> 吃饱阶段

            策略二: 鳄嘴信号:

              根据此策略,我们需要基于鳄嘴指标获取信号。 如果鳄嘴处于觉醒阶段,我们需要查找取到良好的入场的信号。 如果鳄嘴指标处于进食阶段,我们需要得到保持当前持仓的信号。 如果鳄嘴指标处于吃饱阶段,我们需要找到一个离场良机。 如果鳄嘴是其它状态,我们什么也不需要得到。

              简而言之,

              鳄嘴指标 = 觉醒阶段 ==> 发现一个入场良机。

              鳄嘴指标 = 进食阶段 ==> 保持当前持仓。

              鳄嘴指标 = 吃饱阶段 ==> 发现一个离场良机。

              如果鳄嘴指标状态 = 其它内容 ==> 什么都不做。

                策略三: 鳄嘴配合 MA:

                  根据此策略,我们将鳄嘴信号与移动均线信号相结合。 如果我们得到两根绿柱,并且收盘价高于移动平均线,这是发现的一个买入信号。 另一种场景是,如果鳄嘴指标有两根红色,并且收盘价低于移动平均值,则它是发现的一个卖出信号。 或者,如果我们得到其它信息,我们什么也不需要做。

                  简而言之,

                  双绿色柱线,且收盘价 > 移动平均线 ==> 发现一个买入良机。

                  双红色柱线,且收盘价 < 移动平均线 ==> 发现一个卖出良机。

                  其它任何信息 ==> 什么都不做


                  鳄嘴振荡器蓝图

                  在这一部分中,我们将为每个提到的策略创建分步蓝图,以便帮助我们有效和轻松地创建我们的交易系统。 我相信这一步对于交易系统开发非常重要且必不可少,因为它将节省大量时间,即使创建需要时间,然而它可以让您避免忘记任何重要步骤和重复任务,从而做好该做的事情。 我们将致力于需要让计算机为我们做什么,而方法就是以清晰的步骤来具现我们的思路。

                    策略一:鳄嘴状态识别:  

                      基于此策略背后的概念,我们需要计算机,并创建一个智能系统,其可在每次跳价时自动检查鳄嘴指标的一些数值,即当前上涨、上涨之前两个值,和当前下跌,以及下跌之前的前两个值。 经过此检查,我们需要智能系统判定每个值的位置,并进行以下比较,第一个是关于比较鳄嘴上涨当前值和以前值,并判定哪个更大。 第二个是关于比较鳄嘴下跌当前值和以前值,并判定哪个更大。 这种比较的结果将作为我们识别鳄嘴状态所需的信号。

                      如果当前上涨值小于前值,而当前下跌值大于前值,我们要求智能交易系统在图表上的注释里返回休眠阶段的信号。 在另一种情况下,如果当前上涨值大于前值,同时当前下跌值小于前值,我们要求交易系统在注释里返回进食阶段的信号。 在第三种情况下,如果前首个上涨值小于前第二个上涨值,并且前首个下跌值大于前第二个下跌值,同时,若当前上升值大于前值,当前下跌值小于前值, 我们要求交易系统在图表的注释里返回带有觉醒阶段的信号。 在第四个也是最后一个状态下,如果前首个上涨值大于前第二个上涨值,前首个下跌值小于前第二个下跌值,同时,当前上涨值小于前值,当前下跌值大于前值, 我们要求交易系统在图表上的注释里返回带有吃饱阶段的信号。

                      以下是该交易系统蓝图的简单图表:

                      鳄嘴识别蓝图


                        策略二: 鳄嘴信号:

                          根据此交易策略的主要思想,我们需要创建一个交易系统,该系统可返回入场、离场、或保持当前持仓的良机信号。 为此,我们需要交易系统持续检查当前上涨和前两次的上涨值,此外还有当前下跌和前两次的下跌值,以便得到基于鳄嘴状态的信号。

                          我们需要交易系统在图表上的注释里返回的第一个信号是(找到一个入场良机)检查鳄嘴值,且发现有一个觉醒阶段,因为前一个上涨的首个值小于第二个值,而前一个下跌的首个值大于第二个,同时, 当前上涨值大于前值,当前下跌值小于前值。

                          我们需要通过交易系统在图表上的注释里返回的第二个信号是(保持当前持仓)检查鳄嘴值,且发现存在进食阶段,因为当前上涨值大于前值,当前下跌值小于前值。

                          我们需要通过此交易系统在图表的注释里返回的第三个信号是(找到一个离场良机)检查鳄嘴值,且发现存在一个吃饱阶段,因为前一个上升的首个值大于第二个,前一个下跌首个值大于第二个。

                          我们在交易系统中需要的最后一件事是,除了我们在之前提到的三个信号之外,如果有任何信息,则什么都不做。 以下是该交易系统的蓝图:

                          鳄嘴信号蓝图



                            策略三: 鳄嘴配合 MA:

                              根据交易策略,我们需要根据鳄嘴指标、收盘价和移动平均线找到买入或卖出的时机,这与我们在策略部分中学到的相同,以下是如何让计算机做到这一点。

                              我们要求交易系统返回的第一个信号是(找到一个买入良机)检查鳄嘴值,且发现当前上涨大于前值,且前一个上涨的首个值大于第二个值,同时,当前下跌小于前值,第一个下跌的首个值小于第二个, 这意味着我们现在有双根绿柱。 然后,收盘价大于移动平均线。

                              第二个信号是检查鳄嘴,并发现当前上涨小于前值,且前一个上涨的首个值小于第二个(找到一个卖出良机),同时,当前下跌值大于前值,第一个下跌的首个值大于第二个, 这意味着我们有双根红柱。 然后,收盘价小于移动平均线。

                              第三个信号,我们要求交易系统在发现其它东西时不返回任何内容。 以下是该交易系统的蓝图:

                              鳄嘴配合 MA 策略蓝图


                              鳄嘴振荡器交易系统

                              现在,我们来到了本文中最有趣的主题,为每个提到的策略构建交易系统。 这个交易系统可以帮助我们有效地交易,我们先从创建一个简单的交易系统开始,当作我们策略的基础。

                              创建 “Simple Gator Oscillator System” 是为了在图表上返回含有鳄嘴指标当前上涨值和下跌值的注释。 以下步骤创建此交易系统:

                              创建 upGator 和 downGator 的双精度型数组,其为实数型之一,返回含有分数的数值。

                                 double upGatorArray[];
                                 double downGatorArray[];

                              调用 "ArraySetAsSeries" 函数设置数据排列顺序。 其参数:

                                 ArraySetAsSeries(upGatorArray,true);
                                 ArraySetAsSeries(downGatorArray,true);

                              为 gatorDef 创建一个整数型变量,并调用 “iGator” 函数定义鳄嘴振荡器。 返回指标句柄,其参数:

                              • symbol: 确定品种名称,我们将采用 _SYMBOL 应用当前品种。 
                              • period: 确定时间段,我们将采用 _PERIOD 应用当前时间帧。
                              • jaw_period: 确定计算下颚的所需周期,我们将采用(13)。 
                              • jaw_shift: 如果需要,确定下颚的水平偏移。 我们将采用(8)。
                              • teeth_period: to determine the period of the teeth calculation. 我们将采用(8)。
                              • teeth_shift: 确定计算牙齿的周期。 我们将采用(8)。
                              • lips_period: 确定计算额唇的周期。 我们将采用(8)。
                              • lips_shift: 如果需要,确定颚唇的水平偏移。我们采用 (3)。
                              • ma_method: 确定移动平均线的类型。 我们采用 (MODE_SMMA)。
                              • applied_price: 确定计算中应用的价格类型。 我们采用 (PRICE_MEDIAN)。
                              int gatorDef=iGator(_Symbol,_Period,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN);

                              通过调用 “CopyBuffer” 函数为 upGatorArray 和 downGatorArray 定义数据,并存储结果。 其参数:

                              • indicator_handle: 确定指标句柄,我们将采用(gatorDef)。
                              • buffer_num: 确定指标缓冲区编号,我们采用(0 代表 upGator),(2 代表 downGator)。
                              • start_pos: 确定起始位置,我们将采用(0)。
                              • count: 确定要复制的数量,我们将采用(3)。
                              • buffer[]: 确定要复制的目标数组,我们采用(upGatorArray,downGatorArray)。
                                 CopyBuffer(gatorDef,0,0,3,upGatorArray);
                                 CopyBuffer(gatorDef,2,0,3,downGatorArray);

                              为 upGator 和 downGator 创建双精度型变量之后,获取它们的数值。 然后,我们将调用(NormalizeDouble)函数进行舍入。

                              • value: 我们将取 upGatorArray[0] 作为当前值。
                              • digits: 我们采用(6)作为小数点后的位数。
                                 double gatorUpValue=NormalizeDouble(upGatorArray[0],6);
                                 double gatorDownValue=NormalizeDouble(downGatorArray[0],6);

                              调用(Comment)函数显示当前 upGator 和 downGator 的值。

                                 Comment("gatorUpValue = ",gatorUpValue,"\n",
                                         "gatorDownValue = ",gatorDownValue);

                              以下是该交易系统的完整代码:

                              //+------------------------------------------------------------------+
                              //|                               Simple Gator Oscillator System.mq5 |
                              //|                                  Copyright 2022, MetaQuotes Ltd. |
                              //|                                             https://www.mql5.com |
                              //+------------------------------------------------------------------+
                              #property copyright "Copyright 2022, MetaQuotes Ltd."
                              #property link      "https://www.mql5.com"
                              #property version   "1.00"
                              //+------------------------------------------------------------------+
                              void OnTick()
                                {
                                 double upGatorArray[];
                                 double downGatorArray[];
                                 ArraySetAsSeries(upGatorArray,true);
                                 ArraySetAsSeries(downGatorArray,true);
                                 int gatorDef=iGator(_Symbol,_Period,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN);
                                 CopyBuffer(gatorDef,0,0,3,upGatorArray);
                                 CopyBuffer(gatorDef,2,0,3,downGatorArray);
                                 double gatorUpValue=NormalizeDouble(upGatorArray[0],6);
                                 double gatorDownValue=NormalizeDouble(downGatorArray[0],6);
                                 Comment("gatorUpValue = ",gatorUpValue,"\n",
                                         "gatorDownValue = ",gatorDownValue);
                                }
                              //+------------------------------------------------------------------+

                              前面的代码行编写完毕后,我们将对其进行编译,确保没有错误,然后我们在 MetaTrader 5 交易终端的导航器窗口中,于 “Expert Advisors” 文件夹下找到该智能交易系统,如下所示:

                               鳄嘴导航器

                              将智能系统拖放到所需的图表上,我们会发现该 EA 的窗口,如下所示:

                              简单鳄嘴振荡器系统窗口

                              在勾选(允许算法交易),并按(确定)后,我们可以发现 EA 加载到图表上,与以下内容相同

                               简单鳄嘴振荡器系统加载

                              现在,我们已经准备好接收这个交易系统的信号,与下面的测试示例相同:

                              简单鳄嘴振荡器系统信号


                                策略一:鳄嘴状态识别:

                                  基于此策略,以下是为它创建的完整代码模块:

                                  //+------------------------------------------------------------------+
                                  //|                                      Gator Status Identifier.mq5 |
                                  //|                                  Copyright 2022, MetaQuotes Ltd. |
                                  //|                                             https://www.mql5.com |
                                  //+------------------------------------------------------------------+
                                  #property copyright "Copyright 2022, MetaQuotes Ltd."
                                  #property link      "https://www.mql5.com"
                                  #property version   "1.00"
                                  //+------------------------------------------------------------------+
                                  void OnTick()
                                    {
                                     double upGatorArray[];
                                     double downGatorArray[];
                                     ArraySetAsSeries(upGatorArray,true);
                                     ArraySetAsSeries(downGatorArray,true);
                                     int gatorDef=iGator(_Symbol,_Period,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN);
                                     CopyBuffer(gatorDef,0,0,5,upGatorArray);
                                     CopyBuffer(gatorDef,2,0,5,downGatorArray);
                                     double gatorUpValue=NormalizeDouble(upGatorArray[0],6);
                                     double gatorUpPreValue1=NormalizeDouble(upGatorArray[1],6);
                                     double gatorUpPreValue2=NormalizeDouble(upGatorArray[2],6);
                                     double gatorDownValue=NormalizeDouble(downGatorArray[0],6);
                                     double gatorDownPreValue1=NormalizeDouble(downGatorArray[1],6);
                                     double gatorDownPreValue2=NormalizeDouble(downGatorArray[2],6);
                                     if(gatorUpValue<gatorUpPreValue1&&gatorDownValue>gatorDownPreValue1)
                                       {
                                        Comment("Sleeping Phase");
                                       }
                                     else
                                        if(gatorUpValue>gatorUpPreValue1&&gatorDownValue<gatorDownPreValue1)
                                          {
                                           Comment("Eating Phase");
                                          }
                                     if(gatorUpPreValue1<gatorUpPreValue2&&gatorDownPreValue1>gatorDownPreValue2&&
                                        gatorUpValue>gatorUpPreValue1&&gatorDownValue<gatorDownPreValue1)
                                       {
                                        Comment("Awakening Phase");
                                       }
                                     else
                                        if(
                                           gatorUpPreValue1>gatorUpPreValue2&&gatorDownPreValue1<gatorDownPreValue2&&
                                           gatorUpValue<gatorUpPreValue1&&gatorDownValue>gatorDownPreValue1)
                                          {
                                           Comment("Sated Phase");
                                          }
                                    }
                                  //+------------------------------------------------------------------+
                                  

                                  此代码中的区别:

                                  定义并获取 upGator 的最后三个值

                                     double gatorUpValue=NormalizeDouble(upGatorArray[0],6);
                                     double gatorUpPreValue1=NormalizeDouble(upGatorArray[1],6);
                                     double gatorUpPreValue2=NormalizeDouble(upGatorArray[2],6);

                                  定义并获取 downGator 的最后三个值

                                     double gatorDownValue=NormalizeDouble(downGatorArray[0],6);
                                     double gatorDownPreValue1=NormalizeDouble(downGatorArray[1],6);
                                     double gatorDownPreValue2=NormalizeDouble(downGatorArray[2],6);

                                  策略条件:

                                  在休眠阶段的情况下,

                                     if(gatorUpValue<gatorUpPreValue1&&gatorDownValue>gatorDownPreValue1)
                                       {
                                        Comment("Sleeping Phase");
                                       }

                                  在进食阶段的情况下,

                                     else
                                        if(gatorUpValue>gatorUpPreValue1&&gatorDownValue<gatorDownPreValue1)
                                          {
                                           Comment("Eating Phase");
                                          }

                                  在觉醒阶段的情况下,

                                     if(gatorUpPreValue1<gatorUpPreValue2&&gatorDownPreValue1>gatorDownPreValue2&&
                                        gatorUpValue>gatorUpPreValue1&&gatorDownValue<gatorDownPreValue1)
                                       {
                                        Comment("Awakening Phase");
                                       }

                                  在吃饱阶段的情况下,

                                     else
                                        if(
                                           gatorUpPreValue1>gatorUpPreValue2&&gatorDownPreValue1<gatorDownPreValue2&&
                                           gatorUpValue<gatorUpPreValue1&&gatorDownValue>gatorDownPreValue1)
                                          {
                                           Comment("Sated Phase");
                                          }

                                  在编译此代码过程中没有任何错误,并执行 EA 后,我们会发现它被加载到图表上,如下所示:

                                   鳄嘴状态识别加载

                                  正如我们在上一张图表的右上角看到的那样,我们有 鳄嘴状态识别 EA 加载到图表上。

                                  我们可以从测试中找到基于此策略的信号,与以下内容相同:

                                  在休眠信号的情况下:

                                   鳄嘴状态识别休眠信号

                                  正如我们在左上角的上一张图表中看到的,我们有一个基于此策略的睡眠阶段信号。

                                  在进食阶段的情况下:

                                   鳄嘴状态识别进食信号

                                  基于前面的图表,我们可以在左上角找到,根据此策略,我们有一个进食阶段信号。

                                  在觉醒阶段的情况下:

                                  鳄嘴状态识别觉醒信号

                                  正如我们通过上一张图表看到的,我们有一个基于鳄嘴状态识别策略的觉醒阶段信号。

                                  在吃饱阶段的情况下:

                                  鳄嘴状态识别吃饱信号

                                  正如我们在上图中所看到的,我们在左上角有一个吃饱阶段信号。


                                    策略二: 鳄嘴信号策略:

                                      以下是基于此策略所创建交易系统的完整代码。

                                      //+------------------------------------------------------------------+
                                      //|                                                Gator signals.mq5 |
                                      //|                                  Copyright 2022, MetaQuotes Ltd. |
                                      //|                                             https://www.mql5.com |
                                      //+------------------------------------------------------------------+
                                      #property copyright "Copyright 2022, MetaQuotes Ltd."
                                      #property link      "https://www.mql5.com"
                                      #property version   "1.00"
                                      //+------------------------------------------------------------------+
                                      void OnTick()
                                        {
                                         double upGatorArray[];
                                         double downGatorArray[];
                                         ArraySetAsSeries(upGatorArray,true);
                                         ArraySetAsSeries(downGatorArray,true);
                                         int gatorDef=iGator(_Symbol,_Period,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN);
                                         CopyBuffer(gatorDef,0,0,3,upGatorArray);
                                         CopyBuffer(gatorDef,2,0,3,downGatorArray);
                                         double gatorUpValue=NormalizeDouble(upGatorArray[0],6);
                                         double gatorUpPreValue1=NormalizeDouble(upGatorArray[1],6);
                                         double gatorUpPreValue2=NormalizeDouble(upGatorArray[2],6);
                                         double gatorDownValue=NormalizeDouble(downGatorArray[0],6);
                                         double gatorDownPreValue1=NormalizeDouble(downGatorArray[1],6);
                                         double gatorDownPreValue2=NormalizeDouble(downGatorArray[2],6);
                                         bool awakeningPhase = gatorUpPreValue1<gatorUpPreValue2&&gatorDownPreValue1>gatorDownPreValue2&&
                                                               gatorUpValue>gatorUpPreValue1&&gatorDownValue<gatorDownPreValue1;
                                         bool eatingPhase = gatorUpValue>gatorUpPreValue1&&gatorDownValue<gatorDownPreValue1;
                                         bool satedPhase = gatorUpPreValue1>gatorUpPreValue2&&gatorDownPreValue1<gatorDownPreValue2&&
                                                           gatorUpValue<gatorUpPreValue1&&gatorDownValue>gatorDownPreValue1;
                                         if(awakeningPhase)
                                           {
                                            Comment("Find a good entry");
                                           }
                                         else
                                            if(eatingPhase)
                                              {
                                               Comment("Hold current position");
                                              }
                                            else
                                               if(satedPhase)
                                                 {
                                                  Comment("Find a good exit");
                                                 }
                                               else
                                                  Comment("");
                                        }
                                      //+------------------------------------------------------------------+

                                      此策略的差别:

                                      为三个阶段(awakeningPhase, eatingPhase, 和 satedPhase)各创建一个布尔变量;

                                         bool awakeningPhase = gatorUpPreValue1<gatorUpPreValue2&&gatorDownPreValue1>gatorDownPreValue2&&
                                                               gatorUpValue>gatorUpPreValue1&&gatorDownValue<gatorDownPreValue1;
                                         bool eatingPhase = gatorUpValue>gatorUpPreValue1&&gatorDownValue<gatorDownPreValue1;
                                         bool satedPhase = gatorUpPreValue1>gatorUpPreValue2&&gatorDownPreValue1<gatorDownPreValue2&&
                                                           gatorUpValue<gatorUpPreValue1&&gatorDownValue>gatorDownPreValue1;

                                      策略条件:

                                      在觉醒阶段的情况下

                                         if(awakeningPhase)
                                           {
                                            Comment("Find a good entry");
                                           }

                                      在进食阶段的情况下

                                         else
                                            if(eatingPhase)
                                              {
                                               Comment("Hold current position");
                                              }

                                      在吃饱阶段的情况下

                                            else
                                               if(satedPhase)
                                                 {
                                                  Comment("Find a good exit");
                                                 }

                                      其它

                                               else
                                                  Comment("");

                                      编译并执行此代码后,我们会发现 EA 加载到图表,如下所示:

                                      鳄嘴信号加载

                                      正如我们在右上角看到的,鳄嘴信号 EA 加载到图表上。

                                      现在,我们已准备好接收此策略的信号,以下是测试示例:

                                      在觉醒阶段的情况下:

                                      鳄嘴信号入场信号

                                      正如我们在上一张图表中看到的,我们在左上角有一个“找到一个入场良机”信号。

                                      在进食阶段的情况下

                                       鳄嘴信号保持信号

                                      正如我们在上图中所看到的,我们在左上角有一个“保持当前持仓”信号。

                                      在吃饱阶段的情况下

                                       鳄嘴信号离场信号

                                      正如我们在上一张测试图表中看到的那样,作为示例,我们在左上角有一个“找到一个离场良机”信号。


                                      策略三: 鳄嘴配合 MA:

                                      以下是基于此策略创建交易系统的完整代码。

                                      //+------------------------------------------------------------------+
                                      //|                                       Gator with MA strategy.mq5 |
                                      //|                                  Copyright 2022, MetaQuotes Ltd. |
                                      //|                                             https://www.mql5.com |
                                      //+------------------------------------------------------------------+
                                      #property copyright "Copyright 2022, MetaQuotes Ltd."
                                      #property link      "https://www.mql5.com"
                                      #property version   "1.00"
                                      //+------------------------------------------------------------------+
                                      void OnTick()
                                        {
                                         double upGatorArray[];
                                         double downGatorArray[];
                                         MqlRates pArray[];
                                         double maArray[];
                                         ArraySetAsSeries(upGatorArray,true);
                                         ArraySetAsSeries(downGatorArray,true);
                                         ArraySetAsSeries(maArray,true);
                                         int gatorDef=iGator(_Symbol,_Period,13,8,8,5,5,3,MODE_SMMA,PRICE_MEDIAN);
                                         int maDef=iMA(_Symbol,_Period,13,0,MODE_EMA,PRICE_CLOSE);
                                         int data=CopyRates(_Symbol,_Period,0,13,pArray);
                                         CopyBuffer(gatorDef,0,0,3,upGatorArray);
                                         CopyBuffer(gatorDef,2,0,3,downGatorArray);
                                         CopyBuffer(maDef,0,0,3,maArray);
                                         double gatorUpValue=NormalizeDouble(upGatorArray[0],6);
                                         double gatorUpPreValue1=NormalizeDouble(upGatorArray[1],6);
                                         double gatorUpPreValue2=NormalizeDouble(upGatorArray[2],6);
                                         double gatorDownValue=NormalizeDouble(downGatorArray[0],6);
                                         double gatorDownPreValue1=NormalizeDouble(downGatorArray[1],6);
                                         double gatorDownPreValue2=NormalizeDouble(downGatorArray[2],6);
                                         double maValue=NormalizeDouble(maArray[0],5);
                                         double closingPrice=pArray[0].close;
                                         bool douleGreen = gatorUpValue>gatorUpPreValue1&&gatorUpPreValue1>gatorUpPreValue2&&
                                                           gatorDownValue<gatorDownPreValue1&&gatorDownPreValue1<gatorDownPreValue2;
                                         bool douleRed = gatorUpValue<gatorUpPreValue1&&gatorUpPreValue1<gatorUpPreValue2&&
                                                         gatorDownValue>gatorDownPreValue1&&gatorDownPreValue1>gatorDownPreValue2;  
                                         if(douleGreen&&closingPrice>maValue)
                                           {
                                            Comment("Find a good buy position");
                                           }
                                         else
                                            if(douleRed&&closingPrice<maValue)
                                              {
                                               Comment("Find a good sell position");
                                              }
                                            else
                                               Comment("");
                                        }
                                      //+------------------------------------------------------------------+

                                      此策略的差别:

                                      再创建两个数组 pArray 和 maArray;我们 pArray 定义为 “MqlRates” 型,存储价格信息。 而 maArray 定义为 "double" 型;

                                         MqlRates pArray[];
                                         double maArray[];

                                      调用 “ArraySetAsSeries” 函数定义 maArray 中的数据排序;

                                      ArraySetAsSeries(maArray,true);

                                      创建一个整数型变量 maDef ,并调用 “iMA” 函数定义移动平均线,返回指标句柄及其参数:

                                      • symbol:  确定品种名称。 我们采用 (_SYMBOL) 应用当前图表的品种。
                                      • period: 确定时间段,我们采用 _PERIOD 应用当前时间帧,您也可以用(PERIOD_CURRENT)设置同一时间帧。
                                      • ma_period: 确定平均周期,我们采用(13)。 
                                      • ma_shift: 根据需要确定水平偏移。 我们设置(0),因为我们不需要偏移 MA。 
                                      • ma_method: 确定移动平均线类型,我们将设置为 EMA(指数移动平均线)。 
                                      • applied_price: 确定计算中所用的价格类型,我们采用收盘价。
                                      int maDef=iMA(_Symbol,_Period,13,0,MODE_EMA,PRICE_CLOSE);

                                      通过调用 “CopyRates” 函数获取 MqlRates 型的历史数据:

                                      • symbol_name: 确定交易品种名称,我们采用(_Symbol) 应用当前品种。 
                                      • timeframe: 确定时间帧,我们采用(_Period)应用当前时间帧。 
                                      • start_pos: 确定起点位置,我们取(0)从当前位置开始。
                                      • count: 确定要复制的数量,我们取(13)。 
                                      • rates_array[]: 确定要复制的目标数组,我们采用(pArray)。 
                                      int data=CopyRates(_Symbol,_Period,0,13,pArray);

                                      通过调用 “CopyBuffer” 函数在 maArray 里定义数据,并存储结果。

                                      CopyBuffer(maDef,0,0,3,maArray);

                                      获取当前指数移动平均线的值,并将其常规化。

                                      double maValue=NormalizeDouble(maArray[0],5);

                                      获取收盘价的当前值。

                                      double closingPrice=pArray[0].close;

                                      创建布尔变量,标识鳄嘴振荡器指标是双根绿柱,或双根红柱。

                                         bool douleGreen = gatorUpValue>gatorUpPreValue1&&gatorUpPreValue1>gatorUpPreValue2&&
                                                           gatorDownValue<gatorDownPreValue1&&gatorDownPreValue1<gatorDownPreValue2;
                                         bool douleRed = gatorUpValue<gatorUpPreValue1&&gatorUpPreValue1<gatorUpPreValue2&&
                                                         gatorDownValue>gatorDownPreValue1&&gatorDownPreValue1>gatorDownPreValue2; 

                                      策略条件:

                                      买入情况:

                                         if(douleGreen&&closingPrice>maValue)
                                           {
                                            Comment("Find a good buy position");
                                           }

                                      卖出情况:

                                         else
                                            if(douleRed&&closingPrice<maValue)
                                              {
                                               Comment("Find a good sell position");
                                              }

                                      其它:

                                            else
                                               Comment("");

                                      在编译并执行此代码,并附于所需图表后,我们会发现 EA 被加载到图表,如下所示:

                                       鳄嘴配合 MA 策略加载

                                      正如我们在图表右上角看到的,我们在图表上得到鳄嘴配合 MA 的 EA。

                                      现在,我们已准备好接收此策略的信号,以下是测试示例;

                                      买入情况:

                                       鳄嘴配合 MA 策略 买入信号

                                      正如我们在左上角的上图中看到的,我们有一个(找到一个买入良机)信号。

                                      卖出情况:

                                      鳄嘴配合 MA 策略 卖出信号

                                      正如我们所看到的,我们有一个(找到一个卖出良机)信号。

                                      现在我们学习了如何基于不同的策略创建交易系统,这种方法必须让您看到可以应用的不同想法,这是本文和系列的主要宗旨。


                                      结束语

                                      现在,我们涵盖了本文的所有主题,从中学习了如何通过鳄嘴振荡器设计交易系统,我们由此学习到什么是鳄嘴振荡器指标,如何计算它,如何通过三种简单的交易策略运用它,它们是:

                                      • 鳄嘴状态识别:此策略根据不同的条件判定鳄嘴振荡器的状态(觉醒、休眠、进食、吃饱)。
                                      • 鳄嘴信号:根据鳄嘴振荡器的不同条件,获取相应决策时机的信号(找到一个入场良机,保持当前持仓,或者找到一个离场良机)。
                                      • 鳄嘴配合 MA 策略:配合移动平均线指标的鳄嘴振荡器,获取买入或卖出时机的信号。

                                      在我们学会了如何创建一个分步蓝图之后,就能帮助我们有效和轻松地为每个提到的策略创建一个交易系统之后。 然后,我们通过在 MQL5 IDE 中创建这些策略的源代码,为这些策略在 MetaTrader5 交易平台中执行创建了一个交易系统。

                                      我希望您发现这篇文章对您有用,能帮助您从交易中获得更好的结果,我也希望这个帐户可以帮助您找到一种可在您的交易业务中运用的新方法,或者获得有关本文主题或任何相关主题的更多见解,如果发生这种情况,并且您希望阅读更多类似的文章,您可以阅读我的其它有关学习如何基于最流行的技术指标设计交易系统的系列文章。

                                      本文由MetaQuotes Ltd译自英文
                                      原文地址: https://www.mql5.com/en/articles/11928

                                      种群优化算法:蝙蝠算法(BA) 种群优化算法:蝙蝠算法(BA)
                                      在本文中,我将研究蝙蝠算法(BA),它在平滑函数上表现出良好的收敛性。
                                      您应该知道的 MQL5 向导技术(第 05 部分):马尔可夫(Markov)链 您应该知道的 MQL5 向导技术(第 05 部分):马尔可夫(Markov)链
                                      马尔可夫(Markov)链是一个强大的数学工具,能够针对包括金融在内的各个领域的时间序列数据进行建模和预测。 在金融时间序列建模和预测中,马尔可夫链通常用于模拟金融资产随时间的演变,例如股票价格或汇率。 马尔可夫链模型的主要优点之一是其简单性和易用性。
                                      神经网络实验(第 3 部分):实际应用 神经网络实验(第 3 部分):实际应用
                                      在本系列文章中,我会采用实验和非标准方法来开发一个可盈利的交易系统,并检查神经网络是否对交易者有任何帮助。 若在交易中运用神经网络,MetaTrader 5 则可作为近乎自给自足的工具。
                                      构建自动运行的 EA(第 09 部分):自动化(II) 构建自动运行的 EA(第 09 部分):自动化(II)
                                      如果您无法控制其调度表,则自动化就意味着毫无意义。 没有工人能够一天 24 小时高效工作。 然而,许多人认为自动化系统理所当然地每天 24 小时运行。 但为 EA 设置工作时间范围总是有好处的。 在本文中,我们将研究如何正确设置这样的时间范围。