🚀 AI One-Click Generation of mql4 Strategy Code

Mql4 Tutorial: How to Loop Through and Analyze Both Open and Historical Trades

mql4 | Published on: 2025/12/8
The following content is generated by EasyQuant .

Problem Description

How can I get a list of all my closed trades for a specific symbol to calculate my win rate?

Solution

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.

MQL4 Script: Calculate Win Rate

//+------------------------------------------------------------------+
//|                                            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);
   }
}
//+------------------------------------------------------------------+

How It Works

  1. OrdersHistoryTotal(): This function retrieves the total number of records in the account history (including trades, balance adjustments, and cancelled pending orders).
  2. 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.
  3. Filters:
    • Symbol: Checks if OrderSymbol() matches your input.
    • Order Type: 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).
    • Magic Number: Optional filter if you want to isolate a specific Expert Advisor.
  4. Net Profit Calculation: The script sums OrderProfit(), OrderSwap(), and OrderCommission() to determine if the trade was actually profitable in monetary terms.
  5. Calculation: It performs standard division (Wins / Total) * 100 to get the percentage.

How to Use

  1. Open MetaEditor (F4).
  2. Create a new Script (File -> New -> Script).
  3. Name it CalculateWinRate.
  4. Paste the code above into the window.
  5. Compile (F7).
  6. Go back to the MT4 Terminal.
  7. Drag the script from the Navigator -> Scripts folder onto your chart.
  8. Check the Experts tab (at the bottom of the terminal) to see the results.

Q&A

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.