English Русский 中文 Deutsch 日本語 Português
Rayos Elder (Bulls Power y Bears Power)

Rayos Elder (Bulls Power y Bears Power)

MetaTrader 5Ejemplos | 4 diciembre 2018, 15:36
1 734 0
Vladimir Karputov
Vladimir Karputov

Introducción

El sistema comercial Rayos Elder (Elder-Ray) fue descrito por Alexander Elder en su libro "Vivir del Trading" (Trading for a living). Dicho sistema se basa en los osciladores Bulls Power (índice de fuerza alcista), Bears Power (índice de fuerza bajista) y el indicador de tendencia Moving Average (EMA — promediación exponencial).

El sistema comercial es sencillo y complejo al mismo tiempo:

  • sencillo si lo leemos y percibimos literalmente: señal de compra — la tendencia va hacia arriba (EMA) y Bears Power (índice de fuerza bajista) está por debajo de cero, pero aumenta;
  • complejo, si leemos con mayor atención, y además miramos el gráfico en el que están iniciados tanto EMA, como Bears Power: resulta que no todo es tan sencillo, y se dan muy pocos casos así.

En este artículo vamos a pasar por todas las etapas partiendo de lo simple hacia lo complicado, y comprobando las dos variedades del sistema comercial: 

  1. todos los indicadores están en un mismo gráfico (y, por lo tanto, en un mismo marco temporal);
  2. en combinación con el sistema "Selección triple".

Los asesores del artículo están orientados al trabajo solo con las cuentas de compensación. 


Postulados principales

Para entender la esencia del sistema comercial es necesario asimilar claramente qué representa cada elemento de los Rayos Elder: el precio, la EMA, el máximo y el mínimo de los indicadores Bulls Power y Bears Power en cada barra, la fuerza alcista y bajista.

  • Precio — acuerdo momentáneo sobre el coste actual de un activo. Todas las compras se realizan esperando el aumento del precio, mientras que todas las ventas se realizan en previsión de la caída del precio. Solo cuando el comprador está de acuerdo con la compra, y el vendedor con la venta, se realiza la transacción.
  • EMA — media móvil exponencial. Representa el acuerdo medio sobre el coste de un activo en un intervalo determinado. Por ejemplo, la EMA(13) con el marco temporal D1 supone el acuerdo medio sobre el precio de un activo en los últimos 13 días. ¿Por qué es mejor usar una media móvil exponencial, y no una simple? А. Elder responde a esta pregunta en el capítulo 4.2 ("Media móvil"). Siendo breves: la EMA es más sensible a los cambios de tendencia que la media simple.
  • El máximo en Bulls Power muestra la fuerza alcista máxima en esta barra. Cuando el precio crece, los alcistas ganan dinero, porque los alcistas compran, hasta que el precio no ascienda al máximo. El máximo en Bulls Power representa el momento en el que los alcistas tienen deseo de mover el precio más arriba, pero ya no hay dinero.
  • El mínimo en Bears Power muestra la fuerza bajista máxima en la barra dada. Los bajistas ganan dinero cuando el precio cae, y por eso venden hasta que el precio no alcance su mínimo. El mínimo en Bears Power es el momento en el que los alcistas tiene deseo de mover el precio hacia abajo, pero ya no hay posibilidad.
  • La fuerza alcista muestra la capacidad de los alcistas de aumentar el precio sobre el acuerdo medio sobre el coste de un activo. Normalmente, la fuerza alcista es superior a cero; si es menor, significa que a las fuerzas alcistas les ha entrado el pánico y se están hundiendo.
  • La fuerza bajista muestra la capacidad de los bajistas de disminuir el precio por debajo del acuerdo medio sobre el coste de un activo. Normalmente, la fuerza alcista es inferior a cero; si es superior, significa que los alcistas están venciendo a los bajistas por el momento.


Opción 1: todos los indicadores en un mismo gráfico

Vamos a investigar los futuros y acciones en el marco temporal D1. Los tres indicadores (Bulls Power, Bears Power y EMA) se ubican en un mismo gráfico. El periodo de promediación de los tres indicadores es de 13.


Reglas para la compra

  • la tendencia va hacia arriba (nos orientaremos según el indicador EMA);
  • el índice de la fuerza bajista (Bears Power) está por debajo de cero, pero está asciendo;
  • una orden pendiente Buy stop se ubica por encima del máximo de los dos últimos días, y el stop-loss de protección se coloca por debajo del último mínimo.

CATDaily Buy signals

CAT, Daily Buy signals

Reglas para la venta

  • la tendencia va hacia abajo (nos apoyaremos en el indicador EMA);
  • el índice de fuerza alcista (Bulls Power) está por encima de cero, pero está descendiendo;
  • una orden pendiente Sell stop se ubica por debajo del mínimo de los dos últimos días, y el stop-loss de protección se coloca por encima del último máximo.

CATDaily Sell signal

CAT, Daily Sell signals


Reglas comerciales

Según las figuras 1 y 2, podemos notar que en la variante del sistema comercial "Todos los indicadores en un gráfico", las normas para la compra y para la venta se activan en los retrocesos de una tendencia estable. Y esos momentos favorables son bastante escasos, tanto más cuanto el marco temporal analizado es D1. Por eso, en la variante "Todos los indicadores en un gráfico" resulta necesario realizar el análisis de un gran número de instrumentos para aumentar la frecuencia de transacciones en la cuenta comercial.

No obstante, en los gráficos D1 hay una ventaja considerable: el análisis de la inclinación de la EMA y las lecturas de los indicadores Bulls Power y Bears Power se puede realizar solo una vez al día, cuando aparece una nueva barra. Precisamente así funcionará el asesor: esperará una nueva barra del símbolo indicado en el marco temporal D1, y solo después de ello realizará el análisis de la posibilidad de entrada. 

Puesto que los futuros o las acciones solo se negocian en el modo de compensación, no se permiten las posiciones en direcciones opuestas (hedge), mientras que el incremento del volumen de la posición está totalmente permitido. El asesor puede comerciar o bien solo con el símbolo actual, o bien con varios símbolos, que se guardan en un archivo de texto. Si bien todo está claro en lo que respecta al símbolo actual, la selección de varios símbolos puede representar los siguientes problemas:

  • es necesario indicar cerca de cien símbolos de un mercado (por ejemplo, solo los valores);
  • es necesario indicar varios símbolos de diferentes mercados (por ejemplo, futuros y valores).

¿Cómo seleccionar todos los símbolos de un solo mercado? Por ejemplo, tenemos el símbolo "CAT", y este se ubica en la siguiente ruta: "Stock Markets\USA\NYSE/NASDAQ(SnP100)\CAT"

Symbols Specification

Supongamos que este símbolo nos conviene, y queremos elegir el resto de instrumentos de la ramificación "\NYSE/NASDAQ(SnP100)\". En este caso, podemos actuar de la forma siguiente:

  1. abrimos el gráfico de este símbolo;
  2. iniciamos el script (lo llamaremos Symbols on the specified path.mq5), que obtendrá la ruta del símbolo (en el ejemplo de arriba, para el símbolo "CAT" será "Stock Markets\USA\NYSE/NASDAQ(SnP100)") y guardará en un archivo de texto todos los símbolos de la ruta obtenida. El archivo de texto se guardará en la carpeta general Common Data Folder;
  3. en los ajustes del asesor quedará indicar el nombre del archivo de texto.
