Problem Description
Solution
To retrieve lists of trades in MQL4, you must iterate through the order pools provided by the terminal. There are two distinct pools:
MODE_TRADES: Contains currently open market positions and pending orders.MODE_HISTORY: Contains closed positions and deleted pending orders.
Here is a complete script that iterates through both pools and prints the details of the trades to the "Experts" log tab.
MQL4 Script: List Open and Closed Trades
//+------------------------------------------------------------------+
//| TradeListReporter.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
#property script_show_inputs
//--- Input Parameters
input bool FilterByCurrentSymbol = false; // Filter by current chart symbol?
input int MagicNumberFilter = 0; // Filter by Magic Number (0 = All)
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
// --- 1. Process Open Trades ---
Print("==========================================");
Print("=== STARTING LIST: OPEN TRADES ===");
int openCount = GetOpenTrades();
Print("Total Open Trades Found: ", openCount);
// --- 2. Process History Trades ---
Print("==========================================");
Print("=== STARTING LIST: ACCOUNT HISTORY ===");
// Note: History depends on the "Account History" tab settings in Terminal
int historyCount = GetHistoryTrades();
Print("Total History Trades Found: ", historyCount);
Print("==========================================");
}
//+------------------------------------------------------------------+
//| Function to iterate and print Open Trades |
//+------------------------------------------------------------------+
int GetOpenTrades()
{
int count = 0;
int total = OrdersTotal(); // Returns number of open and pending orders
// Iterate backwards is generally safer in EA logic, though forward is fine for reporting
for(int i = total - 1; i >= 0; i--)
{
// Select order from the TRADES pool
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
// Apply Filters
if(FilterByCurrentSymbol && OrderSymbol() != Symbol()) continue;
if(MagicNumberFilter > 0 && OrderMagicNumber() != MagicNumberFilter) continue;
// Print Order Details
string orderType = OrderTypeToString(OrderType());
PrintFormat("Ticket: #%d | Symbol: %s | Type: %s | Lots: %.2f | Open: %.5f | Profit: %.2f",
OrderTicket(),
OrderSymbol(),
orderType,
OrderLots(),
OrderOpenPrice(),
OrderProfit() + OrderSwap() + OrderCommission() // Total PnL
);
count++;
}
}
return(count);
}
//+------------------------------------------------------------------+
//| Function to iterate and print Closed Trades |
//+------------------------------------------------------------------+
int GetHistoryTrades()
{
int count = 0;
int total = OrdersHistoryTotal(); // Returns number of closed orders in loaded history
for(int i = total - 1; i >= 0; i--)
{
// Select order from the HISTORY pool
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
{
// Apply Filters
if(FilterByCurrentSymbol && OrderSymbol() != Symbol()) continue;
if(MagicNumberFilter > 0 && OrderMagicNumber() != MagicNumberFilter) continue;
// Print Order Details
string orderType = OrderTypeToString(OrderType());
PrintFormat("Ticket: #%d | Symbol: %s | Type: %s | Close Time: %s | Profit: %.2f",
OrderTicket(),
OrderSymbol(),
orderType,
TimeToString(OrderCloseTime()),
OrderProfit() + OrderSwap() + OrderCommission()
);
count++;
}
}
return(count);
}
//+------------------------------------------------------------------+
//| Helper: Convert Integer Order Type to String |
//+------------------------------------------------------------------+
string OrderTypeToString(int type)
{
switch(type)
{
case OP_BUY: return("BUY");
case OP_SELL: return("SELL");
case OP_BUYLIMIT: return("BUY LIMIT");
case OP_SELLLIMIT:return("SELL LIMIT");
case OP_BUYSTOP: return("BUY STOP");
case OP_SELLSTOP: return("SELL STOP");
default: return("UNKNOWN");
}
}
Key Implementation Details
-
OrdersTotal()vsOrdersHistoryTotal():OrdersTotal()retrieves the count of currently active trades.OrdersHistoryTotal()retrieves the count of closed trades. Important: This function only sees the history currently loaded in your MT4 "Account History" tab. If you want to see all history, right-click the "Account History" tab in MT4 and select "All History" before running the script.
-
OrderSelect()Modes:- We use
MODE_TRADESfor the first loop to access active positions. - We use
MODE_HISTORYfor the second loop to access closed positions.
- We use
-
Filtering:
- The script includes inputs to filter by
Symbol(e.g., only show EURUSD trades) orMagicNumber(only show trades opened by a specific EA).
- The script includes inputs to filter by
-
Profit Calculation:
OrderProfit()only returns the raw profit from price movement.- To get the actual Net Profit, the code sums
OrderProfit() + OrderSwap() + OrderCommission().
Q&A
Q: Why does OrdersHistoryTotal() return 0 even though I have closed trades?
A: This usually happens if the "Account History" tab in the Terminal window is empty or set to "Today" and no trades were closed today. Right-click inside the Account History tab and select "All History" to ensure MQL4 can access the data.
Q: Can I modify this to write to a CSV file instead of the log?
A: Yes. You would replace the PrintFormat calls with FileWrite. You would need to open a file handle using FileOpen("report.csv", FILE_CSV|FILE_WRITE) at the start and FileClose it at the end.
Q: Does MODE_TRADES include Pending Orders?
A: Yes. OrdersTotal() and MODE_TRADES include active market positions (Buy/Sell) as well as pending orders (Limit/Stop). The helper function OrderTypeToString handles identifying these specific types.