Estudiando las clases de estrategias comerciales de la Biblioteca Estándar - Estrategias personalizadas

Harvester Trading | 19 febrero, 2014

Introducción

Estes artículo está pensado para los usuarios principiantes que quieren abordar correctamente el tema de la customiazción de su asesor, pero sin comenzar a escribirlo desde cero.

MetaTrader 5 proporciona la posibilidad de comerciar con ayuda de asesores, poseyendo unos conocimientos mínimos o nulos de lenguajes de programación, gracias al magnífico potencial del MetaEditor: el Asistente MQL5. El Asistente (en este artículo no explicaremos detalladamente cómo funciona) está pensado para crear programas ya preparados (archivos .mq5 y. ex5), algorítmos y códigos. Su potencial reside en el uso de la Biblioteca Estándar MQL5 y sus clases de estrategias comerciales, que abren para el desarrollador un sinfín de posibilidades.

Estudiando las clases de estrategias comerciales de la Biblioteca Estándar - Estrategias personalizadas

En la Biblioteca Estándar existen multitud de clases de estrategias comerciales, algunas de las cuales se hacen recomendar por sí solas. Muchas de estas clases han sido realizadas sobre la base de famosas investigaciones de los mercados financieros y el análisis de rentabilidad. Existe como mínimo una estrategia para cada indicador del paquete estándar, incluido en MetaTrader 5.

Para la detección de las señales de estas clases, el Asistente MQL5 usa un mecanismo de recurrencia a los indicadores, cuya lógica está programada en forma de "modelos comerciales". Cada asesor concreto generado recurre a los indicadores (a través de la directiva #include) y su conjunto de modelos y decisiones comerciales, las cuales son importadas después al núcleo del asesor para la gestión del comercio.


Asistente MQL5

Para comenzar, necesitaremos crear un asesor en el Asistente MQL5. Para abrir el Asistente MQL5 en el MetaEditor deberá elegir "Crear" en el menú "archivo" o pulse el botón "Crear", y después elija la opción "Asesor (generar)".

Dibujo 1. Crear un archivo nuevo (opción "generar" en el Asistente)

A nuestro experto le pondremos el nombre MyExpert.

Dibujo 2. Nombre y parámetros de un asesor, generado en el Asistente MQL5

Después añadimos dos indicadores/señales (puede elegir cuantos indicadores disponibles desee). En nuestro ejemplo vamos a añadir dos indicadores muy conocidos: el índice de fuerza relativa (RSI - Relative Strength Index) y la media móvil (MA - Moving Average). Añada en primer lugar el indicador RSI, y después el indicador MA.

Dibujo 3. Primero el indicador RSI, después el MA

Para nuestro ejemplo puede crear algunos parámetros a su discreción, o bien dejarlos por defecto.

Dibujo 4. Parámetros de las señales

Una vez pulsado el botón OK y entrado en la siguiente página del Asistente, no elegiremos trading stop, pero si lo desea, puede añadirlo: esto no va a infliur en la temática del artículo. En la siguiente ventana elegiremos 5.0 para el porcentaje del riesgo y 0.1 para el lote, u otros parámetros a su gusto: esto, de nuevo, no influirá en la idea principal de nuestro artículo.


Analizamos el código generado

Tras pasar todas las etapas, obtenemos el archivo "MyExpert.mq5". Vamos a analizar los momentos clave del código generado.

//+------------------------------------------------------------------+
//|                                                     MyExpert.mq5 |
//|                                                        Harvester |
//|                        https://www.mql5.com/en/users/Harvester |
//+------------------------------------------------------------------+
#property copyright "Harvester"
#property link      "https://www.mql5.com/en/users/Harvester"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Include                                                          |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
//--- available signals
#include <Expert\Signal\SignalRSI.mqh>
#include <Expert\Signal\SignalMA.mqh>
//--- available trailing
#include <Expert\Trailing\TrailingNone.mqh>
//--- available money management
#include <Expert\Money\MoneyFixedLot.mqh>

Para empezar, preste atención a los archivos #include, añadidos al código generado por el Asistente. Vemos:

Y después el siguiente fragmento de código:

//--- Creating filter CSignalRSI
   CSignalRSI *filter0=new CSignalRSI;
   if(filter0==NULL)
     {
      //--- failed
      printf(__FUNCTION__+": error creating filter0");
      ExtExpert.Deinit();
      return(-3);
     }
   signal.AddFilter(filter0);

Como ya nos indica el encabezamiento del comentario, es el "filtro" que se aplicará a las condiciones de mercado del asesor generado. filter0 es el primer filtro con índice 0, para él elegimos primero el indicador RSI en nuestro ejemplo.

CSignalRSI indica la clase de la señal RSI. Esta clase se usa para la llamada del indicador RSI y la aplicación sobre él de algunas condiciones para la creación de señales en la compra o la venta, utilizando la lógica de los modelos del Asistente. Y así, RSI será nuestro primer filtro (número 0).

En la parte siguiente están descritos algunos parámetros del filtro, y después la sección sobre trading stop (hemos decidido arreglárnoslas sin usar órdenes de protección). A continuación, la parte del código de gestión de capital.

Continuamos:

//--- Tuning of all necessary indicators
   if(!ExtExpert.InitIndicators())
     {
      //--- failed
      printf(__FUNCTION__+": error initializing indicators");
      ExtExpert.Deinit();
      return(-10);
     }
//--- ok
   return(0);
  }

Aquí se usa el código del archivo incorporado Expert.mqh. Se trata de la inicialización de los indicadores imprescindibles para el funcionamiento del experto.

Y en la última parte del código del asesor generado, podemos ver el código encargado de desinicializar y otras funciones estándar del experto:

//+------------------------------------------------------------------+
//| Deinitialization function of the expert                          |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ExtExpert.Deinit();
  }
//+------------------------------------------------------------------+
//| "Tick" event handler function                                    |
//+------------------------------------------------------------------+
void OnTick()
  {
   ExtExpert.OnTick();
  }
//+------------------------------------------------------------------+
//| "Trade" event handler function                                   |
//+------------------------------------------------------------------+
void OnTrade()
  {
   ExtExpert.OnTrade();
  }
//+------------------------------------------------------------------+
//| "Timer" event handler function                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   ExtExpert.OnTimer();
  }
//+------------------------------------------------------------------+

