Assista a como baixar robôs de negociação gratuitos
Encontre-nos em Twitter!
Participe de nossa página de fãs
Script interessante?
Coloque um link para ele, e permita que outras pessoas também o avaliem
Você gostou do script?
Avalie seu funcionamento no terminal MetaTrader 5
Experts

MACD Sample - expert para MetaTrader 5

Publicado por:
MetaQuotes
Visualizações:
9923
Avaliação:
(51)
Publicado:
2014.07.03 09:45
Atualizado:
2016.11.22 07:33
Freelance MQL5 Precisa de um robô ou indicador baseado nesse código? Solicite-o no Freelance Ir para Freelance

Este EA está incluído no pacote padrão do terminal do cliente MetaTrader 5 e é um exemplo de negociação com EA usando o indicador MACD.

O arquivo do Expert Advisor MACD Sample.mq5 está localizado no seguinte caminho de diretórios: terminal_data_folder\MQL5\Experts\Examples\MACD\". Este Expert Advisor é um exemplo de abordagem orientada a objetos no desenvolvimento de EA.

Vamos considerar a estrutura do Expert Advisor e como ele funciona.


1 Propriedades do EA

1.1. Propriedades do EA

//+------------------------------------------------------------------+
//|                                                  MACD Sample.mq5 |
//|                   Copyright 2009-2013, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "Copyright 2009-2013, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version     "5.20"
#property description "É importante certificar-se que o expert trabalha com um gráfico normal"
#property description "e que o usuário não cometeu erros nas configurações de entrada"
#property description "variáveis (Lots, TakeProfit, TrailingStop) no nosso caso,"
#property description "vamos verificar TakeProfit num gráfico de mais de 2*barras de trend_period"

As primeiras 5 linhas contém um comentário, as sete linhas seguintes definem as propriedades do programa MQL5 (direitos autorais, link, versão, descrição), utilizando as diretivas do pré-processamento #property.

Quando você executa o Expert Advisor ele é exibido numa janela pop-up, na aba "Comum":

Expert Advisor MACD Sample

Figure 1 Janela pop-up na aba comum do EA MACD Sample

1.2. Arquivos Incluídos

Em seguida, a diretiva #include diz ao compilador para incluir os arquivos que contêm as classes de negociação da Biblioteca Padrão (Standard Library).

  • Trade.mqh (CTrade - classe para operações de negociação);
  • SymbolInfo.mqh (CSymbolInfo - classe para trabalhar com as propriedades de um instrumento de negociação);
  • PositionInfo.mqh (CPositionInfo - classe para trabalhar com as propriedades de abertura de posição);
  • AccountInfo.mqh (CAccountInfo - classe para trabalhar com propriedades da conta de negócios).
//--- arquivos include  
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>

Instâncias das classes apropriadas são utilizados como variáveis ​​membros da classe CExpert (Seção 3).

1.3. Entradas

Colocadas como inputs: tipo, nome, valores padrão e um comentário. Na fig. 2 são mostrados os inputs.

//--- Parâmetros dos Inputs do Expert Advisor 
input double InpLots          =0.1; // Lotes (volume)
input int    InpTakeProfit    =50;  // é o alvo - tomada de lucro (em pips)
input int    InpTrailingStop  =30;  // nível do stop móvel (em pips)
input int    InpMACDOpenLevel =3;   // nível de abertura do MACD(em pips)
input int    InpMACDCloseLevel=2;   //nível do fechamento do MACD (em pips)
input int    InpMATrendPeriod =26;  // período da MA que define a tendência

Veja que os nomes dos parâmetros de entrada tem o prefixo "Inp". Observe também que as variáveis ​​globais são prefixados com "Ext". Tal abordagem da nomenclatura das variáveis usadas ​​simplifica uma série de variáveis ​​diferentes.

InpLots - volume das operações de negócios, InpTakeProfit e InpTrailingStop determinam os níveis de tomada de lucro (Take Profit e) e do stop móvel (Trailing Stop),

O texto no comentário na linha de parâmetro de entrada, juntamente com os valores padrão, são exibidas na aba "Options" em vez do nome do parâmetro de entrada:

Figura 2. Parâmetros de entrada do EA MACD Sample

Figura 2. Parâmetros de entrada do EA MACD Sample


1.4. Variáveis ​​Globais

Em seguida, a variável global ExtTimeOut é declarada. Ela será usada para controlar o tempo de execução das operações de negócios.

int ExtTimeOut=10; // tempo (em segundos) das operações de negócios

