Намедни занялся я подключением новостного индикатора к одному из советников.
Выбрал urdala_news, зарекомендовавший себя в Генерике.
Задача сама по себе нехитрая, но после запуска советника в тестере я заметил, что он регулярно сообщает мне о попытках загрузить новости.
И возвращает он одно значение: новости в интервале, или нет.
А если мне чуть более интересную логику хочется, с закрытием в один интервал, запретом открытия в другой - это к нему нужно несколько раз обратиться.
Заглянул я в код и ужаснулся - на вызов основной функции индикатора он что только не делает.
А потом еще, чтобы поделиться этим советником, нужно поделиться индикатором...
В общем, написал я подключаемый модуль, который делает все то же самое, но эффективно - и можно позвать его напрямую из советника и получить структуру вида
struct NewsCheckStatus { int minutesSinceLastNews; int minutesToNextNews; };
Соответственно, объект этот можно получать не чаще раза в минуту и повсеместно переиспользовать.
Технические детали:
Для использования библиотеки нужно ее подключить и создать экземпляр класса NewsLoader:
NewsLoader(int _serverGMTOffset, string _currencies = "", bool _high = true, bool _medium = true, bool _low = true, bool _drawLines = true, bool _onlyDrawFutureNews = false, color _colorHigh = clrRed, color _colorMedium = clrLime, color _colorLow = clrBlue, int _refreshPeriodSeconds = 86400)
Параметры конструктора:
- serverGMTOffset - сдвиг брокера от GMT. Этот параметр может меняться за время жизни советника из-за DST, ниже я объясню, как с этим бороться
- currencies - строка с набором валют через запятую. Определяет, по каким валютам вы хотите фильтровать новости. Если строка пустая, используются две валюты текущего символа
- high, medium, low - фильтрация по волатильности новости: если вы не хотите учитывать малозначимые новости, например, поставьте low в false
- drawLines - рисовать ли вертикальные линии на чарте
- onlyDrawFutureLines - рисовать только линии в будущем
- colorHigh, colorMedium, colorLow - цвета соответствующих линий
- refreshPeriodSeconds - как часто перекачивать новости с сервера. Не злоупотребляйте, эта операция занимает несколько секунд и будет выполнена на одном из обращений из основной программы, запросто может притормозить торговый процесс в важный момент
Как я уже упомянул, в определенный момент за счет перехода на летнее время GMT сдвиг меняется. Новости же поставляются по времени GMT, поэтому, если ничего не делать, они будут отображаться и обсчитываться неправильно - со сдвигом в час.
Если ваша программа умеет обрабатывать DST (например, вы используете мою библиотеку для работы с планировщиком), то достаточно оповестить NewsLoader о новом GMT:
void SetGMTOffset(int _offset)
Он все пересчитает и перерисует (только грядущие новости).
Операция незатратная, можно просто отсылать оффсет на каждом тике, например, так:
NewsCheckStatus newsCheckStatus; tradeTimeStatus = tradeTimeManager.GetTradeTimeStatus(); if (UseNewsFilter) { newsLoader.SetGMTOffset(tradeTimeManager.GetLiveGMTOffset()); newsLoader.CheckNewsStatus(newsCheckStatus); }
Опросить библиотеку можно двумя способами:
void CheckNewsStatus(NewsCheckStatus &newsCheckStatus)
Эта функция вернет вышеупомянутую структуру, которую можно использовать, например, так:
if (newsCheckStatus.minutesSinceLastNews >= TimeAfterNews && newsCheckStatus.minutesToNextNews > TimeBeforeNews) isOrderOpened = CheckOpen();
Или так:
if (UseNewsFilter && CloseTimeBeforeNews != 0 && newsCheckStatus.minutesToNextNews <= CloseTimeBeforeNews) //фильтр новостей
CloseAll(IntegerToString(CloseTimeBeforeNews) + " minutes before news");
А можно просто спросить, нет ли новостей в интервале:
bool IsNews(int _minutesBefore, int _minutesAfter)
Подключение новостей в тестере:
Скачиваем скрипт с маркета: https://www.mql5.com/ru/market/product/23961
Запускаем его с выбранными датами.
Когда закончит, заходим в папочку MQL4/files и копируем файл Calendar.txt в папочку tester/files
Все, новости работают на истории (не забываем выставить правильный GMT offset)
Всем профитов!
