English Русский Español Deutsch 日本語 Português
基于大众交易系统和交易机器人优化点金术的 Expert Advisor(续)

基于大众交易系统和交易机器人优化点金术的 Expert Advisor(续)

MetaTrader 4交易系统 | 17 三月 2016, 14:57
2 029 0
Nikolay Kositsin
Nikolay Kositsin

简介

在我之前的本系列文章中(1234),我介绍了各种最简单的交易系统,它们的特点是仅处理一个时间范围。因此,此类交易系统在更全局化的时间尺度中完全无法对市场趋势的变化做出反应。这会在市场状况发生变化时导致亏损,因为上述系统无法检测到这些变化。实际上,真实交易中基本不能使用仅以从一个时间范围的图表中获取的数据为基础的系统。正常操作中通常至少要用到两个时间范围。当前趋势通常是在较大时间范围的图表上确定的,而此趋势方向上的入市价位是基于较小时间范围的图表计算得出的。依我看来,之前文章中那些最简单的交易策略示例足以让读者学会如何设计此类系统。那么,现在让我们讨论一下如何根据上述推论改进此类交易系统。



使用两个时间范围的交易系统

从逻辑角度看,无论以之前文章中所述的哪个交易系统为基础,实际上都没有什么区别。我们将构建一个更为复杂的系统。至于其初始本质,每个最简单的交易系统都可用以下形式来表示:

对于多头仓:

对于空头仓:

在使用两个时间范围的交易系统中,这些入市条件将根据在较小时间范围上计算的指标来定义。趋势方向将在较大时间范围上确定。因此,包含这些条件的算法如下所示:

对于多头仓:

对于空头仓:

在这种情况下,Trend 变量仅定义较大时间范围上的当前趋势方向,而入市的其他条件将 Expert Advisor 的交易行为限定至该全局趋势的方向上。从程序代码的角度看,无论使用哪种算法,最终也没有任何区别,都将在较大时间范围上检测当前趋势。所以这完全取决于 EA 编写者决定使用什么算法在较小时间范围上计算入市价位,并在较大时间范围上检测当前趋势。让我们分析早前提过的使用 EA Exp_5.mq4 呈示的 OsMA 振荡指标的算法,为了定义当前趋势,我们使用移动 J2JMA.mq4。在这种情况下,交易定义条件将会非常简单:

那么现在我们要向现有 Exp_5.mq4 添加一些代码,以加入上述逻辑。完成的代码如下所示:

//For the EA operation Metatrader\EXPERTS\indicators folder must
//contain indicators 5c_OsMA.mq4 and J2JMA.mq4
//+==================================================================+
//|                                                       Exp_11.mq4 |
//|                             Copyright © 2008,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+==================================================================+
#property copyright "Copyright © 2008, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//----+ +--------------------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR BUY TRADES
extern bool   Test_Up = true;//filter of trade calculations direction
extern double Money_Management_Up = 0.1;
//---- input parameters of the custom indicator J2JMA.mq4
extern int    TimeframeX_Up = 240;
extern int    Length1X_Up = 4;  // depth of the first smoothing
extern int    Phase1X_Up = 100; // parameter of the first smoothing
       //changing in the range -100 ... +100, influences the quality 
       //of the transient process of averaging;  
extern int    Length2X_Up = 4;  // depth of the second smoothing
extern int    Phase2X_Up = 100; // parameter of the second smoothing, 
       //changing in the range -100 ... +100, influences the quality
       //of the transient process of averaging;  
