Три фильтра MACD на US_TECH100: Тестирование на данных брокера за пять лет
Введение
Я анализирую графики уже более двадцати лет, а программирую на MQL5 — около десяти. Мне потребовалось почти десять лет программирования, чтобы почувствовать, что я действительно понимаю, чем занимаюсь, а не просто копирую шаблоны из чужого кода. Два года назад у меня словно что-то щелкнуло, и с тех пор я начал создавать собственные инструменты, а не покупать готовые.
Меня годами беспокоило, как часто продавцы предлагают "улучшенные" индикаторы MACD, просто добавляя фильтры к классической логике пересечения MACD. Они добавляют фильтры рыночного режима, согласование со старшим таймфреймом и сессионные окна. Рекламное обещание всегда одно и то же: эти фильтры превращают "шумный" MACD в надежную систему. За эти годы я приобрел несколько таких продуктов и изучил их результаты. Я подозревал, что большую часть улучшений либо показывали на выборочно отобранных примерах, либо фильтры давали меньше, чем обещала реклама.
Поэтому я использовал реальные данные брокера по US_TECH100 на таймфрейме H1, запустил стратегию пересечения MACD без фильтров, а затем добавлял каждый фильтр по одному, чтобы измерить его влияние на результаты. Ни мнений, ни интерпретаций — только результаты по закрытым сделкам, процент прибыльных сделок и математическое ожидание за пятилетний период.
Результат меня удивил. Фильтр, о котором меньше всего говорят, сильнее всего повлиял на результат. Два из трех "стандартных" фильтров почти ничего не меняли при отдельном использовании. Ниже приведена полная разбивка с кодом MQL5, чтобы вы могли воспроизвести результаты на своих данных.
Эта статья предназначена для двух категорий читателей: трейдеров, только начинающих знакомиться с систематическим анализом, и разработчиков, которым нужны полная реализация на MQL5 и результаты. Обе группы должны прийти к одному выводу: применительно к этому конкретному инструменту и таймфрейму общепринятое мнение о фильтрах MACD не подтверждается данными.
Исходные условия
Данные получены от AvaTrade и экспортированы в CSV с помощью скрипта для детального проверяемого экспорта данных, который считывает их напрямую из H1-потока котировок брокера. Период: c апреля 2021 года по апрель 2026 года. Общее количество баров: 29 646. Символ: US_TECH100, CFD на Nasdaq-100.
Использование именно нативных данных брокера важнее, чем думает большинство людей. Если проводить тестирование на исторических данных сторонних источников, а затем торговать в реальном времени у другого брокера, разницу между результатами часто объясняют проскальзыванием или спредами. На самом деле значительная часть разницы обусловлена различиями в потоках котировок. Эти различия включают построение баров, гэпы выходного дня и паттерны внутридневного шума. Чтобы этого избежать, во всех тестах статьи используются данные, экспортированные напрямую из потока котировок брокера, у которого будет выполняться реальная торговля.
Базовая стратегия намеренно сведена к минимуму:
- покупать, когда гистограмма MACD переходит из отрицательной зоны в положительную;
- продавать, когда гистограмма MACD переходит из положительной зоны в отрицательную;
- стоп-лосс — 2,5 × 14-периодный ATR;
- тейк-профит — 3,0 × 14-периодный ATR;
- максимальный период удержания — 48 баров, если не сработали ни SL, ни TP, закрывать по рынку.
Параметры MACD — классические: 12-26-9. Ничего экзотического. Цель этого упражнения — измерить добавочный эффект каждого фильтра на базовую стратегию, а не оптимизировать ее.
Я нормализую риск на сделку до 1R, чтобы сравнивать результаты более чем по 2 000 сделок без искажений, связанных с размером позиции. При срабатывании тейк-профита (TP) результат составляет +1,2R, 3,0 ATR против SL 2,5 ATR; при срабатывании стоп-лосса (SL) — -1,0R. Таким образом, сравнение конфигураций показывает, какой набор фильтров дает лучший поток сделок с поправкой на риск, независимо от размера счета или кредитного плеча.
Четыре протестированные конфигурации
Я последовательно протестировал четыре варианта конфигурации:
- MACD без фильтров — каждое пересечение MACD является сигналом, фильтры отсутствуют;
- фильтр рыночного режима — торговать только при режиме TREND или NORMAL, но не RANGE или VOLATILE; классификация выполняется по ADX и скользящим процентилям ATR;
- фильтр рыночного режима + согласование со старшим таймфреймом (HTF) — фильтр режима и требование согласования цены с долгосрочным трендом (выше EMA200 для покупок и ниже EMA200 для продаж);
- фильтр рыночного режима + HTF + сессионный фильтр — предыдущие фильтры и требование, чтобы сигнал возникал в основные часы американской торговой сессии, с 14:00 до 20:00 по времени брокера, что охватывает основную торговую сессию NYSE.
Каждая конфигурация дополняет предыдущую. Таким образом, в конфигурации 4 все три фильтра активны одновременно. Такая поэтапная структура важна: она позволяет изолировать добавочный эффект каждого фильтра, а не тестировать их как единый пакет.
Распространенная ошибка в исследованиях, поддержанных продавцами, — сравнивать "исходную стратегию со всем набором фильтров" и представлять разницу как доказательство эффективности набора фильтров. Это не позволяет понять, какой именно фильтр в наборе дает эффект. Возможно, один фильтр обеспечивает все статистическое преимущество, а остальные имеют лишь косметический характер. Или фильтры могут взаимно компенсировать друг друга, и значение будет иметь только один из них. Добавляя их по одному, можно точно увидеть вклад каждого фильтра.
Результаты — полное сравнение
Ниже приведена полная таблица с данными за пять лет по тому же инструменту и с той же логикой входа: меняются только фильтры.
| Конфигурация | Сделки | Процент выигрышных сделок | Математическое ожидание | Профит-фактор | Максимальная просадка |
|---|---|---|---|---|---|
| MACD без фильтров | 2 213 | 46,5 % | +0,017R | 1,03 | -28,8R |
| + фильтр рыночного режима | 1 634 | 46,1 % | +0,013R | 1,02 | -33,4R |
| + фильтр рыночного режима + HTF | 794 | 45,8 % | +0,007R | 1,01 | -29,6R |
| + фильтр рыночного режима + HTF + сессионный фильтр | 195 | 50,3 % | +0,100R | 1,20 | -9,7R |
Поясню, что это означает для трейдера, читающего эту таблицу.
MACD без фильтров на US_TECH100 не так плох, как его иногда представляют. При стопах 2,5/3,0 ATR за пять лет стратегия дает едва положительное математическое ожидание +0,017R на сделку и профит-фактор чуть выше порога безубыточности. На этом, конечно, не разбогатеешь, но и чистым шумом это тоже не назовешь. Это честная отправная точка, о которой многие продавцы в рекламных презентациях предпочитают умалчивать.
Само по себе добавление фильтра рыночного режима практически ничего не изменило. Фильтр исключил 579 сделок, 26% потока, однако у оставшихся сделок схожий процент прибыльных сделок и близкое математическое ожидание. Максимальная просадка даже немного ухудшилась. Это неприятный результат, но именно его показывают данные. Это противоречит утверждениям многих продавцов о фильтрах рыночного режима.
Добавление согласования со старшим таймфреймом поверх фильтра рыночного режима снова немного ухудшило результат. Исключаются еще 840 сделок, а математическое ожидание снижается до +0,007R, что фактически соответствует уровню безубыточности. Правило "торговать по тренду" здесь не добавило торгового преимущества, по крайней мере на H1 при использовании EMA200 для определения тренда.
Именно сессионный фильтр изменил все. Ограничение торговли основной сессией США исключило еще 599 сделок, в результате чего за пять лет осталось всего 195 сделок, около 40 в год. Однако у этих 195 сделок математическое ожидание +0,100R, профит-фактор 1,20 и максимальная просадка в три раза меньше, чем у версии без фильтров.