Nuestro asesor prácticamente sólo usa dos indicadores (RSI y MA) para la toma de decisiones comerciales, con ayuda de la biblioteca estándar de clases comerciales, que usan la lógica de los "filtros" y los "pesos". Puede encontrar información más detallada en el apartado Módulos de señales comerciales en la guía de MQL5. Nuestro objetivo es usar nuestras propias estrategias comerciales en calidad de nuevos filtros.

Para ello vamos a cambiar un poco nuestro archivo MyExpert.mq5. Lo primero de todo, vamos a añadir otro filtro más. Será el filter2 y lo insertaremos inmediatamente después del filter1.

//--- Creating filter CSignalCCIxx
   CSignalCCIxx *filter2=new CSignalCCIxx;
   if(filter2==NULL)
     {
      //--- failed
      printf(__FUNCTION__+": error creating filter2");
      ExtExpert.Deinit();
      return(-4);
     }
   signal.AddFilter(filter2);
//--- Set filter parameters
   filter2.PeriodCCIxx(Signal_CCIxx_PeriodCCI);
   filter2.Applied(Signal_CCIxx_Applied);
   filter2.Weight(Signal_CCIxx_Weight);

Vamos a volver a los archivos #include, que son la esencia de los filtros y la toma de decisiones de mercado. El primer archivo #include <Expert\Expert.mqh> incluye a su vez otros archivos:

Estos archivos constituyen: el módulo principal del asesor, el módulo comercial, el módulo de señales, el módulo de gestión de capital y el módulo de gestión del trading stop. No tenemos intención de analizar estos archivos o cambiarlos. Nuestro objetivo es añadir nuestra propia estrategia en base a los indicadores estándar de MetaTrader 5.

En el código MyExpert.mq5 tenemos los archivos #include de los indicadores RSI y MA, que hemos usado en este ejemplo como señales/filtros para la toma de decisiones comerciales. Ahora añadimos nuestro propio archivo include. Para ello, usaremos la versión modificada ("mejorada") de las señales del indicador CCI.

//+------------------------------------------------------------------+
//| Include                                                          |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
//--- available signals
#include <Expert\Signal\SignalRSI.mqh>
#include <Expert\Signal\SignalMA.mqh>

#include <Expert\Signal\SignalCCIxx.mqh>   // Este es nuestro indicador personalizado

El archivo SignalCCIxx.mqh debe encontrarse en la carpeta \MQL5\Include\Expert\Signal\. Este archivo se integra de manera limitada dentro de la totalidad creada por el Asistente, al igual que otros archivos #include de las clases comerciales de la Biblioteca estándar, estos archivos (SignalRSI.mqh и SignalMA.mqh) están presentes originalmente en esta carpeta.

En nuestro ejemplo, vamos a copiar el archivo fuente CCI, crear sobre su base un nuevo archivo CCIxx con un código ligeramente modificado y lo vamos a usar como archivo #include. Para que sea más sencillo, utilizaremos una copia del indicador CCI de la Biblioteca Estándar.

Copie el archivo "\MQL5\Include\Expert\Signal\SignalCCI.mqh" en el archivo "\MQL5\Include\Expert\Signal\SignalCCIxx.mqh". Para ello, haga una copia del archivo, y después póngale otro nombre.

Vamos a echar un vistazo a este archivo. La integración de este indicador personalizado en el creado por el Asistente MyExpert.mq5 está prácticamente lista. Hemos añadido el código para filter2, como se ha descrito más arriba, ahora sólo queda poner en claro la realización de la señal. Bien, ya no nos vamos a detener más en el código MyExpert.mq5. Ahora concentrémonos en el archivo SignalCCIxx.mqh, ya que será la esencia de nuestra estrategia personalizada.


Estrategia personalizada

Volvemos a la adición de filtros de estrategias "semi-personalizadas" CCIxx, que constituye una versión modificada de SignalCCI.mqh. Y digo "semi-personalizada", porque en realidad no se trata de una nueva señal personalizada, sino de una versión reelaborada del indicador CCI con el conjunto estándar de indicadores de MetaTrader 5. Incluso los usuarios principiantes y los programadores pueden cambiar ligeramente los patrones y filtros del asesor creado por el Asistente MQL5, creando sus propias versiones de los filtros y patrones para la generación de señales sobre compra y venta. Es un método fenomenal para comenzar a trabajar con las estrategias.

Nuestro ejemplo será útil para aquellos que sencillamente quieran añadir algunos modelos personalizados a los indicadores ya existentes, y para aquellos que quieran participar en el Automated Trading Championship, utilizando sólo el Asistente MQL5 para la rápida creación de asesores customizados plenamente funcionales y operativos.

Con sólo una hora de trabajo podrá obtener un asesor totalmente funcional y adecuado para participar en el Campeonato, equipado con trading stop, gestión de capital y todo lo imprescindible para ser comercialmente competitivo. He mencionado que el asesor será adecuado para participar en el Campeonato, porque eso prácticamente significa que el código creado no contendrá errores: ¡a usted, como participante, no le será necesario corrigir nada!

El asesor comerciará correctamente, y esto será suficiente, por lo menos para aquellos que quieran participar pero no tengan conocimientos de programación o no quieran encargar un asesor en el servicio de Trabajo (una buena alternativa, si desea participar en la competición). En el asesor hay muchos parámetros de entrada que pueden ser configurados de manera óptima, para que corresponda al máximo con su estrategia.

Pero, en la práctica, usted se verá limitado sólo por el conjunto estándar de indicadores con los filtros/patrones estándar, propuestos por la compañía MetaQuotes. Tendrá a su alcance una enorme cantidad de combinaciones y posibilidades de comerciar, dado que los indicadores poseen multitud de parámetros: time frames, símbolos, periodos, precios utilizados, etcétera. En este artículo podrá saber cómo aprender rápidamente y de manera sencilla a configurar y añadir patrones/filtros para los indicadores estándar de MetaTrader 5.

Continuaremos trabajando con el archivo SignalCCIxx.mqh y crearemos nuestro propio modelo comrecial sobre señales del indicador CCI. Antes que nada, añadiremos en el archivo MyExpert.mq5 nuevos parámetros de entrada (marcado en amarillo):

