Documente Academic
Documente Profesional
Documente Cultură
Introducción
MetaTrader 5 proporciona una herramienta potente para la comprobación rápida de los conceptos del trading.
Se trata del generador de estrategias de trading de MQL5 Wizard. Se describe el uso de MQL5 Wizard para la
creación automática de códigos de Asesores Expertos en el artículo "MQL5 Wizard: Crear Asesores Expertos sin
programar". El hecho de que el sistema de generación del código sea abierto, permite complementar clases
estándar con clases personalizadas de señales de trading, sistemas de gestión de dinero y módulos de trailing.
En este artículo se describen los principios de escritura de módulos de trailing de posiciones abiertas para su
uso posterior en MQL5 Wizard.
Un Asesor Experto creado con MQL5 Wizard, se basa en cuatro clases base:
La clase CExpert (o sus subclases) es el "motor" principal de un robot de trading. La instancia de la clase
CExpert contiene instancias de las clases CExpertSignal, CExpertMoney y CExpertTrailing (o sus subclases):
De ahora en adelante, nos vamos a referir en con el término "Asesor Experto" en este artículo a una instancia
de la clase CExpert o de su subclase.
Se tratará con más detalle la descripción de la clase CExpert y el proceso de trabajar con ella en un artículo
aparte.
Inicialización Descripción
virtual InitIndicators Creación e inicialización de todos los indicadores y series temporales requeridos
para el funcionamiento del generador de señales de trading
Señales de
modificación de las
posiciones
virtual Generación de una señal para la modificación de una posición larga con
CheckTrailingStopLong determinación del nuevo precio para la orden Stop
virtual Generación de una señal para la modificación de una posición corta con
CheckTrailingStopShort determinación del nuevo precio para la orden Stop
1.1.1 Init
Se llama al método Init() automáticamente justo después de añadir la instancia de clase al Asesor Experto.
No se requiere sobreescritura del método.
1.1.2 ValidationSettings
Se llama al método ValidationSettings() desde el Asesor Experto después de configurar todos los parámetros.
Es necesario sobreescribir el método si hay ajustes de configuración.
Si todos los parámetros son correctos (se pueden usar), el método sobreescrito devolverá true. Si alguno de
los parámetros no es válido, el parámetro devolverá false (no pueden haber más operaciones).
La clase base CExpertTrailing no tiene parámetros ajustables, por tanto, el método siempre devolverá true
sin llevar a cabo ninguna comprobación.
1.1.3 InitIndicators
El método InitIndicators () crea e inicializa todos los indicadores y series temporales necesarios. Se le llama
desde el Asesor Experto tras la configuración y validación de todos los parámetros. Si el generador de señales
de trading usa por lo menos un indicador o serie temporal, habrá que sobreescribir el método.
Hay que usar los indicadores y/o series temporales con las clases correspondientes de la librería estándar. Se
deben añadir los punteros de todos los indicadores y/o series temporales al conjunto de indicadores del Asesor
Experto (un puntero que se le envía como un parámetro).
Si todas las operaciones con los indicadores y/o series temporales tienen éxito (su uso es viable), el método
sobreescrito devolverá true. Si al menos una operación con los indicadores y/o series temporales falla, el
método devolverá false (no puede seguir funcionando).
La clase base CExpertTrailing no usa indicadores o series temporales, por tanto, el método de la clase base
siempre devuelve true, sin llevar a cabo ninguna acción.
El método CheckTrailingStopLong() genera una señal de modificación de una posición larga, definiendo un
nuevo precio para la orden Stop Loss (así como para la orden Take Profit si fuera necesario). Se le llama desde
el Asesor Experto para determinar si hace falta modificar una posición larga. Si desea generar una señal de
modificación de una posición larga, debe ser sobreescrito.
La clase base CExpertTrailing no tiene incluido un algoritmo para la generación de la señal de modificación
de una posición larga, así que el método de la clase base siempre devuelve false.
1.2.2 CheckTrailingStopShort
El método CheckTrailingStopShort() genera una señal de modificación de una posición corta, definiendo un
nuevo precio de la orden Stop Loss (así como para la orden Take Profit si fuera necesario). Se le llama desde
el Asesor Experto para determinar si es necesario modificar una posición corta. Si desea generar una señal de
modificación de una posición corta, debe ser sobreescrito.
La clase base CExpertTrailing no tiene incluido un algoritmo para la generación de la señal de modificación
de una posición corta, así que el método de la clase base siempre devuelve false.
Comencemos:
En primer lugar, creamos (por ejemplo, mediante el mismo MQL5 Wizard) un archivo de inclusión con la
extensión mqh.
Seleccione "Nuevo" (Create) a partir del menú Archivo (o pulse la combinación del teclado Ctrl+N) y elija la
creación de un archivo de inclusión:
Cabe señalar que, para que MQL5 Wizard pueda "reconocer" el archivo como un modulo de trailing de
posiciones abiertas, hay que crearlo en la carpeta Include\Expert\.
Para evitar conflictos con la librería estándar, cree su propia carpeta Include\Expert\Trailing\MyTrailing, en la
cual se guardará el archivo SampleTrailing.mqh, especificando los siguientes parámetros en MQL5 Wizard:
Figura 3. Configuración de la ubicación del archivo de inclusión
//+------------------------------------------------------------------+
//| SampleTrailing.mqh |
//| Copyright 2010, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
//+------------------------------------------------------------------+
//| defines |
//+------------------------------------------------------------------+
// #define MacrosHello "Hello, world!"
// #define MacrosYear 2010
//+------------------------------------------------------------------+
//| DLL imports |
//+------------------------------------------------------------------+
// #import "user32.dll"
// int SendMessageA(int hWnd,int Msg,int wParam,int lParam);
// #import "my_expert.dll"
// int ExpertRecalculate(int wParam,int lParam);
// #import
//+------------------------------------------------------------------+
//| EX5 imports |
//+------------------------------------------------------------------+
// #import "stdlib.ex5"
// string ErrorDescription(int error_code);
// #import
//+------------------------------------------------------------------+
Lo que viene a continuación es un trabajo "manual". Eliminamos las partes que no hacen falta y añadimos las
que necesitamos (incluir el archivo ExpertTrailing.mqh de la librería estándar y la descripción de la clase que
está vacía ahora).
//+------------------------------------------------------------------+
//| SampleTrailing.mqh |
//| Copyright 2010, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010 MetaQuotes Software Corp "
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
//+------------------------------------------------------------------+
//| include files |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
//+------------------------------------------------------------------+
//| Class CSampleTrailing. |
//| Purpose: Clase para el trailing de posiciones abiertas. |
//| Is derived from the CExpertTrailing class. |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
{
};
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| SampleTrailing.mqh |
//| Copyright 2010, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
//+------------------------------------------------------------------+
//| include files |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
//+------------------------------------------------------------------+
//| Class CSampleTrailing. |
//| Purpose: Class for trailing of open positions by |
//| moving the Stop order "to the loseless level". |
//| Is derived from the CExpertTrailingclass. |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
{
};
//+------------------------------------------------------------------+
Vamos a definir ahora los datos necesarios para la toma de decisiones relacionadas con la modificación de
órdenes de protección. En nuestro caso, es el beneficio de una posición modificada en puntos.
Definimos la lista de parámetros de configuración de nuestro módulo para el seguimiento de las posiciones
abiertas. Se requieren dos parámetros:
1. El número de puntos del beneficio de la posición requeridos, para sugerir un desplazamiento de la orden
Stop a un nivel sin pérdidas.
2. El nivel sin pérdidas, es decir, qué cantidad de puntos de beneficio fijamos mediante la orden Stop
desplazada.
La configuración del módulo se almacena en los miembros de datos protegidos de la clase. Se implementará el
acceso a estos ajustes mediante los métodos públicos correspondientes.
Vamos a incluir estos cambios en nuestro archivo:
//+------------------------------------------------------------------+
//| SampleTrailing.mqh |
//| Copyright 2010, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
//+------------------------------------------------------------------+
// i i
//| include files |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
//+------------------------------------------------------------------+
//| Class CSampleTrailing. |
//| Purpose: Class for trailing of open positions |
//| by moving Stop order to a lossless level. |
//| Is derived from the CExpertTrailing class. |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
{
protected:
int m_profit; //threshold level of profit
int m_stop_level; // lossless level
public:
//--- methods of setting adjustable parameters
void Profit(int value) { m_profit=value; }
void StopLevel(int value) { m_stop_level=value; }
};
//+------------------------------------------------------------------+
Para inicializar los parámetros ajustables con los valores por defecto, es necesario añadir el constructor de
clase.
Para comprobar la configuración, vamos a sobreescribir el método virtual ValidationSettings (según la
descripción de la clase base).
Descripción de la clase:
//+------------------------------------------------------------------+
//| SampleTrailing.mqh |
//| Copyright 2010, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
//+------------------------------------------------------------------+
//| include files |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
//+------------------------------------------------------------------+
//| Class CSampleTrailing. |
//| Purpose: Class for trailing of open positions |
//| by moving Stop order to a lossless level. |
//| Is derived from the CExpertTrailing class. |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
{
protected:
int m_profit; // threshold level of profit
int m_stop_level; // lossless level
public:
CSampleTrailing();
//--- methods of setting adjustable parameters
void Profit(int value) { m_profit=value; }
void StopLevel(int value) { m_stop_level=value; }
//--- method of validating the adjustable parameters
virtual bool ValidationSettings();
};
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Validation of adjustable parameters. |
//| INPUT: no. |
//| OUTPUT: true if parameter are correct, false - if not. |
//| REMARK: no. |
//+------------------------------------------------------------------+
bool CSampleTrailing::ValidationSettings()
{
if(!CExpertTrailing::ValidationSettings())
return(false);
//--- check wheter the Init method is called
if(m_symbol==NULL) return(false);
//--- check parameters
if((m_profit-m_stop_level)*m_adjusted_point<=m_symbol.StopsLevel()*m_symbol.Point()
{
printf(__FUNCTION__+": threshold level of profit must be greater than the level o
return(false);
}
//--- ok
return(true);
}
Los parámetros de configuración del módulo implican que la posición debe ser modificada (si se
establece Profit=0, no se realizará la modificación);
La posición aún no ha sido modificada (orden Stop no se mueve a un nivel sin pérdidas);
El beneficio de la posición excede el nivel del umbral establecido en los parámetros.
En este caso, sugerimos que modifique la orden Stop de acuerdo con los ajustes. Para este propósito,
sobreescribimos el método virtual CheckTrailingStopLong y le asignamos la funcionalidad correspondiente.
2. Una señal de modificación de una posición corta aparece cuando se cumplen las siguientes
condiciones:
Los parámetros de configuración del módulo implican que la posición debe ser modificada (si se
establece Profit=0, no se realizará la modificación);
La posición aún no ha sido modificada (orden Stop no se mueve a un nivel sin pérdidas);
El beneficio de la posición excede el nivel del umbral establecido en los parámetros.
En este caso, sugerimos que modifique la orden Stop de acuerdo con los ajustes. Para este propósito,
sobreescribimos el método virtual CheckTrailingStopShort y le asignamos la funcionalidad correspondiente.
Descripción de la clase:
public:
CSampleTrailing();
//--- methods of setting adjustable parameters
void Profit(int value) { m_profit=value; }
void StopLevel(int value) { m_stop_level=value; }
//--- method of validation of adjustable parameters
virtual bool ValidationSettings();
//--- methods of generation of position modification signals
virtual bool CheckTrailingStopLong(CPositionInfo* position,double& sl,double&
virtual bool CheckTrailingStopShort(CPositionInfo* position,double& sl,double&
};
Implementación de los métodos CheckTrailingStopLong y CheckTrailingStopShort:
//+------------------------------------------------------------------+
//| Check for modification of stop orders of a long position. |
//| INPUT: position - pointer to a position object, |
//| sl - link for a new price of stop loss order, |
//| tp - link for a new price of take profit order. |
//| OUTPUT: true if condition is satisfied, false - if not. |
//| REMARK: no. |
//+------------------------------------------------------------------+
bool CSampleTrailing::CheckTrailingStopLong(CPositionInfo* position,double& sl,double&
{
//--- check of pointer
if(position==NULL) return(false);
//--- check of parameter
if(m_profit==0.0) return(false);
//--- already in a lossless zone?
double open=position.PriceOpen();
if(position.StopLoss()>=open) return(false);
//--- check of profit
sl=EMPTY_VALUE;
tp=EMPTY_VALUE;
if(m_symbol.Bid()-open>m_profit*m_adjusted_point)
sl=m_symbol.NormalizePrice(open+m_stop_level*m_adjusted_point);
//---
return(sl!=EMPTY_VALUE);
}
//+------------------------------------------------------------------+
//| Check for modification of stop orders of a short position. |
//| INPUT: position - pointer to a position object, |
//| sl - link to a new price of stop loss order, |
//| tp - link to a new price of take profit order. |
//| OUTPUT: true if condition is satisfied, false - if not. |
//| REMARK: нет. |
//+------------------------------------------------------------------+
bool CSampleTrailing::CheckTrailingStopShort(CPositionInfo* position,double& sl,double&
{
//--- check of pointer
if(position==NULL) return(false);
//--- check of parameter
if(m_profit==0.0) return(false);
//--- already in a lossless zone?
double open=position.PriceOpen();
if(position.StopLoss()<=open) return(false);
//--- check of profit
sl=EMPTY_VALUE;
tp=EMPTY_VALUE;
if(open-m_symbol.Ask()>m_profit*m_adjusted_point)
sl=m_symbol.NormalizePrice(open-m_stop_level*m_adjusted_point);
//---
return(sl!=EMPTY_VALUE);
}
Hemos finalizado la primera condición necesaria: hemos colocado el archivo donde lo va a "encontrar" MQL5
Wizard. Pero esto no es suficiente. MQL5 Wizard no solo debe "encontrar" el archivo, sino que también lo tiene
que "reconocer". Para ello, tenemos que añadir al texto original el descriptor de clase para MQL5 Wizard.
2. La siguiente línea es un descriptor de texto (lo que veremos en MQL5 Wizard al seleccionar la señal) en el
formato "//| Title=<Text> |". Si el texto es demasiado largo para la línea, se puede añadir una línea más (pero
no más) a continuación. </p>
3. Después, está la línea con el tipo de clase indicado en el formato "//| Type=<Type> |". El campo <Type>
debe tener el valor Signal (señal) (además de las señales, MQL5 Wizard reconoce otros tipos de clases).
Escribimos:
//| Type=Trailing |
4. La siguiente línea en el formato "//| Name=<Name> |" representa el nombre corto de la señal (la utiliza
MQL5 Wizard para generar los nombres de las variables globales del expert).
Obtenemos lo siguiente:
//| Name=BreakEven |
5. El nombre de la clase es un elemento importante de la descripción. En la línea con el formato "//| Class=
<ClassNameа> |", el parámetro <ClassName> debe corresponder al nombre de nuestra clase:
//| Class=CSampleTrailing |
6. No rellanamos esta línea, pero hay que tenerla en cuenta (este es el enlace al manual de referencia de
MQL5):
//| Page= |
//| Parameter=Profit,int,20 |
//| Parameter=StopLevel,int,0 |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| SampleTrailing.mqh |
//| Copyright 2010, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
//+------------------------------------------------------------------+
//| include files |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class |
//| Title=Moving a position to a lossless level |
//| Type=Trailing |
//| Name=BreakEven |
//| Class=CSampleTrailing |
//| Page= |
//| Parameter=Profit,int,20 |
//| Parameter=StopLevel,int,0 |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CSampleTrailing. |
//| Purpose: Class for trailing of open positions |
//| by moving Stop order to a lossless level. |
//| Is derived from the CExpertTrailing class. |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
{
protected:
int m_profit; // threshold level of profit
int m_stop_level; // lossless level
public:
CSampleTrailing();
//--- method of setting adjustable parameters
void Profit(int value) { m_profit=value; }
void StopLevel(int value) { m_stop_level=value; }
//--- method of validation of adjustable settings
virtual bool ValidationSettings();
//--- methods of generation of position modification signals
virtual bool CheckTrailingStopLong(CPositionInfo* position,double& sl,double&
virtual bool CheckTrailingStopShort(CPositionInfo* position,double& sl,double&
};
//+------------------------------------------------------------------+
//| Constructor CSampleTrailing. |
//| INPUT: no. |
//| OUTPUT: no. |
//| REMARK: no. |
//+------------------------------------------------------------------+
void CSampleTrailing::CSampleTrailing()
{
//--- setting default values
m_profit =20;
m_stop_level=0;
}
//+------------------------------------------------------------------+
//| Check of adjustable parameters. |
//| INPUT: no. |
//| OUTPUT: true if the parameters are correct, false if not. |
//| REMARK: no. |
//+------------------------------------------------------------------+
bool CSampleTrailing::ValidationSettings()
{
//--- what if the Init has not been called?
if(m_symbol==NULL) return(false);
//--- check of parameters
if((m_profit-m_stop_level)*m_adjusted_point<=m_symbol.StopsLevel()*m_symbol.Point()
{
printf(__FUNCTION__+": threshold level of profit must be greater than the level o
return(false);
}
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Check for modification of stop orders of a long position. |
//| INPUT: position - pointer to a position object, |
//| sl - link for a new price of stop loss order, |
//| tp - link for a new price of take profit order. |
//| OUTPUT: true if condition is satisfied, false if not. |
//| REMARK: no. |
//+------------------------------------------------------------------+
bool CSampleTrailing::CheckTrailingStopLong(CPositionInfo* position,double& sl,double&
{
//--- check of pointer
if(position==NULL) return(false);
//--- check of parameters
if(m_profit==0.0) return(false);
//--- already in a lossless zone?
double open=position.PriceOpen();
if(position.StopLoss()>=open) return(false);
//--- check of profit
sl=EMPTY_VALUE;
tp=EMPTY_VALUE;
if(m_symbol.Bid()-open>m_profit*m_adjusted_point)
sl=m_symbol.NormalizePrice(open+m_stop_level*m_adjusted_point);
//---
return(sl!=EMPTY_VALUE);
}
//+------------------------------------------------------------------+
//| Check for modification of stop orders of a short position. |
//| INPUT: position - pointer to a position object, |
//| sl - link for a new price of stop loss order, |
//| tp - link for a new take profit order. |
//| OUTPUT: true if condition is satisfied, false if not. |
//| REMARK: no. |
//+------------------------------------------------------------------+
bool CSampleTrailing::CheckTrailingStopShort(CPositionInfo* position,double& sl,double&
{
//--- check of pointer
if(position==NULL) return(false);
//--- check of parameters
if(m_profit==0.0) return(false);
//--- already in a lossless zone?
double open=position.PriceOpen();
if(position.StopLoss()<=open) return(false);
//--- check of profit
sl=EMPTY_VALUE;
tp=EMPTY_VALUE;
if(open-m_symbol.Ask()>m_profit*m_adjusted_point)
sl=m_symbol.NormalizePrice(open-m_stop_level*m_adjusted_point);
//---
return(sl!=EMPTY_VALUE);
}
//+------------------------------------------------------------------+
Ya están disponibles los parámetros de entrada especificados en la descripción de los parámetros del módulo
de gestión de posiciones abiertas:
Figura 6. Los parámetros de entrada del módulo de gestión de posiciones abiertas en MQL5 Wizard.
Se pueden conseguir los mejores parámetros de entrada de la estrategia de trading implementada mediante el
probador de estrategias del terminal de MetaTrader 5.
Conclusión
El generador de estrategias de trading de MQL5 Wizard simplifica enormemente los procesos de pruebas de los
conceptos de trading. El código del Asesor Experto generado se basa en las clases de las estrategias de trading
de la librería estándar, que se usan para crear determinadas clases de señales de trading, clases de gestión de
dinero y riesgo y clases de soporte de posición.
El artículo aborda la forma de escribir y conectar al generador de estrategias de trading de MQL5 Wizard, su
propia clase de gestión de posiciones abiertas gracias a mover el nivel de Stop Loss a una zona sin pérdidas
cuando el precio va en la misma dirección que la posición, ofreciendo una protección frente a la disminución
de sus beneficios durante el trading. También informa sobre la estructura y el formato de la descripción de la
clase creada para MQL5 Wizard.