Получение котировок в виде массива структур MqlRates

Для запроса массива котировок, включающего все характеристики баров, предназначена функция CopyRates, имеющая несколько перегрузок.

int CopyRates(const string symbol, ENUM_TIMEFRAMES timeframe, int offset, int count, MqlRates &rates[])

int CopyRates(const string symbol, ENUM_TIMEFRAMES timeframe, datetime start, int count, MqlRates &rates[])

int CopyRates(const string symbol, ENUM_TIMEFRAMES timeframe, datetime start, datetime stop, MqlRates &rates[])

Функция получает в массив rates исторические данные для указанных параметров: символа, таймфрейма и диапазона времени, заданного либо номерами баров, либо значениями start/stop типа datetime.

Функция возвращает количество скопированных элементов массива либо -1 в случае ошибки, код которой можно узнать из _LastError. В частности, ошибка возникнет, если задан несуществующий символ, интервал не содержит данных на сервере или выходит за ограничение по количеству баров на графике (TerminalInfoInteger(TERMINAL_MAXBARS)).

Принципы работы с данной функцией являются общими для всех Copy-функций и были изложены в разделе Обзор Copy-функций для получения массивов котировок.

Структура встроенного типа MqlRates описана следующим образом:

struct MqlRates
{
   datetime time;         // время открытия бара
   double   open;         // цена открытия
   double   high;         // максимальная цена за бар
   double   low;          // минимальная цена за бар
   double   close;        // цена закрытия
   long     tick_volume;  // тиковый объем за бар
   int      spread;       // минимальный спред за бар в пунктах
   long     real_volume;  // биржевой объем за бар
};

Попробуем применить функцию для подсчета среднего размера баров в скрипте SeriesStats.mq5. Во входных переменных предоставим возможность выбора рабочего символа, таймфрейма, количества анализируемых баров и начального смещения в прошлое (0 означает анализ с текущего бара).

input string WorkSymbol = NULL// Symbol (leave empty for current)
input ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT;
input int BarOffset = 0;
input int BarCount = 10000;
 
void OnStart()
{
   MqlRates rates[];
   double range = 0move = 0// подсчет размаха и движения цен в барах
   
   PrintFormat("Requesting %d bars on %s %s",
      BarCountStringLen(WorkSymbol) > 0 ? WorkSymbol : _Symbol,
      EnumToString(TimeFrame == PERIOD_CURRENT ? _Period : TimeFrame));
   
   // запрашиваем всю информацию о BarCount барах в массив MqlRates
   const int n = PRTF(CopyRates(WorkSymbolTimeFrameBarOffsetBarCountrates));
   
   // в цикле подсчитываем среднее для размаха и движения
   for(int i = 0i < n; ++i)
   {
      range += (rates[i].high - rates[i].low) / n;
      move += (fmax(rates[i].openrates[i].close)
             - fmin(rates[i].openrates[i].close)) / n;
   }
   
   PrintFormat("Stats per bar: range=%f, movement=%f"rangemove);
   PrintFormat("Dates: %s - %s",
      TimeToString(rates[0].time), TimeToString(rates[n - 1].time));
}

Набросив скрипт на график EURUSD,H1, мы можем получить примерно следующий результат.

Requesting 100000 bars on EURUSD PERIOD_H1
CopyRates(WorkSymbol,TimeFrame,BarOffset,BarCount,rates)=20018 / ok
Stats per bar: range=0.001280, movement=0.000621
Dates: 2018.07.19 15:00 - 2021.10.11 17:00

Поскольку в терминале стояло ограничение на 20000 баров, запрос 100000 баров смог вернуть только 20018 (лимит и новые сформированные бары после начала сеанса). В самый первый элемент массива (с индексом 0) попал бар со временем 2018.07.19 15:00, а в последний — 2021.10.11 17:00.

Согласно статистике средний размах бара за это время составил 128 пунктов, и движение между открытием и закрытием — 62 пункта.

При запросе информации с помощью начальной и конечной даты (start/stop) имейте в виду, что обе границы трактуются включительно. Поэтому для задания интервала, соответствующего какому-либо бару старшего таймфрейма, следует отнимать от правой границы 1 секунду. Мы применим этот прием в примере SeriesSpread.mq5 в разделе Чтение цены, объема, спреда и времени по индексу бара.