Generate code in 3 minutes
Enter your idea and AI generates runnable code.
To calculate the win rate for a specific symbol based on closed trades, you need to iterate through the account history using OrdersHistoryTotal(), select each order with OrderSelect() using MODE_HISTORY, and filter them by the symbol and order type.
Here is a complete MQL4 script that performs this task. You can drag and drop this script onto any chart, and it will print the statistics to the "Experts" tab in the terminal.
//+------------------------------------------------------------------+
//| CalculateWinRate.mq4 |
//| Copyright 2023, MetaQuotes |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes"
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#property script_show_inputs
//--- Input Parameters
input string TargetSymbol = ""; // Symbol to calculate (Leave empty for current chart symbol)
input int MagicNumber = 0; // Magic Number filter (0 for manual trades/all)
input bool FilterByMagic = false; // Set to true to filter by the MagicNumber above
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
// Determine the symbol to use
string symbolToCheck = TargetSymbol;
if(symbolToCheck == "") symbolToCheck = Symbol();
int totalTrades = 0;
int winningTrades = 0;
int losingTrades = 0;
int breakEvenTrades = 0;
double totalNetProfit = 0.0;
// Get total number of orders in history
int historyTotal = OrdersHistoryTotal();
// Loop through history
for(int i = 0; i < historyTotal; i++)
{
// Select order from history
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
{
// 1. Filter by Symbol
if(OrderSymbol() != symbolToCheck) continue;
// 2. Filter by Magic Number (if enabled)
if(FilterByMagic && OrderMagicNumber() != MagicNumber) continue;
// 3. Filter by Order Type (We only want Buy and Sell, not Balance operations)
if(OrderType() > OP_SELL) continue;
// Increment total count
totalTrades++;
// Calculate Net Profit (Profit + Swap + Commission)
double netProfit = OrderProfit() + OrderSwap() + OrderCommission();
totalNetProfit += netProfit;
// Determine Win/Loss
if(netProfit > 0)
{
winningTrades++;
}
else if(netProfit < 0)
{
losingTrades++;
}
else
{
breakEvenTrades++;
}
}
}
// Output Results
if(totalTrades > 0)
{
double winRate = ((double)winningTrades / totalTrades) * 100.0;
Print("--------------------------------------------------");
Print("Stats for Symbol: ", symbolToCheck);
Print("Total Closed Trades: ", totalTrades);
Print("Winning Trades: ", winningTrades);
Print("Losing Trades: ", losingTrades);
Print("Break-Even Trades: ", breakEvenTrades);
Print("Total Net Profit: ", DoubleToString(totalNetProfit, 2));
Print("WIN RATE: ", DoubleToString(winRate, 2), "%");
Print("--------------------------------------------------");
}
else
{
Print("No closed trades found for symbol: ", symbolToCheck);
}
}
//+------------------------------------------------------------------+
OrdersHistoryTotal(): This function retrieves the total number of records in the account history (including trades, balance adjustments, and cancelled pending orders).OrderSelect(i, SELECT_BY_POS, MODE_HISTORY): We loop through the history index. MODE_HISTORY is crucial here; otherwise, it would look at currently open trades.OrderSymbol() matches your input.OrderType() > OP_SELL excludes pending orders (like OP_BUYLIMIT) that were deleted and balance entries (deposits/withdrawals). We only want OP_BUY (0) and OP_SELL (1).OrderProfit(), OrderSwap(), and OrderCommission() to determine if the trade was actually profitable in monetary terms.(Wins / Total) * 100 to get the percentage.CalculateWinRate.Q: Why does the script include Swap and Commission in the profit calculation?
A: A trade might show a gross profit of $5.00, but if the commission was $7.00, the account actually lost money. To calculate a true "Win Rate" based on account growth, net profit is more accurate than gross profit.
Q: Does this include currently open trades?
A: No. The script uses MODE_HISTORY in the OrderSelect function, so it only calculates based on closed positions.
Q: Why do I see "No closed trades found" even though I have history?
A: Ensure your "Account History" tab in the terminal is set to "All History". If it is set to "Last 3 Months" or "Today", OrdersHistoryTotal() will only see those specific records. Right-click anywhere in the Account History tab and select All History.