extern int    IPCX_Up = 0;/* Selecting prices on which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
//---- input parameters of the custom indicator 5c_OsMA.mq4
extern int    Timeframe_Up = 60;
extern double IndLevel_Up = 0; // breakout level of the indicator
extern int    FastEMA_Up = 12;  // quick EMA period
extern int    SlowEMA_Up = 26;  // slow EMA period
extern int    SignalSMA_Up = 9;  // signal SMA period
extern int    STOPLOSS_Up = 50;  // stop loss
extern int    TAKEPROFIT_Up = 100; // take profit
extern int    TRAILINGSTOP_Up = 0; // trailing stop
extern int    PriceLevel_Up =40; // difference between the current price and
                                         // the price of a pending order triggering
extern bool   ClosePos_Up = true; // forced position closing allowed
//----+ +--------------------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR SELL TRADES
extern bool   Test_Dn = true;//filter of trade calculations direction
extern double Money_Management_Dn = 0.1;
//---- input parameters of the custom indicator J2JMA.mq4
extern int    TimeframeX_Dn = 240;
extern int    Length1X_Dn = 4;  // smoothing depth 
extern int    Phase1X_Dn = 100;  // parameter of the first smoothing
       //changing in the range -100 ... +100, influences the quality
       //of the transient process of averaging;  
extern int    Length2X_Dn = 4;  // smoothing depth
extern int    Phase2X_Dn = 100; // parameter of the second smoothing 
       //changing in the range -100 ... +100, influences the quality 
       //of the transient process of averaging;  
extern int    IPCX_Dn = 0;/* Selecting prices on which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
//---- input parameters of the custom indicator 5c_OsMA.mq4
extern int    Timeframe_Dn = 60;
extern double IndLevel_Dn = 0; // breakout level of the indicator
extern int    FastEMA_Dn = 12;  // quick EMA period
extern int    SlowEMA_Dn = 26;  // slow EMA period
extern int    SignalSMA_Dn = 9;  // signal SMA period
extern int    STOPLOSS_Dn = 50;  // stop loss
extern int    TAKEPROFIT_Dn = 100; // take profit
extern int    TRAILINGSTOP_Dn = 0; // trailing stop
extern int    PriceLevel_Dn = 40; // difference between the current price and
                                         // the price of a pending order triggering
extern bool   ClosePos_Dn = true; // forced position closing allowed
//----+ +--------------------------------------------------------------------------+
//---- Integer variables for the minimum of calculation bars
int MinBarX_Up, MinBar_Up, MinBarX_Dn, MinBar_Dn;
//+==================================================================+
//| TimeframeCheck() functions                                       |
//+==================================================================+
void TimeframeCheck(string Name, int Timeframe)
  {
//----+
   //---- Checking the correctness of Timeframe variable value
   if (Timeframe != 1)
    if (Timeframe != 5)
     if (Timeframe != 15)
      if (Timeframe != 30)
       if (Timeframe != 60)
        if (Timeframe != 240)
         if (Timeframe != 1440)
           Print(StringConcatenate("TimeframeCheck: Parameter ",Name,
                     " cannot ", "be equal to", Timeframe, "!!!"));    
//----+ 
  }
//+==================================================================+
//| Custom Expert functions                                          |
//+==================================================================+
#include <Lite_EXPERT1.mqh>
//+==================================================================+
//| Custom Expert initialization function                            |
//+==================================================================+
int init()
  {
//---- Checking the correctness of Timeframe_Up variable value
   TimeframeCheck("Timeframe_Up", Timeframe_Up); 
   //---- Checking the correctness of TimeframeX_Up variable value
   TimeframeCheck("TimeframeX_Up", TimeframeX_Up);                                                                        
//---- Checking the correctness of Timeframe_Dn variable value
   TimeframeCheck("Timeframe_Dn", Timeframe_Dn);
   //---- Checking the correctness of Timeframe_Dn variable value
   TimeframeCheck("TimeframeX_Dn", TimeframeX_Dn);    
//---- Initialization of variables
   MinBar_Up  = 3 + MathMax(FastEMA_Up, SlowEMA_Up) + SignalSMA_Up;
   MinBarX_Up  = 3 + 30 + 30;
   MinBar_Dn  = 3 + MathMax(FastEMA_Dn, SlowEMA_Dn) + SignalSMA_Dn;
   MinBarX_Dn  = 3 + 30 + 30;                              
//---- end of initialization
   return(0);
  }
//+==================================================================+
//| expert deinitialization function                                 |
//+==================================================================+  
int deinit()
  {
//----+
   
    //---- End of the EA deinitialization
    return(0);
//----+ 
  }
//+==================================================================+
//| Custom Expert iteration function                                 |
//+==================================================================+
int start()
  {
   //----+ Declaring local variables
   double J2JMA1, J2JMA2, Osc1, Osc2;
   //----+ Declaring static variables
   //----+ +---------------------------------------------------------------+
   static double TrendX_Up, TrendX_Dn;
   static datetime StopTime_Up, StopTime_Dn; 
   static int LastBars_Up, LastBarsX_Up, LastBarsX_Dn, LastBars_Dn;
   static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop;
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR LONG POSITIONS                                        |
   //----+ +---------------------------------------------------------------+
   if (Test_Up) 
    {
      int IBARS_Up = iBars(NULL, Timeframe_Up);
      int IBARSX_Up = iBars(NULL, TimeframeX_Up);
      
      if (IBARS_Up >= MinBar_Up && IBARSX_Up >= MinBarX_Up)
       {
         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Up != IBARSX_Up)
          {
           //----+ Initialization of variables
           LastBarsX_Up = IBARSX_Up;
           BUY_Stop = false;
           
           //----+ calculating indicator values for J2JMA   
           J2JMA1 = iCustom(NULL, TimeframeX_Up, 
                                "J2JMA", Length1X_Up, Length2X_Up,
                                             Phase1X_Up, Phase2X_Up,  
                                                     0, IPCX_Up, 0, 1);
           //---                     
           J2JMA2 = iCustom(NULL, TimeframeX_Up, 
                                "J2JMA", Length1X_Up, Length2X_Up,
                                             Phase1X_Up, Phase2X_Up,  
                                                     0, IPCX_Up, 0, 2);
           
           //----+ defining trend
           TrendX_Up = J2JMA1 - J2JMA2;
           //----+ defining a signal for closing trades
           if (TrendX_Up < 0)
                      BUY_Stop = true;                                      
          }
          
         //----+ +----------------------------------------+
         //----+ DEFINING SIGNAL FOR MARKET ENTERING      |
         //----+ +----------------------------------------+
         if (LastBars_Up != IBARS_Up)
          {
           //----+ Initialization of variables 
           BUY_Sign = false;
           LastBars_Up = IBARS_Up;
           StopTime_Up = iTime(NULL, Timeframe_Up, 0)
                                          + 60 * Timeframe_Up;
           //----+ calculating indicator values
           Osc1 = iCustom(NULL, Timeframe_Up, 
                         "5c_OsMA", FastEMA_Up, SlowEMA_Up,
                                               SignalSMA_Up, 5, 1);
           //---                   
           Osc2 = iCustom(NULL, Timeframe_Up, 
                         "5c_OsMA", FastEMA_Up, SlowEMA_Up,
                                               SignalSMA_Up, 5, 2);
           
           //----+ defining signals for trades
           if (TrendX_Up > 0)                                           
            if (Osc2 < IndLevel_Up)
             if (Osc1 > IndLevel_Up)
                        BUY_Sign = true;                               
          }
          
         //----+ +-------------------+
         //----+ EXECUTION OF TRADES |
         //----+ +-------------------+
         if (!OpenBuyLimitOrder1(BUY_Sign, 1, 
              Money_Management_Up, STOPLOSS_Up, TAKEPROFIT_Up,
                                            PriceLevel_Up, StopTime_Up))
                                                                 return(-1);
         if (ClosePos_Up)
                if (!CloseOrder1(BUY_Stop, 1))
                                        return(-1);
                                        
         if (!Make_TreilingStop(1, TRAILINGSTOP_Up))
                                              return(-1);
        }
     }
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR SHORT POSITIONS                                       |
   //----+ +---------------------------------------------------------------+
   if (Test_Dn) 
    {
      int IBARS_Dn = iBars(NULL, Timeframe_Dn);
      int IBARSX_Dn = iBars(NULL, TimeframeX_Dn);
      
      if (IBARS_Dn >= MinBar_Dn && IBARSX_Dn >= MinBarX_Dn)
       {
         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Dn != IBARSX_Dn)
          {
           //--- Initialization of variables 
           LastBarsX_Dn = IBARSX_Dn;
           SELL_Stop = false;
           
           //----+ calculating indicator values for J2JMA   
           J2JMA1 = iCustom(NULL, TimeframeX_Dn, 
                                "J2JMA", Length1X_Dn, Length2X_Dn,
                                             Phase1X_Dn, Phase2X_Dn,  
                                                     0, IPCX_Dn, 0, 1);
           //---                     
           J2JMA2 = iCustom(NULL, TimeframeX_Dn, 
                                "J2JMA", Length1X_Dn, Length2X_Dn,
                                             Phase1X_Dn, Phase2X_Dn,  
                                                     0, IPCX_Dn, 0, 2);
           
           //----+ defining trend                                 
           TrendX_Dn = J2JMA1 - J2JMA2;
           //----+ defining a signal for closing trades
           if (TrendX_Dn > 0)
                      SELL_Stop = true;                                      
          }
         
         //----+ +----------------------------------------+
         //----+ DEFINING SIGNAL FOR MARKET ENTERING      |
         //----+ +----------------------------------------+
         if (LastBars_Dn != IBARS_Dn)
          {
           //----+ Initialization of variables 
           SELL_Sign = false;
           LastBars_Dn = IBARS_Dn;
           StopTime_Dn = iTime(NULL, Timeframe_Dn, 0)
                                          + 60 * Timeframe_Dn;
           //----+ calculating indicator values    
           Osc1 = iCustom(NULL, Timeframe_Dn, 
                         "5c_OsMA", FastEMA_Dn, SlowEMA_Dn,
                                               SignalSMA_Dn, 5, 1);
           //---                   
           Osc2 = iCustom(NULL, Timeframe_Dn, 
                         "5c_OsMA", FastEMA_Dn, SlowEMA_Dn,
                                               SignalSMA_Dn, 5, 2);
           
           //----+ defining signals for trades
           if (TrendX_Dn < 0)                                           
            if (Osc2 > IndLevel_Dn)
             if (Osc1 < IndLevel_Dn)
                        SELL_Sign = true;                               
          }
          
         //----+ +-------------------+
         //----+ EXECUTION OF TRADES |
         //----+ +-------------------+
          if (!OpenSellLimitOrder1(SELL_Sign, 2, 
              Money_Management_Dn, STOPLOSS_Dn, TAKEPROFIT_Dn,
                                            PriceLevel_Dn, StopTime_Dn))
                                                                 return(-1);
          if (ClosePos_Dn)
                if (!CloseOrder1(SELL_Stop, 2))
                                        return(-1);
                                        
          if (!Make_TreilingStop(2, TRAILINGSTOP_Dn))
                                                  return(-1);
        }
     }
   //----+ +---------------------------------------------------------------+
//----+ 
    
    return(0);
  }
//+------------------------------------------------------------------+

尽管方法似乎并不那么复杂,但实际代码看起来比初始 Exp_5mq4 代码大两倍!现在我们来讨论这个结果。我还是只分析 EA 的多头仓部分,空头仓的部分是类似的。用于获取 J2JMA 指标的必要值的额外源代码如下:

//----+ calculating indicator values for J2JMA   
           J2JMA1 = iCustom(NULL, TimeframeX_Up, "J2JMA", Length1X_Up, Phase1X_Up, Length2X_Up, Phase2X_Up, 0, IPCX_Up, 0, 1);
           //---                     
           J2JMA2 = iCustom(NULL, TimeframeX_Up, "J2JMA", Length1X_Up, Phase1X_Up, Length2X_Up, Phase2X_Up, 0, IPCX_Up, 0, 2);
//----+ defining trend
           Trend_Up = J2JMA1 - J2JMA2;

因此,EA 开头部分现在包含六个新外部变量的声明,对应于 J2JMA 指标调用:

extern int    TimeframeX_Up = 240;
extern int    Length1X_Up = 4;  // depth of the first smoothing
extern int    Phase1X_Up = 100; // parameter of the first smoothing
       //changing in the range -100 ... +100, influences the quality 
       //of the transient process of averaging;  
extern int    Length2X_Up = 4;  // depth of the second smoothing
extern int    Phase2X_Up = 100; // parameter of the second smoothing, 
       //changing in the range -100 ... +100, influences the quality
       //of the transient process of averaging;  
extern int    IPCX_Up = 0;/* Selecting prices on which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */

