Baixe o app do Guru IA

+ 2.000.000 downloads

crie um robô com o indicador MACD para metatrader 5 para uso na bolsa brasileira de futuros. As entradas e saidas da operação deverão ocorrer sempre que houver o cruzamento para cima ou para baixo da linha zero

G

Gilberto

20/04/26

Resposta do Guru IA

Para criar um robô (Expert Advisor, ou EA) para o MetaTrader 5 (MT5) que utilize o indicador MACD e opere na bolsa brasileira de futuros (como B3, com ativos como WIN, WDO, etc.), vamos implementar uma estratégia simples baseada no cruzamento da linha MACD com a linha zero.

A lógica da estratégia será a seguinte:

  • Entrada em compra (long): Quando a linha MACD cruza para cima da linha zero (sinal de alta).
  • Entrada em venda (short): Quando a linha MACD cruza para baixo da linha zero (sinal de baixa).
  • Saídas: As posições serão fechadas automaticamente no sinal oposto (ex: fecha long ao cruzar para baixo, e vice-versa). Isso garante que as entradas e saídas ocorram nos cruzamentos, conforme solicitado.
  • Parâmetros do MACD: Usaremos os valores padrão (12, 26, 9), mas você pode ajustá-los no código.
  • Outras configurações: Incluiremos gerenciamento de risco básico (tamanho de lote fixo), verificação de horário de negociação (adaptado para B3, que opera de 9h a 18h em dias úteis), e filtros para evitar múltiplas posições simultâneas.

O código será escrito em MQL5. Para usá-lo:

  1. Abra o MetaEditor no MT5.
  2. Crie um novo Expert Advisor e cole o código abaixo.
  3. Compile e teste em uma conta demo, ajustando para o símbolo desejado (ex: "WINV23" para mini-índice futuro).
  4. Aviso importante: Robôs de trading envolvem riscos financeiros. Teste exaustivamente e use com capital que você pode perder. Isso não é aconselhamento financeiro.

Aqui está o código completo do EA:

//+------------------------------------------------------------------+
//|                                                     MACDZeroCross.mq5 |
//|                        Robô MACD para cruzamento da linha zero   |
//|                                      Para B3 Futuros (Meu Guru)  |
//+------------------------------------------------------------------+
#property copyright "Meu Guru"
#property link      "https://meuguru.com"
#property version   "1.00"
#property strict

// Parâmetros de entrada
input int    MACD_Fast   = 12;    // Período rápido do MACD
input int    MACD_Slow   = 26;    // Período lento do MACD
input int    MACD_Signal = 9;     // Período de sinal do MACD
input double LotSize     = 0.01;  // Tamanho do lote (ajuste para mini-contratos)
input int    Slippage    = 3;     // Slippage máximo
input int    MagicNumber = 12345; // Número mágico para identificar ordens

// Handles e variáveis globais
int macdHandle;
double macdBuffer[2];  // Buffer para valores MACD (atual e anterior)

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Cria handle do indicador MACD
   macdHandle = iMACD(NULL, 0, MACD_Fast, MACD_Slow, MACD_Signal, PRICE_CLOSE);
   if (macdHandle == INVALID_HANDLE)
   {
      Print("Erro ao criar handle do MACD");
      return(INIT_FAILED);
   }
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   if (macdHandle != INVALID_HANDLE) IndicatorRelease(macdHandle);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // Verifica horário de negociação da B3 (9h a 18h, de segunda a sexta)
   MqlDateTime time;
   TimeCurrent(time);
   if (time.day_of_week < 1 || time.day_of_week > 5 || time.hour < 9 || time.hour >= 18) return;
   
   // Obtém valores do MACD (atual e anterior)
   if (CopyBuffer(macdHandle, 0, 0, 2, macdBuffer) < 2) return;  // MAIN_LINE é buffer 0
   
   double macdCurrent = macdBuffer[0];  // Valor atual
   double macdPrevious = macdBuffer[1]; // Valor anterior
   
   // Verifica se há posição aberta
   bool hasLong = false, hasShort = false;
   for (int i = PositionsTotal() - 1; i >= 0; i--)
   {
      if (PositionGetSymbol(i) == Symbol() && PositionGetInteger(POSITION_MAGIC) == MagicNumber)
      {
         if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) hasLong = true;
         else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) hasShort = true;
      }
   }
   
   // Sinal de cruzamento para cima (compra)
   if (macdPrevious <= 0 && macdCurrent > 0)
   {
      if (hasShort) ClosePosition(POSITION_TYPE_SELL);  // Fecha short (saída)
      if (!hasLong) OpenPosition(ORDER_TYPE_BUY);       // Abre long (entrada)
   }
   
   // Sinal de cruzamento para baixo (venda)
   if (macdPrevious >= 0 && macdCurrent < 0)
   {
      if (hasLong) ClosePosition(POSITION_TYPE_BUY);    // Fecha long (saída)
      if (!hasShort) OpenPosition(ORDER_TYPE_SELL);     // Abre short (entrada)
   }
}

//+------------------------------------------------------------------+
//| Função para abrir posição                                        |
//+------------------------------------------------------------------+
void OpenPosition(ENUM_ORDER_TYPE type)
{
   MqlTradeRequest request = {};
   MqlTradeResult result = {};
   
   request.action = TRADE_ACTION_DEAL;
   request.symbol = Symbol();
   request.volume = LotSize;
   request.type = type;
   request.sl = 0;    // Sem stop loss (adicione se quiser)
   request.tp = 0;    // Sem take profit (adicione se quiser)
   request.deviation = Slippage;
   request.magic = MagicNumber;
   
   if (!OrderSend(request, result))
   {
      Print("Erro ao abrir posição: ", result.retcode);
   }
}

//+------------------------------------------------------------------+
//| Função para fechar posição                                       |
//+------------------------------------------------------------------+
void ClosePosition(ENUM_POSITION_TYPE type)
{
   for (int i = PositionsTotal() - 1; i >= 0; i--)
   {
      if (PositionGetSymbol(i) == Symbol() && PositionGetInteger(POSITION_MAGIC) == MagicNumber &&
          PositionGetInteger(POSITION_TYPE) == type)
      {
         MqlTradeRequest request = {};
         MqlTradeResult result = {};
         
         request.action = TRADE_ACTION_DEAL;
         request.position = PositionGetInteger(POSITION_TICKET);
         request.symbol = Symbol();
         request.volume = PositionGetDouble(POSITION_VOLUME);
         request.type = (type == POSITION_TYPE_BUY) ? ORDER_TYPE_SELL : ORDER_TYPE_BUY;
         request.deviation = Slippage;
         
         if (!OrderSend(request, result))
         {
            Print("Erro ao fechar posição: ", result.retcode);
         }
      }
   }
}
//+------------------------------------------------------------------+

Essa implementação é básica e funcional. Ela detecta cruzamentos na função OnTick() e gerencia uma posição por vez. Para melhorias, você pode adicionar stop loss, take profit ou filtros de volume/volatilidade.

Você gostaria de adicionar algum filtro extra, como stop loss baseado em ATR, ou testar essa estratégia em um ativo específico da B3?

Resolvedor

Resolva sua questão com 97% de assertividade

Envie sua pergunta ao nosso resolvedor de tarefas e receba a resposta na hora!

Equipe Meu Guru

Prefere sua atividade resolvida por um professor especialista?

  • Receba resolvida até o seu prazo
  • Converse com o professor pelo chat
  • Garantia de 7 dias contra erros