Рисунок 1. Накопленные R-множители для четырех конфигураций за пять лет данных US_TECH100 на H1
Кривые эквити наглядно иллюстрируют это. Обратите внимание, что MACD без фильтров, серый, и две промежуточные конфигурации, светло-синяя и синяя, дают схожую форму кривой: неровную, с глубокими просадками и лишь незначительно положительным результатом за весь период. Кривая с сессионным фильтром, темно-синяя, ведет себя иначе: она более плавная, с меньшими просадками и меньшим числом сделок, но вклад каждой сделки выше.

Рисунок 2. Количество сделок, процент выигрышных сделок и математическое ожидание на сделку для четырех конфигураций
Разбивка по рыночным режимам, о которой никто не говорит
Когда я сделал разбивку результатов MACD без фильтров по рыночным режимам, я обнаружил нечто, что еще сильнее противоречит общепринятому мнению. Вот как MACD без фильтров показал себя в каждом рыночном режиме:
| Рыночный режим | Сделки | Процент выигрышных сделок | Математическое ожидание |
|---|---|---|---|
| TREND | 1 199 | 45,6 % | +0,005R |
| NORMAL | 435 | 47,4 % | +0,036R |
| RANGE | 78 | 42,3 % | -0,069R |
| VOLATILE | 501 | 48,5 % | +0,042R |
Принято считать, что MACD работает в режиме TREND, не работает в RANGE и ненадежен в условиях VOLATILE. Данные свидетельствуют об обратном.
Да, RANGE — худший режим, единственный с отрицательным математическим ожиданием. Фильтр правильно отсеял эти сделки.
Однако VOLATILE оказался самым эффективным, а не самым худшим режимом для MACD без фильтров. Более высокий процент выигрышных сделок и более высокое математическое ожидание, чем в любой другой категории. При этом TREND, режим, в котором MACD, как предполагается, должен проявлять себя лучше всего, показал самое низкое положительное математическое ожидание из всех четырех.
У меня нет четкого теоретического объяснения этому. Моя рабочая гипотеза состоит в том, что условия VOLATILE на TECH100 часто соответствуют сильным направленным движениям: реакциям на корпоративную отчетность, решениям ФРС и шокам в технологическом секторе, при которых пересечение MACD эффективно улавливает направленный импульс. Между тем TREND по определению ADX может включать медленные, затяжные движения, при которых сигналы пересечения возникают с задержкой, а цена затем часто возвращается к среднему.
Что это означает на практике: созданный мной фильтр рыночного режима исключает VOLATILE, который, как оказалось, является вторым по прибыльности режимом. Именно поэтому один только фильтр рыночного режима не помогает. Он отбрасывает хорошие сделки вместе с плохими.
Такие открытия появляются только при прогоне системы на реальных данных. Основанные на теории статьи о фильтрах рыночного режима никогда бы этого не выявили. После двадцати лет торговли и изучения литературы по стратегиям я пришел к выводу, что разрыв между теорией и эмпирическими результатами — скорее правило, чем исключение.

