- How to open a second order when the first reach some points in loss
- From theory to practice
- reopen a closed order
Use the debugger or print out your variables, including _LastError and prices and find out why. Do you really expect us to debug your code for you?
Code debugging - Developing programs - MetaEditor Help
Error Handling and Logging in MQL5 - MQL5 Articles (2015)
Tracing, Debugging and Structural Analysis of Source Code - MQL5 Articles (2011)
Introduction to MQL5: How to write simple Expert Advisor and Custom Indicator - MQL5 Articles (2010)
Use the debugger or print out your variables, including _LastError and prices and find out why. Do you really expect us to debug your code for you?
Code debugging - Developing programs - MetaEditor Help
Error Handling and Logging in MQL5 - MQL5 Articles (2015)
Tracing, Debugging and Structural Analysis of Source Code - MQL5 Articles (2011)
Introduction to MQL5: How to write simple Expert Advisor and Custom Indicator - MQL5 Articles (2010)
I apologise. My oversight, I don't expect such a thing.
//+------------------------------------------------------------------+ //| Martingale EA with 3 EMA Crossover Entry, Second Trade in Profit, and Trailing Stop Loss | //+------------------------------------------------------------------+ #property copyright "PB" #property link "" #property version "" // Martingale logic to check on every tick #property strict // Input parameters input double InitialLotSize = 0.01; // Initial lot size input double MartingaleMultiplier = 2.0; // Lot size multiplier for Martingale input int MaxMartingaleSteps = 8; // Max Martingale steps input double BasketTakeProfit = 12.5; // Initial Basket Take Profit in base currency input double ProfitIncrement = 6.0; // Profit increment for rechecking input double ProfitCutoff = 5.0; // Profit cutoff below BasketTakeProfit for immediate reversal input double BasketStopLoss = -50.0; // Basket Stop Loss in base currency (negative) input double LossLevel1 = -5.0; // Loss level for 1st Martingale trade (must be negative) input double LossLevel2 = -15.0; // Loss level for 2nd Martingale trade (must be more negative than LossLevel1) input double LossLevel3 = -30.0; // Loss level for 3rd Martingale trade (must be more negative than LossLevel2) input double ProfitLevelForSecondTrade = 5.0; // Profit level to open second trade in the same direction input int StartHour = 2; // Trading start hour (0-23) input int EndHour = 23; // Trading end hour (0-23) input int FastEMAPeriod = 10; // Fast EMA period for trend confirmation input int MediumEMAPeriod = 20; // Medium EMA period for trend confirmation input int SlowEMAPeriod = 50; // Slow EMA period for trend confirmation input ENUM_TIMEFRAMES EMATimeframe = PERIOD_M30; // Timeframe for EMA calculation (M5, M30, H1, etc.) input int MagicNumber = 12345; // Magic Number for trades // Global variables double currentLotSize = InitialLotSize; int totalTradesInBasket = 0; // Total trades in the current basket int martingaleTradesOpened = 0; // Number of Martingale trades opened bool inTrade = false; double lastTradePrice = 0; datetime lastBarTime = 0; int lastTradeDirection = -1; // Track direction of last trade (0 = Buy, 1 = Sell) double lossLevels[3]; // Array to store loss levels bool hasTriggered[3]; // Track if a loss level has been triggered double currentProfitTarget = 0.0; // Current profit target for rechecking double trailingStopLoss = 0.0; // Trailing stop loss level (previous increment) bool profitTargetReached = false; // Flag to indicate if BasketTakeProfit has been reached int lastEMACrossoverDirection = -1; // Track the previous EMA crossover direction (0 = Buy, 1 = Sell, -1 = None) bool hasAddedSecondTrade = false; // Flag to track if the second trade has been added //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { lastBarTime = 0; currentLotSize = InitialLotSize; totalTradesInBasket = 0; martingaleTradesOpened = 0; lastTradeDirection = -1; lastEMACrossoverDirection = -1; hasAddedSecondTrade = false; currentProfitTarget = BasketTakeProfit; trailingStopLoss = BasketTakeProfit - ProfitCutoff; profitTargetReached = false; // Initialize loss levels array lossLevels[0] = LossLevel1; lossLevels[1] = LossLevel2; lossLevels[2] = LossLevel3; // Initialize trigger flags for(int i = 0; i < 3; i++) hasTriggered[i] = false; // Debug prints to verify parameter values Print("DEBUG: LossLevel1 = ", LossLevel1, ", LossLevel2 = ", LossLevel2, ", LossLevel3 = ", LossLevel3); Print("DEBUG: LossLevel1 > LossLevel2: ", LossLevel1 > LossLevel2, ", LossLevel2 > LossLevel3: ", LossLevel2 > LossLevel3); // Validate loss levels if(LossLevel1 >= 0 || LossLevel2 >= 0 || LossLevel3 >= 0) { Print("Error: Loss levels must be negative (e.g., -5, -15, -30)."); return(INIT_PARAMETERS_INCORRECT); } if(!(LossLevel1 > LossLevel2 && LossLevel2 > LossLevel3)) { Print("Error: Loss levels must be in increasing order of negativity (e.g., -5, -15, -30)."); return(INIT_PARAMETERS_INCORRECT); } // Validate ProfitLevelForSecondTrade if(ProfitLevelForSecondTrade <= 0) { Print("Error: ProfitLevelForSecondTrade must be positive."); return(INIT_PARAMETERS_INCORRECT); } // Validate StartHour and EndHour if(StartHour < 0 || StartHour > 23 || EndHour < 0 || EndHour > 23 || StartHour >= EndHour) { Print("Error: StartHour and EndHour must be between 0 and 23, and StartHour must be less than EndHour."); return(INIT_PARAMETERS_INCORRECT); } // Validate ProfitIncrement and ProfitCutoff if(ProfitIncrement <= 0) { Print("Error: ProfitIncrement must be positive."); return(INIT_PARAMETERS_INCORRECT); } if(ProfitCutoff < 0) { Print("Error: ProfitCutoff must be non-negative."); return(INIT_PARAMETERS_INCORRECT); } // Validate EMA periods if(FastEMAPeriod <= 0 || MediumEMAPeriod <= 0 || SlowEMAPeriod <= 0) { Print("Error: EMA periods must be positive."); return(INIT_PARAMETERS_INCORRECT); } if(FastEMAPeriod >= MediumEMAPeriod || MediumEMAPeriod >= SlowEMAPeriod) { Print("Error: EMA periods must be in increasing order (Fast < Medium < Slow)."); return(INIT_PARAMETERS_INCORRECT); } Print("Initialization successful."); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // No cleanup needed } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { if(!IsTradeAllowed()) return; int hour = GetServerHour(); if(hour < StartHour || hour >= EndHour) return; double basketProfit = CalculateBasketProfit(); // Check if basket should be closed due to stop loss if(basketProfit <= BasketStopLoss) { CloseAllTrades(basketProfit); return; } // Check profit against BasketTakeProfit and incremental levels if(basketProfit >= BasketTakeProfit) { if(!profitTargetReached) { profitTargetReached = true; currentProfitTarget = BasketTakeProfit; trailingStopLoss = BasketTakeProfit - ProfitCutoff; } if(basketProfit >= currentProfitTarget) { bool trendContinues = CheckTrendContinuation(); if(trendContinues) { trailingStopLoss = currentProfitTarget; currentProfitTarget += ProfitIncrement; Print("Trend continues. New profit target: ", currentProfitTarget, ", New stop loss: ", trailingStopLoss); } else { CloseAllTrades(basketProfit); return; } } if(basketProfit <= trailingStopLoss) { CloseAllTrades(basketProfit); return; } } // Martingale trades (check on every tick) if(OrdersTotal() < MaxMartingaleSteps + 1 && OrdersTotal() > 0 && martingaleTradesOpened < 3) { int levelIndex = martingaleTradesOpened; if(levelIndex < 3 && basketProfit <= lossLevels[levelIndex] && !hasTriggered[levelIndex]) { if(lastTradeDirection == 0) { OpenBuyTrade(true); hasTriggered[levelIndex] = true; martingaleTradesOpened++; } else if(lastTradeDirection == 1) { OpenSellTrade(true); hasTriggered[levelIndex] = true; martingaleTradesOpened++; } } } ManageTrades(); // Open new trades (only on new bars) if(Time[0] != lastBarTime) { lastBarTime = Time[0]; if(OrdersTotal() < MaxMartingaleSteps + 1) { // First trade in a new basket (totalTradesInBasket == 0) if(totalTradesInBasket == 0) { int crossoverDirection = GetEMACrossoverDirection(); if(crossoverDirection == 0 && lastEMACrossoverDirection != 0) { OpenBuyTrade(false); } else if(crossoverDirection == 1 && lastEMACrossoverDirection != 1) { OpenSellTrade(false); } lastEMACrossoverDirection = crossoverDirection; } // Second trade in profit (after the first trade) else if(totalTradesInBasket == 1 && !hasAddedSecondTrade) { if(basketProfit >= ProfitLevelForSecondTrade) { int crossoverDirection = GetEMACrossoverDirection(); if(lastTradeDirection == 0 && crossoverDirection == 0) { OpenBuyTrade(false); hasAddedSecondTrade = true; Print("Second buy trade added in profit. Lot Size: ", currentLotSize); } else if(lastTradeDirection == 1 && crossoverDirection == 1) { OpenSellTrade(false); hasAddedSecondTrade = true; Print("Second sell trade added in profit. Lot Size: ", currentLotSize); } } } } } } //+------------------------------------------------------------------+ //| Get the current 3 EMA crossover direction | //+------------------------------------------------------------------+ int GetEMACrossoverDirection() { double fastEMA = iMA(NULL, EMATimeframe, FastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 0); double mediumEMA = iMA(NULL, EMATimeframe, MediumEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 0); double slowEMA = iMA(NULL, EMATimeframe, SlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 0); if(fastEMA > mediumEMA && mediumEMA > slowEMA) { return 0; // Bullish } else if(fastEMA < mediumEMA && mediumEMA < slowEMA) { return 1; // Bearish } return -1; // No crossover } //+------------------------------------------------------------------+ //| Check if the trend continues in the same direction using 3 EMA crossover | //+------------------------------------------------------------------+ bool CheckTrendContinuation() { int crossoverDirection = GetEMACrossoverDirection(); bool trendDirection = false; if(lastTradeDirection == 0) { trendDirection = (crossoverDirection == 0); } else if(lastTradeDirection == 1) { trendDirection = (crossoverDirection == 1); } return trendDirection; } //+------------------------------------------------------------------+ //| Calculate total profit of all open trades in base currency | //+------------------------------------------------------------------+ double CalculateBasketProfit() { double totalProfit = 0.0; for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderCloseTime() == 0) { totalProfit += OrderProfit() + OrderSwap() + OrderCommission(); } } } return NormalizeDouble(totalProfit, 2); } //+------------------------------------------------------------------+ //| Close all open trades | //+------------------------------------------------------------------+ void CloseAllTrades(double basketProfit) { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderCloseTime() == 0) { bool success = false; if(OrderType() == OP_BUY) { success = OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrRed); } else if(OrderType() == OP_SELL) { success = OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrRed); } if(!success) { Print("Failed to close order #", OrderTicket(), ". Error: ", GetLastError()); } } } } // Reset after basket closure totalTradesInBasket = 0; martingaleTradesOpened = 0; currentLotSize = InitialLotSize; lastTradePrice = 0; lastTradeDirection = -1; inTrade = false; currentProfitTarget = BasketTakeProfit; trailingStopLoss = BasketTakeProfit - ProfitCutoff; profitTargetReached = false; lastEMACrossoverDirection = -1; hasAddedSecondTrade = false; for(int i = 0; i < 3; i++) hasTriggered[i] = false; Print("Basket closed. Profit: ", basketProfit); } //+------------------------------------------------------------------+ //| Manage open trades | //+------------------------------------------------------------------+ void ManageTrades() { inTrade = false; for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderCloseTime() == 0) { inTrade = true; } } } } //+------------------------------------------------------------------+ //| Open a buy trade | //+------------------------------------------------------------------+ void OpenBuyTrade(bool isMartingale) { double lotSize = NormalizeDouble(currentLotSize, 2); int ticket = OrderSend(Symbol(), OP_BUY, lotSize, Ask, 3, 0, 0, "EMA Buy Step " + IntegerToString(totalTradesInBasket) + (isMartingale ? " (Martingale)" : ""), MagicNumber, 0, clrGreen); if(ticket > 0) { inTrade = true; lastTradePrice = Ask; lastTradeDirection = 0; currentLotSize = NormalizeDouble(currentLotSize * MartingaleMultiplier, 2); totalTradesInBasket++; Print("Buy order opened. Ticket: ", ticket, " Lot Size: ", lotSize, " Next Lot Size: ", currentLotSize); } else { Print("Error opening buy trade: ", GetLastError()); } } //+------------------------------------------------------------------+ //| Open a sell trade | //+------------------------------------------------------------------+ void OpenSellTrade(bool isMartingale) { double lotSize = NormalizeDouble(currentLotSize, 2); int ticket = OrderSend(Symbol(), OP_SELL, lotSize, Bid, 3, 0, 0, "EMA Sell Step " + IntegerToString(totalTradesInBasket) + (isMartingale ? " (Martingale)" : ""), MagicNumber, 0, clrRed); if(ticket > 0) { inTrade = true; lastTradePrice = Bid; lastTradeDirection = 1; currentLotSize = NormalizeDouble(currentLotSize * MartingaleMultiplier, 2); totalTradesInBasket++; Print("Sell order opened. Ticket: ", ticket, " Lot Size: ", lotSize, " Next Lot Size: ", currentLotSize); } else { Print("Error opening sell trade: ", GetLastError()); } } //+------------------------------------------------------------------+ //| Get current server hour | //+------------------------------------------------------------------+ int GetServerHour() { return(TimeHour(TimeCurrent())); }

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use