Assistente MQL5: como criar um módulo de rastreamento de posições abertas

MetaQuotes | 11 fevereiro, 2014

Introdução

MetaTrader 5 possui uma ferramenta poderosa para verificação rápida de ideias de negociação. Este é o gerador de estratégias de negociação do Assistente MQL5. O uso do Assistente do MQL5 para criação automática do código original do Experts Advisors é descrito no artigo "Assistente MQL5: Criação de Expert Advisors sem programação". A abertura do sistema de geração de código permite suplementar as classes padrão com classes adaptadas de sinais de negociação, dinheiro, sistemas de gestão e módulos de rastreamento.

Este artigo descreve os princípios de escrever módulos de rastreamento de posição aberta para suas futuras utilizações no Assistente MQL5.

Um Expert Advisor criado utilizando o Assistente MQL5 é baseado em quatro classes de base:

Figura 1. Estrutura da classe de base CExpert

Figura 1. Estrutura da classe de base CExpert


A classe CExpert (ou sua classe secundária) é o principal "motor" do robô de negociação. O elemento de classe do CExpert contém elementos de classes do CExpertSignal, CExpertMoney e CExpertTrailing (ou de suas classes secundárias):

  1. CExpertSignal - é o gerador principal dos sinais de negociação. O elemento da classe secundária do CExpertSignal incluso na classe CExpert fornece ao Expert Advisor informações sobre possibilidades de entrada no mercado, níveis de entrada e criação de ordens de proteção com base em algoritmos internos. A decisão final sobre a realização de operações de negociação é feita pelo Expert Advisor. Você pode ler sobre como escrever um módulo de sinais de negociação no artigo "Assistente MQL5: Como criar um módulo de sinais de negociação".
  2. CExpertMoney é o sistema principal de gerenciamento de dinheiro e risco. O elemento da subclasse CExpertMoney calcula volumes de posição a serem abertos e ordens pendentes a serem colocadas. A decisão final sobre volumes é feita pelo Expert Advisor. Os princípios do desenvolvimento de módulos de gerenciamento de risco e dinheiro encontram-se descritos no artigo "Assistente MQL5: Como criar um módulo de gerenciamento de risco e dinheiro".
  3. CExpertTrailing é o módulo principal do rastreamento de posições abertas. O elemento da classe secundária CExpertTrailing diz ao Expert Advisor se é necessário modificar as ordens de proteção de uma posição. A decisão final sobre a alteração do pedido é feita pelo Expert Advisor.

Além disso, os seguintes elementos da classe são os membros da classe CExpert:

Mais adiante neste texto, ao dizermos "Expert Advisor" queremos dizer um elemento da classe CExpert e de suas classes secundárias.

Uma descrição mais detalhada da classe CExpert e do processo de trabalhar com ele será abordado em um artigo separado.


1. Classe de base CExpertTrailing

O CExpertTrailing é a base do módulo do rastreamento de posições abertas. Para interagir com o "espaço exterior" a classe CExpertTrailing possui um conjunto de métodos públicos virtuais:

Inicialização

Descrição

virtual Init

A inicialização do elemento de classe fornece sincronização de dados do módulo com dados da EA

virtual ValidationSettings

Validação de parâmetros definidos

virtual InitIndicators

Criação e inicialização de todos os indicadores e séries temporais necessárias para operação do gerador de sinais de negociação

Sinais de Modificação de Posições

virtual CheckTrailingStopLong

Geração de um sinal para modificação de uma longa posição com determinação de um novo preço para Stop order

virtual CheckTrailingStopShort

Geração de um sinal para modificação de uma curta posição com determinação de um novo preço para Stop order


Descrição de métodos

1.1. Métodos de inicialização

1.1.1 Init

O método Init() é automaticamente chamado logo após a adição do elemento de classe ao Expert Advisor. A desativação do método não é necessária.

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

1.1.2 ValidationSettings

O método de ValidationSettings() é chamado do Expert Advisor após a definição de todos os parâmetros. é necessário ativar manualmente o método se houverem configurações de ajuste.

virtual bool ValidationSettings();

O método desativado deve retornar autêntico se todos os parâmetros estiverem corretos (apropriados para uso). Se quaisquer dos parâmetros for inválido, o mesmo deve retornar falso (operação posterior não será possível).

A classe de base CExpertTrailing não possui nenhum parâmetro que possa ser configurado, então, o método sempre retorna sem desempenhar verificações.