Si necesitamos símbolos de varios mercados, iniciaremos el script en cada uno de los mercados (la lista de símbolos se guarda en un archivo único), y a continuación, combinaremos manualmente ambos archivos de texto.

Más abajo, explicaremos la implementación del script Symbols on the specified path.mq5.


Montando el asesor. Opción 1: todos los indicadores en un gráfico

Symbols on the specified path.mq5 — script para obtener el archivo de texto con los símbolos. 

ATENCIÓN: ¡solo el texto "Everything is fine. There are no errors" en la pestaña "Expertos" garantiza que el script ha funcionado sin errores y que el archivo obtenido con los símbolos se puede utilizar para trabajar con el asesor!

Para abreviar el código de las operaciones con archivos, se incluye la clase CFileTxt, mientras que del trabajo con al archivo de texto se encargará m_file_txt, un objeto de la clase CFileTxt. El script ejecuta su trabajo en siete pasos:

//+------------------------------------------------------------------+
//|                                Symbols on the specified path.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.002"
#property script_show_inputs
//---
#include <Files\FileTxt.mqh>
CFileTxt       m_file_txt;                   // file txt object
//--- input parameters
input string   InpFileName="Enter a unique name.txt";  // File name
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- STEP 1
   string current_path="";
   if(!SymbolInfoString(Symbol(),SYMBOL_PATH,current_path))
     {
      Print("ERROR: SYMBOL_PATH");
      return;
     }
//--- STEP 2
   string sep_="\\";                 // A separator as a character 
   ushort u_sep_;                    // The code of the separator character 
   string result_[];                 // An array to get strings 
//--- Get the separator code 
   u_sep_=StringGetCharacter(sep_,0);
//--- Split the string to substrings 
   int k_=StringSplit(current_path,u_sep_,result_);
//--- STEP 3
//--- Now output all obtained strings 
   if(k_>0)
     {
      current_path="";
      for(int i=0;i<k_-1;i++)
         current_path=current_path+result_[i]+sep_;
     }
//--- STEP 4
   string symbols_array[];
   int symbols_total=SymbolsTotal(false);
   for(int i=0;i<symbols_total;i++)
     {
      string symbol_name=SymbolName(i,false);
      string symbol_path="";
      if(!SymbolInfoString(symbol_name,SYMBOL_PATH,symbol_path))
         continue;
      if(StringFind(symbol_path,current_path,0)==-1)
         continue;
      
      int size=ArraySize(symbols_array);
      ArrayResize(symbols_array,size+1,10);
      symbols_array[size]=symbol_name];
     }
//--- STEP 5
   int size=ArraySize(symbols_array);
   if(size==0)
     {
      PrintFormat("ERROR: On path \"%s\" %d symbols",current_path,size);
      return;
     }
   PrintFormat("On path \"%s\" %d symbols",current_path,size);
//--- STEP 6
   if(m_file_txt.Open(InpFileName,FILE_WRITE|FILE_COMMON)==INVALID_HANDLE)
     {
      PrintFormat("ERROR: \"%s\" file in the Data Folder Common folder is not created",InpFileName);
      return;
     }
//--- STEP 7
   for(int i=0;i<size;i++)
      m_file_txt.WriteString(symbols_array[i]+"\r\n");
   m_file_txt.Close();
   Print("Everything is fine. There are no errors");
//---
  }
//+------------------------------------------------------------------+

Algoritmo de funcionamiento del script:

  • STEP 1: para el símbolo actual se determina SYMBOL_PATH, la ruta en el árbol de símbolos;
  • STEP 2: la ruta obtenida es dividida en subcadenas con el separador "\";
  • STEP 3: montamos de nuevo la ruta actual, pero ya sin la última subcadena, puesto que la última subcadena es el nombre del símbolo;
  • STEP 4: ciclo por todos los símbolos disponibles; si para un símbolo la ruta en el árbol de símbolos coincide con la ruta actual, seleccionamos el nombre del símbolo y lo añadimos a la matriz de símbolos detectados;
  • STEP 5: comprobamos el tamaño de la matriz de símbolos detectados;
  • STEP 6: creamos el archivo;
  • STEP 7: escribimos en el archivo nuestra matriz de símbolos detectados y cerramos el archivo.


Elder-Ray 1 — asesor (o varios asesores) con los números de las verisiones 1.xxx, que comerciará según la opción 1: todos los indicadores en un mismo gráfico.

Cómo definir el volumen de la posición — el lote mínimo puede ser diferente

Un experimento sencillo: vamos a comprobar el tamaño del lote mínimo de los futuros y los valores: por analogía con el script Symbols on the specified path.mq5, vamos a iterar todos los símbolos ubicados en la misma ruta que el símbolo actual, solo que en lugar de guardar los símbolos, mostraremos las estadísticas del tamaño del lote mínimo.

Gets minimal volume.mq5 — script para mostrar las estadísticas del volumen mínimo del grupo de símbolos. El script itera un grupo de símbolos y acumula las estadísticas (minimal volume to close a deal y counter) en una matriz bidimensional:

//--- STEP 4
/* 
   symbols_array[][2]:
   [*][minimal volume to close a deal]
   [*][counter]
*/

Aquí tenemos el código completo del script:

//+------------------------------------------------------------------+
//|                                          Gets minimal volume.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- STEP 1
   string current_path="";
   if(!SymbolInfoString(Symbol(),SYMBOL_PATH,current_path))
     {
      Print("ERROR: SYMBOL_PATH");
      return;
     }
//--- STEP 2
   string sep_="\\";                 // A separator as a character 
   ushort u_sep_;                    // The code of the separator character 
   string result_[];                 // An array to get strings 
//--- Get the separator code 
   u_sep_=StringGetCharacter(sep_,0);
//--- Split the string to substrings 
   int k_=StringSplit(current_path,u_sep_,result_);
//--- STEP 3
//--- Now output all obtained strings 
   if(k_>0)
     {
      current_path="";
      for(int i=0;i<k_-1;i++)
         current_path=current_path+result_[i]+sep_;
     }
//--- STEP 4
/* 
   symbols_array[][2]:
   [*][minimal volume to close a deal]
   [*][counter]
*/
   double symbols_array[][2];
   int symbols_total=SymbolsTotal(false);
   for(int i=0;i<symbols_total;i++)
     {
      string symbol_name=SymbolName(i,false);
      string symbol_path="";
      if(!SymbolInfoString(symbol_name,SYMBOL_PATH,symbol_path))
         continue;
      if(StringFind(symbol_path,current_path,0)==-1)
         continue;

      double min_volume=0.0;
      if(!SymbolInfoDouble(symbol_name,SYMBOL_VOLUME_MIN,min_volume))
         continue;
      int size=ArrayRange(symbols_array,0);
      bool found=false;
      for(int j=0;j<size;j++)
        {
         if(symbols_array[j][0]==min_volume)
           {
            symbols_array[j][1]=symbols_array[j][1]+1;
            found=true;
            continue;
           }
        }
      if(!found)
        {
         ArrayResize(symbols_array,size+1,10);
         symbols_array[size][0]=min_volume;
         symbols_array[size][1]=1.0;
        }
     }
//--- STEP 5
   int size=ArrayRange(symbols_array,0);
   if(size==0)
     {
      PrintFormat("ERROR: On path \"%s\" %d symbols",current_path,size);
      return;
     }
//--- STEP 6
   for(int i=0;i<size;i++)
      PrintFormat("Minimal volume %.2f occurs %.1f times",symbols_array[i][0],symbols_array[i][1]);
   Print("Everything is fine. There are no errors");
