Доступ к таймсериям

 

Эксперт выполняет аналитику по открытию нового бара, отдельные тики игнорируются.

Пытаюсь выполнить следующие действия:

int TF[21] = {1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60, 120, 180, 240, 360, 480, 720, 1440, 10080, 43200};

void OnInit() {
  // По количеству баров...
  for (int i = 0; i <= ArraySize(TF)-1; i++)
    Print("TimeFrames["+i+"] = \'"+TF[i]+"\'. Bars[i] = \'"+Bars(_Symbol, GetTF(TF[i]))+"\'.");

  // По времени последнего бара...
  datetime dt[];
  for (int i = 0; i <= ArraySize(TF)-1; i++) {
    if (CopyTime(_Symbol, GetTF(TF[i]), 0, 1, dt) == -1)
      Print("Не удалось скопировать историю.");
    else Print(TimeToString(dt[0]));
  }
}

ENUM_TIMEFRAMES GetTF(int min)
{
  switch(min) {
    case 1:     return (PERIOD_M1);
    case 2:     return (PERIOD_M2);
    case 3:     return (PERIOD_M3);
    case 4:     return (PERIOD_M4);
    case 5:     return (PERIOD_M5);
    case 6:     return (PERIOD_M6);
    case 10:    return (PERIOD_M10);
    case 12:    return (PERIOD_M12);
    case 15:    return (PERIOD_M15);
    case 20:    return (PERIOD_M20);
    case 30:    return (PERIOD_M30);
    case 60:    return (PERIOD_H1);
    case 120:   return (PERIOD_H2);
    case 180:   return (PERIOD_H3);
    case 240:   return (PERIOD_H4);
    case 360:   return (PERIOD_H6);
    case 480:   return (PERIOD_H8);
    case 720:   return (PERIOD_H12);
    case 1440:  return (PERIOD_D1);
    case 10080: return (PERIOD_W1);
    case 43200: return (PERIOD_MN1);
    default:    return (PERIOD_CURRENT);
  }
}

Результат:

2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      2010.01.08 22:00:00
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      Не удалось скопировать историю.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[20] = '43200'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[19] = '10080'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[18] = '1440'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[17] = '720'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[16] = '480'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[15] = '360'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[14] = '240'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[13] = '180'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[12] = '120'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[11] = '60'. Bars[i] = '6479'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[10] = '30'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[9] = '20'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[8] = '15'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[7] = '12'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[6] = '10'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[5] = '6'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[4] = '5'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[3] = '4'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[2] = '3'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[1] = '2'. Bars[i] = '0'.
2010.01.09 12:41:43     tester (EURUSD,H1)      TimeFrames[0] = '1'. Bars[i] = '0'.

Иными словами, эксперт получает от терминала историю только текущего периода. Если, не убирая эксперта с графика, переключиться, скажем, на месяцы, то все работает.

Либо это баг терминала, либо моя ошибка. Прошу помощи специалистов.

Спасибо.

Обработчик события "новый бар"
Обработчик события "новый бар"
  • 2010.10.04
  • Konstantin Gruzdev
  • www.mql5.com
Язык программирования MQL5 позволяет решать задачи на совершенно новом уровне. Даже те задачи, которые уже вроде имеют решения, благодаря объектно-ориентированному программированию могут подняться на качественно новый уровень. В данной статье специально взят простой пример проверки появления нового бара на графике, который был преобразован в достаточно мощный и универсальный инструмент. Какой? Читайте в статье.
 
Смотрите в Документации раздел Организация доступа к данным
 
voix_kas   :

Эксперт выполняет аналитику по открытию нового бара, отдельные тики игнорируются.

Пытаюсь выполнить следующие действия:

Результат:

Иными словами, эксперт получает от терминала историю только текущего периода. Если, не убирая эксперта с графика, переключиться, скажем, на месяцы, то все работает.

Либо это баг терминала, либо моя ошибка. Прошу помощи специалистов.

Спасибо.


Я не считаю себя большим специалистом но попробуй заменить:

 

for (int i = 0; i <= ArraySize(TF)-1; i++) {
    if (CopyTime(_Symbol, GetTF(TF[i]), 0, 1, dt) == -1)
      Print("Не удалось скопировать историю.");
    else Print(TimeToString(dt[0]));
  }

 на

const int количество_попыток = 10;
int   rates_total;
int err=0;

