Problem Description
Solution
To implement a strategy that closes all open trades across the entire account when the total floating profit reaches a specific amount (e.g., $100), you need to use the AccountProfit() function combined with an order closing loop.
Here is the complete, fully functional MQL4 code for an Expert Advisor (EA) that performs this task.
MQL4 Code: Close All at Target Profit
//+------------------------------------------------------------------+
//| CloseAllAtProfitTarget.mq4 |
//| Copyright 2023, MetaQuotes Software Corp. |
//| 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 double TargetProfitUSD = 100.0; // Profit target in deposit currency (e.g., $100)
input int Slippage = 3; // Maximum allowed slippage in points
input bool CloseAllSymbols = true; // True = close all symbols, False = close only current chart symbol
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Basic validation
if(TargetProfitUSD <= 0)
{
Print("Error: TargetProfitUSD must be greater than 0.");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Check if the total account profit has reached or exceeded the target
if(AccountProfit() >= TargetProfitUSD)
{
Print("Target Profit of ", TargetProfitUSD, " reached. Current Profit: ", AccountProfit());
CloseAllTrades();
}
}
//+------------------------------------------------------------------+
//| Function to close all open market orders |
//+------------------------------------------------------------------+
void CloseAllTrades()
{
int total = OrdersTotal();
// Iterate backwards through orders to avoid index shifting issues when closing
for(int i = total - 1; i >= 0; i--)
{
// Select the order by position
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
// Filter by symbol if CloseAllSymbols is false
if(!CloseAllSymbols && OrderSymbol() != Symbol()) continue;
// We only want to close active market orders (OP_BUY or OP_SELL)
int type = OrderType();
bool result = false;
// Refresh rates to get the latest Bid/Ask prices
RefreshRates();
// Handle Buy Orders
if(type == OP_BUY)
{
// Close Buy at Bid price.
// We use MarketInfo to ensure we get the price for the specific order symbol,
// not necessarily the chart the EA is running on.
double bidPrice = MarketInfo(OrderSymbol(), MODE_BID);
result = OrderClose(OrderTicket(), OrderLots(), bidPrice, Slippage, clrRed);
}
// Handle Sell Orders
else if(type == OP_SELL)
{
// Close Sell at Ask price
double askPrice = MarketInfo(OrderSymbol(), MODE_ASK);
result = OrderClose(OrderTicket(), OrderLots(), askPrice, Slippage, clrRed);
}
// Error Handling
if(!result && (type == OP_BUY || type == OP_SELL))
{
Print("Failed to close order #", OrderTicket(), ". Error: ", GetLastError());
}
}
}
}
How It Works
AccountProfit(): This built-in function returns the current floating profit (or loss) of all open positions on the account in the deposit currency.- The Trigger: Inside
OnTick(), the code constantly checksif(AccountProfit() >= TargetProfitUSD). As soon as this is true, it triggers the closing function. - Reverse Loop: In
CloseAllTrades(), the loop runs fromOrdersTotal() - 1down to0. This is critical in MQL4. If you close an order at index 0, the order at index 1 shifts to position 0. A standard forward loop would skip orders; a reverse loop ensures every order is processed. MarketInfo(): The code usesMarketInfo(OrderSymbol(), MODE_BID)instead of justBid. This allows the EA to close trades on other currency pairs (e.g., if the EA is on EURUSD but you have a trade on GBPUSD), ensuring the correct closing price is used.CloseAllSymbolsInput: I added a boolean input. If set totrue, it closes everything on the account. Iffalse, it only closes trades for the specific chart the EA is attached to.
How to Use This Code
- Open MetaTrader 4.
- Press F4 to open the MetaEditor.
- Click New -> Expert Advisor (template) -> Name it "CloseAtProfit".
- Paste the code above into the file, replacing everything else.
- Press F7 or click Compile.
- Go back to the main MT4 window. Drag the "CloseAtProfit" EA from the Navigator onto any chart.
- In the settings window, set your
TargetProfitUSD(e.g., 100). - Ensure AutoTrading is enabled at the top of the terminal.
Q&A
Q: Will this code close pending orders (Limit/Stop orders)?
A: No, the code specifically checks for OP_BUY and OP_SELL. Pending orders do not contribute to floating profit. If you wish to delete pending orders as well, you would need to add checks for OP_BUYLIMIT, OP_SELLLIMIT, etc., and use OrderDelete() instead of OrderClose().
Q: Does this work if I have trades on multiple currency pairs?
A: Yes. Because the code uses MarketInfo(OrderSymbol(), ...) to retrieve prices, it can successfully close a GBPUSD trade even if the EA is running on a EURUSD chart, provided CloseAllSymbols is set to true.
Q: What happens if the market moves while orders are closing?
A: The Slippage input allows for small price deviations during the closing process. If the price moves significantly, the OrderClose function might fail. In a high-frequency production environment, you might implement a while loop to retry closing until the order count is zero, but the provided code is sufficient for standard retail trading needs.