下载MetaTrader 5

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

17 三月 2016, 11:03
Nikolay Kositsin
0
423

简介

因此,MetaQuotes Software Corp. 于 2008 年 7 月 1 日为 2008 年自动交易锦标赛的参赛者开放注册!如果我错过这个机会,中止我撰写表示 EA 构建原理的系列文章,那就太不合逻辑了。所构建 EA 可满足 2008 年自动交易锦标赛的所有规则,且不会容许竞赛中可能导致失去资格的重大错误!

我自然而然地使用了最简单的建仓算法来实现该事件,在本文中,它的交易因素并不有趣,然而最基础的细微事物可能会成为寻找测试的最重要因素,因为他们可以参加多年后的锦标赛!


编写 EA 的总体思路

在我看来,在我们的例子中,通过详细描述 Expert Advisor 的构造可在其与交易服务器互动时提供正确行为,对 Expert Advisor 做出如此概述最具说服力。锦标赛的规则决定了建仓时的金额和同时等于三的挂单。因此,在一个 EA 内使用三种策略,且每个仓位对应一个策略是相当合理的。

我们将针对开立多头和空头仓位使用带有不同参数的相同算法,每次仅使用这些算法开立一个仓位时,需要我们向其分配相同的幻数。因此,我们将拥有六种算法来进入市场,且仅有三种幻数!我将使用基于本系列文章中 第一篇 的移动平均线方向变化的交易系统作为进入算法。为了让算法各不相同,我在其中使用了不同的移动平均数!


Expert Advisor 代码

以下是 EA 代码的一个版本:

//+==================================================================+
//|                                                 Exp_16_Champ.mq4 |
//|                             Copyright © 2008,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+==================================================================+
#property copyright "Copyright © 2008, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//----+ +-----------------------------------------------------------------------+
//---- EXPERT ADVISOR'S INPUTS FOR BUY TRADES 
extern bool   Test_Up1 = true;//a filter for trades calculation direction
extern int    Timeframe_Up1 = 60;
extern double Money_Management_Up1 = 0.1;
extern int    Length_Up1 = 4;  // smoothing depth 
extern int    Phase_Up1 = 100; // parameter ranging within 
          //-100 ... +100, it affects the quality of the transient process; 