1.1.3 Indicadores de inicialização

O método InitIndicators() cria e inicializa todos os indicadores e séries temporais. Ele é chamado do Expert Advisor após todos os parâmetros estarem estabelecidos e validados. O método deve ser desativado no caso do gerador de sinais de negociação utilizar pelo menos um indicador ou série temporal.

virtual bool InitIndicators(CIndicators* indicators);

Indicadores e séries temporais devem ser usados através da conformidade com a Biblioteca padrão. Ponteiros de todos os indicadores e/ou de séries temporais devem ser adicionados à coleção de indicadores do Expert Advisor (ponteiro para o qual é transmitido como um parâmetro).

O método de desativação deve retornar autêntico, se todas as manipulações com os indicadores e/ou séries temporais foram bem sucedidas (elas são adequados para uso). Se pelo menos uma operação com os indicadores e/ou séries temporais falhou, o método deve retornar falso (operação posterior é impossível).

Classe de base CExpertTrailing não utiliza indicadores e séries temporais, então, o método de classe de base retorna sempre autêntico sem desempenhar ação nenhuma.


1.2. Métodos de verificação do sinal da modificação de posição

1.2.1 CheckTrailingStopLong

O método CheckTrailingStopLong() gera um sinal de modificação de uma longa posição, definindo um novo preço de pedido de Stop Loss (assim como para o pedido de Take Profit caso seja necessário). é chamado pelo Expert Advisor para determinar se é necessário modificar uma longa posição. Ele deve ser desativado, se você deseja gerar um sinal de uma longa modificação de posição.

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

O método deve implementar o algoritmo de verificação da condição de modificação da longa posição. Se a condição for satisfeita, a variável sl (bem como a tp, caso seja necessário) deve ser atribuída ao valor apropriado e o método deve retornar autêntico. Conexões para as variáveis sl e tp variáveis devem ser transmitidas como parâmetros. Se a condição não for satisfeita, o método deve retornar falso.

A classe de base CExpertTrailing não possui um algoritmo embutido para geração de um sinal de modificação de longa posição, de modo que o método de classe de base sempre retorna falso.

1.2.2 CheckTrailingStopShort

O método CheckTrailingStopShort() gera um sinal de modificação de uma curta posição, determinando um novo preço de pedido de Stop Loss (bem como pedido de Take Profit, caso seja necessário). Ele é chamado pelo Expert Advisor para determinar se é necessário modificar uma curta posição. O método deve ser desativado, se você deseja gerar um sinal de modificação de curta posição.

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

O método deve implementar o algoritmo de verificação da condição de modificar uma curta posição. Se a condição for satisfeita, a variável sl (bem como a tp, caso seja necessário) deve ser atribuída ao valor apropriado e o método deve retornar autêntico. Conexões para as variáveis sl e tp variáveis devem ser transmitidas como parâmetros. Se a condição não for satisfeita, o método deve retornar falso.

A classe de base CExpertTrailing não possui um algoritmo embutido para geração de um sinal de modificação de curta posição, de modo que o método de classe de base sempre retorna falso.


2. Escrever o Seu Próprio Módulo para Rastrear Posições em Aberto

Agora, depois de ter revisto a estrutura da classe de base CExpertTrailing, você pode começar a criar o seu próprio módulo para seguir posição em aberto.

Como mencionado acima, a classe CExpertTrailing é um conjunto de "cordas" virtuais públicas - métodos, utilizados nos quais o Expert Advisor pode saber a opinião do módulo de rastreamento de posições abertas sobre a necessidade de modificação de ordens de proteção.

Portanto, o nosso principal objetivo é criar nossa própria classe para seguir posições abertas, derivando-as da classe CExpertTrailing, desativando os métodos virtuais adequados, implementando os algoritmos necessários.

Nosso segundo objetivo (e não menos importante) - para tornar a nossa classe "visível" para o Assistente MQL5. Mas, as primeiras coisas primeiro.

2.1. Criação da Classe de Gerador de Sinais de Negociação

Vamos iniciar.

Primeiro, nós criamos (por exemplo, utilizando o mesmo Assistente MQL5) um arquivo incluso com a extensão mqh.

No menu do arquivo selecione "Criar" (ou pressione teclas combinadas Ctrl+N) e indique a criação de um arquivo incluso:

Figura 2. Crie um arquivo incluso utilizando o Assistente MQL5.

