Anda di halaman 1dari 14

MQL5 Wizard: Cómo crear un módulo de Trailing de posiciones abiertas

MetaQuotes Software Corp. | 4 abril, 2014

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:

Figura 1. Estructura de la clase base CExpert.

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):

1. CExpertSignal es el principal generador de señales de trading. La instancia de la subclase CExpertSignal


incluida en la clase CExpert, proporciona al Asesor Experto informaciónes sobre las posibilidades de
entrar al mercado, los niveles de entrada y colocación de órdenes de protección, en función de los
algoritmos internos. La decisión final sobre la ejecución de operaciones de trading la lleva a cabo
el Asesor Experto. Puede leer acerca de cómo escribir un módulo de señales de trading en el artículo
"MQL5 Wizard: Cómo crear un módulo de señales de trading".
2. CExpertMoney es la base de los sistemas de gestión de dinero y de riesgo. La instancia de la subclase
CExpertMoney calcula los volúmenes de posición que se van a abrir y las órdenes que se van a colocar.
La decisión final sobre los volúmenes la lleva a cabo el Asesor Experto. Los principios del desarrollo de
módulos de gestión de dinero y riesgo se describen en el artículo "MQL5 Wizard: Cómo crear un módulo
de gestión de dinero y riesgo".
3. CExpertTrailing es el módulo principal para el seguimiento de las posiciones abiertas. La instancia de la
subclase CExpertTrailing informa al Asesor Experto si es necesario modificar las órdenes de protección
de una posición. La decisión final sobre la modificación de órdenes la toma el Asesor Experto.

Además, las siguientes instancias de clase son miembros de la clase CExpert:

CExpertTrade (para realizar operaciones de trading)


CIndicators (para gestionar los indicadores y las series temporales implicados en el funcionamiento
del Asesor Experto)
CSymbolInfo (para obtener información acerca de un símbolo)
CAccountInfo (para obtener información acerca del estado de la cuenta de trading)
CPositionInfo (para obtener información acerca de las posiciones)
COrderInfo (para obtener información acerca de las órdenes pendientes)

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.

1. La clase base CExpertTrailing


CExpertTrailing es la base del módulo de seguimiento de las posiciones abiertas. Para interactuar con el
"espacio exterior", la clase CExpertTrailing dispone de un conjunto de métodos virtuales públicos:

Inicialización  Descripción

virtual Init Inicialización de la instancia de la clase que proporciona la sincronización de los


datos del módulo con los datos del Asesor Experto.

virtual Validación de los parámetros establecidos


ValidationSettings

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

Descripción de los métodos


1.1. Métodos de Inicialización

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.

virtual bool Init(CSymbolInfo* symbol, ENUM_TIMEFRAMES period, double adjusted_point);

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.

virtual bool ValidationSettings();

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.

virtual bool InitIndicators(CIndicators* indicators);

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.

1.2. Los métodos de comprobación de la señal de modificación de una posición:


1.2.1 CheckTrailingStopLong

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.

virtual bool CheckTrailingStopLong(CPositionInfo* position,double& sl,double& tp)

El método debe implementar el algoritmo de comprobación de la condición de modificación de una posición


larga. Si se cumple la condición, hay que asignar el valor correspondiente a la variable sl (así como a tp, si
fuera necesario) y el método devolverá true. Se deben enviar los enlaces a las variables sl y tp como
parámetros. Si no se cumple la condición, el método devolverá false.

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.

virtual bool CheckTrailingStopShort(CPositionInfo* position,double& sl,double& tp)

El método debe implementar el algoritmo de comprobación de la condición de modificación de una posición


corta. Si se cumple la condición, hay que asignar el valor correspondiente a la variable sl (así como a tp, si
fuera necesario) y el método devolverá true. Se deben enviar los enlaces a las variables sl y tp como
parámetros. Si no se cumple la condición, el método devolverá false.

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.

2. Escribir su propio módulo para el seguimiento de posiciones abiertas


Ahora, tras haber repasado la estructura de la clase base CExpertTrailing, puede empezar a crear su propio
módulo para el seguimiento de posiciones abiertas.
Como se ha mencionado anteriormente, la clase CExpertTrailing es un conjunto de métodos virtuales públicos,
cuyo uso permite al Asesor Experto conocer el criterio del módulo de trailing de posiciones abiertas acerca de
la modificación de las órdenes de protección.
Por consiguiente, nuestro objetivo principal es crear nuestra propia clase para el seguimiento de posiciones
abiertas, derivándola de la clase CExpertTrailing y sobreescribiendo los métodos virtuales correspondientes
con la implementación de los algoritmos necesarios.
Nuestro segundo objetivo (no menos importante) es hacer que nuestra clase sea "visible" para MQL5 Wizard.
Pero lo primero es lo primero.
2.1. Creación de la clase del generador de señales de trading

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:

Figura 2. Crear un archivo de inclusión mediante MQL5 Wizard.

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

Como resultado del funcionamiento de MQL5 Wizard obtenemos la siguiente estructura:

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

Ahora es necesario elegir los algoritmos.


Tomemos el siguiente algoritmo como base de nuestro módulo de trailing de posiciones abiertas: mover la
orden Stop a un nivel sin pérdidas, si el precio va en la dirección requerida por una determinada distancia.
Recoja este planteamiento en su 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"
//+------------------------------------------------------------------+
//| 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();
};
//+------------------------------------------------------------------+

Implementación del método 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);
}

Se han completado todas las tareas preliminares.


Analicemos otra vez nuestros algoritmos más detalladamente.
1. Una señal de modificación de una posición larga 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 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:

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 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);
}

2.2. Escribir la descripción de la clase de señales de trading para MQL5 Wizard


Pasamos ahora a resolver el segundo problema. Nuestro módulo de seguimiento de posiciones abiertas debe
ser reconocido por el generador de estrategias de trading MQL5 Wizard.

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.

Un descriptor de clase es un bloque de comentarios, elaborado de acuerdo con ciertas reglas.


Veamos estas reglas.
1. El bloque de comentarios tiene que comenzar con las siguientes líneas:

// wizard description start


//+------------------------------------------------------------------+
//| Description of the class |

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>

En nuestro caso, tenemos lo siguiente:

//| Title=Signal on the crossing of a price and the MA |


//| entering on its back movement |

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= |

7. Además, hay descripciones de los parámetros de la configuración del módulo.


Este es un conjunto de líneas de código (el número de líneas es igual al número de parámetros).
El formato de cada línea es "//| Parameter=<NameOfMethod>,<TypeOfParameter>,<DefaultValue> |".
A continuación, tenemos nuestro conjunto de parámetros:

//| Parameter=Profit,int,20 |
//| Parameter=StopLevel,int,0 |

8. El bloque de comentarios debe finalizar con las siguientes líneas:

//+------------------------------------------------------------------+
// wizard description end

Vamos a añadir el descriptor al código fuente.

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

Bueno, eso es todo. Ya se puede utilizar el módulo de trailing.


Para que el generador de estrategias de trading MQL5 Wizard pueda usar nuestro módulo, tenemos que
reiniciar MetaEditor (MQL5 Wizard analiza la carpeta Include\Expert solo en el inicio).
Tras el reinicio de MetaEditor, se puede utilizar el módulo de gestión de posiciones abiertas con MQL5 Wizard:
Figura 5. El módulo de gestión de posiciones abiertas en MQL5 Wizard.

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.