English
preview
От новичка до эксперта: Создание анимированного советника для новостей в MQL5 (VI) — Стратегия пост-новостной торговли

От новичка до эксперта: Создание анимированного советника для новостей в MQL5 (VI) — Стратегия пост-новостной торговли

MetaTrader 5Примеры |
46 0
Clemence Benjamin
Clemence Benjamin

Содержание:


Введение

Стратегия, которую мы рассмотрели в предыдущей статье, была сосредоточена на размещении отложенных ордеров незадолго до выхода важных новостей. Цель состояла в том, чтобы извлечь прибыль из резких колебаний цен, которые часто следуют за подобными событиями. Хотя этот подход может быть эффективным, существуют сценарии, когда он не срабатывает — например, когда один из ордеров срабатывает, но не достигает уровня тейк-профита и в конечном итоге вместо этого срабатывает стоп-лосс.

К счастью, в нашей предыдущей реализации мы встроили в советник логику автоматической отмены противоположного отложенного ордера при срабатывании одного ордера. Такая автоматизация имеет решающее значение, поскольку она предотвращает активацию обоих ордеров во время «качелей» на бирже, что в противном случае могло бы привести к двойному убытку. Полагаясь на скорость алгоритма для принятия таких решений в течение миллисекунд, советник обеспечивает уровень точности, которого практически невозможно достичь вручную.

Однако, если трейдер хочет полностью избежать этого риска, возникает необходимость в альтернативной стратегии. В этом обсуждении мы обратим наше внимание на стратегию торговли после выхода новостей - совершение сделок после важного события, — разработанную для дополнения и расширения возможностей существующего советника «Заголовки новостей».

В следующем разделе рассмотрим план интеграции этой стратегии и оценим его осуществимость с помощью анализа истории графиков и реализации живой логики.


Изучение концепции стратегии

Для нашего тестирования и исследования мы планируем использовать данные исторических графиков для анализа поведения рынка после важных новостных событий, в частности, публикации данных о занятости в несельскохозяйственном секторе США (NFP). Поскольку объявления о NFP регулярно публикуются по расписанию (обычно в первую пятницу каждого месяца), их легко идентифицировать и согласовать с известными календарными датами. Это делает их идеальными для изучения того, как реагирует цена в течение минут и часов после выхода новостей.

Сверяясь с датами NFP в экономическом календаре и наблюдая за графиками с подробными данными на минутных таймфреймах, связанными с этими событиями, мы можем получить ценную информацию о том, как различные инструменты ведут себя после появления новостей. Такой подход позволяет нам разработать и точно настроить наш инструмент для торговли после воздействия, который дополнит существующую стратегию отложенных ордеров, предоставляя возможности для входа, как только установится первоначальная волатильность и появится четкое направление.

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

Изучение истории движения цены с помощью пользовательского советника

В этом разделе мы разработаем советник (EA) на MQL5, позволяющий "путешествовать во времени" по историческим данным графика с помощью тестера стратегий MetaTrader 5. Цель состоит в том, чтобы вручную наблюдать за изменением цен вскоре после крупных экономических воздействий — в частности, после публикации данных о занятости в несельскохозяйственном секторе (NFP) - и собирать ценную информацию для разработки нашей торговой стратегии «после воздействия».

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

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

Отчет о занятости в несельскохозяйственном секторе США (NFP) является одним из наиболее важных экономических отчетов на финансовых рынках, особенно по валютным парам, включающим доллар США (USD). Его объявление обычно вызывает немедленные и часто резкие колебания цен, что делает его идеальным кандидатом для торговых стратегий как до, так и после выхода новостей. Для тестирования и разработки стратегии наиболее подходящими инструментами являются пары USD-major, такие как EURUSD, GBPUSD, USDJPY и USDCHF, поскольку они наиболее последовательно и существенно реагируют на публикации NFP. Это делает их идеальными испытательными площадками для алгоритмов, нацеленных на использование моделей волатильности, связанных с основными экономическими новостями.

Прежде чем погрузиться в полную логику и функциональность советника NFP_Event_Replay.mq5, важно понять, как начать программировать такой инструмент. В MetaTrader 5 запустите MetaEditor, затем перейдите в меню File/New/Expert Advisor... (template) и укажите имя, например, NFP_Event_Replay. Это позволит создать базовую структуру с функциями OnInit(), OnDeinit() и OnTick(). С этого момента можно начать выстраивать свою логику — начиная с проверки времени, определения дня выхода новостей и инструментов рисования — постепенно превращая каркас в полнофункциональный индикатор исторических событий, который мы рассмотрим в следующих разделах.

В настоящей статье мы рассмотрим каждую часть советника, помогая как начинающим разработчикам, так и разработчикам среднего уровня на MQL5 понять, как программно отображать прошлые события NFP на исторических графиках, используя прямоугольники, временную логику и вычисления с учетом часовых поясов - мощный способ визуального изучения и уточнения торговых стратегий после выхода новостей.

1. Метаданные и вводимые пользователем данные

В начале советника метаданные описывают автора, версию и назначение советника. Ключевая особенность этого инструмента заключается в том, что он помогает трейдерам визуально воспроизводить и изучать поведение рынка NFP (отчёт о занятости в несельскохозяйственном секторе) в тестере стратегий MetaTrader 5. Два пользовательских параметра — MinutesBefore и MinutesAfter — позволяют трейдеру определить размер окна (в минутах) до и после события, в котором будет отображаться изменение цены. Это позволяет настраивать параметры в зависимости от того, насколько сильно меняется цена в связи с выпуском новостей, который вы хотите изучить.

