MT4 Order History Exporter Script – Full Source Code
You know what's oddly difficult in MT4? Getting a clean export of your trade history. The built-in "Account History" tab lets you save as a report, but it's an HTML mess. And if you want to calculate net profit per pair or analyze your win rate by day of week, you're stuck copy-pasting.
This script solves that. One click, you get a properly formatted CSV file that opens cleanly in Excel, Google Sheets, or any analysis tool.
What This Script Does
It loops through all closed orders in your account history, extracts every relevant field (open time, close time, symbol, type, volume, price, SL, TP, profit, commission, swap), and writes them to a CSV file saved in your MetaTrader
Files folder.The real kicker? It includes a profit calculation in pips alongside the monetary profit. This is super useful if you want to compare performance across different lot sizes.
Complete MQL4 Source Code
``
cpp
//+------------------------------------------------------------------+
//| OrderHistoryExporter.mq4 |
//| Copyright 2026, FXEAR.com |
//| https://www.fxear.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, FXEAR.com"
#property link "https://www.fxear.com"
#property version "1.00"
#property strict
#property script_show_inputs
//--- Input parameters
input int StartYear = 2024; // Start year for filtering (0 = no filter)
input int EndYear = 0; // End year for filtering (0 = no filter)
input string SymbolFilter = ""; // Symbol filter (empty = all)
input bool IncludeCommission = true; // Include commission in net profit
input bool IncludeSwap = true; // Include swap in net profit
input string FileName = "TradeHistory"; // Output file name (without extension)
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart() {
string filename = FileName + ".csv";
int file_handle = FileOpen(filename, FILE_WRITE|FILE_CSV|FILE_READ, ",");
if(file_handle < 1) {
Print("Failed to open file. Error: ", GetLastError());
return;
}
// Write CSV header
string header = "Ticket,OpenTime,CloseTime,Symbol,Type,Volume,OpenPrice,ClosePrice,SL,TP,Profit(USD),Profit(Pips),Commission,Swap,NetProfit";
FileWrite(file_handle, header);
int total_trades = 0;
int filtered_trades = 0;
double total_net_profit = 0;
// Loop through account history
for(int i = OrdersHistoryTotal() - 1; i >= 0; i--) {
if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
total_trades++;
// Apply filters
if(!PassesFilters()) continue;
filtered_trades++;
// Basic order info
int ticket = OrderTicket();
datetime open_time = OrderOpenTime();
datetime close_time = OrderCloseTime();
string symbol = OrderSymbol();
int type = OrderType();
double volume = OrderLots();
double open_price = OrderOpenPrice();
double close_price = OrderClosePrice();
double sl = OrderStopLoss();
double tp = OrderTakeProfit();
// Profit calculations
double profit = OrderProfit();
double commission = OrderCommission();
double swap = OrderSwap();
double net_profit = profit + (IncludeCommission ? commission : 0) + (IncludeSwap ? swap : 0);
total_net_profit += net_profit;
// Pip calculation (for major pairs and indices)
double pip_value = GetPipValue(symbol);
double profit_pips = 0;
if(pip_value > 0) {
if(type == OP_BUY) {
profit_pips = (close_price - open_price) / pip_value;
} else if(type == OP_SELL) {
profit_pips = (open_price - close_price) / pip_value;
}
} else {
profit_pips = 0; // Cannot calculate pips for this symbol
}
// Format datetime as string
string open_time_str = TimeToString(open_time, TIME_DATE|TIME_MINUTES|TIME_SECONDS);
string close_time_str = TimeToString(close_time, TIME_DATE|TIME_MINUTES|TIME_SECONDS);
// Write row
string row = StringFormat("%d,%s,%s,%s,%d,%.2f,%.5f,%.5f,%.5f,%.5f,%.2f,%.1f,%.2f,%.2f,%.2f",
ticket,
open_time_str,
close_time_str,
symbol,
type,
volume,
open_price,
close_price,
sl,
tp,
profit,
profit_pips,
commission,
swap,
net_profit);
FileWrite(file_handle, row);
}
FileClose(file_handle);
// Summary output
Print("=== Export Complete ===");
Print("Total orders found: ", total_trades);
Print("Filtered orders exported: ", filtered_trades);
Print("Total net profit (filtered): $", DoubleToString(total_net_profit, 2));
Print("File saved as: ", filename);
Print("Location: ", TerminalInfoString(TERMINAL_DATA_PATH), "\\MQL4\\Files\\");
// Also show a message box
MessageBox(StringFormat("Export complete!\n%d trades exported\nTotal net profit: $%.2f\nFile: %s",
filtered_trades, total_net_profit, filename),
"Order History Export", MB_OK);
}
//+------------------------------------------------------------------+
//| Check if order passes all filters |
//+------------------------------------------------------------------+
bool PassesFilters() {
// Year filter
if(StartYear > 0) {
MqlDateTime dt;
TimeToStruct(OrderCloseTime(), dt);
if(dt.year < StartYear) return false;
}
if(EndYear > 0) {
MqlDateTime dt;
TimeToStruct(OrderCloseTime(), dt);
if(dt.year > EndYear) return false;
}
// Symbol filter
if(StringLen(SymbolFilter) > 0) {
if(OrderSymbol() != SymbolFilter) return false;
}
// Only closed orders (ensure it's not a pending order)
if(OrderType() > 1 && OrderType() < 6) return false; // Skip pending orders
return true;
}
//+------------------------------------------------------------------+
//| Get pip value for given symbol |
//+------------------------------------------------------------------+
double GetPipValue(string symbol) {
// For forex pairs
if(StringFind(symbol, "JPY") >= 0) {
return 0.01; // JPY pairs have 2 decimal places
}
// For metals and indices
if(StringFind(symbol, "XAU") >= 0 || StringFind(symbol, "GOLD") >= 0) {
return 0.01; // Gold uses 0.01
}
if(StringFind(symbol, "XAG") >= 0 || StringFind(symbol, "SILVER") >= 0) {
return 0.001; // Silver uses 0.001
}
// For crypto
if(StringFind(symbol, "BTC") >= 0 || StringFind(symbol, "ETH") >= 0) {
return 1.0; // Crypto often uses whole numbers
}
// Default: 5-digit broker (0.0001 for most pairs)
return 0.0001;
}
//+------------------------------------------------------------------+
//| Helper: StringFind wrapper for MQL4 |
//+------------------------------------------------------------------+
int StringFind(string text, string search) {
return ::StringFind(text, search, 0);
}
//+------------------------------------------------------------------+
//| Helper: StringLen wrapper |
//+------------------------------------------------------------------+
int StringLen(string text) {
return ::StringLen(text);
}
`
Why This Matters
Most traders I know keep a separate Excel sheet for their trades. They manually enter every single row. It's tedious and error-prone. This script eliminates that work entirely. Run it once a week, and you have a complete dataset for your trading journal.
In my own trading, I use the exported data to calculate my profit factor per session. For example, I discovered that my London session trades have a profit factor of 1.8, while New York session trades are only 1.2. Without this data, I would never have known.
Compilation and Usage
To use this script:
Open MetaEditor (F4 in MT4)
File → New → Script → Next → Name it "OrderHistoryExporter"
Paste the code and compile (F7)
Drag the script from the Navigator onto any chart
The script will show an input dialog — configure your filters
Click OK, and the CSV will be generated in MQL4\Files\
Input Parameters Explained:
StartYear / EndYear: Filter trades by closing year. Set to 0 to disable.
SymbolFilter: Enter a specific symbol like "EURUSD" to export only that pair.
IncludeCommission / IncludeSwap: Toggle whether these are added to net profit.
FileName: Choose your output filename (no spaces recommended).
Troubleshooting:
"Failed to open file": Make sure your MT4 terminal is not running in read-only mode.
No trades exported: Double-check your date filters — if you set StartYear to 2025 and have no trades in 2025, you'll get zero rows.
Pip values show 0: For exotic symbols or custom instruments, the GetPipValue function may need tweaking. You can hardcode the correct pip value for your broker.
A Cool Modification Idea
Here's something I added to my own version: a "Day of Week" column. You can do this by adding TimeDayOfWeek(OrderCloseTime()) to the export. I found that my win rate on Mondays is significantly higher than on Fridays — information that directly shaped my weekly trading plan.
A Note on Data Privacy
The CSV file stays on your local machine. It's saved in your MT4 installation folder and never sent anywhere. This matters because some traders are nervous about sharing trade data with third-party tools. With this script, you own your data 100%.
Reference
The use of OrdersHistoryTotal() and OrderSelect()` follows the official MQL4 documentation for trade history access. See: MQL4 Reference – Trade Functions.---
本文首发于FXEAR.com,原创内容,未经授权禁止转载。