一个新的类似变量 MinBarX_Up 被添加到全局变量的声明行,以获取计算柱的最小值,它跟在 EA 外部变量的后面:

//---- Integer variables for the minimum of calculation bars
int MinBarX_Up, MinBar_Up, MinBarX_Dn, MinBar_Dn;

在 EA 初始化块中,额外检查新外部变量 TimeframeХ_Up 的正确性:

//---- Checking the correctness of TimeframeX_Up variable value
   TimeframeCheck("TimeframeХ_Up", TimeframeX_Up);

MinBarX_Up  = 3 + 30 + 30;

在 EA 的 start() 函数块中执行进一步的代码修改。在本地变量声明行中添加两个新变量:J2JMA1 和 J2JMA2:

//----+ Declaring local variables
   double J2JMA1, J2JMA2, Osc1, Osc2;

Trend_Up 变量被声明为一个静态变量,因为它仅在柱变更时被初始化一次,它的值用于 start() 函数的进一步价格变动:

static double TrendX_Up, TrendX_Dn;

照此类推,变量 LastBarsX_Up 被声明为静态变量:

static int LastBars_Up, LastBarsX_Up, LastBarsX_Dn, LastBars_Dn;

在多头仓的代码中,检查计算的充分性变得更加复杂:

if (Test_Up) 
    {
      int IBARS_Up = iBars(NULL, Timeframe_Up);
      int IBARSX_Up = iBars(NULL, TimeframeX_Up);
      
      if (IBARS_Up >= MinBar_Up && IBARSX_Up >= MinBarX_Up)
       {
         // CODE FOR LONG POSITIONS
       }
     }

