Исходный код
Представляем реализацию 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 выполните следующие шаги:
- Создайте новый файл: Откройте MetaEditor (F4), перейдите в меню 'File' -> 'New' -> 'Custom Indicator' (или 'Expert Advisor' если это основной файл вашего робота). Назовите его, например,
SpreadFilter.mq4. - Вставьте код: Скопируйте предоставленный выше исходный код и вставьте его в созданный файл.
- Компиляция: Сохраните файл (Ctrl+S) и скомпилируйте его (F7). Убедитесь, что нет ошибок.
- Интеграция в ваш EA: В вашем основном файле эксперта (
.mq4) добавьте директиву#includeв начале файла, чтобы подключить функции фильтра:#include "SpreadFilter.mq4" - Использование в торговой логике: Перед каждой попыткой открытия или модификации ордера, вызовите функцию
CanTrade(). Если она возвращаетtrue, продолжайте торговые операции; еслиfalse, воздержитесь от торговли.void OnTick() { // ... ваш торговый алгоритм ... if (CanTrade()) { // Условия для открытия сделки выполнены И спред приемлем // OrderSend(Symbol(), OP_BUY, ...); } else { // Спред слишком широк или фильтр активен, торговля заблокирована // Можно добавить логирование или уведомления } } - Настройка параметров: Параметры
MaxAllowedSpreadPips,NewsEventTimeWindowMinutesиEnableSpreadFilterбудут доступны во вкладке 'Inputs' вашего эксперта. Настройте их в соответствии с вашей торговой стратегией и толерантностью к риску.
Для более продвинутой фильтрации сигналов, особенно в условиях высокой волатильности, рассмотрите возможность использования методов машинного обучения, таких как K-Means, для кластеризации и отсеивания ложных сигналов. Подробнее об этом можно прочитать здесь: K-Means в MQL5: Фильтрация ложных сигналов MACD | FinFluct.
Также, для получения уведомлений о срабатывании фильтра или других важных событиях, вы можете интегрировать Telegram API в ваш MQL-робот: MQL5 и Telegram API: Отправка скриншотов при активации отложенных ордеров.