//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
//--- inputs for expert
input string             Expert_Title         ="MyExpert";  // Document name
ulong                    Expert_MagicNumber   =26287;       // 
bool                     Expert_EveryTick     =false;       // 
//--- inputs for main signal
input int                Signal_ThresholdOpen =40;          // Signal threshold value to open [0...100]
input int                Signal_ThresholdClose=60;          // Signal threshold value to close [0...100]
input double             Signal_PriceLevel    =0.0;         // Price level to execute a deal
input double             Signal_StopLevel     =50.0;        // Stop Loss level (in points)
input double             Signal_TakeLevel     =50.0;        // Take Profit level (in points)
input int                Signal_Expiration    =4;           // Expiration of pending orders (in bars)
input int                Signal_RSI_PeriodRSI =8;           // Relative Strength Index(8,...) Period of calculation
input ENUM_APPLIED_PRICE Signal_RSI_Applied   =PRICE_CLOSE; // Relative Strength Index(8,...) Prices series
input double             Signal_RSI_Weight    =0.7;         // Relative Strength Index(8,...) Weight [0...1.0]
input int                Signal_MA_PeriodMA   =90;          // Moving Average(12,0,...) Period of averaging
input int                Signal_MA_Shift      =0;           // Moving Average(12,0,...) Time shift
input ENUM_MA_METHOD     Signal_MA_Method     =MODE_SMA;    // Moving Average(12,0,...) Method of averaging
input ENUM_APPLIED_PRICE Signal_MA_Applied    =PRICE_CLOSE; // Moving Average(12,0,...) Prices series
input double             Signal_MA_Weight     =0.6;         // Moving Average(12,0,...) Weight [0...1.0]

input int                Signal_CCIxx_PeriodCCI =8;            // Commodity Channel Index(8,...) Period of calculation
input ENUM_APPLIED_PRICE Signal_CCIxx_Applied   =PRICE_CLOSE;  // Commodity Channel Index(8,...) Prices series
input double             Signal_CCIxx_Weight    =0.8;          // Commodity Channel Index(8,...) Weight [0...1.0]

Hemos cambiado los valores de las variables Signal_RSI_Weight y Signal_MA_Weight de 1.0 a 0.7 y 0.6 respectivamente. Para un funcionamiento correcto con los parámetros de entrada para CCIxx (la versión modificada del indicador CCI), hemos acortado estas 3 líneas del código del archivo SignalCCI.mqh y simplemente hemos añadido el postfix "хх".

En la sección "protected" de la declaración de clase hay muchos elementos interesantes:

