Participe de nossa página de fãs
Coloque um link para ele, e permita que outras pessoas também o avaliem
Avalie seu funcionamento no terminal MetaTrader 5
- Publicado por:
- MetaQuotes
- Visualizações:
- 9732
- Avaliação:
- Publicado:
- 2014.07.03 09:45
- Atualizado:
- 2016.11.22 07:33
-
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":
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
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:
- CSampleExpert(void) - um construtor (chamado automaticamente durante a criação de uma instância de classe);
- ~CSampleExpert(void) - um destrutor (chamado automaticamente durante a exclusão de uma instância de classe);
- bool Init(void) - método de inicialização no qual todos os dados necessários para a operação são preparados;
- void Deinit(void) - método de desinicialização;
- 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).
- double m_adjusted_point - variável multiplicador para uma operação correta com cotações 3/5-digitos;
- CTrade m_trade - amostra de classe СTrade;
- CSymbolInfo m_symbol - amostra de classe CSymbolInfo;
- CPositionInfo m_position - amostra de classe СPositionInfo;
- CAccountInfo m_account - amostra de classe CAccountInfo;
- int m_handle_macd - uma variável para armazenar o valor do handle do indicador MACD utilizado.
- int m_handle_ema - uma variável para armazenar o valor do handle do indicador EMA utilizado.
- double m_buff_MACD_main[] - uma array dinâmica do tipo double que é utilizado para solicitar os valores da linha principal do MACD;
- double m_buff_MACD_signal[] - uma array dinâmica do tipo double que é utilizado para solicitar os valores da linha principal do MACD;
- double m_buff_EMA[] - uma array dinâmica do tipo double, que é utilizado para solicitar os valores do indicador EMA;
- double m_macd_current - é usado para armazenar o valor atual da linha principal MACD;
- double m_macd_current - é usado para armazenar o valor anterior da linha principal MACD;
- double m_signal_current - é usado para armazenar o valor atual da linha sinal MACD;
- double m_signal_previous - é usado para armazenar o valor anterior da linha sinal MACD;
- double m_ema_current - é usado para armazenar o valor atual do indicador EMA;
- double m_ema_previous - é usado para armazenar o valor anterior do indicador EMA;
- double m_macd_open_level,
- double m_macd_close_level,
- double m_traling_stop,
- 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:
- bool InitCheckParameters(const int digits_adjust) - verifica a correção de parâmetros de entrada e de inicialização do EA;
- bool InitIndicators(void) - inicialização (criação) dos indicadoresMACD e Moving Average;
- bool LongClosed(void) - retorna verdadeiro (e fecha uma posição comprada) se estiverem reunidas as condições para fechar a posição comprada;
- bool ShortClosed(void) - retorna verdadeiro (e fecha uma posição vendida) se estiverem reunidas as condições para fechar uma posição vendida;
- 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;
- 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;
- 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;
- 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:
- m_macd_current>0 - o valor atual da linha principal do indicador MACD é positivo (o histograma MACD está acima da linha zero);
- 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.
- 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:
- m_macd_current<0 - o valor atual da linha principal do indicador MACD é negativo (o histograma MACD está abaixo da linha zero).
- 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.
- 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:
- m_macd_current<0 - o valor atual da linha principal do indicador MACD é negativo (MACD histograma está abaixo da linha zero);
- 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;
- 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;
- 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:
- m_macd_current>0 - o valor atual da linha principal do indicador MACD é positivo (o histograma MACD está acima da linha zero);
- m_macd_current<m_signal_current && m_macd_previous>m_signal_previous - a linha principal do indicador MACD cruzou a linha sinal para baixo;
- m_macd_current>m_macd_open_level - o valor atual da linha principal MACD é maior do que m_macd_open_level;
- 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
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](https://c.mql5.com/i/code/indicator.png)
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](https://c.mql5.com/i/code/indicator.png)
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](https://c.mql5.com/i/code/expert.png)
Um sistema de negociação usando o indicador T3_TRIX.
![Exp_RSIOMA_V2](https://c.mql5.com/i/code/expert.png)
Sistema de negociação utilizando o indicador RSIOMA_V2.