Баг МТ4, который лишил меня сна

18:59 Naragot 0 Comments


Запуская импульсник, я нарвался на неожиданное поведение потока котировок, и эта проблема меня лишила сна на неделю.

В чём суть


На импульснике я впервые опробовал систему закрытия различных торговых сессий для анализа рынка. То есть, например, робот заканчивал смотреть котировки в 22.59, а возобновлял уже в 8.00. На тестах всё было ровно, но на реале в 8.00 расчёты оказывались какими-то неправильными, что могло породить неверное открытие позиций.

Почему это получилось? Что не так? Я код проверил раз -дцать. Никаких ошибок. На тестах всё отлично, а на реале вот такой вот сюрприз.

Так как дебаг по факту не помогал, пришлось добавлять океан логгирования, чтобы ловить ошибку уже на лайв котировках. Ожидаемо оказалось, что в 8.00 функции обращения к котировкам iTime, iClose, iOpen, iHigh, iLow возвращали значения на 23.00. Внезапно?

Решение проблемы


Я уже думал, что я что-то совершенно не понимаю в программировании, но спасибо Антону и DIMTrade за помощь в решении. Я всё-таки оказался в своём уме. Всё дело в попытках МТ4 экономить память, и доходит это до абсурдного. Если к конкретному таймфрейму инструмента не обращаться, то терминал и не обновляет его значения. Вот так вот. Проспал 9 часов - получи последние известные котировки, а уже после этого система обновит поток котировок. Можно запрашивать М1, М30, Н1, но М15 при этом не обновится.

Решений этой проблемы два.

1) Держать постоянно открытыми графики инструментов с нужными таймфреймами. Если нужно периодически обращаться к EURUSD на M15, то этот график должен быть открыт, если надо ещё и к M30, то и он тоже должен быть открыт. Все нужные таймфреймы на всех нужных символах.

2) Принудительно обновлять постоянно данные котировок заранее до обращения к ним.

Так как держать море графиков мне не захотелось, то я пошёл вторым путём. Моя реализация выглядит так:

datetime currentCandle = iTime(symbol, 1, 0);
if(TimeHour(currentCandle) != Hour())
{
   Print("...updating M1 candles...");
   return;
}
datetime updateCandle = iTime(symbol, 5, 0);
if(TimeHour(updateCandle) != Hour())
{
   Print("...updating M5 candles...");
   return;
}
...и так далее для всех нужных таймфреймов.

Вот такой вот баг лишил меня сна и чуть было не лишил разума.

____________
Подписка на анонс новых постов в Телеграме: @naragot_blog
Подписка на анонс новых постов в Твиттере: @NaragotBlog
Подписка на анонс новых постов в ВКонтакте: Naragot PAMM
Подписка на анонс новых постов в Инстаграме: @naragoth

0 коммент.: