English Русский 中文 Deutsch 日本語 Português
Asesores expertos basados en sistemas de trading populares y alquimia de la optimización de robots de trading (Parte VII)

Asesores expertos basados en sistemas de trading populares y alquimia de la optimización de robots de trading (Parte VII)

MetaTrader 4Sistemas comerciales | 20 abril 2016, 14:57
684 0
Nikolay Kositsin
Nikolay Kositsin

Introducción

De este modo, MetaQuotes Software Corp. dio inicio al registro para participar en el Campeonato de Trading Automatizado de 2008 el 1 de julio de 2008. Sería algo intrascendente para mi perderme esta oportunidad y no seguir con la serie de artículos de la representación de la lógica en la creación de un asesor experto que cumpla formalmente todas las Reglas del Campeonato de Trading Automatizado de 2008 y que no admitiera ningún error crítico durante el concurso, por el que podría quedar descalificado.

Es muy natural que para la realización de este evento yo use los algoritmos más sencillos para abrir posiciones cuyos factores de trading no sean realmente interesantes para nosotros en el contexto de este artículo, mientras que las pequeñas cosas más elementas pueden ser más importantes para buscar el examen, ya que pueden suponer la participación de uno en el Campeonato varios años después.


Idea general de la escritura de un asesor experto

En mi opinión, será más ilustrativo en nuestro caso esbozar dicho asesor experto con una descripción detallada de su creación que realmente proporcionara su comportamiento correcto en su interacción con el servidor de trading. Las Reglas del Campeonato determinan la cantidad de posiciones abiertas y órdenes pendientes colocadas simultáneamente, siendo estas iguales a tres. Por tanto, sería razonable usar tres estrategias en un asesor experto, una por posición.

Usaremos los mismos algoritmos con distintos parámetros para abrir posiciones largas y cortas, mientras que hacer que estos algoritmos abran solo una posición al mismo tiempo requiere que los asignemos a los mismos números mágicos. De este modo, tendremos seis algoritmos para entrar al mercado y solo tres números mágicos. Como algoritmo de entrada, uso un sistema de trading basado en el cambio de la dirección de la media móvil de mi primer artículo en esta serie. Para que el algoritmo sea distinto en cada caso, uso distintas medias móviles en ellos.


Código del asesor experto

Esta es una versión del código del asesor experto:

//+==================================================================+
//|                                                 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);
  }
//+------------------------------------------------------------------+

Aquellos que quieran tener un asesor experto sin las limitaciones indicadas en el Campeonato, pueden optar por Exp_16.mq4. De hecho, podemos ver la variedad de estrategias de trading entre tres algoritmos distintos entre sí de cierta manera. En general, tenemos tres estrategias de trading automatizado absolutamente independientes en un asesor experto. Cuando escribí el código, modifiqué los nombres de las variables en cada estrategia de trading automatizado para evitar coincidencias.

Para hacer transacciones, usé funciones similares a las del archivo Lite_EXPERT1.mqh, que vienen representadas en el archivo Lite_EXPERT_Champ.mqh. Estas funciones requirieron cambios y correcciones mínimos en sus códigos para cumplir los requisitos del Campeonato. Solo usar el código de dichas funciones en los códigos de los asesores expertos de otros participantes es completamente legal, ya que son solo elementos ejecutivos del asesor experto, que no guardan relación con el aspecto intelectual que realmente controla estos elementos.

Por tanto, no hay ninguna necesidad especial de entrar en los detalles de estas funciones o crear algo similar. Sería suficiente leer mis artículos anteriores de esta serie para poder usarlas. En general, el uso de estas funciones en la escritura de asesores expertos es tan efectivo como el uso de chips en el desarrollo y fabricación de dispositivos electrónicos.


A continuación se indica una breve descripción de que se ha considerado en la construcción de estas funciones.
1. Todas las funciones para abrir posiciones y colocar órdenes pendientes detectan la cantidad de posiciones ya abiertas y órdenes pendientes colocadas y, si su cantidad supera las dos, no realiza ninguna acción

2. La distancia mínima desde el precio de apertura de la orden en el que las funciones OpenBuyOrder_Ch(), OpenSellOrder_Ch(), OpenBuyLimitOrder_Ch(), OpenBuyStopOrder_Ch(), OpenSellLimitOrder_Ch() y OpenSellStopOrder_Ch() colocan TakeProfit, siempre es superior que la definida por las Reglas del Campeonato como una especulación. La distancia mínima a StopLoss viene determinada por las propiedades del símbolo de la transacción y es solicitada desde el servidor. Esto también se refiere a las órdenes pendientes. No obstante, debemos tener en cuenta el hecho de que las órdenes pendientes se procesan algunas veces en precios que resultan ser peores que los solicitados. Nuestras TakeProfits pueden entrar en el 'rango' de una estrategia de especulación en este caso. Por tanto, sería mejor apartarse de las estrategias de especulación. De lo contrario, en una buena cantidad de espacios (lo que es bastante posible al final del año) podemos descubrir que nuestro asesor experto ha aparecido bajo la definición de una estrategia especulativa.
No obstante, sería instructivo recordar que, si las TakeProfits son demasiado grandes, el asesor experto puede que realice muy pocas transacciones, lo que puede provocar también su descalificación.

