🚀 AI One-Click Generation of mql4 Strategy Code

How to Code "Stealth" Stop Loss and Take Profit in a Mql4 Expert Advisor

mql4 | Published on: 2025/12/1
The following content is generated by EasyQuant .

Problem Description

How can I write an EA that closes a trade when it reaches a certain profit or loss, without setting the SL/TP on the broker's server?

Solution

Here is a complete, fully functional MQL4 Expert Advisor (EA) designed to manage trades using "Virtual" (or Stealth) Stop Loss and Take Profit levels.

How It Works

  1. Client-Side Monitoring: Instead of sending SL/TP values to the broker, this EA monitors the price locally on your computer.
  2. Trigger: When the price hits your defined Profit or Loss target in pips, the EA sends an immediate OrderClose command.
  3. Stealth: The broker only sees the entry and exit; they do not see your pending stop levels.

The MQL4 Code

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

//--- Input Parameters
input string   Note1             = "=== Trade Settings ===";
input int      VirtualTakeProfit = 50;       // Take Profit in Pips
input int      VirtualStopLoss   = 30;       // Stop Loss in Pips
input int      MagicNumber       = 0;        // 0 = Manage all manual/EA trades
input int      Slippage          = 3;        // Max slippage in points
input bool     UseCurrentSymbol  = true;     // True = Only manage current chart symbol

//--- Global Variables
double PipPoint; // Variable to handle 3/5 digit brokers

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   //--- Calculate Pip Point multiplier for 3/5 digit brokers
   if(Digits == 3 || Digits == 5)
      PipPoint = Point * 10;
   else
      PipPoint = Point;

   Print("Virtual SL/TP EA Initialized. Pip Value: ", DoubleToString(PipPoint, 5));
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // Loop through all open orders
   // We loop backwards (OrdersTotal()-1) to safely close orders without messing up the index
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      // Select the order
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         // Filter: Check Symbol (if enabled)
         if(UseCurrentSymbol && OrderSymbol() != Symbol()) continue;

         // Filter: Check Magic Number (if MagicNumber is 0, it manages ALL trades)
         if(MagicNumber != 0 && OrderMagicNumber() != MagicNumber) continue;

         //--- Logic for BUY Orders
         if(OrderType() == OP_BUY)
         {
            // Calculate current price distance from open price
            double priceMove = Bid - OrderOpenPrice();
            
            // Check Take Profit
            if(priceMove >= VirtualTakeProfit * PipPoint)
            {
               CloseTrade(OrderTicket(), OrderLots(), Bid, "Virtual TP Hit");
            }
            // Check Stop Loss (priceMove will be negative if losing)
            else if(priceMove <= -(VirtualStopLoss * PipPoint))
            {
               CloseTrade(OrderTicket(), OrderLots(), Bid, "Virtual SL Hit");
            }
         }

         //--- Logic for SELL Orders
         if(OrderType() == OP_SELL)
         {
            // Calculate current price distance from open price
            // For sells: OpenPrice - Ask. Positive result = Profit.
            double priceMove = OrderOpenPrice() - Ask;

            // Check Take Profit
            if(priceMove >= VirtualTakeProfit * PipPoint)
            {
               CloseTrade(OrderTicket(), OrderLots(), Ask, "Virtual TP Hit");
            }
            // Check Stop Loss
            else if(priceMove <= -(VirtualStopLoss * PipPoint))
            {
               CloseTrade(OrderTicket(), OrderLots(), Ask, "Virtual SL Hit");
            }
         }
      }
   }
}

//+------------------------------------------------------------------+
//| Helper Function to Close Trades                                  |
//+------------------------------------------------------------------+
void CloseTrade(int ticket, double lots, double price, string comment)
{
   // Refresh rates to ensure we have the latest price before closing
   RefreshRates();
   
   bool closed = OrderClose(ticket, lots, price, Slippage, clrRed);
   
   if(closed)
   {
      Print("Order #", ticket, " Closed. Reason: ", comment);
   }
   else
   {
      Print("Failed to close Order #", ticket, ". Error: ", GetLastError());
   }
}

Key Features of This Code

  1. Pip Calculation (PipPoint):
    The code automatically detects if your broker uses 4-digit or 5-digit pricing (e.g., EURUSD at 1.1000 vs 1.10005). This ensures that if you input "50 pips", it acts as 50 standard pips, not 5 pips (50 points).

  2. Backward Loop:
    for(int i = OrdersTotal() - 1; i >= 0; i--)
    When modifying or closing orders, you must always loop backwards. If you loop forwards (0 to Total) and close index 0, the order at index 1 shifts to index 0, causing the loop to skip an order.

  3. Magic Number Filter:

    • If you set MagicNumber = 0, the EA will manage manual trades and trades opened by other EAs that don't use a Magic Number.
    • If you set a specific ID (e.g., 12345), it will only manage trades belonging to that ID.
  4. Symbol Filter:
    The UseCurrentSymbol input ensures the EA only closes trades for the chart it is attached to. If you set this to false, one instance of the EA can manage trades for your entire account across all pairs.

Important Warnings

  • Terminal Must Be On: Unlike a broker-side SL/TP, this logic runs on your computer. If your internet disconnects or your computer crashes, the Stop Loss will not trigger. It is highly recommended to use a VPS (Virtual Private Server) for this type of strategy.
  • Slippage: In highly volatile markets (news events), the "Virtual" close is a Market Order. You may get filled at a price worse than your virtual level (slippage).

Q&A

Q: Can I use this alongside a hard Stop Loss?
A: Yes. A common strategy is to set a "Virtual SL" at 30 pips and a "Hard (Broker) SL" at 50 pips. This acts as a disaster recovery mechanism in case your internet disconnects.

Q: Does this work for ECN accounts?
A: Yes. The OrderClose function works on ECN accounts. The logic uses Bid for closing Buys and Ask for closing Sells, which is correct for all account types.

Q: How do I install this?
A:

  1. Open MetaTrader 4.
  2. Press F4 to open the MetaEditor.
  3. Click New -> Expert Advisor (template) -> Name it "Virtual_SL_TP".
  4. Paste the code above into the window, replacing everything there.
  5. Click Compile.
  6. Go back to MT4, find the EA in the Navigator, and drag it onto a chart. Ensure "Allow Live Trading" is checked.