class CSignalCCI : public CExpertSignal
  {
protected:
   CiCCI             m_cci;            // object-oscillator
   //--- adjusted parameters
   int               m_periodCCI;      // the "period of calculation" parameter of the oscillator
   ENUM_APPLIED_PRICE m_applied;       // the "prices series" parameter of the oscillator
   //--- "weights" of market models (0-100)
   int               m_pattern_0;      // model 0 "the oscillator has required direction"
   int               m_pattern_1;      // model 1 "reverse behind the level of overbuying/overselling"
   int               m_pattern_2;      // model 2 "divergence of the oscillator and price"
   int               m_pattern_3;      // model 3 "double divergence of the oscillator and price"
   //--- variables
   double            m_extr_osc[10];   // array of values of extremums of the oscillator
   double            m_extr_pr[10];    // array of values of the corresponding extremums of price
   int               m_extr_pos[10];   // array of shifts of extremums (in bars)
   uint              m_extr_map;       // resulting bit-map of ratio of extremums of the oscillator and the price

Eche un vistazo a las variables enteras del tipo m_pattern. Estas variables están numeradas consecutivamente de 0 a 3, cada una de ellas constituye un "patrón" o, en otras palabras, un modelo de mercado para la toma de decisiones sobre compra o venta de instrumentos financieros.

Vamos a añadir dos modelos personalizados: m_pattern_4 y m_pattern_5. Esto se hace, simplemente, añadiendo dos líneas de código (dos variables enteras).

//--- "weights" of market models (0-100)
   int               m_pattern_0;      // model 0 "the oscillator has required direction"
   int               m_pattern_1;      // model 1 "reverse behind the level of overbuying/overselling"
   int               m_pattern_2;      // model 2 "divergence of the oscillator and price"
   int               m_pattern_3;      // model 3 "double divergence of the oscillator and price"

   int               m_pattern_4;      // model 4 "our own first new pattern: values cross the zero"
   int               m_pattern_5;      // model 5 "our own second new pattern: values bounce around the zero"

Si estdudia atentamente este código, entenderá la lógica de la compra y la venta, y todo lo demás. Pero nosotros vamos a concentrar nuestros esfuerzos sólo en añadir nuestros propios modelos de mercado, ya que no es nuestra intención explicar línea por línea cada archivo integrado (los lectores curiosos pueden abrir este archivo y estudiarlos por sí mismos, los beneficios de la Guía MQL5 siempre están a mano).

Asímismo, deberemos realizar lo siguiente: en el archivo CSignalCCIxx.mqh pulse Ctrl+H, e introduzca "CCI" como texto de búsqueda, y "CCIxx" como reemplazo. Pulse el botón "Reemplazar todo", se deberán encontrar y reemplazar 41 entradas. Pasamos a la parte superior del archivo:

//+------------------------------------------------------------------+
//| Class CSignalCCIxx.                                              |
//| Purpose: Class of generator of trade signals based on            |
//|          the 'Commodity Channel Index' oscillator.               |
//| Is derived from the CExpertSignal class.                         |
//+------------------------------------------------------------------+
class CSignalCCIxx : public CExpertSignal
  {
protected:
   CiCCIxx             m_CCIxx;            // object-oscillator

y la sustituimos:

protected:
   CiCCIxx             m_CCIxx;            // object-oscillator

por el siguiente fragmento del archivo fuente SignalCCI.mqh:

protected:
   CiCCI             m_CCIxx;            // object-oscillator

Hemos hecho esto porque CiCCI se presta desde otro archivo include. En caso contrario, se producirán varios errores durante la compilación. Ahora podemos compilar el archivo SignalCCIxx.mqh, y como resultado deberá haber 0 errores y 0 advertencias. Si aun así hay errores, es posible que haya hecho usted algo incorrectamente y deberá repetir todo el proceso.

Ahora pasaremos a lo importante: añadiremos nuestros propios patrones. Por ejemplo, añadiremos 2 modelos comerciales. En total, tendremos 4 señales nuevas (patrones): 2 para la compra y 2 para la venta. Aquí tenemos el fragmento de código que vamos a cambiar:

//+------------------------------------------------------------------+
//| Constructor CSignalCCIxx.                                        |
//| INPUT:  no.                                                      |
//| OUTPUT: no.                                                      |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
void CSignalCCIxx::CSignalCCIxx()
  {
//--- initialization of protected data
   m_used_series=USE_SERIES_HIGH+USE_SERIES_LOW;
//--- setting default values for the oscillator parameters
   m_periodCCIxx  =14;
//--- setting default "weights" of the market models
   m_pattern_0  =90;         // model 0 "the oscillator has required direction"
   m_pattern_1  =60;         // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =100;        // model 2 "divergence of the oscillator and price"
   m_pattern_3  =50;         // model 3 "double divergence of the oscillator and price"
   m_pattern_4  =90;         // model 4 "our own first new pattern: "
   m_pattern_5  =90;         // model 5 "our own second new pattern: 
}

Hemos adjudicado el valor 90 a las variables m_pattern_4 y m_pattern_5, pero usted deberá elegir sus propios valores: son los pesos para los nuevos modelos de mercado y ellos influenciarán de manera total y absoluta en todos los comportamientos comerciales del asesor.

Añadimos dos nuevos modelos de mercado. Serán muy sencillos, están pensados simplemente de manera fantasiosa y no son señales comerciales comprobadas, así que no se le ocurra comerciar con ellos. El instrumento cruzamiento nos ayudará a determinar los valores del indicador CCI (ver los dibujos más abajo) para las barras correspondientes.


Primer modelo

Cruzamiento de la línea cero de abajo hacia arriba

Este es nuestro primer modelo para la condición "voting that price will grow" (apostando por que el precio subirá).

Dibujo 5. Nuestro primer modelo, Subida del precio - CCI en la barra 1      Dibujo 6. Nuestro primer modelo, Subida del precio - indicador CCI en la barra 2


Cruzamiento de la línea cero de arriba hacia abajo

Este es nuestro primero modelo para la condición "voting that price will fall" (apostando por que el precio bajará).

Dibujo 7. Nuestro primer modelo, Bajada del precio - indicador CCI en la Barra 1      Dibujo 8. Nuestro primer modelo, Bajada del precio - indicador CCI en la Barra 2


Segundo modelo

Cruzamiento de la línea cero de arriba hacia abajo, y luego de nuevo hacia arriba

Este es nuestro segundo modelo para la condición "voting that price will grow" (apostando por que el precio subirá).

Dibujo 9. Nuestro segundo modelo, Subida del precio - indicador CCI en la Barra 1   Dibujo 10. Nuestro segundo modelo, Subida del precio - indicador CCI en la Barra 2   Dibujo 11. Nuestro segundo modelo, Subida del precio - indicador CCI en la Barra 3


Cruzamiento de la línea cero de abajo hacia arriba, y luego de nuevo hacia abajo

Este es nuestro segundo modelo para la condición "voting that price will fall" (apostando por que el precio bajará).

Dibujo 12. Nuestro segundo modelo, Bajada del precio - indicador CCI en la Barra 1   Dibujo 13. Nuestro segundo modelo, Bajada del precio - indicador CCI en la Barra 2   Dibujo 14. Nuestro segundo modelo, Bajada del precio - indicador CCI en la Barra 3


Realización de los patrones

Para la realización de estas cuatro condiciones (dos para cada modelo) debemos cambiar el siguiente fragmento de código de esta forma. En la parte inferior hemos añadido líneas de código (destacadas en amarillo) para la condición de compra (ver en los comentarios: "Voting" that price will grow).

//+------------------------------------------------------------------+
//| "Voting" that price will grow.                                   |
//| INPUT:  no.                                                      |
//| OUTPUT: number of "votes" that price will grow.                  |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
int CSignalCCIxx::LongCondition()
  {
   int result=0;
   int idx   =StartIndex();
//---
   if(Diff(idx)>0.0)
     {
      //--- the oscillator is directed upwards confirming the possibility of price growth
      if(IS_PATTERN_USAGE(0)) result=m_pattern_0;      // "confirming" signal number 0
      //--- if the model 1 is used, search for a reverse of the oscillator upwards behind the level of overselling
      if(IS_PATTERN_USAGE(1) && Diff(idx+1)<0.0 && CCIxx(idx+1)<-100.0)
         result=m_pattern_1;      // signal number 1
      //--- if the model 2 or 3 is used, perform the extended analysis of the oscillator state
      if(IS_PATTERN_USAGE(2) || IS_PATTERN_USAGE(3))
        {
         ExtState(idx);
         //--- if the model 2 is used, search for the "divergence" signal
         if(IS_PATTERN_USAGE(2) && CompareMaps(1,1))      // 00000001b
            result=m_pattern_2;   // signal number 2
         //--- if the model 3 is used, search for the "double divergence" signal
         if(IS_PATTERN_USAGE(3) && CompareMaps(0x11,2))   // 00010001b
            return(m_pattern_3);  // signal number 3
        }
      // if the model 4 is used, look for crossing of the zero line
      if(IS_PATTERN_USAGE(4) && CCIxx(idx+1)>0.0 && CCIxx(idx+2)<0.0)
         result=m_pattern_4;      // signal number 4 
      // if the model 5 is used, look for the bouncing around the zero line
      if(IS_PATTERN_USAGE(5) && CCIxx(idx+1)>0.0 && CCIxx(idx+2)<0.0 && CCIxx(idx+3)>0.0)
         result=m_pattern_5;      // signal number 5
     }
//--- return the result
   return(result);
  }

Vamos a cambiar de la misma forma el código correspondiente para la condición de venta. En la parte inferior hemos añadido líneas de código (destacadas en amarillo) para la condición de venta (ver en los comentarios: "Voting" that price will fall).

//+------------------------------------------------------------------+
//| "Voting" that price will fall.                                   |
//| INPUT:  no.                                                      |
//| OUTPUT: number of "votes" that price will fall.                  |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
int CSignalCCIxx::ShortCondition()
  {
   int result=0;
   int idx   =StartIndex();
//---
   if(Diff(idx)<0.0)
     {
      //--- the oscillator is directed downwards confirming the possibility of falling of price
      if(IS_PATTERN_USAGE(0)) result=m_pattern_0;      // "confirming" signal number 0
      //--- if the model 1 is used, search for a reverse of the oscillator downwards behind the level of overbuying
      if(IS_PATTERN_USAGE(1) && Diff(idx+1)>0.0 && CCIxx(idx+1)>100.0)
         result=m_pattern_1;      // signal number 1
      //--- if the model 2 or 3 is used, perform the extended analysis of the oscillator state
      if(IS_PATTERN_USAGE(2) || IS_PATTERN_USAGE(3))
        {
         ExtState(idx);
         //--- if the model 2 is used, search for the "divergence" signal
         if(IS_PATTERN_USAGE(2) && CompareMaps(1,1))      // 00000001b
            result=m_pattern_2;   // signal number 2
         //--- if the model 3 is used, search for the "double divergence" signal
         if(IS_PATTERN_USAGE(3) && CompareMaps(0x11,2))   // 00010001b
            return(m_pattern_3);  // signal number 3
        }
      if(IS_PATTERN_USAGE(4) && CCIxx(idx+1)<0.0 && CCIxx(idx+2)>0.0)
         result=m_pattern_4;      // signal number 4 
      if(IS_PATTERN_USAGE(5) && CCIxx(idx+1)<0.0 && CCIxx(idx+2)>0.0 && CCIxx(idx+3)<0.0)
         result=m_pattern_5;      // signal number 5  
     }
//--- return the result
   return(result);
  }

Preste atención a (idx+1), (idx+2) ... (idx+n) en las líneas añadidas: +1, +2, +3 y etcétera son los números de las barras (velas), precedentes a la barra actual (vela) (la actual es la que aún no se ha formado, es decir, la barra cero).

Dibujo 15. Correspondencia de las barras (velas) de la variable (idx) en el código.

De esta forma, cuanto mayor sea el valor idx+N, más lejos nos encontraremos de la barra actual. Cada barra (idx+n) corresponde al valor del indicador en la misma "posición vertical" en un time frame.

Dibujo 16. Cada barra (idx) corresponde al valor relativo CCI

En el dibujo 16 la barra cero (la primera vela de la derecha, correspondiente al valor idx o (idx+0) en el código) corresponde a un valor CCI inferior al nivel 0.00. Asímismo, la segunda barra (idx +1) y la tercera barra (idx +2) tienen valores inferiores a la línea 0.00. No hemos marcado otras barras con flechas verticales, pero si coloca el cursor del ratón sobre la 4 barra (idx +3), entonces podrá ver que su valor CCI correspondiente es superior a 0.00.

Para la mayoría de los usuarios este hecho resulta obvio, pero para los principiantes es mejor saber cómo se corresponden entre sí las barras/velas en el gráfico de precios, la representación gráfica del indicador CCI, la variable (idx) y el valor de la variable de indicador CCIxx.

Mirando los indicadores del gráfico, es importante intentar "ver" la correspondencia entre las barras/velas y el comportamiento del indicador, así podrá hacer presuposiciones sobre la existencia de una estrategia que pueda ser programada y codificada fácilmente con ayuda del índice de barra (idx) y los valores de la variable de indicador.

En el archivo SignalCCIxx.mqh el código siguiente:

CCIxx(idx+1)>0.0 && CCIxx(idx+2)<0.0

significa literalmente lo siguiente:

El valor de indicador CCI (una barra antes, es decir idx+1) está por encima de la línea del nivel cero del indicador CCI
y
El valor de indicador CCI (dos barras antes, es decir idx+2) está por debajo de la línea  del nivel cero del indicador CCI

Es el ejemplo más sencillo de lo simple que es añadir dos patrones personalizados, basándose sólo en el valor de indicador que elegimos (en este caso - CCI).

La condición "el precio va a aumentar" o "el precio va a caer" hay que añadirla con la descripción de los patrones, y nadie nos prohíbe crear condiciones más complicadas. Antes de la simulación definitiva, vamos a ver los mecanismos de apertura y cierre de posición.

El mecanismo y la lógica están muy bien descritos en la Guía MQL5, en el apartado Clases de estrategias comerciales de la Biblioteca estándar.

En pocas palabras, en el archivo MyExpert.mq5 tenemos 2 parámetros de entrada (dos variables enteras):

//--- inputs for main signal
input int                Signal_ThresholdOpen =40;          // Signal threshold value to open [0...100]
input int                Signal_ThresholdClose=60;          // Signal threshold value to close [0...100]

Estos umbrales de apertura y cierre suponen dos valores que se usan para el cálculo, si (de acuerdo con nuestro modelo comercial) se ha abierto y cerrado después una posición larga o corta. Como valor de umbral se usa una cifra entera del 0 al 100. ¿Qué indican estos parámetros?

Signal_ThresholdOpen es el valor para la apertura de una posición larga o corta, Signal_ThresholdClose es el valor para el cierre de una posición abierta con anterioridad. Estos valores se calculan en el contexto de la lógica de los expertos, generados por el Asistente de MQL5.

Cada señal en los archivos Signal__.mqh (en lugar de __ se pone el nombre del indicador usado, en nuestro caso MA, RSI y CCIxx) consta de los modelos anteriormente descritos. Echémosles de nuevo un vistazo en nuestro ejemplo. En el archivo SignalMA.mqh tenemos 4 patrones, cada uno de los cuales tiene su "peso" relativo:

//--- setting default "weights" of the market models
   m_pattern_0 =80;          // model 0 "price is on the necessary side from the indicator"
   m_pattern_1 =10;          // model 1 "price crossed the indicator with opposite direction"
   m_pattern_2 =60;          // model 2 "price crossed the indicator with the same direction"
   m_pattern_3 =60;          // model 3 "piercing"

Para las señales RSI en el archivo SignalRSI.mqh de manera análoga:

//--- setting default "weights" of the market models
   m_pattern_0  =70;         // model 0 "the oscillator has required direction"
   m_pattern_1  =100;        // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =90;         // model 2 "failed swing"
   m_pattern_3  =80;         // model 3 "divergence of the oscillator and price"
   m_pattern_4  =100;        // model 4 "double divergence of the oscillator and price"
   m_pattern_5  =20;         // model 5 "head/shoulders"

En nuestra señal personalizada SignalCCIxx.mqh (es prácticamente una copia exacta de SignalCCI.mqh) tenemos los siguientes valores:

//--- setting default "weights" of the market models
   m_pattern_0  =90;         // model 0 "the oscillator has required direction"
   m_pattern_1  =60;         // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =100;        // model 3 "divergence of the oscillator and price"
   m_pattern_3  =50;         // model 4 "double divergence of the oscillator and price"
   m_pattern_4  =80;         // model 4 "our own first new pattern: "
   m_pattern_5  =90;         // model 5 "our own second new pattern: "

Los modelos estándar 0, 1, 2, 3 más nuestros propios 4 y 5, con los valores 80 y 90, respectivamente. Cuando añadimos MyExpert.ex5 en el gráfico o lo probamos en el Simulador de estrategias, se calculan consecutivamente todas las señales elegidas (RSI, MA и CCIxx).

Si se cumple la condición de uno o varios de los patrones, la señal se usa en el cálculo siguiente. Por ejemplo, si la condición m_pattern_4 del archivo SignalCCIxx.mqh se cumple:

// if the model 4 is used, look for crossing of the zero line
       if(IS_PATTERN_USAGE(4) && CCIxx(idx+1)>0.0 && CCIxx(idx+2)<0.0)
          result=m_pattern_4;      // signal number 4 

el patrón se convierte en una señal comercial en potencia. En otras palabras, si el valor CCI en la barra 1 > 0.0 y al mismo tiempo el valor CCI en la barra 2 era < 0.0, como se muestra en los dibujos 5 y 6, la condición se cumple y m_pattern_4 (la señal №4) se activa.

El valor del peso establecido para esta señal en nuestra estrategia CCIxx, es igual al valor absoluto 80, pero en el caso "voting that price will fall" (apostando que el precio bajará) se usará el valor -80, y en el caso "voting that the price will grow" (apostando que el precio subirá) el valor 80. La apuesta por la caída del precio añade el símbolo menos al valor original del peso del patrón.

Suponiendo que la condición para m_pattern_4 se cumpla, la posición se abrirá sólo cuando:

De esta forma, podemos estudiar cada modelo como la competencia de 2 grupos: las señales del toro y las señales del oso. Cuando estos modelos/señales unidireccionales (apuesta por la subida del precio) están activados (sus condiciones se cumplen), se suman los unos a los otros, y el resultado se compara con el valor de Signal_ThresholdOpen. Si no hay posiciones abiertas y la suma se compara con el valor de Signal_ThresholdClose para una posición abierta con anterioridad (en nuestro ejemplo se trata de una posición corta), m_pattern_4 de SignalCCIxx.mqh tiene el valor:

Supongamos que TODOS los demás modelos de TODAS las señales (SignalRSI.mqh, SignalMA.mqh y los modelos 0,1,2,3 y 5 de SignalCCIxx.mqh) reciban el valor 0. Es decir, que las señales de los "competidores" están en fuera de "juego", sólo compiten dos m_pattern_4 uno para la compra y otro para la venta. De esta forma, funciona sólo m_pattern_4, porque tiene un valor distinto al valor 0, es decir 80.

//--- setting default "weights" of the market models
   m_pattern_0 =0;          // model 0 "price is on the necessary side from the indicator"
   m_pattern_1 =0;          // model 1 "price crossed the indicator with opposite direction"
   m_pattern_2 =0;          // model 2 "price crossed the indicator with the same direction"
   m_pattern_3 =0;          // model 3 "piercing"

Para las señales RSI en el archivo SignalRSI.mqh de manera análoga:

//--- setting default "weights" of the market models
   m_pattern_0  =0;         // model 0 "the oscillator has required direction"
   m_pattern_1  =0;        // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =0;        // model 2 "failed swing"
   m_pattern_3  =0;        // model 3 "divergence of the oscillator and price"
   m_pattern_4  =0;        // model 4 "double divergence of the oscillator and price"
   m_pattern_5  =0;        // model 5 "head/shoulders"

En nuestra señal personalizada SignalCCIxx.mqh (es prácticamente una copia exacta de SignalCCI.mqh) tenemos los siguientes valores:

//--- setting default "weights" of the market models
   m_pattern_0  =0;        // model 0 "the oscillator has required direction"
   m_pattern_1  =0;        // model 1 "reverse behind the level of overbuying/overselling"
   m_pattern_2  =0;        // model 3 "divergence of the oscillator and price"
   m_pattern_3  =0;        // model 4 "double divergence of the oscillator and price"
   m_pattern_4  =80;       // model 4 "our own first new pattern: "
   m_pattern_5  =0;        // model 5 "our own second new pattern: "

Al principio del artículo habíamos añadido las siguientes líneas:

input int                Signal_CCIxx_PeriodCCI =8;            // Commodity Channel Index(8,...) Period of calculation
input ENUM_APPLIED_PRICE Signal_CCIxx_Applied   =PRICE_CLOSE;  // Commodity Channel Index(8,...) Prices series
input double             Signal_CCIxx_Weight    =0.8;          // Commodity Channel Index(8,...) Weight [0...1.0]

Habíamos estudiado la variable Signal_CCIxx_Weight, que tenía un valor de 0.8. Al alcanzar el valor de umbral, se pone en funcionamiento Signal_ThresholdOpen. El valor se calcula de la forma siguiente:

0.8 (parámetro de entrada Signal_CCIxx_Weight)
*
80 (valor del peso m_pattern_4)
= 64 es la fuerza de la señal para la apuesta por la subida del precio

Es una suposición de que el precio va a subir, porque el algoritmo recibió la señal de "crecimiento del precio" (m_pattern_4 из SignalCCIxx) y el valor 80.

Si, hipotéticamente, recibiese la señal de "caída del precio" (m_pattern_4 из SignalCCIxx), el valor sería igual a -80. El algoritmo simplemente añade el signo menos al patrón. Para la suposición de que el precio caerá, los cálculos serían los siguientes:

0.8 (parámetro de entrada Signal_CCIxx_Weight)
*
-80 (valor del peso m_pattern_4)
= -64 valor negativo para las posiciones cortas

-64 --> 64 (es una magnitud absoluta) constituye la fuerza de la señal para las apuestas por la bajada del precio. La fuerza de la señal se expresa siempre en una magnitud absoluta, al tiempo que para los valores de las posiciones cortas se pone el signo menos, y para los valores de las posiciones largas, el signo más.

Volvamos al ejemplo para la posición larga con un valor alcanzado de 64 y una intensidad de la señal igual a 64. Si no existen otras señales opuestas (con el signo menos) que entren en competencia (m_pattern_N из Signal__), el nivel de Signal_ThresholdOpen con un valor 40 será alcanzado y superado por 24, dado que la fuerza de la señal larga representa 64 (40+24=64), y por consiguiente se abrirá una posición larga.

Por ejemplo, si para la señal Signal_CCIxx_Weight establecemos un valor de 0.4, no se abrirán posiciones largas, dado que:

0.4 (Signal_CCIxx_Weight)
*
80(m_pattern_4)
= 32 (fuerza de la "señal larga")

y el nivel 40 (Signal_ThresholdOpen) no es alcanzado, ya que 32 < 40.

Los valores mostrados más arriba (todos los valores son iguales a 0, a excepción de 80 para m_pattern_4 de SignalCCIxx.mqh) han sido tomados únicamente de manera hipotética, sólamente para que la lógica del Asistente MQL5 y su sistema de pesos y umbrales sea más comprensible. Para sus propios asesores, tendrá usted que adjudicar los pesos preferibles a cada m_pattern_N en cada Signal__. Si al patrón se le adjudica un valor a partir de 0, esto significa, simplemente, que ese modelo sencillamente no se va a usar.

Si queremos establecer otro valor en el ejemplo de arriba (todos los parámetros configurados en 0, a excepción de m_pattern_4 de SignalCCIxx.mqh), y digamos 100 para m_pattern_1 de SignalRSI.mqh, el cálculo cambia, ya que ahora obtenemos 4 competidores:

m_pattern_4 Bullish --> 0.8 * 80 = 64
m_pattern_2 Bullish --> 0.7 * 100 = 70
m_pattern_4 Bearish --> 0.8 * (-80) = -64
m_pattern_2 Bearish --> 0.7 * (-100) = -70

De este modo, obtenemos 4 combinaciones posibles:

A) m_pattern_4 Bullish + m_pattern_2 Bullish = {[0.8 * (80)] + [0.7 * (100)]}/2 = [64 + (70)]/2 = 134/2 = 67
B) m_pattern_4 Bullish + m_pattern_2 Bearish = {[0.8 * (80)] + [0.7 * (-100)]}/2 = [64 + (-70)]/2 = -6/2 = -3
C) m_pattern_4 Bearish + m_pattern_2 Bullish = {[0.8 * (-80)] + [0.7 * (100)]}/2 = [(-64) + 70]/2 = 6/2 = 3
D) m_pattern_4 Bearish + m_pattern_2 Bearish = {[0.8 * (-80)] + [0.7 * (-100)]}/2 = [(-64) + (-70)]/2 = -134/2 = -67