input int MinutesBefore = 5;
input int MinutesAfter = 5;

2. Глобальные переменные и инициализация

Глобальные переменные объявлены для управления именем прямоугольника, отслеживания текущего года и месяца, когда рисунок создан в последний раз, и предотвращения повторных оповещений. Это помогает контролировать логический поток, гарантируя, что прямоугольники не будут повторно нарисованы в один и тот же день и что очистка будет выполнена должным образом во время инициализации и деинициализации.

string rectName = "NFP_Event_Window";
int drawnYear = 0, drawnMonth = 0;
bool alertShown = false;

3. Расчет первой пятницы

Одним из ключевых элементов логики является определение даты первой пятницы каждого месяца. Это важно, поскольку отчет NFP публикуется в первую пятницу каждого месяца. Советник использует календарные вычисления для динамического определения этой даты на основе текущего года и месяца, что позволяет повторно использовать советник в последующие годы без изменений.

//+------------------------------------------------------------------+
//| Calculate day of first Friday                                    |
//+------------------------------------------------------------------+
int GetFirstFriday(int year, int month)
{
    MqlDateTime dt = {0};
    dt.year = year;
    dt.mon = month;
    dt.day = 1;
    datetime first = StructToTime(dt);
    TimeToStruct(first, dt);
    
    // Calculate days to first Friday (5 = Friday)
    int daysToAdd = (5 - dt.day_of_week + 7) % 7;
    return 1 + daysToAdd;
}

4. Проверка IsFirstFriday

Эта функция проверяет, относится ли текущее обрабатываемое значение datetime к первой пятнице месяца. Она полагается на логику предыдущей первой пятницы и сравнивает текущий день и день недели, чтобы определить соответствие требованиям. Эта проверка служит средством предотвращения ненужных вычислений или рисования прямоугольников в дни, не связанные с NFP.

//+------------------------------------------------------------------+
//| Check if date is first Friday                                    |
//+------------------------------------------------------------------+
bool IsFirstFriday(datetime time)
{
    MqlDateTime dt;
    TimeToStruct(time, dt);
    int firstFriday = GetFirstFriday(dt.year, dt.mon);
    return (dt.day_of_week == 5 && dt.day == firstFriday);
}

5. GetTimeGMTOffset

Эта функция определяет местное смещение времени брокера от GMT (UTC) на основе серверного времени. Поскольку события NFP объявляются в США. Восточное время (которое может быть UTC-4 или UTC-5 в зависимости от перехода на летнее время), это смещение необходимо для корректного преобразования временной метки события  в соответствии с часовым поясом брокера и временем на графике.

//+------------------------------------------------------------------+
//| Get UTC offset for a specific time                               |
//+------------------------------------------------------------------+
int GetTimeGMTOffset(datetime time)
{
    MqlDateTime dt;
    TimeToStruct(time, dt);
    datetime timeUTC = StructToTime(dt);
    return (int)(time - timeUTC);
}

6. Инициализация и очистка советника

Когда советник инициализируется (OnInit), он устанавливает 1-секундный таймер, который служит сигналом для постоянной проверки того, находимся ли мы в соответствующей дате NFP. При деинициализации (OnDeinit) он останавливает таймер и удаляет прямоугольный объект, если тот нарисован. Это гарантирует, что сеансы тестирования начнутся чисто и на графике не останется остаточных изображений.

//+------------------------------------------------------------------+
//| Program entry point                                              |
//+------------------------------------------------------------------+
int OnInit()
{
    EventSetTimer(1);
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Cleanup on exit                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    EventKillTimer();
    ObjectDelete(0, rectName);
}

7. OnTimer: Сердце советника

Функция OnTimer является основным исполнительным блоком, вызываемым таймером каждую секунду. Это позволяет избежать избыточной обработки, проверяя изменения текущего времени на графике. Если день является действительной первой пятницей, она вычисляет временную метку выпуска NFP для текущего года и месяца, применяет любое необходимое смещение часового пояса, а затем проверяет, попадает ли текущее время в заданное пользователем прямоугольное окно. Если условия выполнены и изображение за текущий месяц еще не появилось, она рисует прямоугольник события. Кроме того, для лучшей наглядности при тестировании выводятся отладочные сообщения. Вне дней публикации NFP советник сбрасывает переменные отслеживания и удаляет все существующие рисунки.

//+------------------------------------------------------------------+
//| Timer handler - main logic                                       |
//+------------------------------------------------------------------+
void OnTimer()
{
    static datetime lastBarTime = 0;
    datetime now = TimeCurrent();
    
    if(now == lastBarTime) return;
    lastBarTime = now;
    
    MqlDateTime dtNow;
    TimeToStruct(now, dtNow);
    
    // Process only on first Fridays
    if(IsFirstFriday(now))
    {
        // Show alert once per day
        if(!alertShown)
        {
            Alert("NFP Day: Set tester replay speed to 70%");
            alertShown = true;
        }
        
        // Calculate exact NFP release time in UTC
        int releaseDay = GetFirstFriday(dtNow.year, dtNow.mon);
        datetime nfpUTC = GetNFPTimestamp(dtNow.year, dtNow.mon, releaseDay);
        
        // Convert to broker time (Zimbabwe CAT = UTC+2)
        int offset = GetTimeGMTOffset(now);
        datetime nfpBroker = nfpUTC + offset;
        
        // Calculate rectangle boundaries
        datetime startTime = nfpBroker - MinutesBefore*60;
        datetime endTime = nfpBroker + MinutesAfter*60;
        
        // Draw rectangle if in time window
        if(now >= startTime && now <= endTime)
        {
            if(drawnYear != dtNow.year || drawnMonth != dtNow.mon)
            {
                DrawEventWindow(startTime, endTime);
                drawnYear = dtNow.year;
                drawnMonth = dtNow.mon;
                
                // Debug output
                Print("NFP UTC Time: ", TimeToString(nfpUTC, TIME_MINUTES|TIME_SECONDS));
                Print("Broker Time: ", TimeToString(now, TIME_MINUTES|TIME_SECONDS));
                Print("NFP Broker Time: ", TimeToString(nfpBroker, TIME_MINUTES|TIME_SECONDS));
                Print("Event Window: ", TimeToString(startTime), " to ", TimeToString(endTime));
            }
        }
    }
    else
    {
        alertShown = false;
        if(drawnYear != 0 || drawnMonth != 0)
        {
            ObjectDelete(0, rectName);
            drawnYear = 0;
            drawnMonth = 0;
        }
    }
}