Figura 2. Crie um arquivo incluso utilizando o Assistente MQL5

Deve notar-se que, para que o arquivo seja então "detectado" pelo Assistente MQL5 como um módulo de rastreamento de posições abertas, ele deve ser criado na pasta Incluir\Especialista\.

Para descartar na Biblioteca padrão, criamos uma pasta própria Include\Expert\Trailing\MyTrailing.mqh, da qual criamos o arquivo SampleTrailing.mqh, especificando tais parâmetros no Assistente МQL5:

Figura 3. Configuração do local do arquivo incluso.

Figura 3. Configuração do local do arquivo incluso

Como resultado da operação do Assistente MQL5 temos o seguinte padrão:

//+------------------------------------------------------------------+
//|                                               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
//+------------------------------------------------------------------+

O seguinte é apenas trabalho "manual". Remova as partes desnecessárias e adicione o que é necessário (incluindo arquivo ExpertTrailing.mqh da Biblioteca padrão e uma descrição de classe, que agora está vazia).

//+------------------------------------------------------------------+
//|                                               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.                   |
//|             Is derived from the CExpertTrailing class.          |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
  {
  };
//+------------------------------------------------------------------+

Agora, é necessário escolher os algoritmos.

Vamos dar o seguinte algoritmo, como base de nosso módulo de rastreamento de posições abertas: mova o Stop order a um nível lossless (sem perdas), se o preço for em uma direção desejada a uma determinada distância. Reflita isso em nosso arquivo.

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

Agora vamos definir quais os dados são necessários para a tomada de decisões sobre a modificação de pedidos de proteção. No nosso caso - é a vantagem de uma posição modificada em pontos.

Defina a lista de parâmetros de configuração do nosso módulo para seguir as posições abertas. Precisamos de dois parâmetros:

  1. Número de pontos de vantagem de posição necessários para sugerir a mudança de um Stop order para um nível losless (sem perdas).
  2. O nível losless (sem perdas), ou seja, quantos pontos de lucro fixamos pela mudança do Stop order.

As configurações do módulo serão armazenadas em membros de dados protegidos da classe. O acesso às configurações será implementado através de métodos públicos apropriados.

Vamos incluir estas mudanças em nosso arquivo:

//+------------------------------------------------------------------+
//|                                               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:
   //--- methods of setting adjustable parameters
   void               Profit(int value)       { m_profit=value;     }
   void               StopLevel(int value)    { m_stop_level=value; }
  };
//+------------------------------------------------------------------+

Para inicializar parâmetros ajustáveis com valores padrão, precisamos adicionar o construtor da classe.

Para validar as configurações, desative o método virtual ValidationSettings (de acordo com a descrição da classe base).

Descrição da classe:

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

Implementação do método ValidationSettings() (configurações de validação):

//+------------------------------------------------------------------+
//| 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() && m_profit!=0.0)
     {
      printf(__FUNCTION__+": threshold level of profit must be greater than the level of  setting of orders");
      return(false);
     }
//--- ok
   return(true);
  }

Todos os trabalhos preparatórios estão concluídos.

Vamos considerar nossos algoritmos novamente com mais detalhes.

1. Um sinal para a modificação de uma longa posição aparece quando as seguintes condições forem satisfeitas:

Neste caso, sugira modificar o Stop order de acordo com as configurações. Para isso, desative o método virtual CheckTrailingStopLong e preencha-o com a funcionalidade correspondente.

2. Um sinal de uma curta modificação de posição aparece quando as seguintes condições forem satisfeitas:

Neste caso, sugira modificar o Stop order de acordo com as configurações. Para isso, desative o método virtual CheckTrailingStopShort e preencha-o com a funcionalidade correspondente.

Descrição da classe:

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& tp);
   virtual bool       CheckTrailingStopShort(CPositionInfo* position,double& sl,double& tp);
  };