Variante A
Valor positivo 67. Se abre una posición larga, porque se ha alcanzado y superado el umbral Signal_ThresholdOpen con un valor de 40. Después se cierra la posición larga, al ser alcanzado y superado el umbral Signal_ThresholdClose con valor 60 según la magnitud absoluta de la Variante D = -67 = |67|, porque la fuerza de la señal de la Variante D según su magnitud absoluta 67 > 60 (es decir, mayor al umbral Signal_ThresholdClose).

Variante B
Valor negativo -3. No se abren posiciones cortas, porque el umbral de Signal_ThresholdOpen con un valor 40, no ha sido alcanzado y superado en su magnitud absoluta: -3 se ha vuelto igual a 3, cuando nos fijamos en su valor absoluto para el cálculo de "la fuerza de la señal", y 3 < 40 (el valor de la señal para la apertura de la posición). No hay posiciones cortas abiertas y, propiamente, no existe cálculo alguno para el cierre de las posiciones cortas.

Variante C
Valor positivo 3. No se abren posiciones largas, porque el umbral Signal_ThresholdOpen con un valor de 40, no ha sido ni alcanzado, ni superado 3 < 40 (el valor de la señal para la apertura de posición). No hay posiciones largas abiertas y, propiamente, no existe cálculo alguno para el cierre de las posiciones largas.