并且添加了一个新的块:

         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Up != IBARSX_Up)
          {
           //----+ Initialization of variables 
           LastBarsX_Up = IBARSX_Up;
           BUY_Stop = false;
           
           //----+ calculating indicator values for J2JMA   
           J2JMA1 = iCustom(NULL, TimeframeX_Up, 
                                "J2JMA", Length1X_Up, Phase1X_Up,
                                            Length2X_Up, Phase2X_Up,  
                                                     0, IPCX_Up, 0, 1);
           //---                     
           J2JMA2 = iCustom(NULL, TimeframeX_Up, 
                                "J2JMA", Length1X_Up, Phase1X_Up,
                                            Length2X_Up, Phase2X_Up,  
                                                     0, IPCX_Up, 0, 2);
           
           //----+ defining trend                                 
           TrendX_Up = J2JMA1 - J2JMA2;
           //----+ defining a signal for closing trades
           if (Trend_Up < 0)
                      BUY_Stop = true;                                      
          }

在这个必要的块中,对变量 Trend_Up 初始化,此外还在此处定义强制平仓信号(BUY_Stop 变量的初始化)。一般来说,在初始 Exp_5.mq4 中,最后一个变量在“DEFINING SIGNALS FOR MARKET ENTERING”程序块中初始化,但在新 EA 中,更合理的做法是将此初始化放在“DEFINING TREND”块中,并更改其初始化算法。

