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
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:
- Abra o MetaEditor no MT5.
- Crie um novo Expert Advisor e cole o código abaixo.
- Compile e teste em uma conta demo, ajustando para o símbolo desejado (ex: "WINV23" para mini-índice futuro).
- 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?
Resolva sua questão com 97% de assertividade
Envie sua pergunta ao nosso resolvedor de tarefas e receba a resposta na hora!
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