MQL4 Spread Filter: Защита от расширения спреда во время новостей

MQL4 Spread Filter: Защита от расширения спреда во время новостей MQL4 / MQL5 (MetaTrader)
Подробное руководство по реализации функции Spread Filter в MQL4 для защиты торговых операций от неблагоприятного расширения спреда во время выхода макроэкономических новостей. Узнайте, как избежать убытков из-за волатильности.
Суть: Реализация функции защиты от расширения спреда (Spread Filter) в MQL4 позволяет автоматически блокировать торговые операции, когда текущий спред превышает заданный максимально допустимый порог. Это критически важно во время выхода макроэкономических новостей, когда спред может резко увеличиваться, приводя к проскальзываниям и убыткам.

Исходный код

Представляем реализацию Spread Filter для MQL4. Данный код включает в себя функцию IsSpreadAcceptable(), которая проверяет текущий спред на соответствие заданному лимиту, и функцию-заглушку IsNearNewsEvent(), демонстрирующую, как можно было бы интегрировать логику определения близости к новостному событию. В MQL4 нет встроенных средств для парсинга экономического календаря, поэтому для полноценной работы с новостями потребуется внешний источник данных или ручное управление. Для MQL5 эта задача значительно упрощается, как описано в нашей статье: MQL5: Парсинг Экономического Календаря Встроенными Средствами.

Основная функция CanTrade() объединяет эти проверки, позволяя вашему торговому роботу принимать решение о входе в сделку.


//+------------------------------------------------------------------+
//|                                                    SpreadFilter.mq4|
//|                                                     FinFluct.com |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "FinFluct.com"
#property link      "https://finfluct.com"
#property version   "1.00"
#property strict

//--- Входные параметры для Spread Filter
extern double MaxAllowedSpreadPips = 3.0; // Максимально допустимый спред в пунктах (пипсах)
extern int    NewsEventTimeWindowMinutes = 15; // Окно вокруг новости, в течение которого фильтр активен (в минутах)
extern bool   EnableSpreadFilter = true; // Включить/выключить фильтр спреда

//+------------------------------------------------------------------+
//| Проверяет, является ли текущий спред приемлемым.                 |
//| Возвращает true, если спред <= MaxAllowedSpreadPips, иначе false.|
//+------------------------------------------------------------------+
bool IsSpreadAcceptable()
{
    if (!EnableSpreadFilter)
    {
        return true; // Фильтр выключен, спред всегда приемлем
    }

    double currentAsk = MarketInfo(Symbol(), MODE_ASK);
    double currentBid = MarketInfo(Symbol(), MODE_BID);
    double pointValue = MarketInfo(Symbol(), MODE_POINT);

    if (pointValue == 0) // Защита от деления на ноль или некорректных данных
    {
        Print("Error: MODE_POINT is zero. Cannot calculate spread.");
        return false;
    }

    double currentSpreadPoints = (currentAsk - currentBid) / pointValue;

    // Корректировка спреда в пипсах в зависимости от количества знаков после запятой
    int digits = (int)MarketInfo(Symbol(), MODE_DIGITS);
    double spreadInPips;

    if (digits == 5 || digits == 3) // 5-значный брокер (или 3-значный для JPY)
    {
        spreadInPips = currentSpreadPoints / 10.0; // 10 пунктов = 1 пипс
    }
    else // 4-значный брокер (или 2-значный для JPY)
    {
        spreadInPips = currentSpreadPoints; // 1 пункт = 1 пипс
    }

    if (spreadInPips > MaxAllowedSpreadPips)
    {
        Print("Spread Filter: Current spread (", spreadInPips, " pips) exceeds maximum allowed (", MaxAllowedSpreadPips, " pips). Trading blocked.");
        return false;
    }

    return true;
}

//+------------------------------------------------------------------+
//| Проверяет, находимся ли мы в окне вокруг новостного события.     |
//| В MQL4 нет встроенного календаря, поэтому это заглушка.          |
//| Для полноценной работы требуется внешний источник данных.        |
//+------------------------------------------------------------------+
bool IsNearNewsEvent()
{
    // --- ЗАГЛУШКА --- 
    // В MQL4 нет встроенного способа получить данные экономического календаря.
    // Для полноценной работы здесь потребуется:
    // 1. Внешний источник данных (например, через WebRequest к API календаря).
    // 2. Ручное обновление списка новостей.
    // 3. Использование DLL для парсинга.

    // Для демонстрации, предположим, что у нас есть некий "флаг" новости,
    // или мы просто проверяем время, если знаем о новости заранее.
    // Например, если мы знаем, что важная новость будет в 15:30 UTC.
    // В реальном EA, "newsTime" должно динамически загружаться из календаря.
    datetime currentTime = TimeCurrent();
    // Пример: время важной новости (замените на реальное или динамическое значение)
    datetime newsTime = StrToTime("2023.10.26 15:30"); 

    // Проверяем, находится ли текущее время в пределах NewsEventTimeWindowMinutes
    if (currentTime >= newsTime - NewsEventTimeWindowMinutes * 60 &&
        currentTime <= newsTime + NewsEventTimeWindowMinutes * 60)
    {
        Print("Spread Filter: Near a news event. Activating spread check.");
        return true;
    }

    // --- КОНЕЦ ЗАГЛУШКИ ---

    return false;
}

//+------------------------------------------------------------------+
//| Главная функция фильтра спреда, объединяющая проверки.           |
//| Вызывается перед каждой торговой операцией.                      |
//+------------------------------------------------------------------+
bool CanTrade()
{
    if (!EnableSpreadFilter)
    {
        return true; // Фильтр выключен, торговля разрешена
    }

    // Логика: если фильтр включен, всегда проверяем спред.
    // Функция IsNearNewsEvent() может быть использована для дополнительной
    // логики, например, для ужесточения MaxAllowedSpreadPips во время новостей
    // или для вывода предупреждений.
    
    // Пример использования IsNearNewsEvent для динамического изменения порога:
    // if (IsNearNewsEvent()) {
    //     // Временно уменьшаем MaxAllowedSpreadPips для большей осторожности
    //     double tempMaxSpread = MaxAllowedSpreadPips * 0.5; // Например, вдвое строже
    //     // Но для простоты текущей реализации, мы просто вызываем IsSpreadAcceptable()
    //     // с основным параметром, а IsNearNewsEvent() служит для индикации.
    // }

    return IsSpreadAcceptable();
}

//+------------------------------------------------------------------+
//| Пример использования в OnInit (для демонстрации)                 |
//+------------------------------------------------------------------+
int OnInit()
{
    if (EnableSpreadFilter)
    {
        Print("Spread Filter Enabled. Max Allowed Spread: ", MaxAllowedSpreadPips, " pips.");
        Print("News Event Time Window: ", NewsEventTimeWindowMinutes, " minutes.");
    }
    else
    {
        Print("Spread Filter Disabled.");
    }
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Пример использования в OnTick                                    |
//+------------------------------------------------------------------+
void OnTick()
{
    // ... ваш торговый алгоритм ...

    if (CanTrade())
    {
        // ... выполнять торговые операции ...
        // Например: OrderSend(...)
        // Print("Spread is acceptable. Ready to trade.");
    }
    else
    {
        // ... не выполнять торговые операции ...
        // Print("Spread is too wide or filter is active near news. Trading blocked.");
    }

    // ... остальная логика OnTick ...
}

Разбор параметров

  • MaxAllowedSpreadPips: Этот параметр определяет максимально допустимый спред в пипсах (пунктах), при котором разрешена торговля. Если текущий спред превышает это значение, функция CanTrade() вернет false, блокируя торговые операции. Рекомендуется устанавливать это значение исходя из среднего спреда по инструменту и вашей толерантности к риску.
  • NewsEventTimeWindowMinutes: Задает временное окно в минутах до и после предполагаемого выхода важной новости. В течение этого окна функция IsNearNewsEvent() (в случае полноценной реализации с парсингом календаря) будет сигнализировать о близости новости, что может быть использовано для активации или ужесточения фильтра спреда.
  • EnableSpreadFilter: Булевый флаг, позволяющий включать или отключать Spread Filter целиком. Если установлен в false, фильтр не будет влиять на торговые операции.

Как запустить

Для интеграции Spread Filter в ваш торговый робот на MQL4 выполните следующие шаги:

  1. Создайте новый файл: Откройте MetaEditor (F4), перейдите в меню 'File' -> 'New' -> 'Custom Indicator' (или 'Expert Advisor' если это основной файл вашего робота). Назовите его, например, SpreadFilter.mq4.
  2. Вставьте код: Скопируйте предоставленный выше исходный код и вставьте его в созданный файл.
  3. Компиляция: Сохраните файл (Ctrl+S) и скомпилируйте его (F7). Убедитесь, что нет ошибок.
  4. Интеграция в ваш EA: В вашем основном файле эксперта (.mq4) добавьте директиву #include в начале файла, чтобы подключить функции фильтра:
    
    #include "SpreadFilter.mq4"
    
  5. Использование в торговой логике: Перед каждой попыткой открытия или модификации ордера, вызовите функцию CanTrade(). Если она возвращает true, продолжайте торговые операции; если false, воздержитесь от торговли.

    
    void OnTick()
    {
        // ... ваш торговый алгоритм ...
    
        if (CanTrade())
        {
            // Условия для открытия сделки выполнены И спред приемлем
            // OrderSend(Symbol(), OP_BUY, ...);
        }
        else
        {
            // Спред слишком широк или фильтр активен, торговля заблокирована
            // Можно добавить логирование или уведомления
        }
    }
    
  6. Настройка параметров: Параметры MaxAllowedSpreadPips, NewsEventTimeWindowMinutes и EnableSpreadFilter будут доступны во вкладке 'Inputs' вашего эксперта. Настройте их в соответствии с вашей торговой стратегией и толерантностью к риску.

Для более продвинутой фильтрации сигналов, особенно в условиях высокой волатильности, рассмотрите возможность использования методов машинного обучения, таких как K-Means, для кластеризации и отсеивания ложных сигналов. Подробнее об этом можно прочитать здесь: K-Means в MQL5: Фильтрация ложных сигналов MACD | FinFluct.

Также, для получения уведомлений о срабатывании фильтра или других важных событиях, вы можете интегрировать Telegram API в ваш MQL-робот: MQL5 и Telegram API: Отправка скриншотов при активации отложенных ордеров.

Оцените статью
FinFluct