Após declaração da classe CSampleExpert, na linha 76, uma outra variável global é declarada: ExtExpert - instância da classe CSampleExpert:

//---  variável global ExtExpert
CSampleExpert ExtExpert;

O objeto ExtExpert (exemplo da classe CSampleExpert) contém a lógica básica da estratégia de negociação (Seção 3).


2. Manipulando Eventos das Funções

Manipulando Eventos das Funções

2.1. A função de inicialização OnInit()

A função OnInit() é chamada uma vez durante a primeira partida do Expert Advisor. Geralmente no manipulador de eventos OnInit(), o EA está preparado para a operação: os parâmetros de entrada são verificados, indicadores e parâmetros são inicializados, etc. No caso de erros críticos, quando esse trabalho é sem sentido, a função é encerrado com um código de retorno INIT_FAILED.

//+------------------------------------------------------------------+
//|Função de Inicialização do Expert                                 |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- inicialização e criação de todos os objetos necessários
   if(!ExtExpert.Init())
      return(INIT_FAILED);
//--- inicialização bem sucedida
   return(INIT_SUCCEEDED);
  }

Neste caso, o método Init() do objeto ExtExpert é chamado, vai retornar verdadeiro ou falso dependendo da preparação de todos os objetos necessários para a operação (ver Seção 3.4). No caso de um erro, OnInit() é encerrado com um código de retorno INIT_FAILED - é uma maneira correta para completar a operação EA/indicador no caso de uma inicialização mal sucedida.


2.2. A função OnTick()

A função OnTick() é chamada cada vez que uma nova cotação é recebida para o instrumento financeiro do gráfico em que o EA é executado.

//+------------------------------------------------------------------+
//| Função de manipulação de novo tick do Expert                     |
//+------------------------------------------------------------------+
void OnTick(void)
  {
   static datetime limit_time=0; // armazena a última chamada time + timeout
//--- se não decorrer o tempo necessário ele não funcionará  
   if(TimeCurrent()>=limit_time)
     {
      //--- verificando dados
      if(Bars(Symbol(),Period())>2*InpMATrendPeriod)
        {
         //--- após a chamada do método Processing(),  aumentar o valor da limit_time pelo ExtTimeOut
         if(ExtExpert.Processing())
            limit_time=TimeCurrent()+ExtTimeOut;
        }
     }
  }

No manipulador de eventos OnTick() é incluído um mecanismo para chamadas periódicas do método ExtExpert.Processing() que é utilizado para análise de mercado e operações de trading quando estiverem reunidas as condições de negociação.

O intervalo de tempo entre as chamadas é definido pelo valor do parâmetro de entrada ExtTimeOut.


2.3. A função de finalização OnDeInit()

OnDeInit() é chamado quando um EA é removido do gráfico. Se um programa coloca os objectos gráficos durante a operação, então eles podem ser removidos a partir do gráfico.

Neste exemplo sem usar a função de desinicialização, as ações não são executadas.


3. A classe CSampleExpert

3.1. A classe CSampleExpert

//+------------------------------------------------------------------+
//|Amostra da classe no EA MACD Sample                               |
//+------------------------------------------------------------------+
class CSampleExpert
  {
protected: 
   //--- variáveis ​​protegidas - os membros da classe estão disponíveis apenas dentro dos métodos da classe 
   double            m_adjusted_point;             // um multiplicador para cotaçao de 3/5-dígitoss
   CTrade            m_trade;                      // amostra da classe CTrade
   CSymbolInfo       m_symbol;                     // amostra da classe CSymbolInfo
   CPositionInfo     m_position;                   // amostra da classe CPositionInfo 
   CAccountInfo      m_account;                    // amostra da classe CAccountInfo 
   //--- handles dos indicadores 
   int               m_handle_macd;                // manipulador do indicador MACD
   int               m_handle_ema;                 // manipulador do indicador EMA
   //--- buffers dos indicadores 
   double            m_buff_MACD_main[];           // o buffer da linha principal do indicador MACD
   double            m_buff_MACD_signal[];         //o buffer da linha de sinal do indicador MACD 
   double            m_buff_EMA[];                 // buffers do indicador EMA 
   //--- valor corrente dos indicadores
   double            m_macd_current;
   double            m_macd_previous;
   double            m_signal_current;
   double            m_signal_previous;
   double            m_ema_current;
   double            m_ema_previous;
   //--- níveis (pontuação padrão)
   double            m_macd_open_level;
   double            m_macd_close_level;
   double            m_traling_stop;
   double            m_take_profit;

public: 
   //--- construtores
                     CSampleExpert(void);
   //--- destrutores
                     ~CSampleExpert(void);
   //--- público - métodos podem ser chamados de fora da classe 
   //--- método de inicialização
   bool              Init(void);
   //--- método de desinicialização
   void              Deinit(void);
   //--- método de processamento
   bool              Processing(void);
protected: 
   //--- protegido - métodos podem ser acessados ​​somente dentro dos métodos da classe 
   bool              InitCheckParameters(const int digits_adjust);
   bool              InitIndicators(void);
   bool              LongClosed(void);
   bool              ShortClosed(void);
   bool              LongModified(void);
   bool              ShortModified(void);
   bool              LongOpened(void);
   bool              ShortOpened(void);
  };

