Criando um EA de Cruzamento de Médias Móveis no MetaTrader 4

Mike 2021.03.30 19:18 21 0 0
Anexo

Vamos começar a criar esse EA (Expert Advisor) definindo as variáveis de entrada.

//--- parâmetros de entrada
input    int      periodo_ma_rapida = 8;  // Período da Média Móvel Rápida
input    int      periodo_ma_lenta = 20; // Período da Média Móvel Lenta

input    double  takeProfit  = 20.0;  // Take Profit (pips)
input    double  stopLoss    = 20.0  // Stop Loss (pips)

input    double  tamanhoLote     = 0.10;  // Tamanho do Lote
input    double  minimoEquity   = 100.0; // Mínimo Equity ($)

input    int slippage = 3;       // Slippage
input    int numeroMagico = 889;  // Número Mágico


Agora, vamos definir as variáveis globais. Essas variáveis com escopo global estarão disponíveis em todas as funções.

// Variáveis Globais
double  meuPonto    = 0.0;
int      minhaSlippage = 0;
int      CompraTicket   = 0;
int      VendaTicket  = 0;


Quando o EA é executado, a primeira função chamada é a OnInit(). Usamos essa função para validar e inicializar as variáveis globais que serão utilizadas.

int OnInit()
{
   // validação das entradas, sempre valide ao inicializar dados de entrada
   if (periodo_ma_rapida >= periodo_ma_lenta || takeProfit < 0.0 || stopLoss < 0.0 || tamanhoLote < 0.01 || minimoEquity < 10){
      Alert("ATENÇÃO - Dados de entrada não são válidos");
      return (INIT_PARAMETERS_INCORRECT);
   }
   
   double volume_minimo=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(tamanhoLote<volume_minimo)
   {
      string mensagem =StringFormat("Volume menor que o permitido de %.2f",volume_minimo);
      Alert (mensagem);
      return(INIT_PARAMETERS_INCORRECT);
   }
   
   meuPonto = GetPipPoint(Symbol());
   minhaSlippage = GetSlippage(Symbol(),slippage);

   return(INIT_SUCCEEDED);
}


Quando o preço do mercado se move (tick), a função OnTick() será chamada e executará todas as instruções contidas nesse bloco.

Dentro da função OnTick(), chamaremos várias outras funções.

Começamos chamando a função checkMinEquity() para controlar a adequação do equity para operações. Se o equity for suficiente (acima do mínimo), continuamos com a declaração da variável de sinal e chamamos a função NewCandle(), que informa quando uma nova vela é formada.

A função getSignal() irá ler os valores nos dois indicadores de média móvel e retornar a informação sobre um cruzamento, seja para compra ou venda.

Com base nessa informação de sinal, ela será encaminhada para a função transaction(), que definirá as posições de compra ou venda.

Depois, chamamos a função setTPSL(), que serve para definir os preços de take profit e stop loss.

Se o equity não atender ao requisito mínimo, um alerta será exibido e o EA será encerrado.

void OnTick()
{
   if (checkMinEquity()){
      
      int sinal = -1;
      bool novaCandle = NewCandle(Period(), Symbol());
      
      sinal = getSignal(novaCandle);
      transaction(novaCandle, sinal);
      setTPSL();
      
      
   }else{
      // Parar a operação, pois o equity não é suficiente
      Print("EA será encerrado pois o equity é insuficiente");
   }
}


A função para setTPSL()

void setTPSL(){
   int   ordemTotal = 0;
   string   strMN = "", par = "";
   double sl = 0.0, tp = 0.0;
   
   par = Symbol();
   
   ordemTotal = OrdersTotal();
   for (int i=ordemTotal-1; i>=0; i--){
      bool hrsSelect = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      strMN = IntegerToString(OrderMagicNumber());
      if (StringFind(strMN, IntegerToString(numeroMagico), 0) == 0 && StringFind(OrderSymbol(), par, 0) == 0 ){
         if (OrderType() == OP_BUY && (OrderTakeProfit() == 0 || OrderStopLoss() == 0) ){
            if (takeProfit > 0) {
               tp = OrderOpenPrice() + (takeProfit * meuPonto);
            }else{
               tp = OrderOpenPrice();
            }
            if (stopLoss > 0) {
               sl = OrderOpenPrice() - (stopLoss * meuPonto);
            }else{
               sl = OrderStopLoss();
            }
            if (OrderTakeProfit() != tp || OrderStopLoss() != sl ){
               if(OrderModify(OrderTicket(), OrderOpenPrice(), sl, tp, 0, clrBlue)){
                  Print ("Modificação da Ordem Bem Sucedida");
               }
            }
         }
         if (OrderType() == OP_SELL && (OrderTakeProfit() == 0 || OrderStopLoss() == 0) ){
            if (takeProfit > 0) {
               tp = OrderOpenPrice() - (takeProfit * meuPonto);
            }else{
               tp = OrderOpenPrice();
            }
            if (stopLoss > 0) {
               sl = OrderOpenPrice() + (stopLoss * meuPonto);
            }else{
               sl = OrderStopLoss();
            }
            if (OrderTakeProfit() != tp || OrderStopLoss() != sl ){
               if (OrderModify(OrderTicket(), OrderOpenPrice(), sl, tp, 0, clrRed)){
                  Print ("Modificação da Ordem Bem Sucedida");
               }
            }
         }
      }// fim do if número mágico && par
      
   }// fim do for
}


Para educação e compartilhamento, junte-se ao nosso grupo no Telegram t.me/codeMQL


Se você está procurando um App para apoiar suas operações, baixe nosso aplicativo SignalForex na Play Store

https://play.google.com/store/apps/details?id=com.autobotfx.signalforex






    Lista
    Comentário 0