8. GetNFPTimestamp: NFP в 8:30 по восточному времени

Эта функция создает точную временную метку UTC для выпуска NFP. Она использует логику перехода на летнее время в США, чтобы определить, следует ли считать время выхода 12:30 UTC (летом) или 13:30 UTC (зимой). Эта точная временная метка необходима для синхронизации окна графика с реальным временем событий.

//+------------------------------------------------------------------+
//| Create precise UTC timestamp for NFP event                       |
//+------------------------------------------------------------------+
datetime GetNFPTimestamp(int year, int month, int day)
{
    MqlDateTime dt = {0};
    dt.year = year;
    dt.mon = month;
    dt.day = day;
    
    // Determine correct UTC hour based on US daylight saving
    // US Eastern Time: EST = UTC-5 (winter), EDT = UTC-4 (summer)
    // NFP always releases at 8:30 AM US Eastern Time
    bool isDst = IsUSDST(StructToTime(dt));
    dt.hour = isDst ? 12 : 13;  // 12:30 UTC (summer) or 13:30 UTC (winter)
    dt.min = 30;
    
    return StructToTime(dt);
}

9. Логика перехода на летнее время

Чтобы учесть изменения при переходе на летнее время в США (DST), эта функция вычисляет, попадает ли данная дата в окно перехода на летнее время. Согласно законодательству США, летнее время начинается во второе воскресенье марта и заканчивается в первое воскресенье ноября. Вычисляя границы для каждого года и сверяя с ними дату, советник динамически адаптирует свои расчеты временных меток в течение всего года.

//+------------------------------------------------------------------+
//| Check if US is in daylight saving time                           |
//+------------------------------------------------------------------+
bool IsUSDST(datetime time)
{
    MqlDateTime dt;
    TimeToStruct(time, dt);
    
    // US DST rules (since 2007):
    // Starts: Second Sunday in March at 2:00 AM
    // Ends: First Sunday in November at 2:00 AM
    
    // Calculate DST start
    datetime dstStart = GetNthDayOfMonth(dt.year, 3, 0, 2) + (2 * 3600);  // Second Sunday in March at 2:00 AM
    // Calculate DST end
    datetime dstEnd = GetNthDayOfMonth(dt.year, 11, 0, 1) + (2 * 3600);    // First Sunday in November at 2:00 AM
    
    return (time >= dstStart && time < dstEnd);
}

10. GetNthDayOfMonth

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

//+------------------------------------------------------------------+
//| Get nth day of week in a month                                   |
//+------------------------------------------------------------------+
datetime GetNthDayOfMonth(int year, int month, int dayOfWeek, int nth)
{
    MqlDateTime dtFirst = {0};
    dtFirst.year = year;
    dtFirst.mon = month;
    dtFirst.day = 1;
    datetime first = StructToTime(dtFirst);
    
    MqlDateTime dt;
    TimeToStruct(first, dt);
    int firstDayOfWeek = dt.day_of_week;
    
    // Calculate days to the first occurrence
    int daysToAdd = (dayOfWeek - firstDayOfWeek + 7) % 7;
    datetime firstOccurrence = first + daysToAdd * 86400;
    
    // Add weeks for nth occurrence
    if(nth > 1)
    {
        firstOccurrence += (nth - 1) * 7 * 86400;
    }
    
    // Verify if still in same month
    TimeToStruct(firstOccurrence, dt);
    if(dt.mon != month)
    {
        // Adjust to last occurrence in month
        firstOccurrence -= 7 * 86400;
    }
    
    return firstOccurrence;
}

11. Рисование прямоугольника на графике

Как только будет определено корректное временное окно для NFP, советник создаст прямоугольник, охватывающий этот период времени. Прямоугольник охватывает весь видимый ценовой диапазон и оформлен с отличными визуальными свойствами, такими как пунктирные границы и светло-голубая заливка фона. Если прямоугольник уже существует с момента предыдущего запуска, он сначала удаляется, чтобы предотвратить наложение или дублирование.

//+------------------------------------------------------------------+
//| Draw the NFP event window on chart                               |
//+------------------------------------------------------------------+
void DrawEventWindow(datetime start, datetime end)
{
    ObjectDelete(0, rectName);
    
    double high = ChartGetDouble(0, CHART_PRICE_MAX);
    double low = ChartGetDouble(0, CHART_PRICE_MIN);
    
    if(ObjectCreate(0, rectName, OBJ_RECTANGLE, 0, start, high, end, low))
    {
        ObjectSetInteger(0, rectName, OBJPROP_COLOR, clrDodgerBlue);
        ObjectSetInteger(0, rectName, OBJPROP_STYLE, STYLE_DASHDOT);
        ObjectSetInteger(0, rectName, OBJPROP_WIDTH, 2);
        ObjectSetInteger(0, rectName, OBJPROP_BACK, true);
        ObjectSetInteger(0, rectName, OBJPROP_FILL, true);
        ObjectSetInteger(0, rectName, OBJPROP_BGCOLOR, C'240,248,255'); // AliceBlue
    }
}