A classe EA contém declaração das variáveis ​​(membros da classe) e funções (métodos de classe).

Para um trabalho mais conveniente, todas as variáveis ​​de membro de classe contêm o prefixo "m_" (membro), indicando que a variável é um membro da classe. Antes da declaração de uma variável ou um método, seu tipo é especificado (ou o valor de retorno para funções).

Visibilidade de variáveis ​​de membro de classe e métodos são definidos usando modificadores de acesso. Na classe CSampleExpert, os modificadores protegidos e públicos são usados. Todas as variáveis ​​e métodos definidos no seção pública são liberadas e acessíveis a partir do exterior. A classe CSampleExpert tem cinco desses métodos:

  1. CSampleExpert(void) - um construtor (chamado automaticamente durante a criação de uma instância de classe);
  2. ~CSampleExpert(void) - um destrutor (chamado automaticamente durante a exclusão de uma instância de classe);
  3. bool Init(void) - método de inicialização no qual todos os dados necessários para a operação são preparados;
  4. void Deinit(void) - método de desinicialização;
  5. bool Processing(void) - método de processamento.

Declaração das variáveis ​​de membros de classe CSampleExpert com o modificador de acesso protegido estará disponível apenas no interior dos métodos de classe CSampleExpert (e classes criança).

  1. double           m_adjusted_point - variável multiplicador para uma operação correta com cotações 3/5-digitos;
  2. CTrade          m_trade - amostra de classe СTrade;
  3. CSymbolInfo  m_symbol - amostra de classe CSymbolInfo;
  4. CPositionInfo  m_position - amostra de classe СPositionInfo;
  5. CAccountInfo  m_account - amostra de classe CAccountInfo;
  6. int                 m_handle_macd - uma variável para armazenar o valor do handle do indicador MACD utilizado.
  7. int                 m_handle_ema - uma variável para armazenar o valor do handle do indicador EMA utilizado.
  8. double           m_buff_MACD_main[] - uma array dinâmica do tipo double que é utilizado para solicitar os valores da linha principal do MACD;
  9. double           m_buff_MACD_signal[] - uma array dinâmica do tipo double que é utilizado para solicitar os valores da linha principal do MACD;
  10. double           m_buff_EMA[] - uma array dinâmica do tipo double, que é utilizado para solicitar os valores do indicador EMA;
  11. double           m_macd_current - é usado para armazenar o valor atual da linha principal MACD;
  12. double           m_macd_current - é usado para armazenar o valor anterior da linha principal MACD;
  13. double           m_signal_current - é usado para armazenar o valor atual da linha sinal MACD;
  14. double           m_signal_previous - é usado para armazenar o valor anterior da linha sinal MACD;
  15. double           m_ema_current - é usado para armazenar o valor atual do indicador EMA;
  16. double           m_ema_previous - é usado para armazenar o valor anterior do indicador EMA;
  17. double           m_macd_open_level,
  18. double           m_macd_close_level,
  19. double           m_traling_stop,
  20. double           m_take_profit - são usados ​​para armazenar os valores de níveis de preços (definido nos parâmetros de entrada), tendo em conta o multiplicador m_adjusted_point.

Métodos de classe CSampleExpert declarados com o modificador de acesso protegido:

  1. bool  InitCheckParameters(const int digits_adjust) - verifica a correção de parâmetros de entrada e de inicialização do EA;
  2. bool  InitIndicators(void) - inicialização (criação) dos indicadoresMACD e Moving Average;
  3. bool  LongClosed(void) - retorna verdadeiro (e fecha uma posição comprada) se estiverem reunidas as condições para fechar a posição comprada;
  4. bool  ShortClosed(void) - retorna verdadeiro (e fecha uma posição vendida) se estiverem reunidas as condições para fechar uma posição vendida;
  5. bool  LongModified(void) - retorna verdadeiro (e modifica o preço do Stop Loss) se estiverem reunidas as condições para alterar o nível de Stop Loss de uma posição comprada;
  6. bool  ShortModified(void) - retorna verdadeiro (e modifica o preço do Stop Loss) se estiverem reunidas as condições para alterar o nível de Stop Loss de uma posição vendida;
  7. bool  LongOpened(void) - retorna verdadeiro (e abre uma posição comprada) se estiverem reunidas as condições para a abertura de uma posição comprada;
  8. bool  ShortOpened(void) - retorna verdadeiro (e abre uma posição vendida) se estiverem reunidas as condições para abrir uma posição vendida.


3.2. Construtor da Classe CSampleExpert

//+------------------------------------------------------------------+
//| Classe de Construtor CSampleExpert                               |
//+------------------------------------------------------------------+
CSampleExpert::CSampleExpert(void) : m_adjusted_point(0),
                                     m_handle_macd(INVALID_HANDLE),
                                     m_handle_ema(INVALID_HANDLE),
                                     m_macd_current(0),
                                     m_macd_previous(0),
                                     m_signal_current(0),
                                     m_signal_previous(0),
                                     m_ema_current(0),
                                     m_ema_previous(0),
                                     m_macd_open_level(0),
                                     m_macd_close_level(0),
                                     m_traling_stop(0),
                                     m_take_profit(0)
  {
   ArraySetAsSeries(m_buff_MACD_main,true);
   ArraySetAsSeries(m_buff_MACD_signal,true);
   ArraySetAsSeries(m_buff_EMA,true);
  }

O construtor de classe é chamado automaticamente quando um objeto tipo amostra de classe é criado. Quando é chamado, os valores padrões (entre parêntesis) para as variáveis ​​de membro de classe são definidos e a direção de indexação das timeseries é definida para m_buff_MACD_main[], m_buff_MACD_signal[] e m_buff_EMA[].


3.3. O destruidor da classe CSampleExpert

//+------------------------------------------------------------------+
//| Classe de destrutor CSampleExpert                                |
//+------------------------------------------------------------------+
CSampleExpert::~CSampleExpert(void)
  {
  }

O destrutor de classe CSampleExpert não contêm nenhum código.


3.4. O método de inicialização da classe CSampleExpert

//+------------------------------------------------------------------+
//| Inicialização e verificação dos parâmetros de entrada            |
//+------------------------------------------------------------------+
bool CSampleExpert::Init(void)
  {
//--- definição de propriedades comuns
   m_symbol.Name(Symbol());              // símbolo do instrumento financeiro (símbolo do ativo)
   m_trade.SetExpertMagicNumber(12345);  // número mágico
//--- levando em consideração cotação de 3/5-dígitos
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
   m_adjusted_point=m_symbol.Point()*digits_adjust;
//--- definindo os valores dos níveis levando em consideração o modificador m_adjusted_point
   m_macd_open_level =InpMACDOpenLevel*m_adjusted_point;
   m_macd_close_level=InpMACDCloseLevel*m_adjusted_point;
   m_traling_stop    =InpTrailingStop*m_adjusted_point;
   m_take_profit     =InpTakeProfit*m_adjusted_point;
//--- definindo a derrapagem de 3 pontos
   m_trade.SetDeviationInPoints(3*digits_adjust);
//---
   if(!InitCheckParameters(digits_adjust))
      return(false);
   if(!InitIndicators())
      return(false);
//--- completado com sucesso
   return(true);
  }

No método Init(), variáveis ​​de membros de classe são inicializados e os parâmetros de entrada são verificados.

Uma chamada do método Name() para o objeto m_symbol (instância da classe CSymbolInfo) define o nome do símbolo (intrumento financeiro - ativo) em que o Expert Advisor é executado, então o método SetExpertMagicNumber() é chamado; ele define o valor do número mágico da EA para o objeto m_trade (será usado para operações de negócio). Depois disso, o método Digits() é usado para solicitar o número de dígitos das símbolos(intrumento financeiros - ativos) depois do ponto decimal e, se necessário, os valores dos níveis são corrigidos.

Depois o método SetDeviationInPoints() do objecto m_trade é chamado, em que o valor da derrapagem permitida em operações de negócios é definida.


3.5. O método InitCheckParameters da classe CSampleExpert

//+------------------------------------------------------------------+
//| Verificando parâmetros de entrada                                |
//+------------------------------------------------------------------+
bool CSampleExpert::InitCheckParameters(const int digits_adjust)
  {
//--- checando a correção do nível de Take Profit
   if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel())
     {
      printf("Take Profit deve ser maior do que %d",m_symbol.StopsLevel());
      return(false);
     }