Implementação dos métodos CheckTrailingStopLong e 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& tp)
  {
//--- 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& tp)
  {
//--- 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. Escrever uma descrição da classe criada dos sinais de negociação para o Assistente MQL5

Vamos agora para a parte de resolver o segundo problema. Nosso módulo de seguir posições abertas deve ser "reconhecido" pelo gerador de estratégias de negociação do Assistente MQL5.

Nós fizemos a primeira condição necessária: colocamos o arquivo onde ele será "encontrado" pelo Assistente MQL5. Mas não é suficiente. O Assistente MQL5 não deve apenas "encontrar" o arquivo, mas também "reconhecê-lo". Para fazermos isso, temos que acrescentar ao texto original do descritor de classe para o Assistente MQL5.

Um descritor de classe é um bloco de comentários compostos de acordo com certas regras.

Vamos considerar estas regras.

1. O bloco de comentários deve iniciar com as linhas a seguir:

// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |

2. A próxima linha é um descritor de texto (o que veremos no Assistente MQL5 ao escolhermos o sinal) no formato "//| Title= |". Se o texto é muito grande para uma linha, você pode adicionar mais uma linha (mas não mais) depois dele.

No nosso caso, temos o seguinte:

//| Title=Signal on the crossing of a price and the MA               |
//| entering on its back movement                                    |

3. Então chega uma linha com o tipo de classe especificado no formato "//| Type= |". O campo deve ter o valor de sinal (além de sinais, o Assistente MQL5 conhece outros tipos de classes).

Escrever:

//| Type=Trailing                                                    |

4. A próxima linha no formato "//| Name= |" é o nome curto do sinal (é utilizada pelo Assistente MQL5 para gerar os nomes das variáveis globais do especialista).

Obtemos o seguinte:

//| Name=BreakEven                                                   |

5. O nome de uma classe é um elemento importante da descrição. Na linha de formato "//| Class= |", o parâmetro deve ser compatível com o nome da nossa classe:

//| Class=CSampleTrailing                                            |

6. Nós não preenchemos essa linha, mas deve estar presente (isto é um link para a seção referência da linguagem):

//| Page=                                                            |

7. Mais adiante, há descrições de parâmetros de configurações do módulo.

Este é um conjunto de fileiras (o número de fileiras é igual ao número de parâmetros).

O formato de cada linha é "//| Parameter=,, |".

Aqui está nosso conjunto de parâmetros:

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

8. O bloco de comentário deve terminar com as linhas a seguir:

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

Vamos adicionar o descritor ao código de origem.

//+------------------------------------------------------------------+
//|                                               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& tp);
   virtual bool       CheckTrailingStopShort(CPositionInfo* position,double& sl,double& tp);
  };
//+------------------------------------------------------------------+
//| 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() && m_profit!=0.0)
     {
      printf(__FUNCTION__+": threshold level of profit must be greater than the level of setting stop orders");
      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& tp)
  {
//--- 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& tp)
  {
//--- 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);
  }
//+------------------------------------------------------------------+

Bem, isso é tudo. O módulo de rastreamento está pronto para o uso.

Para que o gerador de estratégias de negociação do Assistente MQL5 consiga utilizar nosso módulo, devemos reiniciar o MetaEditor (o Assistente MQL5 examina o arquivo Include\Expert apenas no início).

Após reiniciar o MetaEditor, o módulo criado de gerenciamento de posições abertas pode ser utilizado no Assistente MQL5:

Figura 5. O módulo criado de gerenciamento de posições abertas no Assistente MQL5.

Figura 5. O módulo criado de gerenciamento de posições abertas no Assistente MQL5

Os parâmetros de entrada especificados na seção de descrição de parâmetros de módulo para gerenciamento de posições abertas estão agora disponíveis:

Figura 6. Os parâmetros de entrada do módulo criado de gerenciamento de posições abertas no Assistente MQL5.

Figura 6. Os parâmetros de entrada do módulo criado de gerenciamento de posições abertas no Assistente MQL5

Os melhores valores dos parâmetros de entrada de estratégia de negociação implementada podem ser encontrados utilizando o Verificador de estratégia do terminal do MetaTrader 5.


Conclusão

O gerador de estratégias de negociação do Assistente MQL5 simplifica extremamente o teste de ideias de negociação. O código de especialista gerado é baseado nas classes de estratégias de negociação da biblioteca padrão, os quais são utilizados para criar certas implementações de classes de sinal de negociação, classes de gerenciamento de risco e dinheiro e classes de suporte de posição.

O artigo discute como escrever e conectar ao gerador de estratégias de negociação do Assistente MQL5 a sua própria classe de gerenciamento de posições abertas, movendo o nível de Stop Loss para a zona lossless quando o preço ir em direção da posição, permitindo diminuir levantamentos ao negociar. Fala também sobre a estrutura e o formato da descrição da classe criada para o Assistente MQL5.