12. OnTick (Заполнитель)

Несмотря на то, что советник предназначен для работы с временными событиями, а не с ценовыми тиками, для полноты и совместимости по-прежнему предусмотрена пустая функция OnTick. В данной реализации она не имеет никакого значения, но требуется структурой советника MetaTrader.

Тестирование воспроизведения NFP_Event

После успешной компиляции полноценного советника из приведенных выше разделов кода мы приступили к тестированию его функциональности в режиме визуализации тестера стратегий в MetaTrader 5. Результаты были впечатляющими — в каждый определенный день выпуска NFP советник точно подсвечивал окно события прямоугольником clrAliceBlue. Этот визуальный маркер позволил нам легко определить динамику цен в период объявления NFP. В частности, сегмент повторов с июня 2024 по декабрь 2024 года наглядно иллюстрирует типичный всплеск волатильности, связанный с NFP, подтверждая, что советник корректно определяет и отмечает период событий. Ниже результатов я собрал некоторые из записанных фрагментов графиков, которые теперь будут проанализированы для разработки надежной торговой стратегии «после воздействия», основанной на поведении цен после выхода NFP.

Strategy Tester-NFP_ Event_Replay.ex5

Тестирование NFP_Event_Replay

Лог тестера:

2025.07.17 19:20:59.343 USDJPY.0: symbol to be synchronized
2025.07.17 19:20:59.346 USDJPY.0: symbol synchronized, 3960 bytes of symbol info received
2025.07.17 19:20:59.347 USDJPY.0: history synchronization started
2025.07.17 19:20:59.514 USDJPY.0: load 31 bytes of history data to synchronize in 0:00:00.013
2025.07.17 19:20:59.514 USDJPY.0: history synchronized from 2024.05.26 to 2025.07.20
2025.07.17 19:20:59.547 USDJPY.0: start time changed to 2024.05.27 00:00 to provide data at beginning
2025.07.17 19:20:59.548 USDJPY.0,M1: history cache allocated for 224402 bars and contains 173 bars from 2024.05.26 21:05 to 2024.05.26 23:59
2025.07.17 19:20:59.548 USDJPY.0,M1: history begins from 2024.05.26 21:05
2025.07.17 19:20:59.563 USDJPY.0,M1 (Deriv-Demo): every tick generating
2025.07.17 19:20:59.563 USDJPY.0,M1: testing of Experts\NFP_Event_Replay.ex5 from 2024.01.01 00:00 to 2024.12.31 00:00 started with inputs:
2025.07.17 19:20:59.563   MinutesBefore=5
2025.07.17 19:20:59.563   MinutesAfter=5
2025.07.17 19:29:59.082 2024.06.07 00:00:00   Alert: NFP Day: Set tester replay speed to 70%
2025.07.17 19:30:02.995 2024.06.07 12:25:00   NFP UTC Time: 12:30:00
2025.07.17 19:30:02.995 2024.06.07 12:25:00   Broker Time: 12:25:00
2025.07.17 19:30:02.995 2024.06.07 12:25:00   NFP Broker Time: 12:30:00
2025.07.17 19:30:02.995 2024.06.07 12:25:00   Event Window: 2024.06.07 12:25 to 2024.06.07 12:35
2025.07.17 19:30:41.055 2024.07.05 00:00:00   Alert: NFP Day: Set tester replay speed to 70%
2025.07.17 19:30:41.717 2024.07.05 12:25:00   NFP UTC Time: 12:30:00
2025.07.17 19:30:41.717 2024.07.05 12:25:00   Broker Time: 12:25:00
2025.07.17 19:30:41.717 2024.07.05 12:25:00   NFP Broker Time: 12:30:00
2025.07.17 19:30:41.717 2024.07.05 12:25:00   Event Window: 2024.07.05 12:25 to 2024.07.05 12:35
2025.07.17 19:30:55.060 2024.08.02 00:00:00   Alert: NFP Day: Set tester replay speed to 70%
2025.07.17 19:30:55.551 2024.08.02 12:25:00   NFP UTC Time: 12:30:00
2025.07.17 19:30:55.551 2024.08.02 12:25:00   Broker Time: 12:25:00
2025.07.17 19:30:55.551 2024.08.02 12:25:00   NFP Broker Time: 12:30:00
2025.07.17 19:30:55.551 2024.08.02 12:25:00   Event Window: 2024.08.02 12:25 to 2024.08.02 12:35
2025.07.17 19:31:15.547 2024.09.06 00:00:00   Alert: NFP Day: Set tester replay speed to 70%
2025.07.17 19:31:16.250 2024.09.06 12:25:00   NFP UTC Time: 12:30:00
2025.07.17 19:31:16.250 2024.09.06 12:25:00   Broker Time: 12:25:00
2025.07.17 19:31:16.250 2024.09.06 12:25:00   NFP Broker Time: 12:30:00
2025.07.17 19:31:16.250 2024.09.06 12:25:00   Event Window: 2024.09.06 12:25 to 2024.09.06 12:35
2025.07.17 19:31:30.214 2024.10.04 00:00:00   Alert: NFP Day: Set tester replay speed to 70%
2025.07.17 19:31:30.699 2024.10.04 12:25:00   NFP UTC Time: 12:30:00
2025.07.17 19:31:30.699 2024.10.04 12:25:00   Broker Time: 12:25:00
2025.07.17 19:31:30.699 2024.10.04 12:25:00   NFP Broker Time: 12:30:00
2025.07.17 19:31:30.699 2024.10.04 12:25:00   Event Window: 2024.10.04 12:25 to 2024.10.04 12:35
2025.07.17 21:23:38.212 2024.11.01 00:00:00   Alert: NFP Day: Set tester replay speed to 70%
2025.07.17 21:23:38.448 2024.11.01 12:25:00   NFP UTC Time: 12:30:00
2025.07.17 21:23:38.448 2024.11.01 12:25:00   Broker Time: 12:25:00
2025.07.17 21:23:38.448 2024.11.01 12:25:00   NFP Broker Time: 12:30:00
2025.07.17 21:23:38.448 2024.11.01 12:25:00   Event Window: 2024.11.01 12:25 to 2024.11.01 12:35
2025.07.17 21:23:47.754 2024.12.06 00:00:00   Alert: NFP Day: Set tester replay speed to 70%
2025.07.17 21:23:47.940 2024.12.06 13:25:00   NFP UTC Time: 13:30:00
2025.07.17 21:23:47.940 2024.12.06 13:25:00   Broker Time: 13:25:00
2025.07.17 21:23:47.940 2024.12.06 13:25:00   NFP Broker Time: 13:30:00
2025.07.17 21:23:47.940 2024.12.06 13:25:00   Event Window: 2024.12.06 13:25 to 2024.12.06 13:35