//--- checando a correção do nível de Trailing Stop 
   if(InpTrailingStop*digits_adjust<m_symbol.StopsLevel())
     {
      printf("Trailing Stop deve ser maior do que %d",m_symbol.StopsLevel());
      return(false);
     }
//--- checando a correção do volume (lotes) de negócios
   if(InpLots<m_symbol.LotsMin() || InpLots>m_symbol.LotsMax())
     {
      printf("Valor dos lotes deve ser no intervalo de %f para %f",m_symbol.LotsMin(),m_symbol.LotsMax());
      return(false);
     }
   if(MathAbs(InpLots/m_symbol.LotsStep()-MathRound(InpLots/m_symbol.LotsStep()))>1.0E-10)
     {
      printf("Valor dos lotes não é correspondido com a etapa do lote %f",m_symbol.LotsStep());
      return(false);
     }
//--- mostrar aviso se Take Profit<=Trailing Stop
   if(InpTakeProfit<=InpTrailingStop)
      printf("Aviso: Trailing Stop menor do que o Take Profit");
//--- completado com sucesso
   return(true);
  }

A correção dos parâmetros de entrada da EA é verificada no método InitCheckParameters(). Se algum dos parâmetros é inválido, uma mensagem apropriada é exibida, e a função retorna false.


3.6. O método InitIndicators() da classe CSampleExpert

//+------------------------------------------------------------------+
//| Metodo de Inicializaçao dos Indicadores                          |
//+------------------------------------------------------------------+
bool CSampleExpert::InitIndicators(void)
  {
//--- criando o indicador MACD
   if(m_handle_macd==INVALID_HANDLE)
      if((m_handle_macd=iMACD(NULL,0,12,26,9,PRICE_CLOSE))==INVALID_HANDLE)
        {
         printf("Erro ao criar o indicador MACD");
         return(false);
        }
//--- criando o indicador EMA
   if(m_handle_ema==INVALID_HANDLE)
      if((m_handle_ema=iMA(NULL,0,InpMATrendPeriod,0,MODE_EMA,PRICE_CLOSE))==INVALID_HANDLE)
        {
         printf("Erro ao criar o indicador EMA");
         return(false);
        }
//--- completado com sucesso
   return(true);
  }

No método InitIndicators(), a correção dos valores iniciais das variáveis ​​m_handle_macd e m_handle_ema é verificada (que deve ser igual ao INVALID_HANDLE, já que eles foram inicializados no construtor) e os indicadores técnicos MACD e Moving Average são criados (usando as funções iMACD e iMA). Se bem sucedida, a função retornará verdadeira e os handles dos indicadores são salvos nos membros de classes m_handle_macd e m_handle_ema.

As alças dos indicadores criados, então, ser utilizado para verificar a quantidade de dados calculados (BarsCalculated) e obter os valores numéricos (CopyBuffer) dos indicadores do método Processing().


3.7. O método LongClosed() da classe CSampleExpert

//+------------------------------------------------------------------+
//| Verificando as condições para fechamento das posições compradas  |
//+------------------------------------------------------------------+
bool CSampleExpert::LongClosed(void)
  {
   bool res=false;
//--- deveria a posição ser fechada?
   if(m_macd_current>0)
      if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous)
         if(m_macd_current>m_macd_close_level)
           {
            //--- fechando a posição
            if(m_trade.PositionClose(Symbol()))
               printf("Posição comprada pelo %s foi fechada",Symbol());
            else
               printf("Erro no fechamento da posição pelo %s : '%s'",Symbol(),m_trade.ResultComment());
            res=true;
           }
//--- retornando o resultado
   return(res);
  }

O método LongClosed () retorna verdadeiro (e fecha a posição comprada aberta) se estiverem reunidas as condições para o fechamento da posição:

  1. m_macd_current>0 - o valor atual da linha principal do indicador MACD é positivo (o histograma MACD está acima da linha zero);
  2. m_macd_current<m_signal_current && m_macd_previous>m_signal_previous - a linha principal do indicador MACD cruzou a linha de sinal para baixo.
  3. m_macd_current>m_macd_close_level - o valor atual da linha principal do indicador MACD é maior do que m_macd_close_level.


3.8. O método ShortClosed() da classe CSampleExpert