for (int i = 0; i <= ArraySize(TF)-1; i++)
  {
    do
      {
        rates_total= CopyTime(_Symbol, GetTF(TF[i]), 0, 1, dt);


        Sleep(1);
        err++;
      }
    while(rates_total<=0 && err<количество_попыток);
    if(err>=количество_попыток)
        Print("Не удалось скопировать историю.");
    else
        Print(TimeToString(dt[0]));
  }

 или что то подобное.

 

Rosh, vdv2001.

Спасибо большое за помощь! 

 
Rosh:
Смотрите в Документации раздел Организация доступа к данным

Поскольку эта тема достаточно болезненная, может сделать отдельную тему для обсуждения этого раздела документации (по аналогии со статьями)?

У меня возникли следующие вопросы:

Вопрос 1.

На что влияет выбор символа SymbolSelect? Только ли доступность истории или на что-то ещё? Можно проводить торговые сделки, если символ не выбран?

Вопрос 2.

Функция Bars возвращает количество баров в истории по соответствующему символу периоду. Если, например, в минутных данных будет пропуск (не совершались торговые операции), то Bars должна вернуть 0.

В документации <https://www.mql5.com/ru/docs/series/barsсказано:

Если данные для таймсерии с указанными параметрами при вызове функции Bars() еще не сформированы в терминале, или данные таймсерии в момент вызова функции не синхронизированы с торговым сервером, то функция вернет нулевое значение.

Но как тогда можно отличить отсутствие данных (отсутствие торговых операций) и неготовность данных? Может лучше при неготовности данных возвращать -1?

Вопрос 3.

Что будет если в функции Bars() примет параметр start_time > текущее время? И stop_time > текущее время? Может добавить это в документацию?

Вопрос 4.

Выполняет ли функция Bars() подгрузку данных, если start_time < первой даты в истории на терминале по заданному символу/периоду, или если stop_time > последней даты на терминале по заданному символу/периоду? Или она просто возвращает сколько есть на данный момент без подгрузки?

Вопрос 5.

При вызове функций семейства CopyRates параметр start_time может попадать неточно на начало интервала? Например, для часовой свечки start_time=00:10:00? Какую свечу выдаст: 0:00:00 или 1:00:00?

Вопрос 6.

В https://www.mql5.com/ru/docs/series/timeseries_access сказано:

Теперь необходимо получить начальную дату по уже имеющейся истории для указанной пары символ/период. Возможно, что значение входного параметра startdate, переданного функции CheckLoadHistory() попадает в интервал уже доступной истории, и тогда никакого запроса к торговому серверу не потребуется. Для получения самой первой даты по символу-периоду на данный момент предназначена функция SeriesInfoInteger() с модификатором SERIES_FIRSTDATE.

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

Если мы успешно прошли все проверки, то сделаем последнюю попытку обойтись без обращения к торговому серверу. Сначала узнаем начальную дату, для которой доступны минутные данные в формате HCC. Запросим это значение функцией SeriesInfoInteger() с модификатором SERIES_TERMINAL_FIRSTDATE и опять сравним со значением параметра start_date.

Вопрос 7.

Вызывают ли следующие функции загрузку данных?

SeriesInfoInteger(Symbol, Period, SERIES_SERVER_FIRSTDATE, FirstServerDate)

Документация по MQL5: Доступ к таймсериям и индикаторам / Bars
Документация по MQL5: Доступ к таймсериям и индикаторам / Bars
  • www.mql5.com
Доступ к таймсериям и индикаторам / Bars - Документация по MQL5
 
Maxx:

Вопрос 1.

На что влияет выбор символа SymbolSelect? Только ли доступность истории или на что-то ещё? Можно проводить торговые сделки, если символ не выбран?


Если говорить о тестере (тестировании в нем мульта) то рабочий символ попадает в MarketWatch автоматом, а значит по нему происходит получение окружения и подгрузка необходимой истории (истории грузится при необходимости синхронизации).

Все остальные символы следует добавить в MarketWatch самостоятельно (в коде эксперта)...

Насколько помню терминал синхронизирует историю с торговым сервером, а агенты тестера с терминалом.

PS

Как я понимаю если символ не выбран в тестере по нему точно сделок выполнить не удастся, будут появляться сплошные ошибки.

Хотя, насколько я помню, разработчики в алгоритме тестера предусмотрели это, но в любом случае лучше выбрать все нужные символы в блоке инициализации.

Maxx:

Вопрос 7.

Вызывают ли следующие функции загрузку данных?

SeriesInfoInteger(Symbol, Period, SERIES_SERVER_FIRSTDATE, FirstServerDate)

Я конечно могу и ошибаться, но мне кажется что нет..