//+------------------------------------------------------------------+ //| EA_OrderBlocks_Trader.mq5 | //| Copyright 2025, Nephew_Sam | //| EA qui trade les signaux Order Blocks | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Nephew_Sam" #property link "" #property version "1.00" #include //--- Input parameters input group "════════════ Indicateur ════════════" input string IndicatorName = "Orderblocks_MT5_WithBuffers"; // Nom de l'indicateur input group "════════════ Gestion des trades ════════════" input double LotSize = 0.01; // Taille de lot input int StopLossPips = 50; // Stop Loss en pips input int TakeProfitPips = 100; // Take Profit en pips input int MagicNumber = 123456; // Magic Number input string TradeComment = "OB_EA"; // Commentaire des trades input group "════════════ Filtres ════════════" input bool UseTimeFilter = false; // Utiliser filtre horaire ? input int StartHour = 8; // Heure de début input int EndHour = 20; // Heure de fin input bool OnlyOneTradePerSignal = true; // Un seul trade par signal ? input int MinBarsBetweenTrades = 5; // Barres min entre trades input group "════════════ Gestion du risque ════════════" input bool UseBreakEven = true; // Activer Break Even ? input int BreakEvenPips = 20; // BE après X pips input int BreakEvenPlus = 5; // BE + X pips input bool UseTrailingStop = true; // Activer Trailing Stop ? input int TrailingStopPips = 30; // Trailing Stop en pips input int TrailingStepPips = 10; // Step du Trailing //--- Global variables CTrade trade; int indicatorHandle; double bullBuffer[]; double bearBuffer[]; datetime lastBullSignalTime = 0; datetime lastBearSignalTime = 0; int lastBullBar = -1; int lastBearBar = -1; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Configuration du trade trade.SetExpertMagicNumber(MagicNumber); trade.SetDeviationInPoints(10); trade.SetTypeFilling(ORDER_FILLING_FOK); //--- Charger l'indicateur indicatorHandle = iCustom(_Symbol, _Period, IndicatorName); if(indicatorHandle == INVALID_HANDLE) { Print("Erreur lors du chargement de l'indicateur: ", IndicatorName); return(INIT_FAILED); } //--- Configurer les buffers ArraySetAsSeries(bullBuffer, true); ArraySetAsSeries(bearBuffer, true); Print("EA initialisé avec succès. Magic Number: ", MagicNumber); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(indicatorHandle != INVALID_HANDLE) IndicatorRelease(indicatorHandle); Print("EA arrêté. Raison: ", reason); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- Vérifier si une nouvelle barre s'est formée static datetime lastBarTime = 0; datetime currentBarTime = iTime(_Symbol, _Period, 0); if(currentBarTime == lastBarTime) return; lastBarTime = currentBarTime; //--- Copier les données de l'indicateur if(CopyBuffer(indicatorHandle, 0, 0, 3, bullBuffer) <= 0) { Print("Erreur lors de la copie du buffer Bull"); return; } if(CopyBuffer(indicatorHandle, 1, 0, 3, bearBuffer) <= 0) { Print("Erreur lors de la copie du buffer Bear"); return; } //--- Gérer les positions ouvertes (Break Even & Trailing Stop) ManageOpenPositions(); //--- Vérifier les filtres if(UseTimeFilter && !IsTradeTime()) return; //--- Détecter les signaux CheckForBullishSignal(); CheckForBearishSignal(); } //+------------------------------------------------------------------+ //| Vérifier signal haussier | //+------------------------------------------------------------------+ void CheckForBullishSignal() { //--- Signal sur la barre précédente [1] if(bullBuffer[1] != EMPTY_VALUE && bullBuffer[1] > 0) { //--- Vérifier si signal déjà traité datetime signalTime = iTime(_Symbol, _Period, 1); if(OnlyOneTradePerSignal && signalTime == lastBullSignalTime) return; //--- Vérifier délai entre trades if(Bars(_Symbol, _Period, lastBullSignalTime, signalTime) < MinBarsBetweenTrades) return; //--- Vérifier qu'il n'y a pas déjà une position acheteuse if(HasOpenPosition(POSITION_TYPE_BUY)) return; //--- Ouvrir position acheteuse OpenBuyTrade(); lastBullSignalTime = signalTime; lastBullBar = 1; } } //+------------------------------------------------------------------+ //| Vérifier signal baissier | //+------------------------------------------------------------------+ void CheckForBearishSignal() { //--- Signal sur la barre précédente [1] if(bearBuffer[1] != EMPTY_VALUE && bearBuffer[1] > 0) { //--- Vérifier si signal déjà traité datetime signalTime = iTime(_Symbol, _Period, 1); if(OnlyOneTradePerSignal && signalTime == lastBearSignalTime) return; //--- Vérifier délai entre trades if(Bars(_Symbol, _Period, lastBearSignalTime, signalTime) < MinBarsBetweenTrades) return; //--- Vérifier qu'il n'y a pas déjà une position vendeuse if(HasOpenPosition(POSITION_TYPE_SELL)) return; //--- Ouvrir position vendeuse OpenSellTrade(); lastBearSignalTime = signalTime; lastBearBar = 1; } } //+------------------------------------------------------------------+ //| Ouvrir trade acheteur | //+------------------------------------------------------------------+ void OpenBuyTrade() { double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS); double sl = NormalizeDouble(ask - StopLossPips * point * 10, digits); double tp = NormalizeDouble(ask + TakeProfitPips * point * 10, digits); if(trade.Buy(LotSize, _Symbol, ask, sl, tp, TradeComment)) { Print("✓ Position BUY ouverte à ", ask, " | SL: ", sl, " | TP: ", tp); } else { Print("✗ Erreur ouverture BUY: ", GetLastError()); } } //+------------------------------------------------------------------+ //| Ouvrir trade vendeur | //+------------------------------------------------------------------+ void OpenSellTrade() { double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS); double sl = NormalizeDouble(bid + StopLossPips * point * 10, digits); double tp = NormalizeDouble(bid - TakeProfitPips * point * 10, digits); if(trade.Sell(LotSize, _Symbol, bid, sl, tp, TradeComment)) { Print("✓ Position SELL ouverte à ", bid, " | SL: ", sl, " | TP: ", tp); } else { Print("✗ Erreur ouverture SELL: ", GetLastError()); } } //+------------------------------------------------------------------+ //| Vérifier si position ouverte existe | //+------------------------------------------------------------------+ bool HasOpenPosition(ENUM_POSITION_TYPE posType) { for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionGetSymbol(i) == _Symbol) { if(PositionGetInteger(POSITION_MAGIC) == MagicNumber) { if(PositionGetInteger(POSITION_TYPE) == posType) return true; } } } return false; } //+------------------------------------------------------------------+ //| Gérer les positions ouvertes | //+------------------------------------------------------------------+ void ManageOpenPositions() { for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionGetSymbol(i) == _Symbol) { if(PositionGetInteger(POSITION_MAGIC) == MagicNumber) { ulong ticket = PositionGetInteger(POSITION_TICKET); if(UseBreakEven) CheckBreakEven(ticket); if(UseTrailingStop) CheckTrailingStop(ticket); } } } } //+------------------------------------------------------------------+ //| Vérifier et appliquer Break Even | //+------------------------------------------------------------------+ void CheckBreakEven(ulong ticket) { if(!PositionSelectByTicket(ticket)) return; double openPrice = PositionGetDouble(POSITION_PRICE_OPEN); double currentSL = PositionGetDouble(POSITION_SL); double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS); ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); if(posType == POSITION_TYPE_BUY) { double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double beLevel = openPrice + BreakEvenPips * point * 10; double newSL = NormalizeDouble(openPrice + BreakEvenPlus * point * 10, digits); if(bid >= beLevel && (currentSL < openPrice || currentSL == 0)) { if(trade.PositionModify(ticket, newSL, PositionGetDouble(POSITION_TP))) { Print("✓ Break Even activé pour ticket: ", ticket); } } } else if(posType == POSITION_TYPE_SELL) { double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double beLevel = openPrice - BreakEvenPips * point * 10; double newSL = NormalizeDouble(openPrice - BreakEvenPlus * point * 10, digits); if(ask <= beLevel && (currentSL > openPrice || currentSL == 0)) { if(trade.PositionModify(ticket, newSL, PositionGetDouble(POSITION_TP))) { Print("✓ Break Even activé pour ticket: ", ticket); } } } } //+------------------------------------------------------------------+ //| Vérifier et appliquer Trailing Stop | //+------------------------------------------------------------------+ void CheckTrailingStop(ulong ticket) { if(!PositionSelectByTicket(ticket)) return; double openPrice = PositionGetDouble(POSITION_PRICE_OPEN); double currentSL = PositionGetDouble(POSITION_SL); double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS); ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); if(posType == POSITION_TYPE_BUY) { double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double trailLevel = bid - TrailingStopPips * point * 10; if(trailLevel > currentSL + TrailingStepPips * point * 10) { double newSL = NormalizeDouble(trailLevel, digits); if(trade.PositionModify(ticket, newSL, PositionGetDouble(POSITION_TP))) { Print("✓ Trailing Stop ajusté pour ticket: ", ticket, " nouveau SL: ", newSL); } } } else if(posType == POSITION_TYPE_SELL) { double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double trailLevel = ask + TrailingStopPips * point * 10; if(trailLevel < currentSL - TrailingStepPips * point * 10 || currentSL == 0) { double newSL = NormalizeDouble(trailLevel, digits); if(trade.PositionModify(ticket, newSL, PositionGetDouble(POSITION_TP))) { Print("✓ Trailing Stop ajusté pour ticket: ", ticket, " nouveau SL: ", newSL); } } } } //+------------------------------------------------------------------+ //| Vérifier si dans la plage horaire | //+------------------------------------------------------------------+ bool IsTradeTime() { MqlDateTime dt; TimeToStruct(TimeCurrent(), dt); if(dt.hour >= StartHour && dt.hour < EndHour) return true; return false; } //+------------------------------------------------------------------+