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

Asesores Expertos basados en sistemas populares de trading, y un poco de alquimia en la optimización de robots (Parte III)

MetaTrader 4Sistemas comerciales | 6 enero 2016, 10:06
678 0
Nikolay Kositsin
Nikolay Kositsin

Introducción

Un lector del artículo anterior me ha pedido que explique cómo se puede automatizar el proceso de backtesting con el objetivo de obtener los resultados de todas las optimizaciones a la vez. Por otra parte, no es recomendable hacer las pruebas manualmente, sino que este proceso se tiene que automatizar. Así que la idea es fantástica. Además, MQL4 ofrece todo lo necesario para esta implementación. Comenzaré pues este artículo intentado solucionar el problema expuesto.


Automatización del backtesting

Para solucionar esta tarea necesitamos lo siguiente:

1. Incluir este archivo en la cabecera del Asesor Experto:

//+==================================================================+
//| Función personalizada de backtesting                             |
//+==================================================================+
#include <IsBackTestingTime.mqh>

Con esta directiva incluimos la función IsBackTestingTime() en el código del EA. Por cierto, no olvide poner el archivo IsBackTestingTime.mqh en la carpeta INCLUDE. Esta función:

bool IsBackTestingTime()
 {
 } 

define el periodo de tiempo donde tiene lugar la optimización de backtesting. En estos periodos de tiempo la función devuelve siempre 'true', y en otros intervalos devuelve 'false'. También se añaden variables externas al código del EA con esta directiva:

//---- Declaración de variables externas para backtesting
extern datetime Start_Time = D'2007.01.01'; // hora de inicio de la optimización
extern int Opt_Period = 3; // periodo de optimización en meses; si es menor que cero, los parámetros son en días.
extern int Test_Period = 2; // periodo de pruebas en meses
extern int Period_Shift = 1; // paso del cambio del periodo de optimización en meses
extern int Opt_Number = 0; // número de optimización

Espero que todos los que han leído mi artículo anterior entiendan bien el significado de estas variables, de modo que no hace falta explicarlo otra vez.

2. Antes de llamar a la función IsBackTestingTime(), el bloque de código de la función de inicio limita la operación del EA a determinados periodos de tiempo de acuerdo al número de optimización de backtesting.

 //----+ Ejecución de las condiciones de backtesting
   if (!IsBackTestingTime())
                       return(0);

Esto se puede representar esquemáticamente de esta manera:

//+==================================================================+
//|                                                 Exp_BackTest.mq4 |
//|                             Copyright © 2008,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+==================================================================+
#property copyright "Copyright © 2008, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//+==================================================================+
//| Función personalizada de backtesting                             |
//+==================================================================+
#include <IsBackTestingTime.mqh>
//---- PARÁMETROS DE ENTRADA DEL EA
//---- VARIABLES GLOBALES DEL EA
//+==================================================================+
//| FUNCIONES DEL EA DEFINIDAS POR EL USUARIO                        |
//+==================================================================+
 
//+==================================================================+
//| Función de inicialización del EA                                 |
//+==================================================================+
int init()
  {
//----+ +------------------------------------------------------------+    
//---- CÓDIGO DE INICIALIZACIÓN DEL EA
//----+ +------------------------------------------------------------+                 
//---- fin de la inicialización
   return(0);
  }
//+==================================================================+
//| Función de iteración del Asesor Experto                          |
//+==================================================================+
int start()
  {
   //----+ Ejecución de las condiciones de backtesting
   if (!IsBackTestingTime())
                       return(0);             
   //----+ +---------------------------------------------------------+    
   //----+ CÓDIGO DEL ALGORITMO DEL EA
   //----+ +---------------------------------------------------------+
//----+ 
    
    return(0);
  }
//+------------------------------------------------------------------+

Si le interesa la solución detallada de este problema eche un vistazo al código de Exp_5_1.mq4, que es el código del EA del artículo anterior, Exp_5.mq4 se ha modificado para el backtesting. En realidad no hay mucha diferencia entre la optimización del EA en comparación con un Asesor Experto sencillo. Sin embargo, a excepción de Opt_Number, creo que las variables de backtesting no se deberían optimizar, aunque posiblemente usted opine de otra manera.