Variante D
Valor negativo -67. Se abre una posición corta, porque el umbral Signal_ThresholdOpen con un valor de 40, ha sido alcanzado y superado por la fuerza de la señal, cuya magnitud absoluta ha sido calculada en -67, es decir 67, y 67 > 40. Después la posición corta se cierra, cuando se alcanza y supera el umbral Signal_ThresholdClose con un valor de 60 según el valor de la Variante A = 67, porque 67 (fuerza de la señal A) > 60 (es decir, mayor al umbral Signal_ThresholdClose).

En otras palabras, para la apertura de posiciones cortas, primero tenemos que determinar la dirección causante del valor negativo de la señales, después tenemos que transformar el valor en una maginitud absoluta para el cálculo de la fuerza de la señal, que después se comparará con el valor del umbral Signal_ThresholdOpen con objeto de aclarar cuál de los dos es mayor.

El cierre de las posiciones largas se ejecuta de manera análoga: primero cerramos la posición larga conforme al valor negativo (y al contrario, para el cierre de una posición corta el valor es positivo), después este valor negativo se transformará en magnitud absoluta y se comparará con el valor del umbral Signal_ThresholdClose.

Para la apertura de posiciones largas y el cierre de cortas los cálculos se llevan a cabo con las cifras positivas (no hay señales con el signo menos), por eso las magnitudes absolutas no se contemplan. De tener entre manos un valor positivo de señal, se pone en funcionamiento la apertura de posiciones largas, así como el cierre de posiciones cortas.