//+------------------------------------------------------------------+
//|  Verificando as condições para fechamento das posições vendida   |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortClosed(void)
  {
   bool res=false;
//--- deveria a posição ser fechada?
   if(m_macd_current<0)
      if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous)
         if(MathAbs(m_macd_current)>m_macd_close_level)
           {
            //--- fechando a posição
            if(m_trade.PositionClose(Symbol()))
               printf("Posição vendida pelo %s foi fechada",Symbol());
            else
               printf("Erro no fechamento da posição pelo %s : '%s'",Symbol(),m_trade.ResultComment());
            res=true;
           }
//--- retornando o resultado
   return(res);
  }

O método ShortClosed() retorna verdadeiro (e fecha a posição vendida aberta) se estiverem reunidas as condições para o fechamento da posição:

  1. m_macd_current<0 - o valor atual da linha principal do indicador MACD é negativo (o histograma MACD está abaixo da linha zero).
  2. m_macd_current>m_signal_current && m_macd_previous<m_signal_previous - a linha principal do indicador MACD cruzou a linha de sinal para cima.
  3. MathAbs(m_macd_current)>m_macd_close_level - oo valor atual da linha principal do indicador MACD é maior do que m_macd_close_level.


3.9. O método LongModified() da classe CSampleExpert

//+------------------------------------------------------------------+
//| Verificando as condições para modificação das posições compradas |
//+------------------------------------------------------------------+
bool CSampleExpert::LongModified(void)
  {
   bool res=false;
//--- verificando se o Trailing Stop é solicitado
   if(InpTrailingStop>0)
     {
      if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop)
        {
         double sl=NormalizeDouble(m_symbol.Bid()-m_traling_stop,m_symbol.Digits());
         double tp=m_position.TakeProfit();
         if(m_position.StopLoss()<sl || m_position.StopLoss()==0.0)
           {
            //--- modificação do Stop Loss e Take Profit da posição
            if(m_trade.PositionModify(Symbol(),sl,tp))
               printf("Posição Comprada pelo %s foi modificada",Symbol());
            else
              {
               printf("Erro na modificação da posição pelo %s : '%s'",Symbol(),m_trade.ResultComment());
               printf("Parâmetros modificados : SL=%f,TP=%f",sl,tp);
              }
            res=true;
           }
        }
     }
//--- retornando o resultado
   return(res);
  } 

O método LongModified() retorna verdadeiro (e modifica o valor Stop Loss da posição) se estiverem reunidas as condições necessárias para a modificação da posição comprada: Se o valor da entrada InpTrailingStop>0, então o fato da passagem do preço pelos pontos do InpTrailingStop a partir do preço de abertura na direção da posição é verificado. Em seguida, o valor do novo nível Stop Loss é calculado e o parâmetro de Stop Loss da posição aberta é modificado.


3.10. O método ShortModified da classe CSampleExpert

//+------------------------------------------------------------------+
//| Verificando as condições para modificação das posições vendidas  |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortModified(void)
  {
   bool   res=false;
//--- verificando se o Trailing Stop é solicitado
   if(InpTrailingStop>0)
     {
      if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop))
        {
         double sl=NormalizeDouble(m_symbol.Ask()+m_traling_stop,m_symbol.Digits());
         double tp=m_position.TakeProfit();
         if(m_position.StopLoss()>sl || m_position.StopLoss()==0.0)
           {
            //--- modificação do Stop Loss e Take Profit da posição
            if(m_trade.PositionModify(Symbol(),sl,tp))
               printf("Posição vendida pelo %s foi modificada",Symbol());
            else
              {
               printf("Erro na modificaçaõ da posição pelo%s : '%s'",Symbol(),m_trade.ResultComment());
               printf("Parâmetros modificados : SL=%f,TP=%f",sl,tp);
              }
            res=true;
           }
        }
     }
//--- returnando o resultado
   return(res);
  }

O método ShortModified() retorna verdadeiro (e modifica o valor Stop Loss da posição) se estiverem reunidas as condições necessárias para a modificação da posição: Se o valor da entrada InpTrailingStop>0, então o fato da passagem do preço pelos pontos do InpTrailingStop a partir do preço de abertura na direção da posição é verificado. Em seguida, o valor do novo nível Stop Loss é calculado e o parâmetro de Stop Loss da posição aberta é modificado.


3.11. O método LongOpened () da classe CSampleExpert