最重要的是在块“DEFINING SIGNALS FOR MARKET ENTERING”中对信号定义算法做一个小调整:

           //----+ defining signals for trades
           if (TrendX_Up > 0)                                           
            if (Osc2 < IndLevel_Up)
             if (Osc1 > IndLevel_Up)
                        BUY_Sign = true;

完成所有修改后,此算法使用变量 Trend_Up 将当前趋势方向考虑在内。

现在来说一些关于 EA 优化的细节。EA 一般都应仅针对多头仓或空头仓进行单独的优化,但即便在这种情况下,要优化的外部变量也非常多。也许同时优化所有这些变量并不合理。尤其是,优化的遗传算法不会优化八个以上的变量!这种情况下,最合适的解决方案是固定某些变量的值,仅优化其余未固定值的变量,即最紧急的变量。优化之后,选择最合适的方法,试着优化其余参数。

例如,对于多头仓,方法如下:

包含测试程序的这些设置的文件 Exp_11.ini 在 TESTER.zip 存档中。这里我们无需优化 Money_Management_Up 和 TimeframeX_Up。至于 TimeframeX_Up 变量,要注意的是,它的值必须大于变量 Timeframe_Up 的值。Length1X_Up 的值的可变范围相当大,而 Phase1X_Up 的值的范围为 -100 至 100。最好在第一次优化时固定参数 Length2X_Up、Phase2X_Up 和 IPCX_Up 的值,我在上一篇文章中介绍 Exp_5.mq4 时提到的 IndLevel_Up 参数也是如此。对于 FastEMA_Up 和 SlowEMA_Up 参数,参数变更的下限值不应太小。当然,它们可以表现出令人惊异的结果,但这种结果有任何意义吗?优化之后还应检查使用追踪止损位是否合理。但在趋势变化时,应始终通过逻辑变量 ClosePos_Up 强制平仓。最好将其值固定为“true”。