3. El tamaño menor y mayor de una posición a abrir, así como el paso mínimo de los cambios determinados por las reglas del Campeonato se escriben en todas estas funciones con los valores de las variables a inicializar. Por tanto, dichos errores ya han sido evitados.

4. Antes de abrir una posición, las funciones OpenBuyOrder_Ch() y OpenSellOrder_Ch() comprueban el tamaño de esta posición y la propia posición por si hubiera el dinero suficiente en el depósito para dicho tamaño y reducir la cantidad de lotes a valores aceptables. Por tanto, cuando trabaja con estas funciones, nuestro asesor experto está exento de errores como "volumen de transacciones no válido" en cualquier caso. Por desgracia, es imposible corregir el tamaño del lote en las órdenes pendientes de esta forma, ya que es imposible predecir la cantidad de activos libres en el depósito en el momento de activarse la orden pendiente. Por tanto, un escritor de asesores expertos puede estar muy atento cuando se inicializan las variables externas 'Money_Management' de las funciones OpenBuyLimitOrder_Ch(), OpenBuyStopOrder_Ch(), OpenSellLimitOrder_Ch() y OpenSellStopOrder_Ch(), especialmente por los grandes valores de las StopLoss.

5. Todas las funciones para la gestión de posiciones mantienen pausas correctas entre transacciones de acuerdo con los códigos de error que se producen.

6. Antes de cerrar una posición o borrar una orden pendiente, o desplazar las StopLoss, las funciones CloseOrder_Ch(), CloseOrder_Ch() y Make_TreilingStop_Ch() comprueban que la posición esté bloqueada, si está bloqueada, no realizan ninguna acción.

7. Antes de cerrar una posición, la función CloseOrder_Ch() comprueba su ganancia neta para que no sea de tipo especulativa. Si las posiciones resultan estar dentro del rango de especulación, no realiza ninguna acción.

8. La función Make_TreilingStop_Ch() no mueve a StopLoss en el rango de precio en el que el beneficio de la posición cerrada por esta StopLoss pueda quedar dentro del 'rango de especulación'.

Conclusión

Bueno, ahí está todo lo que quería decir sobre el comportamiento ejemplar de un asesor experto en el Campeonato de Trading Automatizado. Por supuesto, hay un problema más, uno más real que tiene que ver con el exuberante consumo de recursos de la CPU. No obstante, en la mayoría de casos, este problema suele depender de indicadores escritos de forma poco eficaz a los que llama el asesor experto durante su funcionamiento. Y este es un par de zapatos completamente distinto.

Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/1542

Archivos adjuntos |
EXPERTS.zip (7.42 KB)
INCLUDE.zip (20.82 KB)
indicators.zip (7.85 KB)
TESTER.zip (4.49 KB)
Operaciones con grupos de archivos Operaciones con grupos de archivos
Algunas veces es necesario realizar las mismas operaciones con un grupo de archivos. Si tenemos una lista de archivos en un grupo, esto no es un problema. Sin embargo, si necesitamos hacer esta lista nosotros mismos, surge la pregunta: &quot;¿C&oacute;mo podemos hacerlo?&quot; El art&iacute;culo propone hacerlo mediante las funciones FindFirstFile() y FindNextFile() incluidas en kernel32.dll.
Operaciones de archivo a través de WinAPI Operaciones de archivo a través de WinAPI
El entorno de MQL4 se basa en el concepto de "sandbox" seguro: solo está permitido leer y guardar archivos usando el lenguaje en algunas carpetas preestablecidas. Esto protege al usuario de MetaTrader 4 del peligro potencial de dañar datos importantes en el disco duro. No obstante, a veces es necesario dejar esa área segura. Este artículo está dedicado al problema de cómo hacerlo de una forma fácil y correcta.
Repaso de HTML usando MQL4 Repaso de HTML usando MQL4
Hoy d&iacute;a, HTML es uno de los tipos de documentos m&aacute;s utilizados. El terminal de cliente de MetaTrader 4 nos permite guardar las declaraciones, informes de pruebas y optimizaciones como archivos .html. A veces es necesario para obtener informaci&oacute;n de dichos archivos en un programa MQL4. El art&iacute;culo describe una de las variantes de c&oacute;mo obtener la estructura y contenidos de HTML.
Cambiar los parámetros externos de los programas de MQL4 sin reiniciar Cambiar los parámetros externos de los programas de MQL4 sin reiniciar
El artículo describe un método para cambiar los parámetros externos de los programas de MQL4 sobre la marcha, sin reiniciar.