MetaTrader5
Lazy Bot MT5 : L'EA idéal pour le trading quotidien sur MetaTrader 5
Bienvenue à tous les traders ! Aujourd'hui, on va parler d'un outil pratique pour tous ceux qui utilisent MetaTrader 5 : le Lazy Bot MT5, un Expert Advisor (EA) qui gère vos transactions de manière efficace.
1. Paramètres d'entrée
// Importer les classes externes
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\OrderInfo.mqh>
//--- Définir des variables prédéfinies pour la lisibilité du code
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
//--- paramètres d'entrée
input string EASettings = "---------------------------------------------";
input int InpMagicNumber = 123456; // Numéro magique
input string InpBotName = "LazyBot_V1"; // Nom du bot
input double Inpuser_lot = 0.01; // Lots
input double Inpuser_SL = 5.0; // Stoploss (en Pips)
input double InpAddPrice_pip = 0; // Distance de [H], [L] au prix d'OP (en Pips)
input int Inpuser_SLippage = 3; // Glissement maximum autorisé (en Pips)
input double InpMax_spread = 0; // Spread maximum autorisé (en Pips) (0 = flottant)
input bool isTradingTime = true; // Autoriser le temps de trading
input int InpStartHour = 7; // Heure de début
input int InpEndHour = 22; // Heure de fin
input bool isVolume_Percent = false; // Autoriser le volume en pourcentage
input double InpRisk = 1; // Pourcentage de risque sur le solde (%)
2. Initialisation des variables locales
// Paramètres locaux
datetime last;
int totalBars;
int Pips2Points; // glissement 3 pips (3=points, 30=points)
double Pips2Double; // Stoploss 15 pips (0.015)
double slippage;
double acSpread;
string strComment = "";
CPositionInfo m_position; // objet position de trading
CTrade m_trade; // objet de trading
CSymbolInfo m_symbol; // objet info symbole
CAccountInfo m_account; // wrapper info compte
COrderInfo m_order; // objet commandes en attente
3. Code principal
Voici comment fonctionne notre stratégie : chaque jour, le bot supprimera toutes les anciennes commandes et trouvera les valeurs les plus élevées et les plus basses de la barre quotidienne précédente pour envoyer deux ordres en attente : BUY_STOP et SELL_STOP. (Pas de TakeProfit).
a/ Fonction d'initialisation de l'Expert
int OnInit() {
//---
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())) 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/ Fonction de tick de l'Expert
void OnTick() {
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) == false) {
Comment("LazyBot\nTrading non autorisé.");
return;
}
// Obtenir le temps de trading
MqlDateTime timeLocal;
MqlDateTime timeServer;
TimeLocal(timeLocal);
TimeCurrent(timeServer);
// Ne pas travailler les jours fériés.
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 = "\nHeure locale = " + hourLocal;
strComment += "\nHeure actuelle = " + hourCurrent;
strComment += "\nSpread = " + (string)acSpread;
strComment += "\nTotal de barres = " + (string)totalBars;
Comment(strComment);
// Vérifier le Trailing
TrailingSL();
//---
if(last != iTime(m_symbol.Name(), PERIOD_D1, 0)) {
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 Calculer le signal et envoyer des ordres
void OpenOrder() {
double TP_Buy = 0, TP_Sell = 0;
double SL_Buy = 0, SL_Sell = 0;
// Vérifier le Spread maximum
if(InpMax_spread != 0) {
if(acSpread > InpMax_spread) {
Print(__FUNCTION__, " > Le spread actuel est supérieur au spread autorisé !...");
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);
// Pour 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__, "--> Erreur d'achat");
}
// Pour 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__, "--> Erreur de vente");
}
}
3.2 Nouveau jour, supprimer toutes les anciennes commandes
void DeleteOldOrds() {
string sep=";"; // Un séparateur comme caractère
ushort u_sep; // Le code du caractère séparateur
string result[]; // Un tableau pour obtenir des chaînes
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 Le bot a une fonction "trailing StopLoss" qui ajuste le SL en fonction des mouvements de prix
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();
// Pour les ordres d'achat
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());
}
}
// Pour les ordres de vente
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());
}
}
}
}
}
}
Conclusion
Le Lazy Bot MT5 est un outil formidable pour tous ceux qui souhaitent automatiser leurs transactions sur MetaTrader 5. Grâce à sa capacité à gérer les ordres en fonction des fluctuations du marché, il peut vous faire gagner un temps précieux tout en maximisant vos chances de succès. N'hésitez pas à l'essayer et à partager vos retours !
2022.12.14