//+------------------------------------------------------------------+
//| Verificar a abertura de uma posição comprada                     |
//+------------------------------------------------------------------+
bool CSampleExpert::LongOpened(void)
  {
   bool res=false;
//--- Verificar as condições para a abertura de uma posição comprada 
   if(m_macd_current<0)
      if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous)
         if(MathAbs(m_macd_current)>(m_macd_open_level) && m_ema_current>m_ema_previous)
           {
            double price=m_symbol.Ask();
            double tp   =m_symbol.Bid()+m_take_profit;
            //--- verificando a margem livre
            if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_BUY,InpLots,price)<0.0)
               printf("Não tem dinheiro. Margem Livre = %f",m_account.FreeMargin());
            else
              {
               //--- abertura de uma posição comprada
               if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,InpLots,price,0.0,tp))
                  printf("Posição pelo %s foi aberta",Symbol());
               else
                 {
                  printf("Erro de abertura da posição BUY pelo %s : '%s'",Symbol(),m_trade.ResultComment());
                  printf("Abrir parâmetros : price=%f,TP=%f",price,tp);
                 }
              }
            res=true;
           }
//--- retornando o resultado
   return(res);
  }

O método LongOpened() retorna verdadeiro (e abre uma posição comprada) se estiverem reunidas as condições necessárias para a abertura de uma posição comprada:

  1. m_macd_current<0 - o valor atual da linha principal do indicador MACD é negativo (MACD histograma está abaixo da linha zero);
  2. m_macd_current>m_signal_current && m_macd_previous<m_signal_previous - a linha principal do indicador MACD cruzou a linha do sinal para cima;
  3. MathAbs(m_macd_current)>m_macd_open_level - o valor atual da linha principal do módulo indicador MACD é maior do que m_macd_open_level;
  4. m_ema_current>m_ema_previous - ema cresce.

Quando estiverem reunidas todas as condições, a margem livre é verificada (o método FreeMarginCheck() da classe CAccountInfo da biblioteca padrão) e uma posição comprada é aberta usando o método PositionOpen() da classe CTrade .


3.12. O método ShortOpened da classe CSampleExpert

//+------------------------------------------------------------------+
//| Verificar a abertura de uma posição vendida                      |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortOpened(void)
  {
   bool res=false;
//--- Verificar as condições para a abertura de uma posição vendida
   if(m_macd_current>0)
      if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous)
         if(m_macd_current>(m_macd_open_level) && m_ema_current<m_ema_previous)
           {
            double price=m_symbol.Bid();
            double tp   =m_symbol.Ask()-m_take_profit;
            //--- verificando a margem livre
            if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL,InpLots,price)<0.0)
               printf("Não tem dinheiro. Margem Livre = %f",m_account.FreeMargin());
            else
              {
               //--- abertura de uma posição vendida
               if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,InpLots,price,0.0,tp))
                  printf("Posição pelo %s foi aberta",Symbol());
               else
                 {
                  printf("Erro de abertura da posição SELL pelo  %s : '%s'",Symbol(),m_trade.ResultComment());
                  printf("Abrir parâmetros : price=%f,TP=%f",price,tp);
                 }
              }
            res=true;
           }
//--- retornando o resultado
   return(res);
  }

O método ShortOpened() retorna verdadeiro (e abre uma posição vendida) se estiverem reunidas as condições necessárias para a abertura de uma posição vendida:

  1. m_macd_current>0 - o valor atual da linha principal do indicador MACD é positivo (o histograma MACD está acima da linha zero);
  2. m_macd_current<m_signal_current && m_macd_previous>m_signal_previous - a linha principal do indicador MACD cruzou a linha sinal para baixo;
  3. m_macd_current>m_macd_open_level - o valor atual da linha principal MACD é maior do que m_macd_open_level;
  4. m_ema_current<m_ema_previous - ema diminui.

Quando estiverem reunidas todas as condições, a margem livre é verificado (o método FreeMarginCheck() da classe CAccountInfo da biblioteca padrão) e uma posição curta é aberta usando o método PositionOpen() da classe CTrade .


3.13 O método Processing() da classe CSampleExpert