extern int    IPC_Up1 = 0;/* Choosing prices to calculate  
the indicator on (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_Up1 = 50;  // StopLoss
extern int    TAKEPROFIT_Up1 = 100; // TakeProfit
extern bool   ClosePos_Up1 = true; // enable forcible closing the position
//----+ +-----------------------------------------------------------------------+
//---- EXPERT ADVISOR'S INPUTS FOR SELL TRADES 
extern bool   Test_Dn1 = true;//a filter for trades calculation direction
extern int    Timeframe_Dn1 = 60;
extern double Money_Management_Dn1 = 0.1;
extern int    Length_Dn1 = 4;  // smoothing depth 
extern int    Phase_Dn1 = 100; // parameter ranging within
         // -100 ... +100, it affects the quality of the transient process; 
extern int    IPC_Dn1 = 0;/* Choosing prices to calculate 
the indicator on (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_Dn1 = 50;  // StopLoss
extern int   TAKEPROFIT_Dn1 = 100; // TakeProfit
extern bool   ClosePos_Dn1 = true; // enable forcible closing the position
//----+ +-----------------------------------------------------------------------+
//---- EXPERT ADVISOR'S INPUTS FOR BUY TRADES 
extern bool   Test_Up2 = true;//a filter for trades calculation direction
extern int    Timeframe_Up2 = 60;
extern double Money_Management_Up2 = 0.1;
extern int    Length1_Up2 = 4;  // first smoothing depth 
extern int    Phase1_Up2 = 100; // parameter of the first smoothing, 
       //ranging within -100 ... +100, it affects the quality 
       //of the averaging transient;  
extern int    Length2_Up2 = 4;  // second smoothing depth 
extern int    Phase2_Up2 = 100; // parameter of the second smoothing, 
       //ranging within -100 ... +100, it affects the quality 
       //of the averaging transient;  
extern int    IPC_Up2 = 0;/* Choosing prices to calculate 
the indicator on (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_Up2 = 50;  // StopLoss
extern int    TAKEPROFIT_Up2 = 100; // TakeProfit
extern bool   ClosePos_Up2 = true; // enable forcible closing the position
//----+ +-----------------------------------------------------------------------+
//---- EXPERT ADVISOR'S INPUTS FOR SELL TRADES 
extern bool   Test_Dn2 = true;//a filter for trades calculation direction
extern int    Timeframe_Dn2 = 60;
extern double Money_Management_Dn2 = 0.1;
extern int    Length1_Dn2 = 4;  // smoothing depth 
extern int    Phase1_Dn2 = 100;  // parameter of the first smoothing, 
       //ranging within -100 ... +100, it affects the quality 
       //of the averaging transient;  
extern int    Length2_Dn2 = 4;  // smoothing depth 
extern int    Phase2_Dn2 = 100; // parameter of the second smoothing, 
       //ranging within -100 ... +100, it affects the quality 
       //of the averaging transient;  
extern int    IPC_Dn2 = 0;/* Choosing prices to calculate 
the indicator on (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_Dn2 = 50;  // StopLoss
extern int   TAKEPROFIT_Dn2 = 100; // TakeProfit
extern bool   ClosePos_Dn2 = true; // enable forcible closing the position
//----+ +-----------------------------------------------------------------------+
//---- EXPERT ADVISOR'S INPUTS FOR BUY TRADES 
extern bool   Test_Up3 = true;//a filter for trades calculation direction
extern int    Timeframe_Up3 = 60;
extern double Money_Management_Up3 = 0.1;
extern int    Period_Up3 = 10;  // LSMA period
extern int    Length_Up3 = 4;  // smoothing depth 
extern int    Phase_Up3 = 100; // parameter of smoothing, 
       //ranging within -100 ... +100, it affects the quality 
       //of the averaging transient;  
extern int    IPC_Up3 = 0;/* Choosing prices to calculate 
the indicator on (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_Up3 = 50;  // StopLoss
extern int    TAKEPROFIT_Up3 = 100; // TakeProfit
extern bool   ClosePos_Up3 = true; // enable forcible closing the position
//----+ +-----------------------------------------------------------------------+
//---- EXPERT ADVISOR'S INPUTS FOR SELL TRADES 
extern bool   Test_Dn3 = true;//a filter for trades calculation direction
extern int    Timeframe_Dn3 = 60;
extern double Money_Management_Dn3 = 0.1;
extern int    Period_Dn3 = 10;  // LSMA period
extern int    Length_Dn3 = 4;  // smoothing depth 
extern int    Phase_Dn3 = 100;  // parameter smoothing, 
       //ranging within -100 ... +100, it affects the quality 
       //of the averaging transient;  
extern int    IPC_Dn3 = 0;/* Choosing prices to calculate 
the indicator on (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_Dn3 = 50;  // StopLoss
extern int   TAKEPROFIT_Dn3 = 100; // TakeProfit
extern bool   ClosePos_Dn3 = true; // enable forcible closing the position
//----+ +-----------------------------------------------------------------------+

//---- Integer variables for the minimum of estimated bars
int MinBar_Up1, MinBar_Up2, MinBar_Up3;
int MinBar_Dn1, MinBar_Dn2, MinBar_Dn3;
//+==================================================================+
//| Custom Expert functions                                          |
//+==================================================================+
#include <Lite_EXPERT_Champ.mqh>
//+==================================================================+
//| TimeframeCheck() functions                                       |
//+==================================================================+
void TimeframeCheck(string Name, int Timeframe)
  {
//----+
   //---- Checking the value of the 'Timeframe' variable for correctness
   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 values of short-position timeframe variables for correctness
   TimeframeCheck("Timeframe_Up1", Timeframe_Up1);
   TimeframeCheck("Timeframe_Up2", Timeframe_Up2);
   TimeframeCheck("Timeframe_Up3", Timeframe_Up3);

//---- Checking the values of long-position timeframe variables for correctness 
   TimeframeCheck("Timeframe_Dn1", Timeframe_Dn1); 
   TimeframeCheck("Timeframe_Dn2", Timeframe_Dn2); 
   TimeframeCheck("Timeframe_Dn3", Timeframe_Dn3);
   
//---- Initialization of variables             
   MinBar_Up1 = 4 + 39 + 30;
   MinBar_Up2 = 4 + 30;
   MinBar_Up3 = 4 + Period_Up3 + 30;
   
   MinBar_Dn1 = 4 + 39 + 30;
   MinBar_Dn2 = 4 + 30;  
   MinBar_Dn3 = 4 + Period_Dn3 + 30;                                          
//---- initialization complete
   return(0);
  }
//+==================================================================+
//| expert deinitialization function                                 |
//+==================================================================+  
int deinit()
  {
//----+
   
    //---- Expert Advisor initialization complete
    return(0);
//----+ 
  }
//+==================================================================+
//| Custom Expert iteration function                                 |
//+==================================================================+
int start()
  {
   //----+ Declaration of local variables
   int    bar;
   double Mov[3], dMov12, dMov23;
   //----+ Declaration of static variables
   static int LastBars_Up1, LastBars_Dn1;
   static int LastBars_Up2, LastBars_Dn2;
   static int LastBars_Up3, LastBars_Dn3;
   
   static bool BUY_Sign1, BUY_Stop1, SELL_Sign1, SELL_Stop1;
   static bool BUY_Sign2, BUY_Stop2, SELL_Sign2, SELL_Stop2;
   static bool BUY_Sign3, BUY_Stop3, SELL_Sign3, SELL_Stop3;
   
   //+------------------------------------------------------------------------+
   
   //----++ CODE FOR LONG POSITIONS
   if (Test_Up1) 
    {
      int IBARS_Up1 = iBars(NULL, Timeframe_Up1);
      
      if (IBARS_Up1 >= MinBar_Up1)
       {
         if (LastBars_Up1 != IBARS_Up1)
          {
           //----+ Initialization of variables 
           BUY_Sign1 = false;
           BUY_Stop1 = false;
           LastBars_Up1 = IBARS_Up1; 
           
           //----+ CALCULATING THE INDICATORS' VALUES AND LOADING THEM TO BUFFERS        
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Up1, 
                                "JFatl", Length_Up1, Phase_Up1, 
                                                   0, IPC_Up1, 0, bar);
           
           //----+ DETERMINING SIGNALS FOR TRADES 
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
                                          
           if (dMov23 < 0)
              if (dMov12 > 0)
                        BUY_Sign1 = true;
                          
           if (dMov12 < 0)
                        BUY_Stop1 = true;                                           
          }
          //----+ MAKING TRADES
          if (!OpenBuyOrder_Ch(BUY_Sign1, 1, Money_Management_Up1, 
                                          STOPLOSS_Up1, TAKEPROFIT_Up1))
                                                                 return(-1);
          if (ClosePos_Up1)
                if (!CloseOrder_Ch(BUY_Stop1, 1))
                                        return(-1);
        }
     }
     
   //----++ CODE FOR SHORT POSITIONS
   if (Test_Dn1) 
    {
      int IBARS_Dn1 = iBars(NULL, Timeframe_Dn1);
      
      if (IBARS_Dn1 >= MinBar_Dn1)
       {
         if (LastBars_Dn1 != IBARS_Dn1)
          {
           //----+ Initialization of variables 
           SELL_Sign1 = false;
           SELL_Stop1 = false;
           LastBars_Dn1 = IBARS_Dn1; 
           
           //----+ CALCULATING THE INDICATORS' VALUES AND LOADING THEM TO BUFFERS        
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Dn1, 
                                "JFatl", Length_Dn1, Phase_Dn1, 
                                                   0, IPC_Dn1, 0, bar);
           
           //----+ DETERMINING SIGNALS FOR TRADES
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
                                           
           if (dMov23 > 0)
              if (dMov12 < 0)
                       SELL_Sign1 = true;
                          
           if (dMov12 > 0)
                       SELL_Stop1 = true;                                           
          }
          //----+ MAKING TRADES
          if (!OpenSellOrder_Ch(SELL_Sign1, 1, Money_Management_Dn1, 
                                            STOPLOSS_Dn1, TAKEPROFIT_Dn1))
                                                                   return(-1);
          if (ClosePos_Dn1)
                if (!CloseOrder_Ch(SELL_Stop1, 1))
                                          return(-1);
        }
     }
    //+------------------------------------------------------------------------+
    //----++ CODE FOR LONG POSITIONS
   if (Test_Up2) 
    {
      int IBARS_Up2 = iBars(NULL, Timeframe_Up2);
      
      if (IBARS_Up2 >= MinBar_Up2)
       {
         if (LastBars_Up2 != IBARS_Up2)
          {
           //----+ Initialization of variables 
           BUY_Sign2 = false;
           BUY_Stop2 = false;
           LastBars_Up2 = IBARS_Up2; 
           
           //----+ CALCULATING THE INDICATORS' VALUES AND LOADING THEM TO BUFFERS        
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Up2, 
                                "J2JMA", Length1_Up2, Length2_Up2,
                                             Phase1_Up2, Phase2_Up2,  
                                                  0, IPC_Up2, 0, bar);
           
           //----+ DETERMINING SIGNALS FOR TRADES 
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
                                          
           if (dMov23 < 0)
              if (dMov12 > 0)
                        BUY_Sign2 = true;
                          
           if (dMov12 < 0)
                        BUY_Stop2 = true;                                           
          }
          //----+ MAKING TRADES
          if (!OpenBuyOrder_Ch(BUY_Sign2, 2, Money_Management_Up2, 
                                          STOPLOSS_Up2, TAKEPROFIT_Up2))
                                                                 return(-1);
          if (ClosePos_Up2)
                if (!CloseOrder_Ch(BUY_Stop2, 2))
                                          return(-1);
        }
     }
     
   //----++ CODE FOR SHORT POSITIONS
   if (Test_Dn2) 
    {
      int IBARS_Dn2 = iBars(NULL, Timeframe_Dn2);
      
      if (IBARS_Dn2 >= MinBar_Dn2)
       {
         if (LastBars_Dn2 != IBARS_Dn2)
          {
           //----+ Initialization of variables 
           SELL_Sign2 = false;
           SELL_Stop2 = false;
           LastBars_Dn2 = IBARS_Dn2; 
           
           //----+ CALCULATING THE INDICATORS' VALUES AND LOADING THEM TO BUFFERS        
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Dn2, 
                                "J2JMA", Length1_Dn2, Length2_Dn2,
                                               Phase1_Dn2, Phase2_Dn2,  
                                                   0, IPC_Dn2, 0, bar);
           
           //----+ DETERMINING SIGNALS FOR TRADES
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
                                           
           if (dMov23 > 0)
              if (dMov12 < 0)
                       SELL_Sign2 = true;
                          
           if (dMov12 > 0)
                       SELL_Stop2 = true;                                           
          }
          //----+ MAKING TRADES
          if (!OpenSellOrder_Ch(SELL_Sign2, 2, Money_Management_Dn2, 
                                            STOPLOSS_Dn2, TAKEPROFIT_Dn2))
                                                                   return(-1);
          if (ClosePos_Dn2)
                if (!CloseOrder_Ch(SELL_Stop2, 2))
                                           return(-1);
        }
     }
    //+------------------------------------------------------------------------+
    //----++ CODE FOR LONG POSITIONS
   if (Test_Up3) 
    {
      int IBARS_Up3 = iBars(NULL, Timeframe_Up3);
      
      if (IBARS_Up3 >= MinBar_Up3)
       {
         if (LastBars_Up3 != IBARS_Up3)
          {
           //----+ Initialization of variables 
           BUY_Sign3 = false;
           BUY_Stop3 = false;
           LastBars_Up3 = IBARS_Up3; 
           
           //----+ CALCULATING THE INDICATORS' VALUES AND LOADING THEM TO BUFFERS        
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Up3, 
                              "JLSMA", Period_Up3, Length_Up3, Phase_Up3,  
                                                         0, IPC_Up3, 0, bar);
           
           //----+ DETERMINING SIGNALS FOR TRADES 
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
                                          
           if (dMov23 < 0)
              if (dMov12 > 0)
                        BUY_Sign3 = true;
                          
           if (dMov12 < 0)
                        BUY_Stop3 = true;                                           
          }
          //----+ MAKING TRADES
          if (!OpenBuyOrder_Ch(BUY_Sign3, 3, Money_Management_Up3, 
                                          STOPLOSS_Up3, TAKEPROFIT_Up3))
                                                                 return(-1);
          if (ClosePos_Up3)
                if (!CloseOrder_Ch(BUY_Stop3, 3))
                                          return(-1);
        }
     }
     
   //----++ CODE FOR SHORT POSITIONS
   if (Test_Dn3) 
    {
      int IBARS_Dn3 = iBars(NULL, Timeframe_Dn3);
      
      if (IBARS_Dn3 >= MinBar_Dn3)
       {
         if (LastBars_Dn3 != IBARS_Dn3)
          {
           //----+ Initialization of variables 
           SELL_Sign3 = false;
           SELL_Stop3 = false;
           LastBars_Dn3 = IBARS_Dn3; 
           
           //----+ CALCULATING THE INDICATORS' VALUES AND LOADING THEM TO BUFFERS        
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Dn3, 
                              "JLSMA", Period_Dn3, Length_Dn3, Phase_Dn3,  
                                                         0, IPC_Dn3, 0, bar);
                                                         
           //----+ DETERMINING SIGNALS FOR TRADES
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
                                           
           if (dMov23 > 0)
              if (dMov12 < 0)
                       SELL_Sign3 = true;
                          
           if (dMov12 > 0)
                       SELL_Stop3 = true;                                           
          }
          //----+ MAKING TRADES
          if (!OpenSellOrder_Ch(SELL_Sign3, 3, Money_Management_Dn3, 
                                            STOPLOSS_Dn3, TAKEPROFIT_Dn3))
                                                                   return(-1);
          if (ClosePos_Dn3)
                if (!CloseOrder_Ch(SELL_Stop3, 3))
                                          return(-1);
        }
     }
    //+------------------------------------------------------------------------+
//----+ 
    
    return(0);
  }
//+------------------------------------------------------------------+

想获得不受锦标赛规则限制的 EA 的人,可以前往 Exp_16.mq4。实际上,我们可以看到三种算法的交易策略相互之间在某一方面有所区别。总体而言,我们在一个 Expert Advisor 内有完全独立的三个自动化交易策略。编写代码时,我在每个自动交易系统(ATS)中修改了变量名称以避免出现一致。

为进行交易,我使用文件 Lite_EXPERT1.mqh 中的相似函数,这些函数由文件 Lite_EXPERT_Champ.mqh 表示。这些函数要求对他们的代码进行微小更改和纠正,以符合锦标赛的要求。单独在其他参赛者的 EA 代码中使用这些函数的代码是合乎法规的,因为这些代码只是 EA 的执行元素,且和实际控制该等元素的智能填充无关!

所以,并没有特别需求来获得这些函数的所有细节或创建属于你自己的相似函数。阅读我此系列中的早前文章,便足以让你使用这些函数了。总体而言,使用编写 EA 的这些函数和使用芯片进行电子设备开发和制造一样有效。


以下是对构建这些函数时应考虑的要点的简要概述。
1.所有用于建仓和下挂单的函数会检测已开立仓位和已下挂单的数量,如果该数量超过两个,则不会采取任何行动。

2.订单的开仓价位与函数 OpenBuyOrder_Ch(), OpenSellOrder_Ch(), OpenBuyLimitOrder_Ch(), OpenBuyStopOrder_Ch(), OpenSellLimitOrder_Ch() 和 OpenSellStopOrder_Ch() 设置获利位之间的最小距离,总是超出锦标赛规则对剥头皮的规定范围。StopLoss 的最小距离由已交易品种的属性所决定,并由服务器提出申请。这也与挂单相关。然而,你应考虑到有时挂单所处理的价位会比申请价位糟糕的事实。在此情况下,你的获利位可能会进入剥头皮策略的“范围”!所以获利位最好呆在远离剥头皮策略的地方。否则,鉴于许多缺口(很有可能出现在年底),你会发现你的 EA 已直接归入了剥头皮策略的定义!
然而,需要给出启发性提醒的是,如果获利位过大,则 EA 的交易可能过少,从而可能导致 EA 也失去资格!

3.待开立的最大和最小的仓位,以及受锦标赛规则决定的最小更改步骤,都和需要初始化的变量值一同写入所有这些函数中。因此,这些错误已经规避!

4.开立仓位前,函数 OpenBuyOrder_Ch() 和 OpenSellOrder_Ch() 检查仓位的大小并检查仓位本身的保证金金额是否足以匹配其大小,并降低手数至可接受的值。因此,处理这些函数时,你的 EA 在任何情况下都可避免出现诸如“无效交易量”这样的错误。遗憾的是,以这种方式纠正挂单的手数大小是不可能的,因为无法预测从挂单触发起保证金的自由资产量是多少。因此 EA 编写者必须在初始化函数 OpenBuyLimitOrder_Ch(), OpenBuyStopOrder_Ch(), OpenSellLimitOrder_Ch() 和 OpenSellStopOrder_Ch() 外部变量时非常专心,尤其是对于 StopLosses 的大数值。

5.所有用于仓位管理的函数在交易之间根据错误发生代码进行正确暂停。

6.平仓或删除挂单,或移动 StopLosses 前,函数 CloseOrder_Ch(), CloseOrder_Ch() 和 Make_TreilingStop_Ch() 将检查冻结的仓位,如果仓位被冻结,则无需进行任何操作。

7.平仓前,函数 CloseOrder_Ch() 将检查其净盈余没有剥头皮特征。如果发现仓位在剥头皮范围内,则无需进行任何操作。

8.函数 Make_TreilingStop_Ch() 没有将 StopLoss 移入价格范围内,在此范围内由 StopLoss 平仓的盈利可能会进入“剥头皮范围”内。

总结

以上便是所有我想说的关于自动交易锦标赛中 EA 的典型行为。当然,还有一个和 EA 对 CPU 资源过分消耗相关的实际问题。在多数情况下,这个问题通常取决于 EA 在操作过程中调用的无效编写指标。但这是另一个主题了。

本文译自 MetaQuotes Software Corp. 撰写的俄文原文
原文地址: https://www.mql5.com/ru/articles/1542

附加的文件 |
EXPERTS.zip (7.42 KB)
INCLUDE.zip (20.82 KB)
indicators.zip (7.85 KB)
TESTER.zip (4.49 KB)
方便的剥头皮交易 方便的剥头皮交易

本文描述了创建用于进行方便的剥头皮交易工具的方法。但是,这种开始交易的方法可以用于任何交易。

分组文件的操作 分组文件的操作

有时候需要对一组文件执行相同的操作。如果你有包含在一组中的文件列表,则没有问题。但是,如果你需要自己制作列表,问题就出现了:“我该如何去做呢?”文本提出了利用 kernel32.dll 中包含的 FindFirstFile() 和 FindNextFile() 函数实现的方法。

MetaEditor:模板作为支点 MetaEditor:模板作为支点

可一次性为 EA 编写完成所有准备工作并且这些准备工作可供以后持续使用,这对我们很多读者而言可能还有点陌生。

通过 WINAPI 进行文件操作 通过 WINAPI 进行文件操作

MQL4 环境是基于安全“沙盒”概念:通过语言读取和保存文件的功能仅限于部分预定义的文件夹。这将保护 MetaTrader 4 的用户避免 HDD 上的重要数据受到破坏的潜在危险。但是,离开该安全区域有时也是必要的。本文专门介绍如何能够简单而正确地进行该操作。