Анализ событий NFP после воздействия

Советник эффективно помогал нам точно определять дни NFP на основе нашей настроенной логики. В то время как предыдущее анимированное воспроизведение давало краткий обзор, оно не было идеальным для тщательного изучения мелких деталей движения цены из-за высокой скорости воспроизведения. Чтобы решить эту проблему, я собрал ниже серию неподвижных изображений, позволяющих провести более целенаправленный и детальный анализ. Эти снимки дают более четкое представление о реакции рынка на окно вокруг события NFP, облегчая выявление повторяющихся паттернов и проведение мозгового штурма жизнеспособных стратегий для использования движений после воздействия. Просмотрите изображения и прочтите мои мысли прямо под картинками.

NFP June 2024

NFP за июнь 2024 г.

NFP July 2024

NFP за июль 2024 г.

NFP Aug 2024

NFP за август 2024 г.

NFP Sep 2024

NFP за сентябрь 2024 г.

NFP Oct 2024

NFP за октябрь 2024 г.

NFP Nov 2024

NFP за ноябрь 2024 г.

NFP Dec 2024

NFP за декабрь 2024 г.

Приведенный выше набор изображений дает четкое визуальное представление о динамике цен до, во время и после выхода новостей NFP. Эти снимки показывают, как рынки реагируют на такие важные события. Я считаю, что благодаря интеграции машинного обучения и более глубокому анализу исторических данных о важных новостях можно выявить многие скрытые паттерны и торговые возможности. Из результатов, полученных во второй половине 2024 года, можно сделать ключевой вывод: когда две или более японских свечи следовали за первоначальным скачком в одном направлении, цена часто сохраняла этот импульс. Однако в тех случаях, когда такое подтверждение отсутствовало, рынок не мог поддерживать движение, зачастую вместо этого разворачиваясь или консолидируясь.

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

План стратегии

Когда происходит важное новостное событие, оно часто вызывает резкий бычий или медвежий скачок в течение нескольких тиков. В некоторых случаях рынок может быстро протестировать оба направления — вверх и вниз — перед установлением равновесия, что может привести к преждевременным стоп-аутам или непреднамеренному срабатыванию ордеров. Чтобы избежать рисков, связанных с этой начальной волатильностью, данная стратегия фокусируется на открытии сделок вскоре после резкого скачка, когда рынок демонстрирует более четкие намерения. Вход основан на подтверждении условий, которые следуют за событием, а не на ожидании самого движения. Ниже мы описываем как бычью, так и медвежью стратегии, основанные на этом подходе «после воздействия».

Бычья настройка

После бычьего скачка, вызванного важным новостным событием, наша стратегия требует, чтобы прежде чем открывать длинную позицию, две последовательные бычьи свечи отображались в качестве подтверждения. Как только появляются эти подтверждающие свечи, мы открываем сделку на покупку. Диапазон цен, охватываемый двумя свечами, определяет нашу зону риска — это становится основой для установки стоп-лосса. Уровень тейк-профита должен обеспечивать вознаграждение, превышающее риск, при сохранении благоприятного соотношения риска и вознаграждения. В некоторых сценариях такая настройка может также сигнализировать о начале сильного скачка импульса, предлагая потенциал для получения исключительно высокой прибыли, если ее зафиксировать на ранней стадии. На иллюстрации ниже, взятой из визуализации тестера стратегий во время воспроизведения события NFP, показана настройка в действии.

Strategy on Bullish momentum setup

Стратегия «после воздействия» — Настройки бычьего импульса

Медвежья настройка

Медвежья настройка отражает подход, описанный в бычьей настройке выше. Ниже приведено изображение, иллюстрирующее, как обычно проявляется этот паттерн.

Strategy on a Bearish Setup

Стратегия «после воздействия» — Настройки медвежьего импульса

То, что мы сделали выше, - это упражнение по разработке стратегии, основанной на анализе движения цены. Используя возможности MQL5, мы создали уникальный советник, способный воспроизводить и помечать события NFP, что было бы утомительно, отнимало много времени и неэффективно выполнялось вручную. Такой подход позволил нам получить ценную информацию и практические идеи, которые теперь могут быть воплощены в торговой логике. На следующем этапе мы сосредоточимся на реализации торговой стратегии, позволяющей советнику обнаруживать эти настройки и автоматически совершать сделки. Эта новая логика дополнит стратегию отложенных ордеров, которую мы рассматривали ранее, создавая более надежный и универсальный инструмент для торговли на новостях.


Финальная реализация — Интеграция стратегии «после воздействия» в советник «Заголовки новостей»

Чтобы сделать наш советник «Заголовки новостей» более гибким и мощным, следующим логичным шагом является интеграция обеих стратегий — подхода отложенных ордеров и стратегии подтверждения после воздействия - в единую систему. В то время как стратегия отложенных ордеров направлена на то, чтобы зафиксировать первоначальный всплеск волатильности путем размещения сделок непосредственно перед выходом новостей, основанная на подтверждении стратегия позволяет советнику разумно реагировать после того, как рынок обнаружит своё смещение.

Комбинируя оба метода, советник может торговать как на немедленном пробое, так и на последовательном движении, которое часто следует за ним. Такая система двойного подхода повышает гибкость и повышает шансы на получение прибыльных результатов, независимо от того, вызывают ли новости резкий, безошибочный пробой или «качели», за которыми следует более четкий тренд. На этом этапе разработки мы внедрим обе стратегии в логику советника, позволив ему выбирать, чередовать или даже комбинировать их в зависимости от профиля события или пользовательских настроек.

Давайте перейдем к следующим шагам: разделим приведенный ниже код на разделы, подробно объяснив каждый раздел и показав, как именно недавно добавленные строки интегрируются с существующими модулями и общей стратегией.

Шаг 1: Конфигурация входных данных «после воздействия»

В самом верху советника мы вводим специальный блок входных параметров, позволяющий пользователю включать или отключать стратегию «после воздействия» и корректировать ее поведение. В MQL5 входные данные определяют константу времени компиляции, которую трейдеры могут настроить в диалоговом окне свойств советника. Здесь логический флажок включает или выключает функцию, в то время как цифровые входные данные указывают временной интервал до события (минуты до и после), минимальную величину скачка в пипсах, количество требуемых баров подтверждения, буфер за пределами контрольного максимума или минимума и желаемое соотношение прибыли к риску. Такой дизайн делает стратегию легко настраиваемой без изменения самого кода.

//--- POST-IMPACT STRATEGY INPUTS -------------------------------------
input bool   InpEnablePostImpact       = false;  // Enable post-impact market orders
input int    InpPostImpactBeforeMin    = 0;      // Minutes before event to start window
input int    InpPostImpactAfterMin     = 5;      // Minutes after event to end window
input double InpSpikeThresholdPipsPI   = 20.0;   // Minimum pip spike magnitude
input int    InpConfirmBarsPI          = 2;      // Number of confirming bars
input double InpBufferPipsPI           = 5.0;    // Buffer beyond reference high/low
input double InpRR_PIP                 = 2.0;    // Desired reward:risk ratio

Шаг 2: Глобальные объекты переменных состояния

Чтобы управлять жизненным циклом функции, мы объявляем несколько глобальных переменных. Такие флаги, как postImpactPlaced и postRectDrawn, гарантируют, что мы выделим наш график и разместим рыночный ордер только один раз за событие. Мы присваиваем прямоугольному объекту уникальный строковый идентификатор, чтобы можно было надежно создавать его, ссылаться на него и удалять. Кроме того, мы создаем отдельный объект CTrade, который предоставляет советнику встроенные торговые методы (Buy(), Sell() и т.д.) для программного исполнения ордеров.

// Trade object & post-impact state
CTrade  trade;
bool    postImpactPlaced = false;          // Ensures only one post-impact trade
string  postRectName     = "PostImpact_Window";  // Unique object name
bool    postRectDrawn    = false;          // Ensures rectangle drawn once

Шаг 3: Сброс состояния в ReloadEvents()

Всякий раз, когда советник обновляет список предстоящих экономических событий, он вызывает ReloadEvents(). В конце этой процедуры мы сбрасываем все флаги состояния «после поздействия» и удаляем все существующие прямоугольные объекты. Такой подход “с чистого листа” гарантирует, что каждое новое событие обрабатывается независимо, что позволяет избежать остаточных артефактов или дублирования сделок с предыдущих событий.

// Inside ReloadEvents(), after nextEventTime is computed:
ordersPlaced      = false;
postImpactPlaced  = false;
postRectDrawn     = false;
ObjectDelete(0, postRectName);  // Remove any old rectangle

Шаг 4: Рисование окна «после воздействия»

В главном обработчике таймера (OnTimer()), как только текущее серверное время попадает в заданное пользователем окно вокруг важного события, мы рисуем полупрозрачный прямоугольник на графике. Мы извлекаем из графика видимые максимумы и минимумы цен, затем используем функции управления объектами MQL5 для создания и стилизации OBJ_RECTANGLE. Логический флаг гарантирует, что это рисование произойдет только один раз, что делает событие визуально заметным без перерисовки при каждом тике.