//---
  }
//+------------------------------------------------------------------+

Algoritmo de funcionamiento del script:

  • STEP 1: para el símbolo actual se determina SYMBOL_PATH, la ruta en el árbol de símbolos;
  • STEP 2: la ruta obtenida es dividida en subcadenas con el separador "\";
  • STEP 3: montamos de nuevo la ruta actual, pero ya sin la última subcadena, puesto que la última subcadena es el nombre del símbolo;
  • STEP 4: ciclo por todos los símbolos disponibles; si para un símbolo la ruta en el árbol de símbolos coincide con la ruta actual, obtenemos el volumen mínimo del símbolo y realizamos la búsqueda en la matriz de símbolos. Si ya existe ese valor, aumentamos el contador. Si ese valor aún no existe, lo añadimos a la matriz y ponemos el contador en "1.0";
  • STEP 5: comprobamos el tamaño de la matriz de símbolos detectados;
  • STEP 6: mostramos las estadísticas.

Resultado del inicio con valores:

Gets minimal volume (CAT,D1)    Minimal volume 1.00 occurs 100.0 times

y con futuros:

Gets minimal volume (RTSRIU8,D1)        Minimal volume 1.00 occurs 77.0 times

- en los dos mercados el tamaño del lote es el mismo: 1.0.

Esto significa que no vamos a complicar el sistema, y tomaremos como lote mínimo el tamaño "1.0".


Visualización de los indicadores usados

Cuando usted inicie la simulación visual en el simulador, verá los indicadores que usa el asesor. Pero cuando este asesor se inicie en el gráfico en el terminal, los indicadores no se mostrarán. En este sistema comercial querríamos ver estos indicadores en un gráfico en el terminal para controlar visualmente el funcionamiento del asesor. Algo así:

CATDaily visual trading

Como puede ver, aquí hemos usado para todos los indicadores nuestros ajustes propios de color y grosor de línea (por supuesto, todo ello se ha hecho manualmente). Pero, para visualizar automáticamente los indicadores usados en el gráfico en el terminal, será necesario reescribir ligeramente los indicadores Moving Average, Bulls Power y Bears Power. Ya hemos implementado algo semejante en el código de Custom Moving Average Input Color, en los parámetros de entrada se mostrará el color del indicador: este parámetro de entrada está disponible al crear el indicador a partir del asesor. Solo queda escribir otros tres indicadores a su imagen y semejanza.

Estos indicadores (Custom Moving Average Inputs, Custom Bulls Power Inputs y Custom Bears Power Inputs) se pueden descargar en CodeBase. Preste atención a que los indicadores se deben ubicar en la carpeta raíz [data folder]\MQL5\Indicators\.


Elder-Ray 1.001.mq5visualización de los indicadores utilizados, para los que se puede ajustar el color y la anchura. Funciona tanto en el simulador de estrategias, como al iniciar el asesor en el gráfico:

Elder-Ray 1.001

¿Cómo se implementa esto?

La principal condición es la presencia de los indicadores Custom Moving Average InputsCustom Bulls Power Inputs y Custom Bears Power Inputs en la carpeta [data folder]\MQL5\Indicators

Three indicators

El control del aspecto externo de los indicadores, así como el ajuste del periodo, se realiza en los parámetros de entrada, mientras que para trabajar con los indicadores, se declaran tres variables en las que luego se guardarán los manejadores de los indicadores (handle_iCustom_MA, handle_iCustom_Bulls y handle_iCustom_Bears).

//+------------------------------------------------------------------+
//|                                                  Elder-Ray 1.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
//---

//---
enum ENUM_INPUT_SYMBOLS
  {
   INPUT_SYMBOLS_CURRENT=0,   // current symbol
   INPUT_SYMBOLS_FILE=1,      // text file
  };
//--- input parameters
input ENUM_INPUT_SYMBOLS   InpInputSymbol       = INPUT_SYMBOLS_FILE;   // works on ...
input uint                 InpNumberMinLots     = 1;                    // Number of minimum lots
//--- Custom Moving Average Inputs
input int                  Inp_MA_ma_period     = 13;                   // MA: averaging period 
input int                  Inp_MA_ma_shift      = 0;                    // MA: horizontal shift 
input ENUM_MA_METHOD       Inp_MA_ma_method     = MODE_EMA;             // MA: smoothing type 
input ENUM_APPLIED_PRICE   Inp_MA_applied_price = PRICE_CLOSE;          // MA: type of price 
input color                Inp_MA_Color         = clrChartreuse;        // MA: Color
input int                  Inp_MA_Width         = 2;                    // MA: Width
//--- Custom Bulls Power Inputs
input int                  Inp_Bulls_ma_period  = 13;                   // Bulls Power: averaging period 
input color                Inp_Bulls_Color      = clrBlue;              // Bulls Power: Color
input int                  Inp_Bulls_Width      = 2;                    // Bulls Power: Width
//--- Custom Bears Power Inputs
input int                  Inp_Bears_ma_period  = 13;                   // Bears Power: averaging period 
input color                Inp_Bears_Color      = clrRed;               // Bears Power: Color
input int                  Inp_Bears_Width      = 2;                    // Bears Power: Width

int    handle_iCustom_MA;                    // variable for storing the handle of the iCustom indicator
int    handle_iCustom_Bulls;                 // variable for storing the handle of the iCustom indicator 
int    handle_iCustom_Bears;                 // variable for storing the handle of the iCustom indicator 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()


En OnInit() se crean los manejadores de los indicadores personalizados (se usa iCustom), y se añaden al gráfico los indicadores creados (se usa ChartIndicatorAdd).

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iCustom
   handle_iCustom_MA=iCustom(Symbol(),Period(),"Custom Moving Average Inputs",
                             Inp_MA_ma_period,
                             Inp_MA_ma_shift,
                             Inp_MA_ma_method,
                             Inp_MA_Color,
                             Inp_MA_Width,
                             Inp_MA_applied_price);
