Basics of Trade Management in MQL4

One of the necessary components of each trading strategy is the constant monitoring of all the open trades. So let’s look more closely at the proper way on how to process all the trades that belong to the particular strategy.

Each strategy should have a unique MagicNumber which is set during the opening of each trade.

OrderSend(Symbol(), OP_BUY, Size, Ask, 0, SL, TP, NULL, UniqueStrategyNumber, 0, clrNONE)

There are multiple situations when you need to process all the trades: Modifying SL/TP, closing all the trades, calculating cumulative profit, exposition, or any other desired metric. To prevent most of the problems and to execute everything needed, here is how it can be done:

// Iterate over all the trades beginning from the last one to prevent reindexing
for (int i = OrdersTotal() - 1; i >= 0; i--) {

	// Select trade by its position and check Magic Number
	if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == UniqueStrategyNumber) {

		// Example 1: Calculate exposition
		if (OrderType() == OP_BUY) {
			Expo = Expo + OrderLots();
		} else if (OrderType() == OP_SELL) {
			Expo = Expo - OrderLots();
		}

		// Example 2: Calculate profit
		NetProfit = NetProfit + OrderProfit() + OrderCommission() + OrderSwap();

		// Example 3a: Close Buy trade			
		if (OrderType() == OP_BUY) {
			if (OrderClose(OrderTicket(), OrderLots(), Bid, 0, clrNONE) == false) {
				Alert("Cannot close the trade due to: ", ErrorDescription(GetLastError()));
			}

		// Example 3b: Close Sell trade
		} else if (OrderType() == OP_SELL) {
			if (OrderClose(OrderTicket(), OrderLots(), Ask, 0, clrNONE) == false) {
				Alert("Cannot close the trade due to: ", ErrorDescription(GetLastError()));
			}
		}

	}
}

You need to process all the active trades – OrdersTotal() to make sure you will not miss any of them. After selecting the trade – OrderSelect() from a pool of currently active trades – MODE_TRADES using their position as an identifier – SELECT_BY_POS, you need to check if the OrderMagicNumber() matches the preset one in the strategy.

As shown in the code above, you will need to start iterating from the most recently opened trade (highest index) through the trades to the oldest one (lowest index). This has to be done, especially when closing all the trades, to prevent them from reindexing.

Here you can see an example of how the trades are indexed. In the first column, you can see their OrderTicket() and index that I added:

Trade Indexing

When closing the trades from the oldest one [3] – all remaining trades [2], [1], [0] will keep their index. When doing that the opposite way starting from [0] – the trade indexes will change as follows:

// First iteration closing trade on position [0]
[0] -> Closed
[1] -> [0]  
[2] -> [1]   
[3] -> [2] 

// Second iteration - closing the trade on position [1]
[0]  
[1] -> Closed  
[2] -> [1]

// Third and fourth iteration - no trade on position [2] and [3]
[0]
[1]

// 2 trades left

The reindexing happens immediately after you close the trade [0]. In the end, this will result in closing every other trade so half of them will be left behind.

When managing multiple strategies in one MT4 terminal, there are more possible problems occurring when processing the trades. Do you have any idea what else may happen and why the solution described above may not be 100% safe? Let me see your ideas in the comments.

Still, have no trading account yet? Open an account at one of my trusted brokers suitable for algorithmic trading completely for free and start testing today!

This post contains affiliate links. If you use these links to register at one of the trusted brokers, I may earn a commission. This helps me to create more free content for you. Thanks!