MetaTrader5
Lazy Bot MT5: O EA Ideal para Operações de Breakout Diárias
Se você está em busca de um robô de trading que simplifique suas operações no MetaTrader 5, o Lazy Bot MT5, também conhecido como Daily Breakout EA, pode ser a solução que você precisa. Neste post, vamos explorar suas funcionalidades e como configurá-lo para maximizar seus lucros.
1. Parâmetros de Entrada
Configurações do EA:
// Importando classes externas
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\OrderInfo.mqh>
//--- Definindo variáveis para legibilidade do código
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
//--- parâmetros de entrada
input string EASettings = "---------------------------------------------"; //-------- <Configurações do EA> --------
input int InpMagicNumber = 123456; // Número Mágico
input string InpBotName = "LazyBot_V1"; // Nome do Bot
input string TradingSettings = "---------------------------------------------"; //-------- <Configurações de Trading> --------
input double Inpuser_lot = 0.01; // Tamanho dos Lotes
input double Inpuser_SL = 5.0; // Stoploss (em Pips)
input double InpAddPrice_pip = 0; // Distância de [H], [L] até OP_Price (em Pips)
input int Inpuser_SLippage = 3; // Slippage máximo permitido (em Pips)
input double InpMax_spread = 0; // Spread máximo permitido (em Pips) (0 = flutuante)
2. Inicialização de Variáveis Locais
// Parâmetros locais
datetime last;
int totalBars;
int Pips2Points; // slippage 3 pips
double Pips2Double; // Stoploss 15 pips
double slippage;
double acSpread;
string strComment = "";
CPositionInfo m_position; // objeto de posição de trade
CTrade m_trade; // objeto de trading
CSymbolInfo m_symbol; // objeto de informações do símbolo
CAccountInfo m_account; // wrapper de informações da conta
COrderInfo m_order; // objeto de ordens pendentes
3. Código Principal
O Lazy Bot MT5 elimina todas as ordens antigas a cada dia, identifica os valores mais altos e mais baixos da barra diária anterior e envia duas ordens pendentes: BUY_STOP e SELL_STOP (sem TakeProfit).
a/ Função de Inicialização do Expert
int OnInit()
{
//---
// Detecção de 3 ou 5 dígitos
if(_Digits % 2 == 1) {
Pips2Double = _Point * 10;
Pips2Points = 10;
slippage = 10 * Inpuser_SLippage;
} else {
Pips2Double = _Point;
Pips2Points = 1;
slippage = Inpuser_SLippage;
}
if(!m_symbol.Name(Symbol())) // define o nome do símbolo
return(INIT_FAILED);
RefreshRates();
m_trade.SetExpertMagicNumber(InpMagicNumber);
m_trade.SetMarginMode();
m_trade.SetTypeFillingBySymbol(m_symbol.Name());
m_trade.SetDeviationInPoints(slippage);
return(INIT_SUCCEEDED);
}
b/ Função Tick do Expert
void OnTick()
{
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) == false) {
Comment("LazyBot\nTrade not allowed.");
return;
}
// Obtenção da hora local e do servidor
MqlDateTime timeLocal;
MqlDateTime timeServer;
TimeLocal(timeLocal);
TimeCurrent(timeServer);
if(timeServer.day_of_week == 0 || timeServer.day_of_week == 6)
return;
int hourLocal = timeLocal.hour;
int hourCurrent = timeServer.hour;
acSpread = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
strComment = "\nHora Local = " + hourLocal;
strComment += "\nHora Atual = " + hourCurrent;
strComment += "\nSpread = " + (string)acSpread;
strComment += "\nTotal de Barras = " + (string)totalBars;
Comment(strComment);
// Verifica o Trailing
TrailingSL();
if(last != iTime(m_symbol.Name(), PERIOD_D1, 0)) {
// Verifica o horário de trading
if(isTradingTime) {
if(hourCurrent >= InpStartHour) {
DeleteOldOrds();
OpenOrder();
last = iTime(m_symbol.Name(), PERIOD_D1, 0);
}
} else {
DeleteOldOrds();
OpenOrder();
last = iTime(m_symbol.Name(), PERIOD_D1, 0);
}
}
}
3.1 Calcular sinal e enviar ordens
void OpenOrder()
{
double TP_Buy = 0, TP_Sell = 0;
double SL_Buy = 0, SL_Sell = 0;
// Verifica o Spread máximo
if(InpMax_spread != 0) {
if(acSpread > InpMax_spread) {
Print(__FUNCTION__, " > o Spread atual é maior que o permitido!");
return;
}
}
double Bar1High = m_symbol.NormalizePrice(iHigh(m_symbol.Name(), PERIOD_D1, 1));
double Bar1Low = m_symbol.NormalizePrice(iLow(m_symbol.Name(), PERIOD_D1, 1));
double lot1 = CalculateVolume();
double OpenPrice = m_symbol.NormalizePrice(Bar1High + InpAddPrice_pip * Pips2Double);
// Para BUY_STOP
SL_Buy = m_symbol.NormalizePrice(OpenPrice - Inpuser_SL * Pips2Double);
totalBars = iBars(m_symbol.Name(), PERIOD_D1);
string comment = InpBotName + ";" + m_symbol.Name() + ";" + totalBars;
if(CheckVolumeValue(lot1) && CheckOrderForFREEZE_LEVEL(ORDER_TYPE_BUY_STOP, OpenPrice) && CheckMoneyForTrade(m_symbol.Name(), lot1, ORDER_TYPE_BUY) && CheckStopLoss(OpenPrice, SL_Buy)) {
if(!m_trade.BuyStop(lot1, OpenPrice, m_symbol.Name(), SL_Buy, TP_Buy, ORDER_TIME_GTC, 0, comment))
Print(__FUNCTION__, "--> Erro ao comprar");
}
// Para SELL_STOP
OpenPrice = m_symbol.NormalizePrice(Bar1Low - InpAddPrice_pip * Pips2Double);
SL_Sell = m_symbol.NormalizePrice(OpenPrice + Inpuser_SL * Pips2Double);
if(CheckVolumeValue(lot1) && CheckOrderForFREEZE_LEVEL(ORDER_TYPE_SELL_STOP, OpenPrice) && CheckMoneyForTrade(m_symbol.Name(), lot1, ORDER_TYPE_SELL) && CheckStopLoss(OpenPrice, SL_Sell)) {
if(!m_trade.SellStop(lot1, OpenPrice, m_symbol.Name(), SL_Sell, TP_Sell, ORDER_TIME_GTC, 0, comment))
Print(__FUNCTION__, "--> Erro ao vender");
}
}
3.2 Novo dia, delete todas as ordens antigas
void DeleteOldOrds()
{
string sep=";"; // Um separador como caráter
ushort u_sep; // O código do caráter separador
string result[]; // Um array para obter strings
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(m_order.SelectByIndex(i)) {
u_sep = StringGetCharacter(sep, 0);
string Ordcomment = m_order.Comment();
int k = StringSplit(Ordcomment, u_sep, result);
if(k > 2) {
string sym = m_symbol.Name();
if((m_order.Magic() == InpMagicNumber) && (sym == result[1])) {
m_trade.OrderDelete(m_order.Ticket());
}
}
}
}
}
3.3 Função de Trailing StopLoss
void TrailingSL()
{
double SL_in_Pip = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--) {
if(m_position.SelectByIndex(i)) {
if((m_position.Magic() == InpMagicNumber) && (m_position.Symbol() == m_symbol.Name())) {
double order_stoploss1 = m_position.StopLoss();
if(m_position.PositionType() == POSITION_TYPE_BUY) {
SL_in_Pip = NormalizeDouble((Bid - order_stoploss1), _Digits) / Pips2Double;
if(SL_in_Pip > Inpuser_SL) {
order_stoploss1 = NormalizeDouble(Bid - (Inpuser_SL * Pips2Double), _Digits);
m_trade.PositionModify(m_position.Ticket(), order_stoploss1, m_position.TakeProfit());
}
}
if(m_position.PositionType() == POSITION_TYPE_SELL) {
SL_in_Pip = NormalizeDouble((m_position.StopLoss() - Ask), _Digits) / Pips2Double;
if(SL_in_Pip > Inpuser_SL) {
order_stoploss1 = NormalizeDouble(Ask + (Inpuser_SL * Pips2Double), _Digits);
m_trade.PositionModify(m_position.Ticket(), order_stoploss1, m_position.TakeProfit());
}
}
}
}
}
}
Para mais informações sobre como utilizar o Lazy Bot MT5, confira os vídeos abaixo:
Vídeo MQL4:
Vídeo MQL5:
2022.12.14