Primero se determina el signo más y el signo menos para la apertura de posiciones largas o la apertura de posiciones cortas, o bien para el cierre de posiciones cortas o el cierre de posiciones largas, respectivamente. Después calculamos sus valores absolutos para la compararlos con los valores de umbral Signal_ThresholdOpen y Signal_ThresholdClose, que siempre tienen signo positivo.


Información detallada sobre la posición

Veamos la posición con más detalle:

La posición larga se abre si:

Open_long >= Signal_ThresholdOpen
SI Signal_ThresholdClose <= Signal_ThresholdOpen
Obtenemos una señal de venta, porque la posición larga será invertida si:
Open_short > Signal_ThresholdClose Y Open_short > Signal_ThresholdOpen
Obtenemos una señal de venta, porque la posición larga será cerrada si:
Open_short > Signal_ThresholdClose Y Open_short < Signal_ThresholdOpen

SI Signal_ThresholdClose >= Signal_ThresholdOpen
Obtenemos una señal de venta, porque la posición larga será invertida si:
Open_short > Signal_ThresholdClose O Open_short > Signal_ThresholdOpen
Obtenemos una señal de venta, porque la posición larga será cerrada si:
Open_short > Signal_ThresholdClose O Open_short < Signal_ThresholdOpen

En el caso de Signal_ThresholdClose >= Signal_ThresholdOpen se tratará de un "O" lógico, porque la expresión Signal_ThresholdClose >= Signal_ThresholdOpen ya incluye en sí mismo el valor Signal_ThresholdOpen. De esta modo, la posición será cerrada y determinada de nuevo por el valor Signal_ThresholdClose >= Signal_ThresholdOpen, es decir, se invertirá, en cualquier caso, en la dirección de la venta.