Рисунок 3. Распределение сделок MACD без фильтров и математическое ожидание по рыночным режимам
Сессионный фильтр — почему он сработал
Сессионный фильтр концептуально самый простой из трех: торговать только с 14:00 до 20:00 по времени брокера, что охватывает основную американскую сессию. Ничего о структуре рынка, ничего о пороговых значениях ADX. Только временной интервал.
И тем не менее именно этот фильтр обеспечил заметное улучшение. От профит-фактора 1,01, фильтр режима + HTF, до 1,20, все три фильтра вместе. От максимальной просадки -29,6R до -9,7R. От математического ожидания +0,007R до +0,100R — шестикратное улучшение.
По моей интерпретации, вне основных часов торговли в США ликвидность на TECH100 ниже, спреды шире, а непропорционально большая доля "сигналов пересечения MACD" возникает во время неуверенного ночного дрейфа. Такие сигналы обычно возвращаются к среднему еще до достижения цели 3,0 ATR, поэтому стратегия без фильтров накапливает небольшие убытки. Исключите эти часы — и качество оставшихся сигналов заметно повысится.
Это соответствует тому, что уже известно институциональным трейдинговым подразделениям: качество исполнения и надежность сигналов зависят от ликвидности. Розничные трейдеры, как правило, недооценивают этот фактор, поскольку сосредотачиваются на математике индикаторов и игнорируют микроструктуру рынка. Данные по TECH100 свидетельствуют о том, что выбор времени торговой сессии важнее любой комбинации статистических фильтров, применяемых к самому индикатору.
Хочу подчеркнуть, что этот вывод зависит от конкретного инструмента. Окно сессионного фильтра, подходящее для TECH100, будет существенно иным для EUR/USD, где есть лондонские пики ликвидности, или для сырой нефти с ее основными часами торгов и влиянием публикаций Американского института нефти. Принцип переносим, но конкретные параметры — нет.
Реализация классификатора рыночных режимов в MQL5
Для читателей, желающих воспроизвести этот подход, ниже приведен компактный классификатор рыночных режимов на MQL5. Это упрощенная версия того, что я использую; ее достаточно, чтобы воспроизвести показанные выше классификации.
//+------------------------------------------------------------------+ //| RegimeClassifier.mqh | //| Marcelo Borasi | //| | //| Location: MQL5/Include/MBorasi/RegimeClassifier.mqh | //| | //| Simple 4-state market regime classifier based on ADX and | //| adaptive ATR percentiles. See the companion article for | //| methodology and empirical results. | //+------------------------------------------------------------------+ #property copyright "Marcelo Borasi" #property version "1.00" //+------------------------------------------------------------------+ //| Market regime enumeration | //+------------------------------------------------------------------+ enum ENUM_REGIME { REGIME_TREND, REGIME_NORMAL, REGIME_RANGE, REGIME_VOLATILE }; //+------------------------------------------------------------------+ //| Class for classifying market regime | //+------------------------------------------------------------------+ class CRegimeClassifier { private: int m_adx_handle; int m_atr_handle; int m_lookback; // rolling window for ATR percentile double m_adx_trend_th; // ADX above this = TREND candidate double m_adx_range_th; // ADX below this = RANGE candidate public: CRegimeClassifier(void) : m_adx_handle(INVALID_HANDLE), m_atr_handle(INVALID_HANDLE), m_lookback(500), m_adx_trend_th(25.0), m_adx_range_th(20.0) {} //+------------------------------------------------------------------+ //| Initialization method | //+------------------------------------------------------------------+ bool Init(string symbol, ENUM_TIMEFRAMES tf, int adx_period = 14, int atr_period = 14, int lookback = 500, double trend_th = 25.0, double range_th = 20.0) { m_adx_handle = iADX(symbol, tf, adx_period); m_atr_handle = iATR(symbol, tf, atr_period); if(m_adx_handle == INVALID_HANDLE || m_atr_handle == INVALID_HANDLE) return(false); m_lookback = lookback; m_adx_trend_th = trend_th; m_adx_range_th = range_th; return(true); } //+------------------------------------------------------------------+ //| Classify current regime at the given bar shift | //+------------------------------------------------------------------+ ENUM_REGIME Classify(int shift = 0) { double adx[]; if(CopyBuffer(m_adx_handle, 0, shift, 1, adx) <= 0) return(REGIME_NORMAL); double atr[]; if(CopyBuffer(m_atr_handle, 0, shift, m_lookback, atr) <= 0) return(REGIME_NORMAL); double close_now = iClose(_Symbol, _Period, shift); if(close_now <= 0) return(REGIME_NORMAL); double atr_pct_now = 100.0 * atr[m_lookback - 1] / close_now; double atr_pcts[]; ArrayResize(atr_pcts, m_lookback); for(int i = 0; i < m_lookback; i++) { double c = iClose(_Symbol, _Period, shift + m_lookback - 1 - i); atr_pcts[i] = (c > 0) ? 100.0 * atr[i] / c : 0.0; } ArraySort(atr_pcts); double p20 = atr_pcts[(int)(m_lookback * 0.20)]; double p80 = atr_pcts[(int)(m_lookback * 0.80)]; double adx_now = adx[0]; if(atr_pct_now > p80) return(REGIME_VOLATILE); if(adx_now > m_adx_trend_th) return(REGIME_TREND); if(adx_now < m_adx_range_th && atr_pct_now < p20) return(REGIME_RANGE); return(REGIME_NORMAL); } //+------------------------------------------------------------------+ //| Release indicator handles | //+------------------------------------------------------------------+ void Release(void) { if(m_adx_handle != INVALID_HANDLE) IndicatorRelease(m_adx_handle); if(m_atr_handle != INVALID_HANDLE) IndicatorRelease(m_atr_handle); } }; //+------------------------------------------------------------------+
Этот класс использует два хэндла индикаторов, ADX и ATR, и скользящее окно длиной 500 баров для расчета адаптивных процентилей волатильности. Логика классификации намеренно сделана прозрачной. Можно прочитать каждое условие и понять, что оно означает. Настройте пороговые значения под свой инструмент.
Чтобы использовать этот класс в советнике или индикаторе:
#include <MBorasi/RegimeClassifier.mqh> CRegimeClassifier regime; //+------------------------------------------------------------------+ //| Initialization function of the expert | //+------------------------------------------------------------------+ int OnInit() { if(!regime.Init(_Symbol, _Period)) return(INIT_FAILED); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Deinitialization function of the expert | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { regime.Release(); } //+------------------------------------------------------------------+ //| Function-event handler "tick" | //+------------------------------------------------------------------+ void OnTick() { ENUM_REGIME current = regime.Classify(0); if(current == REGIME_RANGE) return; // skip this signal // ... rest of strategy logic } //+------------------------------------------------------------------+
Здесь нет ничего волшебного. Ценность заключается в калибровке на основе данных, а не в коде. Пороговые значения ADX 25/20 и отсечки по 20-му и 80-му процентилям ATR — значения, к которым я пришел после тестирования на данных TECH100. На другом инструменте эти значения пришлось бы калибровать иначе.
Практический совет для всех, кто реализует это: вычисление скользящего процентиля ATR требует больше вычислительных ресурсов, чем кажется. На каждом новом баре заново сортируются последние 500 значений процентилей ATR, что имеет сложность O(n log n). На ликвидных символах, где OnTick может срабатывать много раз за один бар, эти накладные расходы могут стать существенными. Самая простая оптимизация — вычислять классификацию один раз на бар, в OnTimer или на первом тике нового бара, и кэшировать результат.
Как использовать вспомогательный скрипт
К статье прилагаются два файла MQL5, размещенные ниже. Вместе они позволяют любому читателю за несколько минут воспроизвести анализ на данных своего брокера.
Файл 1: RegimeClassifier.mqh — подключаемый файл, содержащий класс CRegimeClassifier, показанный в разделе кода выше. У него нет зависимостей, кроме стандартных функций MetaTrader 5.
Файл 2: MACD_Filter_Backtest.mq5 — скрипт, загружающий исторические бары с графика, на котором он запущен, применяющий четыре последовательные конфигурации фильтров и выводящий полученные метрики в лог на вкладке "Эксперты". Кроме того, он записывает CSV-файл с полным списком сделок для дальнейшего анализа.
Установка:
- Поместите файл RegimeClassifier.mqh в папку MQL5/Include/MBorasi/. Создайте подпапку MBorasi, если она отсутствует.
- Поместите файл MACD_Filter_Backtest.mq5 в папку MQL5/Scripts/.
- В MetaEditor откройте скрипт и скомпилируйте его. Скрипт должен компилироваться без предупреждений.
- В MetaTrader 5 откройте график H1 для тестируемого символа. Для воспроизведения числовых результатов статьи рекомендуется US_TECH100.
- Перетащите скрипт из панели "Навигатор" на график.
- Появится диалоговое окно с входными параметрами. Нажмите "ОК", чтобы принять настройки по умолчанию, или сначала измените их.
Вывод: скрипт выполняется за несколько секунд и выводит полные результаты в Журнал "Эксперты" в нижней части MetaTrader 5. Результаты также экспортируются в MQL5/Files/MACD_Backtest_[символ]_[период]_BACKTEST.csv для дальнейшего анализа в Excel или Python.
Почему скрипт, а не советник: анализ выполняется один раз по всем доступным историческим барам и формирует статический отчет. Скрипт — подходящий тип объекта MQL5 для такого разового оффлайн-анализа. Советник добавил бы накладную нагрузку из-за непрерывной обработки тиков, которая здесь не нужна. Пользовательский индикатор мог бы отображать значения на графике, но не позволяет экспортировать CSV или корректно выполнять сравнение нескольких конфигураций.
Как проводилось тестирование на исторических данных
Методология бэктеста важна, поскольку именно она определяет, являются ли представленные цифры реальными или артефактами, подогнанными под историю. Мой протокол:
Источник данных. OHLC-данные брокера, экспортированные напрямую из H1-потока котировок AvaTrade. Не Dukascopy и не CSV-пакеты от сторонних продавцов. Это важно, потому что при запуске стратегии в реальной торговле вы будете использовать поток котировок того же брокера. Тестирование на исторических данных с другим потоком котировок часто дает результаты, которые не выдерживают проверки в реальной торговле.
Количество баров. 29 646 баров H1 за 5 лет. Этого достаточно, чтобы охватить несколько рыночных режимов: медвежий рынок 2022 года, затяжной рост в 2023 году, ралли на теме ИИ в 2024 году, всплеск волатильности в 2025 году и активность начала 2026 года.
Моделирование сделок. Для каждого сигнала моделируется дальнейшее движение бар за баром. Проверяется, был ли достигнут SL с закрытием на -1R, сработал ли TP с закрытием на +1,2R и наступил ли тайм-аут через 48 баров с закрытием по рынку. Пессимистическое допущение: на барах, где и SL, и TP могли быть достигнуты в пределах одного бара, считать, что первым сработал SL. Это стандартная практика в консервативном тестировании на исторических данных, которая обычно слегка занижает результаты.
Нормализация математического ожидания. Все сделки выражены в R-множителях, поэтому анализ не зависит от масштаба. Это также означает, что результаты применимы независимо от размера счета, к которому они применяются.
Базовые допущения. В базовом сценарии предполагается отсутствие проскальзывания и комиссий. Я оставил этот вариант чистым, чтобы изолировать эффект фильтра. Реальная торговля ухудшила бы результаты всех четырех конфигураций примерно на одинаковую величину, что не изменило бы относительных сравнений. Приблизительная оценка для TECH100: 2-3 пункта спреда на полный цикл сделки; при стопе в 2,5 ATR это соответствует примерно 0,05R транзакционных издержек на сделку. На 2 213 сделках это дает 110R совокупных издержек, чего достаточно, чтобы превратить MACD без фильтров из едва прибыльной стратегии в слегка убыточную. Это еще раз подтверждает, что стратегия без фильтров на практике не является жизнеспособной системой.
Это далеко не самое сложное тестирование на исторических данных. В него не включены моделирование последовательностей сделок методом Монте-Карло, пошаговая оптимизация (walk-forward) порогов рыночных режимов и анализ чувствительности параметров по сетке. Но оно честное, воспроизводимое и основано на реальных данных брокера. Код MQL5 и CSV-файлы, необходимые для воспроизведения результата, укладываются менее чем в 300 строк кода.
Что эти фильтры не решают
Есть несколько моментов, о которых стоит сказать прямо: я не хочу, чтобы читатели подумали, будто я пытаюсь продать какую-то систему.
Даже полностью отфильтрованная конфигурация (все три фильтра) дает математическое ожидание всего +0,100R на сделку и процент выигрышных сделок 50,3%. Это означает следующее:
- Чтобы статистическое преимущество проявилось, нужно совершить много сделок. 40 сделок в год на одном инструменте не обеспечат заметного дохода.
- Серии убыточных сделок статистически неизбежны. Данные показывают, что в какой-то момент была серия из восьми убыточных сделок подряд. Чтобы продолжать торговать после этого, нужна самодисциплина.
- Профит-фактор 1,20 дает лишь небольшой запас прочности. Небольшие изменения спреда, исполнения или рыночного режима могут привести к тому, что этот показатель в будущих данных опустится ниже 1,0.
- Комиссии и спреды при реальной торговле могут легко съесть 30-50% математического ожидания, показанного в тестировании на исторических данных. При математическом ожидании +0,050R после учета издержек один неудачный месяц может свести на нет прибыль за целый год.
- Результаты относятся только к TECH100 H1 с этими конкретными настройками SL/TP. Измените любой из этих параметров — и ранжирование фильтров может измениться.
Фильтры не создают альфу: они уменьшают шум вокруг уже имеющегося сигнала. Если исходный сигнал слабый, фильтрация его не спасет. В данном случае пересечение MACD на TECH100 H1 имеет небольшое положительное статистическое преимущество, а сессионный фильтр превращает его из "почти отсутствующего" в "видимое, но умеренное".
Урок, который я извлек из этого упражнения после всех этих лет изучения графиков и написания кода: контекст микроструктуры рынка (то, когда вы торгуете, а не только то, чем вы торгуете) зачастую важнее тонкой настройки индикаторов, которой мы так увлекаемся. Двадцать лет назад я бы потратил шесть месяцев на оптимизацию периодов MACD. Теперь я прогоняю данные и вижу, что сессионное окно влияет на математическое ожидание в шесть раз сильнее, чем настройка индикатора.
Другой урок, который труднее принять тем, кто любит программирование: большая часть того, что продается на коммерческом рынке как "продвинутый MACD с фильтрами", не выдерживает строгого эмпирического тестирования на нативных данных брокера. Это не заговор: просто продавцы тестируют системы на чрезмерно очищенных данных, а розничные трейдеры редко проверяют их на собственных потоках котировок. Усилия на проверку несопоставимы с ценой торговли по несовершенной системе в течение года.
Дальнейшие шаги для читателей
Если вы хотите расширить этот анализ на основе собственных данных, вот что я бы порекомендовал в порядке значимости.
Для начала проведите такое же тестирование на исторических данных с потоком котировок вашего брокера для US_TECH100 на таймфрейме H1. Сравните полученные результаты с моими. Если результаты существенно различаются, причина в потоке котировок вашего брокера или поведении спреда, а не в стратегии. Это упражнение даст вам больше понимания особенностей вашего брокера, чем год пассивной торговли.
Во-вторых, измените сессионное окно. Протестируйте интервал с 14:30 до 20:00, основную торговую сессию NYSE, и сравните его с интервалом с 13:00 до 22:00, расширенной американской сессией, включая премаркет и торговлю после закрытия. Математическое ожидание изменится. Этот анализ чувствительности ценнее любой настройки параметров самого MACD.
В-третьих, проведите тестирование на другом инструменте. Золото, S&P 500 и Dow Jones ведут себя иначе, чем Nasdaq-100, несмотря на внутридневную корреляцию. Исходя из моего опыта торговли этими инструментами, я ожидаю, что ранжирование эффективности фильтров изменится. Сессионная фильтрация может по-прежнему быть важнее на американских индексах, но на золоте фильтр старшего таймфрейма, HTF, может иметь больший вес из-за другого профиля волатильности.
В-четвертых, добавьте фильтр дивергенции как четвертое условие. Мои результаты по Helix, моему собственному индикатору, показывают, что пересечения, подтвержденные дивергенцией, как правило, дают более надежные сигналы, но я не включил этот фильтр в статью, чтобы сохранить чистоту сравнения. Это следующий фильтр, который логично изучить.
В-пятых, не подгоняйте параметры под тестовый период. Разделите данные пополам, подберите параметры на первой половине и вслепую оцените результат на второй. Если результаты выдержат проверку, у вас будет устойчивая стратегия. Если на второй половине результаты резко ухудшатся, значит, вы, сами того не осознавая, занимались подгонкой под историю.
Приведенного выше кода классификатора рыночных режимов и методологии тестирования на исторических данных достаточно, чтобы самостоятельно выполнить все эти проверки. Если вы это сделаете, мне было бы действительно интересно узнать о результатах на других инструментах. Сообщество тех, кто в экосистеме MQL5 занимается строгим эмпирическим тестированием, невелико, и ему не помешали бы новые участники.
Примечание о созданном решении
Я потратил большую часть двух лет на доработку полной версии этой логики и оформил ее в виде скомпилированного индикатора для личного использования, а затем и для продажи. В него добавлено еще несколько фильтров, которые я сознательно не включил в эту статью: адаптивная калибровка порогов, пауза после ложных сигналов и более аккуратная обработка торговых сессий в разных часовых поясах брокеров. Решение опубликовано в MQL5 Market под названием Helix MACD для трейдеров, которые предпочитают готовую реализацию, а не самостоятельную разработку и калибровку.
Я упоминаю об этом для полноты картины, а не как об основной идее статьи. Суть статьи — в приведенных выше данных и коде. Любой желающий может воспроизвести эти результаты и проверить их.
Заключение
Комбинация из трех фильтров в стратегии пересечения MACD дает заметное улучшение по сравнению с MACD без фильтров, но не так, как это обычно представляют в рекламных заявлениях продавцов. Сама по себе фильтрация по рыночному режиму не дала ничего измеримого. Само по себе согласование со старшим таймфреймом, HTF, также не дало ничего измеримого. Основную работу выполнил сессионный фильтр.
Практический вывод из пяти лет данных по TECH100 H1 таков: если вы собираетесь торговать пересечениями MACD на американских индексах, самым важным параметром будут не настройки MACD и не логика рыночного режима. Главное — в какие часы дня вы разрешаете системе срабатывать. Все остальное имеет второстепенное значение.
Это противоречит распространенному на рынке индикаторов убеждению, что чем сложнее продукт, тем лучше он продается. Но данные есть данные.
Если бы я прочитал эту статью двадцать лет назад, я бы сэкономил много времени на оптимизации параметров индикаторов, которые, как оказалось, не имели существенного значения. У современного разработчика, читающего эти строки, есть преимущество, которого у меня не было: доступ к недорогим данным, быстрым ноутбукам и среде разработки MQL5, позволяющей проверять гипотезы за часы, а не за недели. Используйте это преимущество, чтобы проверять утверждения, а не принимать их на веру.
Весь код, упомянутый в этой статье, приложен ниже. В таблице ниже описаны файлы исходного кода, прилагаемые к статье.
| # | Название | Описание |
|---|---|---|
| 1 | RegimeClassifier.mqh | Подключаемый файл, содержащий класс CRegimeClassifier. Обеспечивает определение рыночного режима по четырем состояниям, TREND, NORMAL, RANGE, VOLATILE, с использованием ADX и адаптивных порогов на основе процентилей ATR. Перед компиляцией скрипта файл следует поместить в папку MQL5/Include/MBorasi/. |
| 2 | MACD_Filter_Backtest.mq5 | Автономный скрипт, воспроизводящий полное тестирование на исторических данных из статьи. Проходит по всем доступным историческим барам на графике, применяет четыре последовательно усложняющиеся конфигурации фильтров, MACD без фильтров, +Regime, +Regime+HTF и +Regime+HTF+Session, и выводит полный набор метрик в лог на вкладке "Эксперты". Кроме того, скрипт экспортирует подробный CSV-файл в папку MQL5/Files/ для дальнейшего анализа. |
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/22290
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Особенности написания Пользовательских Индикаторов
Как реализовать прогнозирование с помощью AutoARIMA в MQL5
Нейросети в трейдинге: Управление риском через распределение результатов (Вычислительная основа)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Сессионные фильтры очень дешево вычисляются под любой заранее заданный PF. Но нужна валидация, где количество сделок - слабый показатель.
Вы можете после сессионного фильтра иметь тысячи сделок и PF > 2. Но это с высокой вероятностью будет подгонка. Должны быть валидационные механизмы.