// In OnTimer(), when now ∈ [evt - BeforeMin, evt + AfterMin]
if(!postRectDrawn && now >= winStart && now <= winEnd)
{
   double hi = ChartGetDouble(0, CHART_PRICE_MAX);
   double lo = ChartGetDouble(0, CHART_PRICE_MIN);
   ObjectCreate(0, postRectName, OBJ_RECTANGLE, 0, winStart, hi, winEnd, lo);
   ObjectSetInteger(0, postRectName, OBJPROP_COLOR, clrOrange);
   ObjectSetInteger(0, postRectName, OBJPROP_STYLE, STYLE_DASH);
   ObjectSetInteger(0, postRectName, OBJPROP_BACK,  true);
   ObjectSetInteger(0, postRectName, OBJPROP_FILL,  true);
   postRectDrawn = true;
}

Шаг 5: Обнаружение резких скачков цен при размещении рыночных ордеров

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

// In OnTimer(), once now > winEnd and !postImpactPlaced
int barIdx = iBarShift(_Symbol, PERIOD_M1, evt, true);
if(barIdx >= 0)
{
   double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT), pip = point*10.0;
   double o = iOpen(_Symbol,PERIOD_M1,barIdx), c = iClose(_Symbol,PERIOD_M1,barIdx);
   double spike = (c - o)/pip;
   if(MathAbs(spike) >= InpSpikeThresholdPipsPI)
   {
      bool bullish = (c > o), ok = true;
      for(int i=1; i<=InpConfirmBarsPI; i++)
      {
         double oi = iOpen(_Symbol,PERIOD_M1,barIdx-i), ci = iClose(_Symbol,PERIOD_M1,barIdx-i);
         if(bullish ? (ci <= oi) : (ci >= oi)) { ok=false; break; }
      }
      if(ok)
      {
         int entryBar = barIdx - InpConfirmBarsPI - 1;
         double entry = iOpen(_Symbol,PERIOD_M1,entryBar);
         double refP  = bullish ? iLow(_Symbol,PERIOD_M1,barIdx-1)
                                : iHigh(_Symbol,PERIOD_M1,barIdx-1);
         double sl   = bullish ? refP - InpBufferPipsPI*pip : refP + InpBufferPipsPI*pip;
         double rr   = MathAbs(entry - sl);
         double tp   = bullish ? entry + rr*InpRR_PIP : entry - rr*InpRR_PIP;
         postImpactPlaced = true;
         trade.SetExpertMagicNumber(888888);
         trade.SetDeviationInPoints(5);
         if(bullish)
            trade.Buy(InpOrderVolume, _Symbol, entry, sl, tp, "PostImpact Buy");
         else
            trade.Sell(InpOrderVolume, _Symbol, entry, sl, tp, "PostImpact Sell");
      }
   }
}

Полностью интегрированный, компактный исходный код, включающий все функции, представлен в конце данной статьи и готов к компиляции. Теперь можно перейти к разделу тестирования.


Тестирование

Полностью интегрированный советник «Заголовки новостей» не удалось должным образом протестировать в тестере стратегий, поскольку тестер не поддерживает календарь и новостные ленты в режиме реального времени. Режим воспроизведения с помощью комбинированного советника не давал значимых сигналов, поэтому я перенес логику ордеров post‑impact в специальный советник NFP_Event_Replay. Используя фреймворк воспроизведения, в котором данные о занятости в несельскохозяйственном секторе моделируются на основе исторических данных, я смог быстро проверить поведение стратегии при входе, стоп—лоссе и тейк‑профите, не дожидаясь важных объявлений в реальном времени. Приведенная ниже анимация, взятая из тестера стратегий, демонстрирует, что логика «после воздействия» работает точно так, как задумано, в контролируемых, воспроизводимых условиях. Ознакомьтесь со второй версией NFP_Event_Replay с полной торговой логикой, приведенной в конце статьи.

Post-impact strategy test result

Результаты тестирования стратегии «после воздействия» в отношении выпуска новостей об NFP в первую пятницу июля 2024 года

New Headline EA with Post Impact Order Execution

Советник «Заголовки новостей» исполнением ордеров «после воздействия»


Заключение

Мы только что завершили еще одно углубленное образовательное исследование ‑ на этот раз интегрировали торговую стратегию «после воздействия» в наш советник «Заголовки новостей», а затем проверили ее с помощью фреймворка NFP_Event_Replay. Торгуя сразу после выхода важных новостей, мы применим настройки с большей вероятностью: первоначальный всплеск волатильности прошел, цена “установилась”, а подтверждающие бары дают нам ясность в отношении направления и силы. Этот подход органично сочетается с другими нашими тактиками, основанными на новостях, делая советника более универсальным и надежным.

Более того, те же методы, которые мы использовали здесь — систематическое обнаружение событий, фильтры скачков на основе пипсов, мультибарное подтверждение и управление соотношением прибыли и риска, ‑ можно усовершенствовать с помощью машинного обучения или ИИ. Представьте себе модель, которая адаптирует свой порог скачков или правила подтверждения на основе исторических показателей успешности для различных валют или типов новостей. У нас есть достаточно возможностей для доработки каждой созданной нами функции, будь то визуализация на графике, оповещения или автоматическое размещение ордеров. И, конечно, несмотря на то, что мы сосредоточились на NFP для обеспечения точности анализа на истории и скорости тестирования в тестере стратегий, этот инструмент по-прежнему полезен и для реальной торговли NFP.

С удовольствием выслушаю ваши отзывы! Поделитесь своим опытом, идеями или вопросами в комментариях ниже. Вместе мы сможем продолжить упрощать разработку на MQL5 и создавать все более мощные, удобные для трейдера алгоритмические инструменты.


