🚀 AI One-Click Generation of mql4 Strategy Code

Mastering the MqlRates Structure for Advanced Analysis in Mql4

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

Problem Description

How do I use the MqlRates structure to get historical bar data?

Solution

To use the MqlRates structure in MQL4, you typically use it in conjunction with the CopyRates() function. This approach allows you to store Open, High, Low, Close, Time, and Volume data for a specific bar into a single structure, rather than accessing separate arrays (like Open[], High[], etc.).

Here is a step-by-step guide and a complete script example.

1. The MqlRates Structure Definition

The MqlRates structure stores information about the prices, volume, and spread of a single bar. It contains the following fields:

  • datetime time: Period start time.
  • double open: Open price.
  • double high: The highest price of the period.
  • double low: The lowest price of the period.
  • double close: Close price.
  • long tick_volume: Tick volume.
  • int spread: Spread.
  • long real_volume: Trade volume (usually 0 for Forex).

2. Implementation Steps

  1. Declare an array of type MqlRates.
  2. Set array indexing using ArraySetAsSeries(true) if you want index 0 to represent the current (newest) bar.
  3. Copy data using CopyRates().
  4. Access data using the dot operator (e.g., rates[0].close).

3. Code Example

This script retrieves the last 10 bars of history for the current symbol and prints the details to the "Experts" log.

#property copyright "Copyright 2023, Quantitative Trading"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property script_show_inputs

//--- Input parameters
input int      BarsToCopy = 10;  // Number of bars to retrieve

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   // 1. Declare the array of MqlRates structures
   MqlRates rates[];
   
   // 2. Set indexing as time series
   // true = Index 0 is the newest bar, Index 1 is the previous bar, etc.
   // false = Index 0 is the oldest bar retrieved.
   ArraySetAsSeries(rates, true);
   
   // 3. Copy historical data
   // Parameters: Symbol, Timeframe, Start Position, Count, Target Array
   int copied = CopyRates(Symbol(), Period(), 0, BarsToCopy, rates);
   
   // 4. Check if data was copied successfully
   if(copied <= 0)
   {
      Print("Error copying price data. Error Code: ", GetLastError());
      return;
   }
   
   Print("Successfully copied ", copied, " bars.");
   
   // 5. Loop through the data and print details
   // Since we set ArraySetAsSeries to true, i=0 is the current forming bar
   for(int i = 0; i < copied; i++)
   {
      string info = StringFormat("Bar Index [%d]: Time=%s, O=%.5f, H=%.5f, L=%.5f, C=%.5f, Vol=%I64d",
                                 i,
                                 TimeToString(rates[i].time),
                                 rates[i].open,
                                 rates[i].high,
                                 rates[i].low,
                                 rates[i].close,
                                 rates[i].tick_volume);
      Print(info);
   }
   
   // Example: Accessing specific data
   double previousClose = rates[1].close;
   Print("Previous Bar Close: ", previousClose);
}
//+------------------------------------------------------------------+

Key Considerations

  • Efficiency: Using CopyRates is generally faster and cleaner than calling iOpen, iHigh, iLow, etc., individually inside a loop, especially when you need multiple data points for the same bar.
  • Portability: This syntax is highly compatible with MQL5, making it easier to port your strategies to MetaTrader 5 in the future.
  • Error Handling: Always check the return value of CopyRates. If it returns -1 or 0, the data copy failed (often due to history not being synced yet), and you should handle the error using GetLastError().

Q&A

Q: What is the difference between MqlRates and standard arrays like Open[]?
A: Open[], Close[], etc., are predefined arrays that give direct access to specific price types. MqlRates is a structure that groups all data (OHLCV) for a specific bar into a single object. MqlRates is better for passing bar data to functions or storing history snapshots.

Q: Does CopyRates handle the current forming bar?
A: Yes. If you start copying from index 0, the first element will contain the data of the current unfinished bar. The close price in the structure will represent the current Bid price.

Q: Why use ArraySetAsSeries(rates, true)?
A: By default, dynamic arrays fill from left to right (Index 0 is the oldest). Traders usually prefer Index 0 to be the "current" bar (matching the behavior of Open[] or Close[]). ArraySetAsSeries(true) enforces this reverse indexing.