Generate code in 3 minutes
Enter your idea and AI generates runnable code.
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.
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).MqlRates.ArraySetAsSeries(true) if you want index 0 to represent the current (newest) bar.CopyRates().rates[0].close).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);
}
//+------------------------------------------------------------------+
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.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: 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.