Основные уроки

Урок Описание
1. Торговля «после воздействия» Торговать сразу после выхода важных новостей вполне возможно, и это может повысить вероятность выигрыша, если подождать, пока спадет первоначальная волатильность.
2. Обнаружение событий на основе времени Использование функций даты и времени MQL5 для программного определения местоположения определенных событий календаря, таких как первая пятница каждого месяца (день NFP), и приведения логики в соответствие с реальными планами-графиками.
3. Визуализация тестера стратегий Создание визуальных элементов, таких как прямоугольники и линии, для обозначения исторических окон во время тестирования на истории, что улучшает ручную оценку стратегии без использования внешних инструментов.
4. Динамическое рисование объектов Использование ObjectCreate() и ObjectSetInteger() для динамической отрисовки объектов диаграммы на основе вычисленного времени и значений, что позволяет отслеживать события и получать визуальную обратную связь.
5. Работа в режиме реального времени в сравнении с режимом тестирования Использование MQLInfoInteger(MQL_TESTER) позволяет различать тестер стратегий и исполнение в режиме реального времени, позволяя настраивать логические пути для тестирования и производственных сред.
6. Управление сделками посредством CTrade Интеграция класса CTrade для безопасного и структурированного размещения ордеров, определения стоп-лосса, тейк-профита и отмены ордеров в стратегиях как «до воздействия», так и «после воздействия».
7. Логика подтверждения «после воздействия» Создание отложенных торговых позиций на основе подтверждения свечами после сильных скачков - более безопасная и управляемая правилами альтернатива мгновенному исполнению.
8. Пользовательская настройка входных параметров Использование входных переменных позволяет пользователям контролировать, какие стратегии активны, сколько свечей подтверждения требуется и какие уровни влияния событий должны запускать логику.
9. Интеграция API Calendar Использование встроенных функций календаря MQL5 (CalendarValueHistory, CalendarEventById и т.д.) для работы с предстоящими экономическими событиями без зависимостей от внешних API.
10. Рендеринг пользовательского интерфейса на основе Canvas Использование класса CCanvas для создания пользовательских интерфейсов прокрутки экономических новостей, технических индикаторов и аналитических данных, основанных на ИИ, непосредственно отображаемых на графике.
11. Разработка гибридной стратегии Объединение отложенных ордеров «до воздействия» и реактивных сделок «после воздействия» в единую систему советников с условиями выполнения обеспечивает гибкость и адаптивность к различным рыночным условиям.

Содержимое вложения

Имя файла Версия Описание
NFP_Event_Replay.mq5 1.0 Визуальный инструмент тестер стратегий, который помечает окна событий NFP прямоугольниками на основе исторической логики первой пятницы и перехода на летнее время в США. Помогает вручную анализировать реакцию цен во время важных новостных событий.
News_Headline_EA.mq5 1.11 Советник с экономическим календарем в режиме реального времени с прокруткой событий, заголовками новостей Alpha Vantage, аналитикой с использованием ИИ и логикой исполнения двойной стратегии как для отложенных ордеров, так и для сделок с подтверждением после воздействия. Включает совместимость NFP replay во время тестирования.
NFP_Event_Replay.mq5 1.01 Вторая версия советника NFP replay, теперь содержащая полную логику исполнения ордеров «после воздействия».

К содержанию

Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/18817

Прикрепленные файлы |
Нейросети в трейдинге: Единый взгляд на пространство и время (Окончание) Нейросети в трейдинге: Единый взгляд на пространство и время (Окончание)
Фреймворк Extralonger демонстрирует уникальную способность интегрировать пространственные и временные факторы в единую модель, обеспечивая высокую точность прогнозов. Его архитектура позволяет адаптироваться к разным горизонтам планирования и финансовым инструментам, сохраняя прозрачность и управляемость системы.
Арбитражная алготорговля на теории графов Арбитражная алготорговля на теории графов
В рамках статьи треугольный арбитраж представляется как задача поиска циклов в ориентированном графе, где вершины — валюты, рёбра — валютные пары с весами-курсами. Прибыльный цикл: произведение весов >1. Созданные нами алгоритмы Floyd-Warshall и DFS находят оптимальные пути обмена валют, возвращающиеся в исходную точку с прибылью.
От новичка до эксперта: Советник Reporting EA - Настройка рабочего процесса От новичка до эксперта: Советник Reporting EA - Настройка рабочего процесса
Брокерские конторы часто предоставляют отчеты по торговым счетам через регулярные промежутки, основанные на заранее определенном графике. Эти фирмы, используя свои технологии API, имеют доступ к активности на вашем аккаунте и торговой истории, что позволяет им создавать отчеты о результатах работы от вашего имени. Аналогичным образом, терминал MetaTrader 5 хранит подробные записи о вашей торговой активности, которые можно использовать с помощью MQL5 для создания полностью настраиваемых отчетов и определения персонализированных способов доставки.
Возможности Мастера MQL5, которые вам нужно знать (Часть 52): Осциллятор Accelerator Возможности Мастера MQL5, которые вам нужно знать (Часть 52): Осциллятор Accelerator
Осциллятор ускорения (Accelerator Oscillator) — еще один индикатор Билла Вильямса, который отслеживает ускорение ценового импульса, а не только его темп. Хотя он во многом похож на осциллятор Awesome, который мы рассматривали в недавней статье, он стремится избежать эффектов запаздывания, концентрируясь на ускорении, а не только на скорости. Мы, как обычно, рассмотрим паттерны индикатора, а также их значение в торговле с помощью советника, собранного в Мастере.