Es importante recordar que después de la optimización, durante las pruebas, obtenemos resultados que no están dentro del período de optimización, sino después del mismo, ¡más allá del límite derecho! No es buena idea optimizar el backtesting de una sola vez con un algoritmo genético; por el contrario, es mucho más interesante analizar profundamente cada optimización de backtesting por separado sin la variable de entrada Opt_Number.

Pero incluso en este caso, tal aproximación facilita la comprensión del comportamiento del EA. Recuerde que el valor de la variable externa Opt_Number puede variar desde cero hasta un determinado valor máximo que se define del siguiente modo: tomar el periodo total en que se llevan a cabo todas las optimizaciones de backtesting (en meses) y restar el periodo de optimización de backtesting en meses (Opt_Period) y el periodo de backtesting (Test_Period). Añada uno al valor obtenido. El resultado obtenido es el máximo de la variable Opt_Number, si Period_Shift vale uno.


Sistemas de trading basados en el cruce de dos medias móviles

Esta variante de sistema de trading es bastante popular. Ahora vamos a analizar el algoritmo subyacente de estas estrategias. Este es el algoritmo de entrada para las posiciones largas:

Para las posiciones cortas es así:

Se pueden utilizar dos medias móviles idénticas con parámetros diferentes a modo de indicadores. Se asume que el parámetro que define la promediación de la media MovA siempre es más pequeño que el de la media MovB. Así, en este sistema de trading MovA es la media rápida y MovB es la media lenta. Esta es la implementación de la variante basada en dos medias JMA:

//+==================================================================+
//|                                                        Exp_6.mq4 |
//|                             Copyright © 2007,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+==================================================================+
#property copyright "Copyright © 2007, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//----+ +-------------------------------------------------------------------------------+
//---- PARÁMETROS DE ENTRADA DEL EA PARA LAS POSICIONES DE COMPRA 
extern bool   Test_Up = true;//filtro de la dirección de cálculo
extern int    Timeframe_Up = 240;
extern double Money_Management_Up = 0.1;
extern int    LengthA_Up = 4;  // profundidad de suavizado de la media rápida
extern int    PhaseA_Up = 100; // parámetro que varía en el rango 
          //-100 ... +100, influye en la calidad del proceso de transición de la media rápida