//+------------------------------------------------------------------------+
//| função principal retorna verdadeiro se qualquer posição for processada |
//+------------------------------------------------------------------------+
bool CSampleExpert::Processing(void)
  {
//--- atualizando as cotações
   if(!m_symbol.RefreshRates())
      return(false);
//--- atualizando os valores dos indicadores
   if(BarsCalculated(m_handle_macd)<2 || BarsCalculated(m_handle_ema)<2)
      return(false);
   if(CopyBuffer(m_handle_macd,0,0,2,m_buff_MACD_main)  !=2 ||
      CopyBuffer(m_handle_macd,1,0,2,m_buff_MACD_signal)!=2 ||
      CopyBuffer(m_handle_ema,0,0,2,m_buff_EMA)         !=2)
      return(false);
//--- para simplificar o trabalho com os indicadores e para um acesso mais rápido
//--- os valores atuais dos indicadores são salvos em variáveis ​​internas (membros de classe)
   m_macd_current   =m_buff_MACD_main[0];
   m_macd_previous  =m_buff_MACD_main[1];
   m_signal_current =m_buff_MACD_signal[0];
   m_signal_previous=m_buff_MACD_signal[1];
   m_ema_current    =m_buff_EMA[0];
   m_ema_previous   =m_buff_EMA[1];
//--- é importante a entrada correta no mercado, mas uma saída correta é ainda mais importante
//--- primeiro verifica se existe uma posição aberta
   if(m_position.Select(Symbol()))
     {
      if(m_position.PositionType()==POSITION_TYPE_BUY)
        {
         //--- Se necessário, vamos tentar fechar ou modificar uma posição comprada
         if(LongClosed())
            return(true);
         if(LongModified())
            return(true);
        }
      else
        {
         //--- Se necessário, vamos tentar fechar ou modificar uma posição vendida
         if(ShortClosed())
            return(true);
         if(ShortModified())
            return(true);
        }
     }
//--- nao abre posição
   else
     {
      //--- verificar as condições e abrir uma posição comprada, se necessário
      if(LongOpened())
         return(true);
      //--- verificar as condições e abrir uma posição vendida, se necessário
      if(ShortOpened())
         return(true);
     }
//--- sair sem o processamento da posição
    return(false);
  }

O método de Processing() da classe CSampleExpert é o método do Expert Advisor. O método de Processing() é chamado no manipulador de eventos OnTick() e o intervalo de tempo entre as chamadas sucessivas deste método é monitorado (não menos do que os segundos do ExtTimeOut) (seção 2.2).

Ao chamar os métodos RefreshRates() da classe CSymbolInfo, as cotações são atualizados. A função BarsCalculated() é usada para solicitar o número de barras para que os indicadores MACD e Moving Average sejam calculados (seção 3.6.); se o número de barras é inferior a 2, vai sair da função e retornar falso.

Em seguida,a função CopyBufferchamada, solicita os dois últimos valores de indicadores técnicos (os principais sinais e linhas MACD e movendo-se valores médios); e se a quantidade de dados copiados é menor do que dois, em seguida, saia da função. Depois os valores dos indicadores a partir das arrays m_buff_MACD_main[], m_buff_MACD_signal[] e m_buff_EMA[] são copiados para as variáveis ​​m_macd_current, m_macd_previous, m_signal_current, m_signal_previous, m_ema_current e m_ema_previous.

O próximo passo é trabalhar com uma posição realizada por meio da classe CPositionInfo da biblioteca padrão. Se o método Select() chamado retorna verdadeiro, então isso significa que atualmente existe uma posição aberta, seu tipo é determinado usando o método PositionType(). Além disso o trabalho é realizado de acordo com o tipo de posição aberta.


4. Backtesting

Os melhores valores dos parâmetros podem ser encontrados usando o Strategy Tester do terminal MetaTrader 5.

A Figura 3 mostra os resultados do teste deste Expert Advisor para o ano 2013 com as configurações padrão.

Figure 3. Resultados do backtesting do Expert Advisor MACD Sample

Figure 3. Resultados do backtesting do Expert Advisor MACD Sample

Conclusões

O Expert Advisor MACD Sample, incluído no pacote de entrega padrão do terminal MetaTrader 5 é um exemplo de abordagem orientada a objetos no desenvolvimento de um EA.


Traduzido do russo pela MetaQuotes Ltd.
Publicação original: https://www.mql5.com/ru/code/2154

MultiT3_TRIXx7Signal MultiT3_TRIXx7Signal

O indicador MultiT3_TRIXx7Signal mostra informações sobre as tendências usando os valores de sete indicadores T3_TRIX de diferentes timeframes.

BackgroundCandle_T3_TRIX_HTF BackgroundCandle_T3_TRIX_HTF

O indicador desenha candles retangulares coloridos para um período de timeframe maior. Os Retângulos coloridos são preenchido de acordo com a direção do histograma T3_TRIX.

Exp_T3_TRIX Exp_T3_TRIX

Um sistema de negociação usando o indicador T3_TRIX.

Exp_RSIOMA_V2 Exp_RSIOMA_V2

Sistema de negociação utilizando o indicador RSIOMA_V2.