🚀 AI One-Click Generation of mql4 Strategy Code

The Ultimate Guide to Managing Open Positions in Mql4 EAs

mql4 | Published on: 2025/11/26
The following content is generated by EasyQuant .

Problem Description

How can I check all my currently open trades and modify their stop-loss or take-profit?

Solution

To modify the Stop Loss (SL) or Take Profit (TP) of all open trades in MQL4, you need to iterate through the order pool, select each order, calculate the new price levels, and send a modification request to the server.

Here is a complete, robust script that demonstrates how to loop through all open positions for the current symbol and apply new SL/TP levels based on points.

MQL4 Script: Modify All Open Trades

//+------------------------------------------------------------------+
//|                                            ModifyAllTrades.mq4   |
//|                        Copyright 2023, Quantitative AI Assistant |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Quantitative AI Assistant"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property script_show_inputs

//--- Input Parameters
input int      InpStopLossPoints   = 50;    // Stop Loss in Points (0 to disable)
input int      InpTakeProfitPoints = 100;   // Take Profit in Points (0 to disable)
input int      InpMagicNumber      = 0;     // Magic Number (0 for manual trades)
input bool     InpAllSymbols       = false; // Modify trades for all symbols?

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   // Adjust points for 3/5 digit brokers
   double pnt = Point;
   if(Digits == 3 || Digits == 5) pnt *= 10;

   int total = OrdersTotal();
   
   // Iterate backwards to handle potential index shifts safely
   for(int i = total - 1; i >= 0; i--)
   {
      // 1. Select the order
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) 
      {
         Print("Failed to select order index: ", i, ". Error: ", GetLastError());
         continue;
      }

      // 2. Filter by Symbol (unless AllSymbols is true)
      if(!InpAllSymbols && OrderSymbol() != Symbol()) continue;

      // 3. Filter by Magic Number (optional, remove if modifying all)
      if(InpMagicNumber != 0 && OrderMagicNumber() != InpMagicNumber) continue;

      // 4. Filter by Order Type (Only Buy and Sell, ignore pending orders)
      if(OrderType() > OP_SELL) continue;

      // Variables for calculation
      double openPrice = OrderOpenPrice();
      double newSL = 0;
      double newTP = 0;
      double currentSL = OrderStopLoss();
      double currentTP = OrderTakeProfit();

      // 5. Calculate new prices based on direction
      if(OrderType() == OP_BUY)
      {
         if(InpStopLossPoints > 0)   newSL = NormalizeDouble(openPrice - (InpStopLossPoints * pnt), Digits);
         else newSL = currentSL; // Keep existing if input is 0
         
         if(InpTakeProfitPoints > 0) newTP = NormalizeDouble(openPrice + (InpTakeProfitPoints * pnt), Digits);
         else newTP = currentTP; // Keep existing if input is 0
      }
      else if(OrderType() == OP_SELL)
      {
         if(InpStopLossPoints > 0)   newSL = NormalizeDouble(openPrice + (InpStopLossPoints * pnt), Digits);
         else newSL = currentSL;
         
         if(InpTakeProfitPoints > 0) newTP = NormalizeDouble(openPrice - (InpTakeProfitPoints * pnt), Digits);
         else newTP = currentTP;
      }

      // 6. Check if modification is actually required to avoid Error 1 (ERR_NO_RESULT)
      // We compare doubles using a small epsilon or simply check inequality after normalization
      if(MathAbs(newSL - currentSL) < Point && MathAbs(newTP - currentTP) < Point) 
      {
         Print("Order #", OrderTicket(), " already has these levels. Skipping.");
         continue;
      }

      // 7. Send Modification Request
      bool res = OrderModify(
         OrderTicket(),    // Ticket
         OrderOpenPrice(), // Open Price (Must be the original open price)
         newSL,            // New Stop Loss
         newTP,            // New Take Profit
         0,                // Expiration (0 for market orders)
         clrNONE           // Arrow Color
      );

      if(!res)
      {
         Print("Error modifying order #", OrderTicket(), ". Error code: ", GetLastError());
      }
      else
      {
         Print("Successfully modified order #", OrderTicket());
      }
   }
}

Key Logic Explanation

  1. OrdersTotal() & Loop Direction:
    We use OrdersTotal() to get the count of open and pending orders. We loop from OrdersTotal() - 1 down to 0. While OrderModify doesn't remove orders from the list, iterating backwards is a best practice in MQL4 to ensure stability if you later decide to close orders within the same loop.

  2. OrderSelect(..., MODE_TRADES):
    This selects orders from the "Trade" tab (active positions and pending orders). Do not use MODE_HISTORY here, as that accesses closed trades.

  3. Filters:

    • Symbol: OrderSymbol() == Symbol() ensures you only modify trades for the chart the script is running on.
    • Type: OrderType() <= OP_SELL ensures we only modify active Buy (0) and Sell (1) positions, ignoring pending orders (Limit/Stop).
  4. NormalizeDouble():
    This is critical. Prices calculated mathematically (e.g., 1.12345 + 0.00100) can result in floating-point artifacts (e.g., 1.1244500000001). Sending un-normalized prices to OrderModify often results in Error 129 (Invalid Price). Always normalize to Digits.

  5. Error 1 Prevention:
    If you try to modify an order with the exact same SL and TP it already has, the server returns Error 1 (ERR_NO_RESULT). The code checks MathAbs(newSL - currentSL) < Point to ensure values have actually changed before calling the server.

Common Error Codes

  • 129 (ERR_INVALID_PRICE): Usually caused by failing to use NormalizeDouble.
  • 130 (ERR_INVALID_STOPS): The SL or TP is too close to the current market price. You must check MarketInfo(Symbol(), MODE_STOPLEVEL) if you are setting tight stops.
  • 4108 (ERR_INVALID_TICKET): The order closed before the script could modify it, or OrderSelect failed.

Q&A

Q: Can I use this code to modify Pending Orders (Limit/Stop) as well?
A: Yes, but you need to remove the check if(OrderType() > OP_SELL) continue;. Also, note that for pending orders, the OrderOpenPrice() parameter in OrderModify allows you to change the entry price, whereas for open market orders, that parameter must remain the current open price.

Q: How do I set the SL to the exact Open Price (Break Even)?
A: In the calculation section, instead of adding/subtracting points, simply set newSL = OrderOpenPrice().

Q: Why does the script use OrderOpenPrice() in OrderModify?
A: The OrderModify function signature requires the Open Price as the second parameter. For active market orders, you cannot change the open price, but you must still pass the original value. Passing 0 or the current Bid/Ask will result in an error.