extern int    IPCA_Up = 0;/* Selección de precios donde se calcula el indicador 
por la media rápida (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    LengthB_Up = 4; // incremento de la profundidad de suavizado de la media lenta
extern int    PhaseB_Up = 100; // parámetro que varía en el rango 
          //-100 ... +100, influye en la calidad del proceso de transición de la media lenta; 
extern int    IPCB_Up = 0;/* Selección de precios donde se calcula el indicador 
por la media lenta (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; // cierre de posición forzado permitido
//----+ +-------------------------------------------------------------------------------+
//---- PARÁMETROS DE ENTRADA DEL EA PARA LAS POSICIONES DE VENTA 
extern bool   Test_Dn = true;//filtro de la dirección de cálculo
extern int    Timeframe_Dn = 240;
extern double Money_Management_Dn = 0.1;
extern int    LengthA_Dn = 4;  // profundidad de suavizado de la media rápida
extern int    PhaseA_Dn = 100; // parámetro que varía en el rango
         // -100 ... +100, influye en la calidad del proceso de transición de la media rápida; 
extern int    IPCA_Dn = 0;/* Selección de precios donde se calcula el indicador 
por la media rápida (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    LengthB_Dn = 4; // incremento de la profundidad de suavizado de la media lenta
extern int    PhaseB_Dn = 100; // parámetro que varía en el rango
         // -100 ... +100, influye en la calidad del proceso de transición de la media lenta; 
extern int    IPCB_Dn = 0;/* Selección de precios donde se calcula el indicador 
por la media lenta(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; // cierre de posición forzado permitido
//----+ +-------------------------------------------------------------------------------+
//---- Variables enteras para el cálculo mínimo de las barras
int MinBar_Up, MinBar_Dn;
//+==================================================================+
//| Funciones personalizadas del Asesor Experto                      |
//+==================================================================+
#include <Lite_EXPERT1.mqh>
//+==================================================================+
//| Función de inicialización del EA                                 |
//+==================================================================+
int init()
  {
//---- Comprobación del valor de la variable Timeframe_Up
   if (Timeframe_Up != 1)
    if (Timeframe_Up != 5)
     if (Timeframe_Up != 15)
      if (Timeframe_Up != 30)
       if (Timeframe_Up != 60)
        if (Timeframe_Up != 240)
         if (Timeframe_Up != 1440)
           Print(StringConcatenate("El parámetro Timeframe_Up no puede ",  
                                  "ser igual a ", Timeframe_Up, "!!!"));
//---- Comprobación del valor de la variable Timeframe_Dn 
   if (Timeframe_Dn != 1)
    if (Timeframe_Dn != 5)
     if (Timeframe_Dn != 15)
      if (Timeframe_Dn != 30)
       if (Timeframe_Dn != 60)
        if (Timeframe_Dn != 240)
         if (Timeframe_Dn != 1440)
           Print(StringConcatenate("El parámetro Timeframe_Dn no puede ",  
                                 "ser igual a ", Timeframe_Dn, "!!!")); 
//---- Inicialización de variables            
   MinBar_Up = 4 + 30;
   MinBar_Dn = 4 + 30;                                        
//---- fin de la inicialización
   return(0);
  }
//+==================================================================+
//| Función de desinicialización del EA                              |
//+==================================================================+  
int deinit()
  {
//----+
   
    //---- Fin de la desinicialización del EA
    return(0);
//----+ 
  }
//+==================================================================+
//| Función de iteración del Asesor Experto                          |
//+==================================================================+
int start()
  {
   //----+ Declaración de variables locales
   int    bar;
   double MovA[2], MovB[2];
   //----+ Declaración de variables estáticas
   static int LastBars_Up, LastBars_Dn;
   static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop;
   
   //----++ CÓDIGO DE LAS POSICIONES LARGAS
   if (Test_Up)
    {
      int IBARS_Up = iBars(NULL, Timeframe_Up);
      
      if (IBARS_Up >= MinBar_Up)
       {
         if (LastBars_Up != IBARS_Up)
          {
           //----+ Inicialización de variables 
           BUY_Sign = false;
           BUY_Stop = false;
           LastBars_Up = IBARS_Up;
           
           //----+ CÁLCULO DE LOS VALORES DEL INDICADOR Y SUBIDA A LOS BÚFERES        
           for(bar = 1; bar < 3; bar++)
                     MovA[bar - 1] =                  
                         iCustom(NULL, Timeframe_Up, 
                                "JJMA", LengthA_Up, PhaseA_Up, 
                                                   0, IPCA_Up, 0, bar);
           for(bar = 1; bar < 3; bar++)
                MovB[bar - 1] =                  
                   iCustom(NULL, Timeframe_Up, 
                     "JJMA", LengthA_Up + LengthB_Up, PhaseB_Up, 
                                                   0, IPCB_Up, 0, bar);
                                                   
           //----+ DEFINICIÓN DE SEÑALES DE TRADING                                          
           if ( MovA[1] < MovB[1])
               if ( MovA[0] > MovB[0])
                        BUY_Sign = true;
                          
            if ( MovA[0] > MovB[0])
                        BUY_Stop = true;                                           
          }
          
          //----+ EJECUCIÓN DE SEÑALES
          if (!OpenBuyOrder1(BUY_Sign, 1, Money_Management_Up, 
                                          STOPLOSS_Up, TAKEPROFIT_Up))
                                                                 return(-1);
          if (ClosePos_Up)
                if (!CloseOrder1(BUY_Stop, 1))
                                        return(-1);
        }
     }
     
   //----++ CÓDIGO DE LAS POSICIONES CORTAS
   if (Test_Dn)
    {
      int IBARS_Dn = iBars(NULL, Timeframe_Dn);
      
      if (IBARS_Dn >= MinBar_Dn)
       {
         if (LastBars_Dn != IBARS_Dn)
          {
           //----+ Inicialización de variables 
           SELL_Sign = false;
           SELL_Stop = false;
           LastBars_Dn = IBARS_Dn; 
           
           //----+ CÁLCULO DE LOS VALORES DEL INDICADOR Y SUBIDA A LOS BÚFERES
           for(bar = 1; bar < 3; bar++)
                     MovA[bar - 1] =                  
                         iCustom(NULL, Timeframe_Dn, 
                                "JJMA", LengthA_Dn, PhaseA_Dn, 
                                                   0, IPCA_Dn, 0, bar);
           for(bar = 1; bar < 3; bar++)
                MovB[bar - 1] =                  
                   iCustom(NULL, Timeframe_Dn, 
                     "JJMA", LengthA_Dn + LengthB_Dn, PhaseB_Dn, 
                                                   0, IPCB_Dn, 0, bar);
           
           //----+ DEFINICIÓN DE SEÑALES DE TRADING                                          
           if ( MovA[1] > MovB[1])
               if ( MovA[0] < MovB[0])
                        SELL_Sign = true;
                          
            if ( MovA[0] < MovB[0])
                        SELL_Stop = true;                                                
          }
          //----+ EJECUCIÓN DE SEÑALES
          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);
  }
//+------------------------------------------------------------------+

Sistemas de trading basados en el cruce de dos osciladores


Esta estrategia comercial se puede utilizar con medias móviles y con osciladores; en este caso último, como escribí en el artículo anterior, es mejor colocar órdenes pendientes en vez de entrar al mercado inmediatamente cuando se reciben las señales. A modo de ejemplo se puede utilizar un diagrama MACD.

El siguiente algoritmo coloca órdenes pendientes BuyLimit:

Y este es el algoritmo de las órdenes de tipo SellLimit:

El código de este EA se parece al del anterior:
//+==================================================================+
//|                                                        Exp_7.mq4 |
//|                             Copyright © 2007,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+==================================================================+
#property copyright "Copyright © 2007, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//----+ +---------------------------------------------------------------------------+
//---- PARÁMETROS DE ENTRADA PARA LAS OPERACIONES DE COMPRA 
extern bool   Test_Up = true; // filtro de dirección de cálculo
extern int    Timeframe_Up = 240;
extern double Money_Management_Up = 0.1;
extern int    FST_period_Up = 12;  // periodo de la media rápida
extern int    SLO_period_Up = 22; // incremento del periodo de la media lenta
extern int    SIGN_period_Up = 8; // periodo de la línea de señal
extern int    Price_Up = 0;  // selección de precios con los que se calcula MACD
extern int    STOPLOSS_Up = 50;  // stop loss
extern int    TAKEPROFIT_Up = 100; // take profit
extern int    PriceLevel_Up =40; // diferencia entre el precio actual y 
                                         // el precio de lanzamiento de la orden pendiente
extern bool   ClosePos_Up = true; // cierre forzado de la posición permitido
//----+ +---------------------------------------------------------------------------+
//---- PARÁMETROS DE ENTRADA DEL EA PARA LAS POSICIONES DE VENTA 
extern bool   Test_Dn = true; // filtro de dirección de cálculo
extern int    Timeframe_Dn = 240;
extern double Money_Management_Dn = 0.1;
extern int    FST_period_Dn = 12;  // periodo de la media rápida
extern int    SLO_period_Dn = 22; // incremento del periodo de la media lenta
extern int    SIGN_period_Dn = 8; // periodo de la línea de señal
extern int    Price_Dn = 0;  // selección de precios con los que se calcula MACD
extern int    STOPLOSS_Dn = 50;  // stop loss
extern int    TAKEPROFIT_Dn = 100; // take profit
extern int    PriceLevel_Dn =40;  // diferencia entre el precio actual y 
                                         // el precio de lanzamiento de la orden pendiente
extern bool   ClosePos_Dn = true; // cierre forzado de la posición permitido
//----+ +---------------------------------------------------------------------------+
//---- Variables enteras para el cálculo mínimo de las barras
int MinBar_Up, MinBar_Dn;
//+==================================================================+
//| Funciones personalizadas del Asesor Experto                      |
//+==================================================================+
#include <Lite_EXPERT1.mqh>
//+==================================================================+
//| Función de inicialización del Asesor Experto                     |
//+==================================================================+
int init()
  {
//---- Comprobación del valor de la variable Timeframe_Up
   if (Timeframe_Up != 1)
    if (Timeframe_Up != 5)
     if (Timeframe_Up != 15)
      if (Timeframe_Up != 30)
       if (Timeframe_Up != 60)
        if (Timeframe_Up != 240)
         if (Timeframe_Up != 1440)
           Print(StringConcatenate("El parámetro Timeframe_Up no puede ",  
                                  "ser igual a ", Timeframe_Up, "!!!"));
//---- Comprobación del valor de la variable Timeframe_Dn 
   if (Timeframe_Dn != 1)
    if (Timeframe_Dn != 5)
     if (Timeframe_Dn != 15)
      if (Timeframe_Dn != 30)
       if (Timeframe_Dn != 60)
        if (Timeframe_Dn != 240)
         if (Timeframe_Dn != 1440)
           Print(StringConcatenate("El parámetro Timeframe_Dn no puede ",  
                                 "ser igual a ", Timeframe_Dn, "!!!")); 
//---- Inicialización de variables             
   MinBar_Up = 4 + FST_period_Up + SLO_period_Up + SIGN_period_Up;
   MinBar_Dn = 4 + FST_period_Dn + SLO_period_Dn + SIGN_period_Dn;                                        
//---- fin de la inicialización
   return(0);
  }
//+==================================================================+
//| función de desinicialización del experto                         |
//+==================================================================+  
int deinit()
  {
//----+
   
    //---- Fin de desinicialización del EA
    return(0);
//----+ 
  }
//+==================================================================+
//| Función de iteración del Asesor Experto                          |
//+==================================================================+
int start()
  {
   //----+ Declaración de variables locales
   int    bar;
   double MovA[2], MovB[2];
   //----+ Declaración de variables estáticas
   static int LastBars_Up, LastBars_Dn;
   static datetime StopTime_Up, StopTime_Dn; 
   static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop;
   
   //----++ CÓDIGO DE LAS POSICIONES LARGAS
   if (Test_Up)
    {
      int IBARS_Up = iBars(NULL, Timeframe_Up);
      
      if (IBARS_Up >= MinBar_Up)
       {
         if (LastBars_Up != IBARS_Up)
          {
           //----+ Inicialización de variables 
           BUY_Sign = false;
           BUY_Stop = false;
           LastBars_Up = IBARS_Up;
           StopTime_Up = iTime(NULL, Timeframe_Up, 0)
                                            + 60 * Timeframe_Up;
           
           //----+ CÁLCULO DE LOS VALORES DEL INDICADOR Y SUBIDA A LOS BÚFERES           
           for(bar = 1; bar < 3; bar++)
             MovA[bar - 1] = iMACD(NULL, Timeframe_Up, 
                      FST_period_Up, FST_period_Up + SLO_period_Up,
                                         SIGN_period_Up, Price_Up, 0, bar);
                          
           for(bar = 1; bar < 3; bar++)
             MovB[bar - 1] = iMACD(NULL, Timeframe_Up, 
                      FST_period_Up, FST_period_Up + SLO_period_Up,
                                         SIGN_period_Up, Price_Up, 1, bar);
                 
           //----+ DEFINICIÓN DE SEÑALES DE TRADING                                          
           if ( MovA[1] < MovB[1])
               if ( MovA[0] > MovB[0])
                        BUY_Sign = true;
                          
            if ( MovA[0] > MovB[0])
                        BUY_Stop = true;                                           
          }
          
          //----+ EJECUCIÓN DE SEÑALES
          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);
        }
     }
     
   //----++ CÓDIGO DE LAS POSICIONES CORTAS
   if (Test_Dn)
    {
      int IBARS_Dn = iBars(NULL, Timeframe_Dn);
      
      if (IBARS_Dn >= MinBar_Dn)
       {
         if (LastBars_Dn != IBARS_Dn)
          {
           //----+ Inicialización de variables 
           SELL_Sign = false;
           SELL_Stop = false;
           LastBars_Dn = IBARS_Dn;
           StopTime_Dn = iTime(NULL, Timeframe_Dn, 0) 
                                            + 60 * Timeframe_Dn; 
           
           //----+ CÁLCULO DE LOS VALORES DEL INDICADOR Y SUBIDA A LOS BÚFERES          
           for(bar = 1; bar < 3; bar++)
             MovA[bar - 1] = iMACD(NULL, Timeframe_Dn, 
                      FST_period_Dn, FST_period_Dn + SLO_period_Dn,
                                         SIGN_period_Dn, Price_Dn, 0, bar);
                          
           for(bar = 1; bar < 3; bar++)
             MovB[bar - 1] = iMACD(NULL, Timeframe_Dn, 
                      FST_period_Dn, FST_period_Dn + SLO_period_Dn,
                                         SIGN_period_Dn, Price_Dn, 1, bar);
           
           //----+ DEFINICIÓN DE SEÑALES DE TRADING                                          
           if ( MovA[1] > MovB[1])
               if ( MovA[0] < MovB[0])
                        SELL_Sign = true;
                          
            if ( MovA[0] < MovB[0])
                        SELL_Stop = true;                                                
          }
          //----+ EJECUCIÓN DE SEÑALES
          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);
        }
     }
//----+ 
    
    return(0);
  }
//+------------------------------------------------------------------+


Conclusión

Llegados aquí ya podemos terminar este artículo. Hemos implementado una nueva variante de sistema de trading en forma de Asesor Experto combinando indicadores. Espero que este artículo sirva de ayuda a los programadores principiantes de EA. Con lo expuesto aquí usted podrá mejorar sus habilidades, y le ayudará a tomar ideas para convertir algoritmos correctamente formalizados en Asesores Expertos completamente funcionales.

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

Archivos adjuntos |
EXPERTS.zip (8.58 KB)
INCLUDE.zip (17.88 KB)
indicators.zip (5.19 KB)
TESTER.zip (5.27 KB)
Diagnóstico de mercado por pulsos Diagnóstico de mercado por pulsos
En este artículo intentamos visualizar la intensidad de algunos mercados en particular, así como sus sus periodos de tiempo. El objetivo es detectar sus regularidades y patrones de comportamiento.
Un ayudante para el trader basado en un análisis MACD ampliado Un ayudante para el trader basado en un análisis MACD ampliado
El script 'Trader's Assistant' (ayudante del trader), que sirve para tomar decisiones en la apertura de operaciones, se basa en un análisis ampliado del estado de MACD en las tres últimas barras de cualquier marco temporal. También se puede utilizar en backtesting.
Teoría del mercado Teoría del mercado
A día de hoy, aún no existe una teoría del mercado lógica y definitiva, que abarque todos los tipos y variedades de mercados de mercancías y servicios, micro y macro mercados, semejantes a fórex. El artículo habla de la esencia de la nueva teoría del mercado, basada en el análisis del beneficio; descubre las leyes del cambio del precio actual, y también revela el principio de funcionamiento del mecanismo que permite al precio encontrar su valor óptimo, mediante la formación de una cadena de precios virtuales, capaces de generar un efecto de control sobre el propio precio. Los mecanismos de formación y cambio de las tendencias en el mercado han sido desvelados.
Análisis comparativo de 30 indicadores y osciladores Análisis comparativo de 30 indicadores y osciladores
El presente artículo describe el funcionamiento de un Asesor Experto que realiza el análisis comparativo de 30 indicadores y osciladores. El objetivo es compilar un paquete de índices eficaz para hacer trading.