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:
- 13834
- 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
![Math-System](https://c.mql5.com/i/code/indicator.png)
Um conjunto de alvos de níveis de suporte/resistência para o movimento de preço previsto.
![DigitalF-T01](https://c.mql5.com/i/code/indicator.png)
Um filtro digital de tendência rápida, com uma linha de referência, implementado na forma de uma nuvem.
![MA_3HTF](https://c.mql5.com/i/code/indicator.png)
Três médias móveis de três períodos de tempo diferentes em um gráfico.
![ColorBlauErgodicMACD](https://c.mql5.com/i/code/indicator.png)
Oscilador MACD Ergódigo implementado na forma de histograma colorido.