//--- if the handle is not created 
   if(handle_iCustom_MA==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code 
      PrintFormat("Failed to create handle of the iCustom indicator (\"Custom Moving Average Inputs\") for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early 
      return(INIT_FAILED);
     }

//--- create handle of the indicator iCustom
   handle_iCustom_Bulls=iCustom(Symbol(),Period(),"Custom Bulls Power Inputs",
                                Inp_Bulls_ma_period,
                                Inp_Bulls_Color,
                                Inp_Bulls_Width);
//--- if the handle is not created 
   if(handle_iCustom_Bulls==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code 
      PrintFormat("Failed to create handle of the iCustom indicator (\"Custom Bulls Power Inputs\") for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early 
      return(INIT_FAILED);
     }

//--- create handle of the indicator iCustom
   handle_iCustom_Bears=iCustom(Symbol(),Period(),"Custom Bears Power Inputs",
                                Inp_Bears_ma_period,
                                Inp_Bears_Color,
                                Inp_Bears_Width);
//--- if the handle is not created 
   if(handle_iCustom_Bears==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code 
      PrintFormat("Failed to create handle of the iCustom indicator (\"Custom Bears Power Inputs\") for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early 
      return(INIT_FAILED);
     }

   ChartIndicatorAdd(0,0,handle_iCustom_MA);
   int windows_total=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
   ChartIndicatorAdd(0,windows_total,handle_iCustom_Bulls);
   ChartIndicatorAdd(0,windows_total+1,handle_iCustom_Bears);
//---
   return(INIT_SUCCEEDED);
  }


Ahorramos recursos. Elder-Ray 1.010.mq5

Los símbolos analizados de un mismo grupo pueden llegar a los cien. Por eso, es lógico que nos preguntemos por el tema del ahorro de la memoria operativa, y es que en cada gráfico habrá tres indicadores. Como sucede en el caso con el lote mínimo, no hay nada mejor que comprobar el gasto de recursos del asesor. Ya de paso, podemos avanzar un poco en el montaje de nuestro asesor: vamos a añadir un código que lee desde un archivo de texto los nombres de los símbolos de un grupo y trabaja con ellos.

En el asesor se incluye la clase CFileTxt (ya la hemos utilizado en el script Symbols on the specified path.mq5), un objeto de esta clase m_file_txt es responsable del acceso al archivo de texto y la lectura de información desde el archivo. Asimismo, incluimos la clase CSymbolInfo — el objeto de esta clase m_symbol se encarga de comprobar la existencia de un símbolo y de añadir el símbolo a la ventana "Observación del mercado". ¿Por qué hemos elegido precisamente CSymbolInfo, y no la implementación con la ayuda de SymbolInfoInteger y SymbolSelect de la función? Todo es muy sencillo: en la clase CSymbolInfo todo el código de comprobación, adición o muestra de mensajes sobre errores se encuentra oculto dentro de la clase, y en el asesor solo necesitamos escribir estas tres líneas:

         if(!m_symbol.Name(name)) // sets symbol name
           {
            m_file_txt.Close();
            return(INIT_FAILED);
           }

No estará de más recordar que todos los símbolos del experto multidivisa deberán ser añadidos a la ventana "Observación del mercado": Activación de los símbolos necesarios en la ventana "Observación del Mercado" para los EAs multidivisas

Bien, el asesor funciona según el siguiente algoritmo: OnInit() abre el archivo de texto, calcula el símbolo e intenta directamente crear tres indicadores personalizados (Custom Moving Average Inputs, Custom Bulls Power Inputs y Custom Bears Power Inputs) según el símbolo calculado en el marco temporal actual. Si no se ha logrado crear el indicador (no ha habido barras suficientes para crear Custom Moving Average Inputs), continuamos por el ciclo. Si los indicadores han sido creados, introducimos el nombre del símbolo en la matriz m_symbols_array, y los manejadores de los tres indicadores, en la matriz tridimensional m_handles_array. De esta forma, en la primera dimensión, ambas matrices cotienen de forma sincrónica información sobre el nombre del símbolo y sobre los manejadores en este símbolo:

//---
   if(m_file_txt.Open(InpFileName,FILE_READ|FILE_COMMON)==INVALID_HANDLE)
     {
      PrintFormat("ERROR: \"%s\" file in the Data Folder Common folder is not open: %d",InpFileName,GetLastError());
      return(INIT_FAILED);
     }
//--- symbol info object OR file txt object
   if(InpInputSymbol==INPUT_SYMBOLS_FILE)
     {
      //--- read data from the file 
      int counter=0;
      while(!m_file_txt.IsEnding())
        {
         counter++;
         Print("Iteration ",counter);
         string name=m_file_txt.ReadString();
         if(!m_symbol.Name(name)) // sets symbol name
           {
            m_file_txt.Close();
            return(INIT_FAILED);
           }
         int MA,Bulls,Bears;
         if(!CreateHandles(name,Period(),MA,Bulls,Bears))
            continue; //return(INIT_FAILED);
         int size=ArraySize(m_symbols_array);
         ArrayResize(m_symbols_array,size+1,10);
         ArrayResize(m_handles_array,size+1,10);
         m_symbols_array[size]=name;
         m_handles_array[size][0]=MA;
         m_handles_array[size][1]=Bulls;
         m_handles_array[size][2]=Bears;
        }
      m_file_txt.Close();
     }
   else
     {
      if(!m_symbol.Name(Symbol())) // sets symbol name
         return(INIT_FAILED);
     }
//---
   ChartIndicatorAdd(0,0,handle_iCustom_MA);

Los manejadores del indicador se crean en CreateHandles().

Bien, el consumo de memoria se ha medido con TERMINAL_MEMORY_USED y ha sido valorado visualmente en el administrador de tareas de Windows 10. Para determinar el consumo de memoria paso a paso, en la versión 1.010 se han desactivado especialmente unas cuantas líneas de código (las líneas han sido comentadas). En la versión final 1.010, todas las líneas de adición de símbolos y creación de indicadores han sido comentadas.

  • Inicio del asesor de forma habitual: el asesor se ha fijado al gráfico:
    • inicio del terminal (los símbolos del archivo de texto no han sido aún añadidos a la ventana de "Observación del mercado") — TERMINAL_MEMORY_USED 345 МБ, administrador de tareas de 26 a 90 MB;
    • añadimos casi cien símbolos a la ventana "Observación del mercado" — TERMINAL_MEMORY_USED 433 MB, administrador de tareas + 10 MB;
    • y ahora creamos tres indicadores según cada uno de ellos: TERMINAL_MEMORY_USED 5523 MB, administrador de tareas 300 MB.
  • Inicio del simulador (sin visualización) — TERMINAL_MEMORY_USED 420 MB, en el administrador de tareas, 5 GB.


Conclusión: TERMINAL_MEMORY_USED muestra el consumo total de RAM y el espacio del disco. Y, puesto que el consumo de RAM en el modo normal no supera los 300 MB, no vamos a ahorrar nada.


La tendencia (EMA) es...

Definir la dirección de la tendencia (EMA) es la principal tarea del asesor. No es posible determinar la tendencia en una barra, necesitamos la información de varias de ellas. Vamos a marcar este parámetro como "bars". Aquí tenemos tres gráficos de valores CAT, MCD y V. La tendencia se puede definir como: tendencia ascendente "+1", no hay tendencia "0" y tendencia descendente "—1"

Trend (EMA) is ...

Cuando en el gráfico "CAT" muestra la tendencia "0" (4 barras hacia abajo, 4 hacia arriba, el cambio en las demás barras es insignificante), en "MCD" muestra la tendencia "—1" (8 barras hacia abajo, las demás en un estado indeterminado) y en "V" muestra la tendencia "0" (6 barras hacia arriba, 2 o 3 hacia abajo). Es posible que haya que introducir el parámetro different, la diferencia mínima entre las lecturas del indicador en barras contiguas. 


Determinamos la tendencia. Elder-Ray 1.020.mq5

Condiciones para la presencia de tendencia: durante bars, EMA deberá dirigirse en una dirección. Probablemente, después debamos comprobar dos parámetros adicionales: 

  • different — diferencia mínima entre las lecturas del indicador en barras contiguas;
  • trend percentage — porcentaje mínimo de lecturas del indicador en una dirección (en la figura: el símbolo CAT - el indicador EMA está dirigido de forma opuesta en el intervalo bars, mientras que en el símbolo MCD, todas (o casi todas) las lecturas del indicador EMA están en la misma dirección).


Qué se ha añadido y quitado en la versión 1.020: 

  • no se ha implementado el parámetro different — la diferencia mínima entre las lecturas del indicador en barras contiguas;
  • "—" enumeración enum ENUM_INPUT_SYMBOLS — se ha decidido que el asesor trabaje solo con los símbolos del archivo de texto;
  • "+" parámetro number of bars for identifying the trend — el número de barras para identificar la tendencia de EMA;
  • "+" parámetro minimum percentage of the trend — calidad mínima de la tendencia (unidireccionalidad);
  • "+" matriz m_prev_bars — matriz para guardar la hora de apertura de la barra anterior;
  • "+" temporizador de 60 segundos — en el temporizador se comprueba la nueva barra.


Bloque para capturar la nueva barra y determinar la dirección de la tendencia

En OnTimer(), iteramos cada 60 segundo por la matriz de símbolos (m_symbols_array), cargada desde el archivo de texto, y captamos la nueva barra en el símbolo de la matriz. Obtenemos en la matriz ema_array los datos del indicador EMA, suficientes para determinar la tendencia. Realizamo el cálculo: cuántas barras se ha desplazo el indicador hacia arriba, y cuántas hacia abajo. Imprimimos los patrones detectados.

//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   int size=ArraySize(m_symbols_array);
   for(int i=0;i<size;i++)
     {
      //--- we work only at the time of the birth of new bar
      datetime PrevBars=m_prev_bars[i];
      datetime time_0=iTime(m_symbols_array[i],Period(),0);
      if(time_0==PrevBars)
         continue;
      m_prev_bars[i]=time_0;
      double ema_array[];
      ArraySetAsSeries(ema_array,true);
/*
      m_handles_array[*][MA][Bulls][Bears]
*/
      if(!iMAGetArray(m_handles_array[i][0],0,InpBarsEMA+2,ema_array))
         continue;
      int upwards=0;
      int downward=0;
      for(int j=1;j<InpBarsEMA+1;j++)
        {
         if(ema_array[j]>ema_array[j+1])
            upwards++;
         else if(ema_array[j]<ema_array[j+1])
            downward++;
        }
      if((double)upwards>InpBarsEMA*InpMinTrendPercentage/100.0)
         Print("On ",m_symbols_array[i]," trend UP!");
      else if((double)downward>InpBarsEMA*InpMinTrendPercentage/100.0)
         Print("On ",m_symbols_array[i]," trend DOWN!");
      else
         Print("On ",m_symbols_array[i]," trend NONE!");
     }
  }

Resultados de la definición de tendencia. Ajustes: number of bars for identifying the trend — 6, minimum percentage of the trend — 75%. Recordemos que si trabajamos en el momento en que aparece una nueva barra, la barra cero no será tenida en cuenta:

Trend on symbols


Trend on symbols


Colocamos órdenes pendientes (Buy stop o Sell stop). Elder-Ray 1.030.mq5

¿Cómo evitar el error de falta de fondos al abrir una posición? Puesto que estamos trabajando con órdenes pendientes, la respuesta será: ¡"de ninguna forma"! Podemos optar por alguna solución a medias, pero no es posible garantizar nada, y el motivo principal es que nadie sabe en qué momento se activará una orden pendiente, o si se activará en absoluto.

Bien, el asesor ya ha aprendido más o menos a determinar la tendencia, ahora necesitamos, usando las Reglas de compra y las Reglas de venta, encontrar los puntos en los que se puede colocar una orden pendiente. Para abrir BUY, se realizará una comprobación muy sencilla: el valor del indicador Bears Power en la barra #1 deberá ser inferior a cero y superior al valor de Bears Power en la barra #2. Para abrir SELL, la comprobación será inversa: el valor del indicador Bulls Power en la barra #1 deberá ser superior a cero e inferior al valor de Bears Power en la barra #2.

En la descripción de la estrategia, Alexander Elder dijo que para abrir una posición BUY "... el Stop-Loss de protección se coloca por debajo del último mínimo ...", y para abrir una posición SELL "... el Stop-Loss de protección se coloca por encima del último máximo ...". El propio concepto de "último" resulta difuso, por eso hemos comprobado las dos variantes:

  1. colocar el stop-loss según los precios de la barra #1 y
  2. realizar la búsqueda del extremo más próximo.

La variante 1 no ha resultado viable: el stop-loss se activaba con mucha frecuencia, por eso, en el código del asesor Elder-Ray 1.030.mq5, hemos optado por la variante número 2: buscar el extremo más próximo.


Buscando el extremo más próximo

La función busca el extremo más próximo:

Nearest extremum

Si no se ha encontrado el extremo o se ha detectado un error, se retorna false:

//+------------------------------------------------------------------+
//| Find the nearest extremum                                        |
//+------------------------------------------------------------------+
bool NearestExtremum(ENUM_SERIESMODE type,double &price)
  {
   if(type==MODE_LOW)
     {
      //--- search for the nearest minimum
      double low_array[];
      ArraySetAsSeries(low_array,true);
      int copy=CopyLow(m_symbol.Name(),Period(),0,100,low_array);
      if(copy==-1)
         return(false);
      double low=DBL_MAX;
      for(int k=0;k<copy;k++)
        {
         if(low_array[k]<low)
            low=low_array[k];
         else if(low_array[k]>low)
            break;
        }
      if(low!=DBL_MAX)
        {
         price=low;
         return(true);
        }
     }
   else if(type==MODE_HIGH)
     {
      //--- search for the nearest maximum
      double high_array[];
      ArraySetAsSeries(high_array,true);
      int copy=CopyHigh(m_symbol.Name(),Period(),0,100,high_array);
      if(copy==-1)
         return(false);
      double high=DBL_MIN;
      for(int k=0;k<copy;k++)
        {
         if(high_array[k]>high)
            high=high_array[k];
         else if(high_array[k]<high)
            break;
        }
      if(high!=DBL_MIN)
        {
         price=high;
         return(true);
        }
     }
//---
   return(false);
  }


Qué se ha añadido y quitado en la versión 1.030: 

  • "+" clase comercial CPositionInfo (y m_position - objeto de esta clase);
  • "+" clase comercial CTrade (y m_trade - objeto de esta clase);
  • "+" clase comercial COrderInfo (y m_order - objeto de esta clase);
  • "+" trailing (parámetros Trailing Stop y Trailing Step);
  • "+" magic number — identificador único del experto;
  • "+" OnInit() — comprobación del tipo de cuenta: si se trata de una cuenta con cobertura, se prohíbe el comercio y se muestra un error;
  • OnInit() — se ha modificado el orden de visualización: si se ha iniciado el simulador de estrategias, y el símbolo actual (el símbolo en el que está inicializado el experto) está en el archivo de texto, no añadimos los indicadores al símbolo actual (ChartIndicatorAdd no se usa);
  • OnTimer() — se ha añadido el código de confirmación de la señal y las operaciones comerciales para la colocación de las órdenes pendientes Buy Stop y Sell Stop;
  • OnTradeTransaction() — se ha añadido un mecanismo de compensación si ha tenido lugar el viraje de posición o el cierre parcial de la misma;
  • "+" al activarse el algoritmo de compensación, en OnTradeTransaction() NO SE COLOCA un stop-loss, en lugar de ello, se moderniza la función de trailing: si durante la iteración de posiciones se detecta una posición sin stop-loss, se colocará uno según las reglas de búsqueda del extremo más próximo;
  • "+" se ha añadido la variable m_magic_compensation — el identificador de transacciones de compensación.

Para poder aclararnos en la situación cuando se activa una orden pendiente en dirección opuesta a la posición actual, debemos analizar tres situaciones típicas después de la activación de una orden pendiente Buy Stop:

№ Posición existente, volumenOrden pendiente activada, volumenPosición resultante, volumenObservación para el momento de activación de la orden pendientemagic de la posición Algoritmo de compensación (importante: antes de la compensación, establecemos el magic en m_magic_compensation)nuevo magic de la posición
 1 Sell 1.0 Buy Stop 3.0 Buy 2.0Viraje de posición (dirección de la transacción DEAL_ENTRY_INOUT) m_magicAbrir adicionalmente Buy con volumen 3.0 — 2.0 = 1.0 m_magic_compensation
 2 Sell 1.0 Buy Stop 1.0 ---Cierre completo de la posición (dirección de la transacción DEAL_ENTRY_OUT) m_magicBuscando posición. Si no hay posición, abrir Buy con un volumen 1.0 m_magic_compensation
 3 Sell 2.0 Buy Stop 1.0 Sell 1.0Cierre parcial de la posición (dirección de la transacción DEAL_ENTRY_OUT) m_magicBuscando posición. Si hay posición y esta es opuesta a Buy, abrimos Buy con un volumen 1.0 + 1.0 = 2.0 m_magic_compensation

Para cada uno de los tres casos, hemos preparado una lista de transacciones y órdenes (simulación en una cuenta de compensación real, pero en el simulador). Para generar los informes de las transacciones y órdenes hemos usado el código del script History Deals and Orders.

#1: Sell 1.0 -> Buy Stop 3.0

Sell 1.0, Buy Stop 3.0

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|1                   |0                   |2016.12.08 00:00:00 |1481155200000       |DEAL_TYPE_BALANCE   |DEAL_ENTRY_IN       |0                   |DEAL_REASON_CLIENT  |0                  
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|0.00                |0.00000             |0.00                |0.00                |50000.00            |                    |                                         |                   
Order 0 is not found in the trade history between the dates 2010.08.07 11:06:20 and 2018.08.10 00:00:00

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|2                   |2                   |2016.12.08 00:00:00 |1481155200100       |DEAL_TYPE_SELL      |DEAL_ENTRY_IN       |15489               |DEAL_REASON_EXPERT  |2                  
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|1.00                |79.31               |0.00                |0.00                |0.00                |V                   |                                         |                   
Order:
|Ticket              |Time setup          |Type                |State               |Time expiration     |Time done           |Time setup msc      |Time done msc       |Type filling       
|2                   |2016.12.08 00:00:00 |ORDER_TYPE_SELL     |ORDER_STATE_FILLED  |2016.12.08 00:00:00 |2016.12.08 00:00:00 |1481155200100       |1481155200100       |ORDER_FILLING_FOK  
|Type time           |Magic               |Reason              |Position id         |Position by id     
|1970.01.01 00:00:00 |15489               |ORDER_REASON_EXPERT |2                   |0                  
|Volume initial      |Volume current      |Open price          |sl                  |tp                  |Price current       |Price stoplimit    
|1.00                |0.00                |79.31               |0.00                |0.00                |79.39               |0.00               
|Symbol              |Comment                                  |Extarnal id        
|V                   |                                         |                   

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|3                   |3                   |2016.12.08 17:27:37 |1481218057877       |DEAL_TYPE_BUY       |DEAL_ENTRY_INOUT    |15489               |DEAL_REASON_EXPERT  |2                  
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|3.00                |79.75               |0.00                |0.00                |-0.44               |V                   |                                         |                   
Order:
|Ticket              |Time setup          |Type                |State               |Time expiration     |Time done           |Time setup msc      |Time done msc       |Type filling       
|3                   |2016.12.08 14:30:00 |ORDER_TYPE_BUY_STOP |ORDER_STATE_FILLED  |2016.12.08 14:30:00 |2016.12.08 17:27:37 |1481207400100       |1481218057877       |ORDER_FILLING_RETURN
|Type time           |Magic               |Reason              |Position id         |Position by id     
|1970.01.01 00:00:00 |15489               |ORDER_REASON_EXPERT |2                   |0                  
|Volume initial      |Volume current      |Open price          |sl                  |tp                  |Price current       |Price stoplimit    
|3.00                |0.00                |79.74               |75.17               |0.00                |79.74               |0.00               
|Symbol              |Comment                                  |Extarnal id        
|V                   |                                         |                   

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|4                   |4                   |2016.12.09 23:59:00 |1481327940000       |DEAL_TYPE_SELL      |DEAL_ENTRY_OUT      |0                   |DEAL_REASON_CLIENT  |2                  
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|2.00                |79.13               |0.00                |0.00                |-1.24               |V                   |end of test                              |                   
Order:
|Ticket              |Time setup          |Type                |State               |Time expiration     |Time done           |Time setup msc      |Time done msc       |Type filling       
|4                   |2016.12.09 23:59:00 |ORDER_TYPE_SELL     |ORDER_STATE_FILLED  |2016.12.09 23:59:00 |2016.12.09 23:59:00 |1481327940000       |1481327940000       |ORDER_FILLING_FOK  
|Type time           |Magic               |Reason              |Position id         |Position by id     
|1970.01.01 00:00:00 |0                   |ORDER_REASON_CLIENT |2                   |0                  
|Volume initial      |Volume current      |Open price          |sl                  |tp                  |Price current       |Price stoplimit    
|2.00                |0.00                |79.13               |0.00                |0.00                |79.13               |0.00               
|Symbol              |Comment                                  |Extarnal id        
|V                   |end of test                              |                   


#2: Sell 1.0 -> Buy Stop 1.0

Sell 1.0, Buy Stop 1.0

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|1                   |0                   |2016.12.08 00:00:00 |1481155200000       |DEAL_TYPE_BALANCE   |DEAL_ENTRY_IN       |0                   |DEAL_REASON_CLIENT  |0                  
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|0.00                |0.00000             |0.00                |0.00                |50000.00            |                    |                                         |                   
Order 0 is not found in the trade history between the dates 2010.08.07 11:06:20 and 2018.08.10 00:00:00

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|2                   |2                   |2016.12.08 00:00:00 |1481155200100       |DEAL_TYPE_SELL      |DEAL_ENTRY_IN       |15489               |DEAL_REASON_EXPERT  |2                  
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|1.00                |79.31               |0.00                |0.00                |0.00                |V                   |                                         |                   
Order:
|Ticket              |Time setup          |Type                |State               |Time expiration     |Time done           |Time setup msc      |Time done msc       |Type filling       
|2                   |2016.12.08 00:00:00 |ORDER_TYPE_SELL     |ORDER_STATE_FILLED  |2016.12.08 00:00:00 |2016.12.08 00:00:00 |1481155200100       |1481155200100       |ORDER_FILLING_FOK  
|Type time           |Magic               |Reason              |Position id         |Position by id     
|1970.01.01 00:00:00 |15489               |ORDER_REASON_EXPERT |2                   |0                  
|Volume initial      |Volume current      |Open price          |sl                  |tp                  |Price current       |Price stoplimit    
|1.00                |0.00                |79.31               |0.00                |0.00                |79.39               |0.00               
|Symbol              |Comment                                  |Extarnal id        
|V                   |                                         |                   

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|3                   |3                   |2016.12.08 17:27:37 |1481218057877       |DEAL_TYPE_BUY       |DEAL_ENTRY_OUT      |15489               |DEAL_REASON_EXPERT  |2                  
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|1.00                |79.75               |0.00                |0.00                |-0.44               |V                   |                                         |                   
Order:
|Ticket              |Time setup          |Type                |State               |Time expiration     |Time done           |Time setup msc      |Time done msc       |Type filling       
|3                   |2016.12.08 14:30:00 |ORDER_TYPE_BUY_STOP |ORDER_STATE_FILLED  |2016.12.08 14:30:00 |2016.12.08 17:27:37 |1481207400100       |1481218057877       |ORDER_FILLING_RETURN
|Type time           |Magic               |Reason              |Position id         |Position by id     
|1970.01.01 00:00:00 |15489               |ORDER_REASON_EXPERT |2                   |0                  
|Volume initial      |Volume current      |Open price          |sl                  |tp                  |Price current       |Price stoplimit    
|1.00                |0.00                |79.74               |75.17               |0.00                |79.74               |0.00               
|Symbol              |Comment                                  |Extarnal id        
|V                   |                                         |                   


#3: Sell 2.0 -> Buy Stop 1.0

Sell 2.0, Buy Stop 1.0

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|1                   |0                   |2016.12.08 00:00:00 |1481155200000       |DEAL_TYPE_BALANCE   |DEAL_ENTRY_IN       |0                   |DEAL_REASON_CLIENT  |0                  
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|0.00                |0.00000             |0.00                |0.00                |50000.00            |                    |                                         |                   
Order 0 is not found in the trade history between the dates 2010.08.07 11:06:20 and 2018.08.10 00:00:00

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|2                   |2                   |2016.12.08 00:00:00 |1481155200100       |DEAL_TYPE_SELL      |DEAL_ENTRY_IN       |15489               |DEAL_REASON_EXPERT  |2                  
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|2.00                |79.31               |0.00                |0.00                |0.00                |V                   |                                         |                   
Order:
|Ticket              |Time setup          |Type                |State               |Time expiration     |Time done           |Time setup msc      |Time done msc       |Type filling       
|2                   |2016.12.08 00:00:00 |ORDER_TYPE_SELL     |ORDER_STATE_FILLED  |2016.12.08 00:00:00 |2016.12.08 00:00:00 |1481155200100       |1481155200100       |ORDER_FILLING_FOK  
|Type time           |Magic               |Reason              |Position id         |Position by id     
|1970.01.01 00:00:00 |15489               |ORDER_REASON_EXPERT |2                   |0                  
|Volume initial      |Volume current      |Open price          |sl                  |tp                  |Price current       |Price stoplimit    
|2.00                |0.00                |79.31               |0.00                |0.00                |79.39               |0.00               
|Symbol              |Comment                                  |Extarnal id        
|V                   |                                         |                   

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|3                   |3                   |2016.12.08 17:27:37 |1481218057877       |DEAL_TYPE_BUY       |DEAL_ENTRY_OUT      |15489               |DEAL_REASON_EXPERT  |2                  
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|1.00                |79.75               |0.00                |0.00                |-0.44               |V                   |                                         |                   
Order:
|Ticket              |Time setup          |Type                |State               |Time expiration     |Time done           |Time setup msc      |Time done msc       |Type filling       
|3                   |2016.12.08 14:30:00 |ORDER_TYPE_BUY_STOP |ORDER_STATE_FILLED  |2016.12.08 14:30:00 |2016.12.08 17:27:37 |1481207400100       |1481218057877       |ORDER_FILLING_RETURN
|Type time           |Magic               |Reason              |Position id         |Position by id     
|1970.01.01 00:00:00 |15489               |ORDER_REASON_EXPERT |2                   |0                  
|Volume initial      |Volume current      |Open price          |sl                  |tp                  |Price current       |Price stoplimit    
|1.00                |0.00                |79.74               |75.17               |0.00                |79.74               |0.00               
|Symbol              |Comment                                  |Extarnal id        
|V                   |                                         |                   

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|4                   |4                   |2016.12.09 23:59:00 |1481327940000       |DEAL_TYPE_BUY       |DEAL_ENTRY_OUT      |0                   |DEAL_REASON_CLIENT  |2                  
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|1.00                |79.13               |0.00                |0.00                |0.18                |V                   |end of test                              |                   
Order:
|Ticket              |Time setup          |Type                |State               |Time expiration     |Time done           |Time setup msc      |Time done msc       |Type filling       
|4                   |2016.12.09 23:59:00 |ORDER_TYPE_BUY      |ORDER_STATE_FILLED  |2016.12.09 23:59:00 |2016.12.09 23:59:00 |1481327940000       |1481327940000       |ORDER_FILLING_FOK  
|Type time           |Magic               |Reason              |Position id         |Position by id     
|1970.01.01 00:00:00 |0                   |ORDER_REASON_CLIENT |2                   |0                  
|Volume initial      |Volume current      |Open price          |sl                  |tp                  |Price current       |Price stoplimit    
|1.00                |0.00                |79.13               |0.00                |0.00                |79.13               |0.00               
|Symbol              |Comment                                  |Extarnal id        
|V                   |end of test                              |                   


Hay otra situación más, ya en la cuenta real y en tiempo real (no en el simulador): según el mercado, Buy con un volumen 2.0 (la orden comercial de apertura de Buy ha generado dos transacciones con volúmenes 1.0 — 20087494 y 20087495), a continuación, se ha colocado una Sell limit con un volumen 2.0 para fijar el beneficio y el cierre de la posición. Un poco más tarde, esta Sell limit se ha ejecutado en dos pasadas (transacciones 20088091 y 20088145). Logs:

Buy 2.0, Sell limit 2.0 

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|20087494            |29080489            |2018.08.10 07:23:34 |1533885814000       |DEAL_TYPE_BUY       |DEAL_ENTRY_IN       |0                   |DEAL_REASON_CLIENT  |29080489           
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|1.00                |14595               |-0.10               |0.00                |0.00                |RTSGZU8             |                                         |                   
Order:
|Ticket              |Time setup          |Type                |State               |Time expiration     |Time done           |Time setup msc      |Time done msc       |Type filling       
|29080489            |2018.08.10 07:23:34 |ORDER_TYPE_BUY      |ORDER_STATE_FILLED  |2018.08.10 07:23:34 |2018.08.10 07:23:34 |1533885814000       |1533885814000       |ORDER_FILLING_RETURN
|Type time           |Magic               |Reason              |Position id         |Position by id     
|1970.01.01 00:00:00 |0                   |ORDER_REASON_CLIENT |29080489            |0                  
|Volume initial      |Volume current      |Open price          |sl                  |tp                  |Price current       |Price stoplimit    
|2.00                |0.00                |0                   |0                   |0                   |14588               |0                  
|Symbol              |Comment                                  |External id        
|RTSGZU8             |                                         |13_31861873584     

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|20087495            |29080489            |2018.08.10 07:23:34 |1533885814000       |DEAL_TYPE_BUY       |DEAL_ENTRY_IN       |0                   |DEAL_REASON_CLIENT  |29080489           
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|1.00                |14595               |-0.10               |0.00                |0.00                |RTSGZU8             |                                         |                   
Order:
|Ticket              |Time setup          |Type                |State               |Time expiration     |Time done           |Time setup msc      |Time done msc       |Type filling       
|29080489            |2018.08.10 07:23:34 |ORDER_TYPE_BUY      |ORDER_STATE_FILLED  |2018.08.10 07:23:34 |2018.08.10 07:23:34 |1533885814000       |1533885814000       |ORDER_FILLING_RETURN
|Type time           |Magic               |Reason              |Position id         |Position by id     
|1970.01.01 00:00:00 |0                   |ORDER_REASON_CLIENT |29080489            |0                  
|Volume initial      |Volume current      |Open price          |sl                  |tp                  |Price current       |Price stoplimit    
|2.00                |0.00                |0                   |0                   |0                   |14588               |0                  
|Symbol              |Comment                                  |External id        
|RTSGZU8             |                                         |13_31861873584     

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|20088091            |29080662            |2018.08.10 08:03:08 |1533888188000       |DEAL_TYPE_SELL      |DEAL_ENTRY_OUT      |0                   |DEAL_REASON_CLIENT  |29080489           
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|1.00                |14626               |-0.10               |0.00                |0.46                |RTSGZU8             |                                         |                   
Order:
|Ticket              |Time setup          |Type                |State               |Time expiration     |Time done           |Time setup msc      |Time done msc       |Type filling       
|29080662            |2018.08.10 07:27:19 |ORDER_TYPE_SELL_LIMIT |ORDER_STATE_FILLED  |2018.08.10 07:27:19 |2018.08.10 08:05:42 |1533886039000       |1533888342000       |ORDER_FILLING_RETURN
|Type time           |Magic               |Reason              |Position id         |Position by id     
|1970.01.01 00:00:00 |0                   |ORDER_REASON_CLIENT |29080489            |0                  
|Volume initial      |Volume current      |Open price          |sl                  |tp                  |Price current       |Price stoplimit    
|2.00                |0.00                |14626               |0                   |0                   |14624               |0                  
|Symbol              |Comment                                  |External id        
|RTSGZU8             |                                         |13_31862155871     

Deal:
|Ticket              |Order               |Time                |Time msc            |Type                |Entry               |Magic               |Reason              |Position ID        
|20088145            |29080662            |2018.08.10 08:05:42 |1533888342000       |DEAL_TYPE_SELL      |DEAL_ENTRY_OUT      |0                   |DEAL_REASON_CLIENT  |29080489           
|Volume              |Price               |Commission          |Swap                |Profit              |Symbol              |Comment                                  |External ID        
|1.00                |14626               |-0.10               |0.00                |0.46                |RTSGZU8             |                                         |                   
Order:
|Ticket              |Time setup          |Type                |State               |Time expiration     |Time done           |Time setup msc      |Time done msc       |Type filling       
|29080662            |2018.08.10 07:27:19 |ORDER_TYPE_SELL_LIMIT |ORDER_STATE_FILLED  |2018.08.10 07:27:19 |2018.08.10 08:05:42 |1533886039000       |1533888342000       |ORDER_FILLING_RETURN
|Type time           |Magic               |Reason              |Position id         |Position by id     
|1970.01.01 00:00:00 |0                   |ORDER_REASON_CLIENT |29080489            |0                  
|Volume initial      |Volume current      |Open price          |sl                  |tp                  |Price current       |Price stoplimit    
|2.00                |0.00                |14626               |0                   |0                   |14624               |0                  
|Symbol              |Comment                                  |External id        
|RTSGZU8             |                                         |13_31862155871     


Consejos de simulación 1.xxx

  • Intente dejar en el archivo de texto los valores con un precio más o menos igual.
  • Al realizar la simulación en el archivo de texto, es mejor dejar una pequeña cantidad de símbolos. Caso ideal: dejar un símbolo y realizar la simulación según el mismo.


Opción 2: en combinación con el sistema "Selección triple"

En la opción 1 (todos los indicadores en un gráfico), el indicador de tendencia estaba en el mismo marco temporal. En la opción 2, el indicador de tendencia se encontrará en el mayor marco temporal. De esta forma, se añadirá solo un nuevo parámetro: el marco temporal de tendencia (Trend timeframe).

La opción 2 se ha implementado en el asesor Elder-Ray 2.000.mq5.


Archivos adjuntos al artículo:

NombreTipo de archivoDescripción
Symbols on the specified path.mq5ScriptForma el archivo de texto con los símbolos de este grupo, se guarda en Commom Data Folder
Gets minimal volume.mq5ScriptMuestra las estadísticas sobre el volumen mínimo del grupo dado.
Elder-Ray 1.001.mq5AsesorMuestra la visualización de los indicadores usados
Elder-Ray 1.010.mq5AsesorComenzamos a trabajar con el archivo de texto y a crear los indicadores según los símbolos del archivo. El asesor servirá para observar el consumo de la memoria utilizada
Elder-Ray 1.020.mq5AsesorDeterminamos la tendencia. Comprobamos que la tendencia se determine correctamente
Elder-Ray 1.030.mq5AsesorVersión de trabajo según la Opción 1: todos los indicadores en un mismo gráfico
Elder-Ray 2.000.mq5AsesorOpción 2: en combinación con el sistema "Selección triple"


Conclusión

El sistema comercial Rayos Elder (Bulls Power y Bears Power) es viable, especialmente en combinación con el sistema "Selección triple", cuando el indicador de tendencia (EMA) se calcula en un marco temporal mayor que los indicadores Bulls Power (índice de fuerza alcista) y Bears Power (índice de fuerza bajista).

Al simular el asesor, debemos recordar que en el archivo de texto preparado puede haber hasta 100 símbolos: para iniciar la simulación con semejante número de símbolos, podríamos necesitar hasta 10 minutos solo para el inicio, y hasta 5 Gb de memoria durante la simulación. 

No importa cuánto confiemos en el asesor, siempre querremos intervenir en el proceso con nuestras propias manos. Por ejemplo, durante la escritura del artículo y la simulación de las versiones de los asesores, nosotros hemos actuado así:

CAT and V manual

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

Usando indicadores para la optimización RealTime de EAs Usando indicadores para la optimización RealTime de EAs
No es ningún secreto que el éxito del funcionamiento de cualquier robot comercial depende de la correcta elección de sus parámetros (su optimización). Pero los parámetros óptimos para un intervalo temporal no siempre resultan los mejores en otro intervalo de la historia. Con frecuencia, asesores que son rentables en la simulación, dan pérdidas en tiempo real. Aquí nos surje la pregunta concerniente a la necesidad de optimizar continuamente. Allá donde aparece mucho trabajo rutinario, el hombre busca la forma de automatizarlo. En este artículo proponemos nuestro enfoque particular para solucionar esta tarea.
Combinando una estrategia de tendencia y una de flat Combinando una estrategia de tendencia y una de flat
Existen diferenets estrategias comerciales. Unas buscan la dirección del movimiento y comercian según la tendencia. Otras definen los intervalos de las oscilaciones de precio y comercian dentro de estos corredores. Así que nos surge la pregunta, ¿podemos combinar los dos enfoques para aumentar la rentabilidad de nuestro comercio?
Modelo de continuación de movimiento - búsqueda en el gráfico y estadísticas de ejecución Modelo de continuación de movimiento - búsqueda en el gráfico y estadísticas de ejecución
En este artículo vamos a describir la definición programática de uno de los modelos de continuación del movimiento. La base del trabajo viene constituida por dos ondas: la principal y la de corrección. Como extremos se usarán fractales, además de los llamados fractales potenciales, los extremos que no se han formado aún como fractales.
Modelando series temporales con ayuda de símbolos personalizados según las leyes de distribución establecidas Modelando series temporales con ayuda de símbolos personalizados según las leyes de distribución establecidas
En el artículo se presenta una panorámica de las posibilidades del terminal a la hora de crear y trabajar con símbolos personalizados, ofreciendo diversas opciones de modelado de la historia comercial con la ayuda de símbolos personalizados, de tendencia y diferentes patrones gráficos.