La posición corta se abre si:

Open_short >= Signal_ThresholdOpen.
Signal_ThresholdClose <= Signal_ThresholdOpen
Obtenemos la señal de compra, por eso la posición corta será invertida si:
Open_long > Signal_ThresholdClose Y Open_long > Signal_ThresholdOpen
Obtenemos la señal de compra, por eso la posición corta será cerrada si:
Open_long > Signal_ThresholdClose Y Open_long < Signal_ThresholdOpen

SI Signal_ThresholdClose >= Signal_ThresholdOpen
Obtenemos la señal de compra, por eso la posición corta será invertida si:
Open_long > Signal_ThresholdClose O Open_long > Signal_ThresholdOpen
Obtenemos la señal de compra, por eso la posición corta será cerrada si:
Open_long > Signal_ThresholdClose O Open_long < Signal_ThresholdOpen

En el caso de Signal_ThresholdClose >= Signal_ThresholdOpen se tratará de un "O" lógico, porque la expresión Signal_ThresholdClose >= Signal_ThresholdOpen ya incluye en sí mismo el valor Signal_ThresholdOpen. De esta forma, la posición será cerrada y determinada de nuevo por el valor Signal_ThresholdClose >= Signal_ThresholdOpen, es decir, se invertirá, en cualquier caso, en la dirección de la compra.

El mecanismo de apertura y cierre de posición del asesor, creado por el Asistente, está pensado concienzudamente, ya que se basa en un sistema de pesos, valores y umbrales de puesta en funcionamiento. Usando este mecanismo, la gestión de las posiciones se llevará a cabo "metódicamente" y sin errores de lógica.


Nivel de precios y expiración de la señal

Existe otra variable importante más:

input double             Signal_PriceLevel    =0.0;         // Price level to execute a deal

Esta variable es muy importante para la comprensión básica del mecanismo del asesor creado por el Asistente. Se puede representar de una manera sencilla, de la forma siguiente:

Dibujo 17. Órdenes stop y limit, dependiendo del valor Signal_PriceLevel

Por ejemplo:

EURUSD - Posiciones largas

Signal_PriceLevel = -70 (menos 70)
al recibir la señal de apertura de posición (por ejemplo, precio actual = 1.2500),
el asesor emitirá una orden Buy Stop, compuesta por 1.2500 + 70 = 1,2570
(peor que el precio actual, desde el punto de vista de los toros)


Signal_PriceLevel = 60 (más 60)
al recibir la señal de apertura de posición (por ejemplo, precio actual = 1.2500),
el asesor emitirá una orden Buy Limit, compuesta por 1.2500 - 60 = 1,2440
(mejor que el precio actual, desde el punto de vista de los toros)


EURUSD - Posiciones cortas

Signal_PriceLevel = -70 (menos 70)
al recibir la señal de apertura de posición (por ejemplo, precio actual = 1.2500),
el asesor emitirá una Sell Stop, compuesta por 1.2500 - 70 = 1,2430
(mejor que el precio actual, desde el punto de vista de los osos)


Signal_PriceLevel = 60 (más 60)
al recibir la señal de apertura de posición (por ejemplo, precio actual = 1.2500),
el asesor emitirá una Sell Limit, compuesta por 1.2500 + 60 = 1,2560
(peor que el precio actual, desde el punto de vista de los osos)


Finalmente, el parámetro de entrada

input int                Signal_Expiration    =4;           // Expiration of pending orders (in bars)

determina cuántas veces (expresado en barras) actuarán las órdenes Stop/Limit.


Bloque-esquema

Para que resulte más comprensible, puede echarle un vistazo a este esquema simplificado, que refleja de manera aproximada el mecanismo de funcionamiento del asesor generado por el Asistente MQL5.

Dibujo 18. Esquema simplificado del procesado de las órdenes y las posiciones


Simulador de estrategias

Ahora vamos a volver a nuestra estrategia, así que compilaremos el archivo SignalCCIxx.mqh. Si lo ha hecho todo correctamente, no debería haber ningún error. De hecho, hemos añadido 2 nuevos modelos de mercado para la toma de decisiones comerciales. Cada patrón incluye las condiciones de compra y venta, así como las condiciones de apertura y cierre de posición.

Ahora vamos a compilar el archivo MyExpert.mq5, y si todo está en orden, el compilador mostrará 0 errores y 0 advertencias. Bueno, vamos a ponerlo en marcha en el Simulador de estrategias. He usado los parámetros para EUR/USD en un periodo de tiempo correspondiente al último Automated Trading Championship 2011.

Dibujo 19. Configuración de parámetros para la simulación ATC2011 con MyExpert.mq5

A pesar de que el asesor arroja "buenos" resultados y que incrementa en más de dos veces el depósito inicial en menos de 3 meses con un lote fijo, no recomiendo usarlo para el comercio real. Le recomiendo añadir sus propios modelos de mercado y experimentar con ellos, optimizándolos hasta que no obtenga los resultados que le convengan.

En cualquier caso, nuestro objetivo es mostrar que la ampliación de las clases de estrategias comerciales existentes funciona.

Dibujo 20. Resultados de pseudo ATC2011 con MyExpert.mq5

Puede crear nuevos modelos de mercado y compartirlos con los miembros de MQL5.community. Con la ayuda del Asistente MQL5 y este sencillo método descrito en el artículo, le será fácil comprobar y testar estos patrones. Este artículo es un ejemplo de cómo estudiar las clases de estrategias comerciales de la biblioteca estándar y lo sencillo que es cambiar las bibliotecas para crear sistemas comerciales propios.


Conclusión

Hemos añadido fácilmente 2 filtros/plantillas para la señal CCI. Puede hacer lo mismo con otros indicadores, creando, así, su propio grupo de señales. Si se pone manos a la obra con este trabajo, de manera concienzuda, obtendrá un potente instrumento para comerciar.

Se trata de un método cómodo para crear sus propias estrategias, basta con entender las bases del funcionamiento de su propio indicador. El Asistente MQL5 cumplirá con el resto del trabajo relacionado con las funciones comerciales y las operaciones del asesor. Eso le ahorrará tiempo y le garantizará el correcto funcionamiento del robot comercial.

Podrá escribir su propia estrategia de manera sencilla con ayuda de los indicadores estándar MetaTrader 5, empaquetándolos en un asesor listo para el Campeonato.