优化期间,策略测试程序中的图表周期应等于变量 Timeframe_Up 或 Timeframe_Dn 的值(取决于优化期间的交易方向),在某个帐户上进行最终测试或操作时,图表周期应设为等于这些值的最小值。还有个重要的细节。此 Expert Advisor 使用至少两个时间范围,因此在帐户上下载用于优化、测试和操作的历史数据之时要留心这一点,尤其是你使用在不同经销商开立的多个帐户时更要注意。

第四篇文章中,我介绍了如何导出 Microsoft Excel 中进一步统计分析的优化结果。在我看来,这篇文章中提供的 EA 最适合此类程序。如果有人要试用这个 EA,我用帐号修改了此 EA 代码,作为本文的推荐 EA (Exp_11_2.mq4)。此代码附于本文之后。



针对不同时间范围的两个图表的计算数据的另一个 EA 使用示例

我想,仅仅一个基于此理念的 EA 示例还不足以供本文使用,所以我会再加一个根据此原理构建的Expert Advisor。我将以我第一篇文章中的第一个 EA Exp_1.mq4 为基础。用于定义入市条件和管理仓位的代码部分已准备就绪。现在我们需要定义较大时间范围的活跃市场趋势。在此 Expert Advisor 中,我使用指标 MAMA_NK.mq4:

在这种情况下,定义趋势方向的条件是第一个柱上两个移动之间的差值:

让我们用类似方式编写一段代码,以 Exp_11.mq4 的代码为模板:

//+==================================================================+
//|                                                       Exp_12.mq4 |
//|                             Copyright © 2008,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+==================================================================+
#property copyright "Copyright © 2008, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//----+ +---------------------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR BUY TRADES
extern bool   Test_Up = true;//filter of trade calculations direction
extern double Money_Management_Up = 0.1;
//----
extern int    TimeframeX_Up = 240;
extern double FastLimitX_Up = 0.5;
extern double SlowLimitX_Up = 0.05;
extern int    IPCX_Up = 9;/* Selecting prices, upon which the indicator will be calculated
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close, 15-Heiken Ashi Open0.) */
//---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
extern int    Timeframe_Up = 60;
extern int    Length_Up = 4;  // smoothing depth
extern int    Phase_Up = 100; // parameter changing in the range
          //-100 ... +100, influences the quality of a transient process;
extern int    IPC_Up = 0;/* Selecting prices, upon which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int    STOPLOSS_Up = 50;  // stop loss
extern int    TAKEPROFIT_Up = 100; // take profit
extern bool   ClosePos_Up = true; // forced position closing is allowed
//----+ +---------------------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR SELL TRADES 
extern bool   Test_Dn = true;//filter of trade calculations direction
extern double Money_Management_Dn = 0.1;
//----
extern int    TimeframeX_Dn = 60;
extern double FastLimitX_Dn = 0.5;
extern double SlowLimitX_Dn = 0.05;
extern int    IPCX_Dn = 9;/* Selecting prices, upon which the indicator will be calculated 
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close, 15-Heiken Ashi Open0.) */
//---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
extern int    Timeframe_Dn = 60;
extern int    Length_Dn = 4;  // smoothing depth
extern int    Phase_Dn = 100; // parameter changing in the range
         // -100 ... +100, influences the quality of a transient process; 
