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
- Visualizações:
- 14778
- Avaliação:
- Publicado:
- 2014.01.14 12:31
- Atualizado:
- 2018.06.04 17:56
-
Precisa de um robô ou indicador baseado nesse código? Solicite-o no Freelance Ir para Freelance
O EA de média móvel está incluído no pacote padrão do terminal do cliente MetaTrader 5 e é um exemplo da EA que negocia com o indicador de Média Móvel.
O arquivo EA Moving Average.mq5 está localizado na pasta "terminal_data_folder\MQL5\Experts\Examples\Moving Average\". Este EA é um exemplo da utilização de indicadores técnicos, histórico de negociações e funções classes de negociação da biblioteca padrão. Além disso, o AE inclui um sistema de gestão de dinheiro que é baseado nos resultados das negociações
Vamos considerar a estrutura do Expert Advisor e como ele funciona.
1. Propriedades do EA
//+------------------------------------------------------------------+ //| Moving Averages.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 "1.00
As primeiras 5 linhas contêm um comentário, as três linhas seguintes definem as propriedades do programa MQL5 (copyright, link, versão) utilizando as diretivas de pré-processamento #Property.
Quando você executa o Expert Advisor eles são exibidos na aba "Common":
Figura 1. Parâmetros comuns de EA Média Móvel
1.2. Arquivos de include
Em seguida, a diretiva #Include diz ao compilador para incluir o arquivo "Trade.mqh".
Este arquivo é parte da Biblioteca Padrão, que contém a classe CTrade para facilitar o acesso as funções de negociação.
#include <Trade\Trade.mqh>
O nome do arquivo de inclusão é mostrado entre parênteses "<>;", de modo que o caminho está definido em relação ao diretório: "terminal_data_folder\Include\".
1.3 Entradas
Vai-se o tipo, nome, valores padrão e um comentário. O seu papel é mostrado na fig. 2.
input double MaximumRisk = 0.02; // Risco máximo em porcentagem input double DecreaseFactor = 3; // Fator de rebaixamento input int MovingPeriod = 12; // Período da Média Móvel input int MovingShift = 6; // Deslocamento da Média Móvel
Os parâmetros MaximumRisk e DecreaseFactor serão utilizados para o gerenciamento de dinheiro, MovingPeriod e MovingShift definem o período e o deslocamento do indicador técnico Média Móvel que será usado ou verificará as condições de negociação.
O texto no comentário na linha de parâmetro de entrada, juntamente com os valores padrão, são exibidos na aba "Options" em vez do nome do parâmetro de entrada:
Fig. 2. Parâmetros de entrada do EA Média Móvel
1.4. Variáveis globais
Em seguida, a variável global ExtHandle é declarada. Ela será usada para armazenar o manipulador do indicador Média Móvel.
//--- int ExtHandle=0;
Ele é seguido por seis funções. A finalidade de cada um deles está descrito no comentário antes do corpo da função:
- TradeSizeOptimized() - Calcula o tamanho ideal do lote;
- CheckForOpen() - Verifica as condições para abertura de posição;
- CheckForClose() - Verifica as condições de fechamento da posição;
- OnInit() - função de inicialização do Expert;
- OnTick() - Função tick do Expert;
- OnDeinit() - Função de desinicialização do Expert;
As três últimas funções são funções de manipulação de evento; as três primeiras funções de serviço são chamadas em seu código.
2. Funções de manipulação de eventos
2.1. A função de inicialização OnInit()
A função OnInit() é chamada uma vez durante a inicialização do Expert Advisor. Geralmente no manipulador de eventos OnInit() a EA está preparada para a operação: os parâmetros de entrada são verificados, os indicadores e parâmetros são inicializados, etc No caso de erros críticos, quando o funcionamento não faz sentido, a função é encerrada com um código de retorno INIT_FAILED.
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(void) { //--- ExtHandle=iMA(_Symbol,_Period,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE); if(ExtHandle==INVALID_HANDLE) { printf("Erro ao criar o indicador MA"); return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); }
Desde que a negociação do EA é baseada no indicador de média móvel, chama-se IMA() e o indicador de Média Móvel é criado e seu manipulador é salvo na variável global ExtHandle.
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 símbolo do gráfico, em que a EA é executada.
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick(void) { //--- if(PositionSelect(_Symbol)) CheckForClose(); else CheckForOpen(); //--- }
A função PositionSelect() é usada para definir se existe uma posição em aberto para o símbolo atual.
Se houver posições em aberto, a função CheckForClose() é chamada, ela analisa o estado atual do mercado e fecha a posição em aberta, caso contrário CheckForOpen() é chamado, ela verifica as condições de entrada no mercado e abre uma nova posição, se tais condições ocorrerem.
2.3. A função de desinicialização OnDeInit()
OnDeInit () é chamada quando um EA é removido a partir do gráfico. Se um programa coloca os objectos gráficos durante a operação, eles podem ser removidos a partir do gráfico.
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+
Neste caso, não há a realização de nenhuma ação durante a desinicialização do Expert Advisor.
3. Funções de serviço
3.1. Função TradeSizeOptimized()
Esta função calcula e retorna o valor do tamanho do lote ideal para a posição de abertura com o nível de risco especificado e os resultados das negociações.
//+------------------------------------------------------------------+ //| Calcular o tamanho ideal do lote | //+------------------------------------------------------------------+ double TradeSizeOptimized(void) { double price=0.0; double margin=0.0; //--- Calcula o tamanho do lote if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price)) return(0.0); if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin)) return(0.0); if(margin<=0.0) return(0.0); double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_FREEMARGIN)*MaximumRisk/margin,2); //--- Calcular o comprimento da série de operações consecutivas de perda if(DecreaseFactor>0) { //--- Pedido de todo o histórico de negociação HistorySelect(0,TimeCurrent()); //-- int orders=HistoryDealsTotal(); // O número total de ofertas int losses=0; // O número de ofertas de perda na série for(int i=orders-1;i>=0;i--) { ulong ticket=HistoryDealGetTicket(i); if(ticket==0) { Print("HistoryDealGetTicket failed, no trade history"); break; } //--- verificando o símbolo de negociação if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol) continue; //--- verificando o lucro double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT); if(profit>0.0) break; if(profit<0.0) losses++; } //--- if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1); } //--- Normalizando e verificando os valores permitidos para o volume de negociações double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP); lot=stepvol*NormalizeDouble(lot/stepvol,0); double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN); if(lot<minvol) lot=minvol; double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX); if(lot>maxvol) lot=maxvol; //--- retorna o valor do volume de negociação return(lot); }
A função SymbolInfoDouble() é utilizada para verificar a disponibilidade de preços para o símbolo atual, em seguinda, a função OrderCalcMargin() é utilizada para solicitar a margem necessária para colocar uma ordem (neste caso uma ordem de compra). O tamanho inicial do lote é determinado a partir do valor da margem requerida para colocar uma ordem, a margem livre da conta (AccountInfoDouble(ACCOUNT_FREEMARGIN)) e o valor máximo permitido de risco especificadas no parâmetro de entrada MaximumRisk.
Se o valor do parâmetro de entrada DecreaseFactor é positivo, as ordens históricas são analisadas e o tamanho do lote é ajustado tendo em conta as informações sobre a série máxima de negócios com perda: o tamanho inicial do lote é multiplicado pelo tamanho (1-perdas/DecreaseFactor).
Em seguida, o volume de negociação é "arredondado" para o valor que é múltiplo do passo mínimo permitido do volume (stepvol) para o símbolo atual. Além disso, os valores máximos (maxvol) e mínimos (minvol) possíveis do volume de negociação são solicitados, e se o valor do lote sair dos limites desejados, ele é ajustado. Como resultado, a função retorna o valor calculado do volume de negóciação.
3.2. Função CheckForOpen()
CheckForOpen() é usado para verificar as condições das posições de abertura ela abre-a quando ocorrem as condições de negociação (neste caso, quando o preço cruza a média móvel).
//+------------------------------------------------------------------+ //| Verificar a existência das condições de abertura de posição | //+------------------------------------------------------------------+ void CheckForOpen(void) { MqlRates rt[2]; //--- Copia os valores do preço if(CopyRates(_Symbol,_Period,0,2,rt)!=2) { Print("CopyRates of ",_Symbol," failed, no history"); return; } //--- Negocia somento no primeiro tick da barra if(rt[1].tick_volume>1) return; //--- Obtém o valor atual do indicador de média móvel double ma[1]; if(CopyBuffer(ExtHandle,0,0,1,ma)!=1) { Print("CopyBuffer from iMA failed, no data"); return; } //--- verifica os sinais ENUM_ORDER_TYPE signal=WRONG_VALUE; if(rt[0].open>ma[0] && rt[0].close<ma[0]) signal=ORDER_TYPE_SELL; // condição de venda else { if(rt[0].open<ma[0] && rt[0].close>ma[0]) signal=ORDER_TYPE_BUY; // condição de compra } //--- verificações adicionais if(signal!=WRONG_VALUE) if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) if(Bars(_Symbol,_Period)>100) { CTrade trade; trade.PositionOpen(_Symbol,signal,TradeSizeOptimized(), SymbolInfoDouble(_Symbol,signal==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK), 0,0); } //--- }
Ao negociar usando o movimento, você precisa verificar se o preço cruza a média móvel. Usando a função CopyRates(), dois valores dos preços atuais são copiados no array de estruturas rt[], rt[1] corresponde à barra atual, rt[0] - barra completa.
Um nova barra é iniciada através da verificação do volume de escala da barra atual se ele for igual a 1, uma nova barra se iniciou Deve-se notar que este método de detecção de um nova barra pode falhar em alguns casos (quando as cotações vêm em pacotes), então o fato do início da formação de uma nova barra deve ser feita através do armazenamento e da comparação do tempo da cotação atual (ver IsNewBar).
O valor atual do indicador de média móvel é solicitado usando a função CopyBuffer() e ela é salva no array ma[] que contém apenas um valor. O programa verifica se o preço cruzou a média móvel e faz verificações adicionais (se a negociação com o EA é possível e se há a presença de barras no histórico). Se for bem sucedido, uma posição adequada para o símbolo é aberto chamando o método PositionOpen() do objeto de negociação (uma instância de CTrade).
O preço da abertura da posição é definida através da função SymbolInfoDouble() que retorna o preço de Bid ou Ask, dependendo do valor da variável de sinal. O volume da posição é determinada pela chamada de TradeSizeOptimized() descrito acima.
3.3. Função CheckForClose()
CheckForClose() verifica as condições para o fechamento da posição e fecha se as condições para fechamento ocorrer.
//+------------------------------------------------------------------+ //| Verifica a existência de condições de fechamento da posição | //+------------------------------------------------------------------+ void CheckForClose(void) { MqlRates rt[2]; //--- Copy price values if(CopyRates(_Symbol,_Period,0,2,rt)!=2) { Print("CopyRates of ",_Symbol," failed, no history"); return; } //--- Negocia somento no primeiro tick da nova barra if(rt[1].tick_volume>1) return; //--- Obtêm o valor atual do indicador Média Móvel double ma[1]; if(CopyBuffer(ExtHandle,0,0,1,ma)!=1) { Print("CopyBuffer from iMA failed, no data"); return; } //--- Obter o tipo de posição selecionada anteriormente usando PositionSelect() bool signal=false; long type=PositionGetInteger(POSITION_TYPE); if(type==(long)POSITION_TYPE_BUY && rt[0].open>ma[0] && rt[0].close<ma[0]) signal=true; if(type==(long)POSITION_TYPE_SELL && rt[0].open<ma[0] && rt[0].close>ma[0]) signal=true; //--- verificações adicionais if(signal) if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) if(Bars(_Symbol,_Period)>100) { CTrade trade; trade.PositionClose(_Symbol,3); } //--- }
O algoritmo da função CheckForClose() é semelhante ao algoritmo CheckForOpen(). Dependendo da direção das posições atuais em aberto, as condições de seus fechamento são verificadas novamente (o preço cruza a MA para baixo para comprar ou para cima, para vender). Uma posição em aberto é fechada chamando o método PositionClose() do objeto de negociação (instância CTrade).
4. Backtesting
Os melhores valores dos parâmetros podem ser encontrados usando o Strategy Tester do terminal MetaTrader 5.
Por exemplo, quando se otimizar o parâmetro MovingPeriod no intervalo 2012.01.01-2013.08.01, os melhores resultados são obtidos com MovingPeriod = 45:
Resultados do Backtesting do Expert Advisor da média móvel
Conclusões:
O Expert Advisor de média móvel está incluído no pacote padrão do terminal MetaTrader 5 é um exemplo da utilização de indicadores técnicos, histórico de negociação, funções classes de negociação da biblioteca padrão. Além disso, o AE inclui um sistema de gestão de dinheiro que é baseado nos resultados das negociações
Traduzido do russo pela MetaQuotes Ltd.
Publicação original: https://www.mql5.com/ru/code/1921

Um conjunto de alvos de níveis de suporte/resistência para o movimento de preço previsto.

Um filtro digital de tendência rápida, com uma linha de referência, implementado na forma de uma nuvem.

Três médias móveis de três períodos de tempo diferentes em um gráfico.

Oscilador MACD Ergódigo implementado na forma de histograma colorido.