extern int    IPC_Dn = 0;/* Selecting prices, upon which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int   STOPLOSS_Dn = 50;  // stop loss
extern int   TAKEPROFIT_Dn = 100; // take profit
extern bool   ClosePos_Dn = true; // forced position closing is allowed
//----+ +---------------------------------------------------------------------------+
//---- Integer variables for the minimum of counted bars
int MinBar_Up, MinBar_Dn, MinBarX_Up, MinBarX_Dn;
//+==================================================================+
//| Custom Expert functions                                          |
//+==================================================================+
#include <Lite_EXPERT1.mqh>
//+==================================================================+
//| TimeframeCheck() functions                                       |
//+==================================================================+
void TimeframeCheck(string Name, int Timeframe)
  {
//----+
   //---- Checking the correctness of Timeframe variable value
   if (Timeframe != 1)
    if (Timeframe != 5)
     if (Timeframe != 15)
      if (Timeframe != 30)
       if (Timeframe != 60)
        if (Timeframe != 240)
         if (Timeframe != 1440)
           Print(StringConcatenate("Parameter ",Name,
                     " cannot ", "be equal to ", Timeframe, "!!!"));    
//----+ 
  }
//+==================================================================+
//| Custom Expert initialization function                            |
//+==================================================================+
int init()
  {
//---- Checking the correctness of Timeframe_Up variable value
   TimeframeCheck("TimeframeX_Up", TimeframeX_Up);
//---- Checking the correctness of Timeframe_Up variable value
   TimeframeCheck("Timeframe_Up", Timeframe_Up);
//---- Checking the correctness of Timeframe_Dn variable value 
   TimeframeCheck("TimeframeX_Dn", TimeframeX_Dn);
//---- Checking the correctness of Timeframe_Dn variable value 
   TimeframeCheck("Timeframe_Dn", Timeframe_Dn);
//---- Initialization of variables
   MinBarX_Up = 1 + 7;
   MinBar_Up = 4 + 39 + 30;
   MinBarX_Dn = 1 + 7;
   MinBar_Dn = 4 + 39 + 30;                                       
//---- end of initialization
   return(0);
  }
//+==================================================================+
//| expert deinitialization function                                 |
//+==================================================================+  
int deinit()
  {
//----+
   
    //---- End of the EA deinitialization
    return(0);
//----+ 
  }
//+==================================================================+
//| Custom Expert iteration function                                 |
//+==================================================================+
int start()
  {
   //----+ Declaration of local variables
   int    bar;
   double Mov[3], dMov12, dMov23, Mama1, Fama1;
   //----+ declaration of static variables
   static double TrendX_Up, TrendX_Dn;
   static int LastBars_Up, LastBars_Dn, LastBarsX_Up, LastBarsX_Dn;
   static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop;
   
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR LONG POSITIONS                                        |
   //----+ +---------------------------------------------------------------+
   if (Test_Up) 
    {
      int IBARS_Up = iBars(NULL, Timeframe_Up);
      int IBARSX_Up = iBars(NULL, TimeframeX_Up);
      
      if (IBARS_Up >= MinBar_Up && IBARSX_Up >= MinBarX_Up)
       {       
         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Up != IBARSX_Up)
          {
           //----+ Initialization of variables 
           LastBarsX_Up = IBARSX_Up;
           BUY_Stop = false;
           
           //----+ calculating indicator values
           Fama1 = iCustom(NULL, TimeframeX_Up, 
                    "MAMA_NK", FastLimitX_Up, SlowLimitX_Up, IPCX_Up, 0, 1);
           //---         
           Mama1 = iCustom(NULL, TimeframeX_Up, 
                    "MAMA_NK", FastLimitX_Up, SlowLimitX_Up, IPCX_Up, 1, 1);
           //----+ defining trend
           TrendX_Up = Mama1 - Fama1;
           //----+ defining signals for trade closing
           if (TrendX_Up < 0)
                      BUY_Stop = true;                                      
          }
         
         //----+ +----------------------------------------+
         //----+ DEFINING SIGNAL FOR MARKET ENTERING      |
         //----+ +----------------------------------------+
         if (LastBars_Up != IBARS_Up)
          {
           //----+ Initialization of variables 
           BUY_Sign = false;
           LastBars_Up = IBARS_Up; 
           
           //----+ calculating indicator values and uploading them into buffer      
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Up, 
                                "JFatl", Length_Up, Phase_Up, 
                                                   0, IPC_Up, 0, bar);
           
           //----+ defining signals for trades
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
            
           if (TrendX_Up > 0)                     
              if (dMov23 < 0)
                if (dMov12 > 0)
                        BUY_Sign = true;                                    
          }
         
         //----+ +-------------------+
         //----+ EXECUTION OF TRADES |
         //----+ +-------------------+
          if (!OpenBuyOrder1(BUY_Sign, 1, Money_Management_Up, 
                                          STOPLOSS_Up, TAKEPROFIT_Up))
                                                                 return(-1);
          if (ClosePos_Up)
                if (!CloseOrder1(BUY_Stop, 1))
                                        return(-1);
        }
     }
     
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR SHORT POSITIONS                                       |
   //----+ +---------------------------------------------------------------+
   if (Test_Dn) 
    {
      int IBARS_Dn = iBars(NULL, Timeframe_Dn);
      int IBARSX_Dn = iBars(NULL, TimeframeX_Dn);
      
      if (IBARS_Dn >= MinBar_Dn && IBARSX_Dn >= MinBarX_Dn)
       {
         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Dn != IBARSX_Dn)
          {
           //----+ Initialization of variables
           LastBarsX_Dn = IBARSX_Dn;
           SELL_Stop = false;
           
           //----+ calculating indicator values
           Fama1 = iCustom(NULL, TimeframeX_Dn, 
                    "MAMA_NK", FastLimitX_Dn, SlowLimitX_Dn, IPCX_Dn, 0, 1);
           //---         
           Mama1 = iCustom(NULL, TimeframeX_Dn, 
                    "MAMA_NK", FastLimitX_Dn, SlowLimitX_Dn, IPCX_Dn, 1, 1);
           //----+ defining trend
           TrendX_Dn = Mama1 - Fama1;
           //----+ defining signals for trade closing
           if (TrendX_Dn > 0)
                      SELL_Stop = true;                                      
          }
         
         //----+ +----------------------------------------+
         //----+ DEFINING SIGNAL FOR MARKET ENTERING      |
         //----+ +----------------------------------------+
         if (LastBars_Dn != IBARS_Dn)
          {
           //----+ Initialization of variables 
           SELL_Sign = false;
                      LastBars_Dn = IBARS_Dn; 
           
           //----+ calculating indicator values and uploading them into buffer     
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Dn, 
                                "JFatl", Length_Dn, Phase_Dn, 
                                                   0, IPC_Dn, 0, bar);
           
           //----+ defining signals for trades   
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
            
           if (TrendX_Dn < 0)                                 
              if (dMov23 > 0)
                if (dMov12 < 0)
                       SELL_Sign = true;                                         
          }
          
         //----+ +-------------------+
         //----+ EXECUTION OF TRADES |
         //----+ +-------------------+
          if (!OpenSellOrder1(SELL_Sign, 2, Money_Management_Dn, 
                                            STOPLOSS_Dn, TAKEPROFIT_Dn))
                                                                   return(-1);
          if (ClosePos_Dn)
                if (!CloseOrder1(SELL_Stop, 2))
                                        return(-1);
        }
     }
//----+ 
    
    return(0);
  }
//+------------------------------------------------------------------+

尽管此 EA 的基本算法不同于前一个 EA,但这种情况下,使用两个图表的基本理念看上去仍是绝对可行的。



总结

我认为本文所述的自动交易系统构建方法将帮助已有一些 EA 编写经验的读者用最少的精力构建类似的 Expert Advisor。这里还要说明一点,即此类 Expert Advisor 的实用价值很大程度上取决于其正确的优化。


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

附加的文件 |
EXPERTS.zip (19.56 KB)
INCLUDE.zip (25.55 KB)
indicators.zip (14.02 KB)
TESTER.zip (6.72 KB)
非交易 EA 的测试指标 非交易 EA 的测试指标
全部指标可以分为两组:静态指标(一旦显示后始终保持不变,不随新报价变化)和动态指标(仅显示当前时刻的状态,新价格出现时要完全重新绘制)。静态指标的效力在图表上直接可见。但如何检验动态指标的有效性呢?这是本文要探讨的问题。
基于大众交易策略和交易机器人优化点金术的 Expert Advisor(续) 基于大众交易策略和交易机器人优化点金术的 Expert Advisor(续)
在本文中,作者提出了用于改进前面几篇文章介绍的交易系统的方法。本文适用于已有 Expert Advisor 编写经验的交易者。
谬误,第 1 部分:资金管理排第二位,并不是很重要 谬误,第 1 部分:资金管理排第二位,并不是很重要
以 0.1 手为基础的第一次策略测试结果展示正在变成论坛上的事实标准。从专业人士那里获得&ldquo;还不错&rdquo;的评价后,新手会看到&ldquo;0.1&rdquo;测试带来了相当保守的结果,并决定引入一个更积极进取的资金管理方式,以为正数学期望值会自动提供正面的成果。让我们看看会达成什么结果。此外,我们将试着构建多个极具指导意义的人工余额图。
图形行-请求的元语言交易和合格交易学习 图形行-请求的元语言交易和合格交易学习
本文描述了跟传统技术分析兼容且简单可行的图形交易请求语言。随附的 Gterminal 是一个半自动的 Expert Advisor,用于图形分析的交易结果。最好用于自我学习和交易新手的培训。