Алгоритм извлечения торговых правил из паттернов в MQL5
С чего начинается задача
Я вижу на графике повторяющиеся свечные последовательности, но не понимаю, являются ли они статистически значимыми и можно ли на них построить воспроизводимый торговый сигнал. Мне нужен способ формализовать паттерн, проверить его предсказательную силу на истории и отфильтровать случайные совпадения. Дополнительно требуется, чтобы отобранные правила автоматически превращались в условия входа и выхода в советнике MQL5.
Именно эту задачу решает советник PatternAssociationRulesExpertAdvisor. Статья покажет, как он движется от визуального наблюдения к формализованному торговому сигналу: шаг за шагом — кодирование паттерна, сбор статистики, фильтрация значимых правил и их превращение в ордера с диагностикой в логе.
Формализация паттерна: бинарная строка U/D
Любой трейдер, проведя за графиком несколько лет, замечает повторяющиеся ценовые последовательности: три свечи вверх, потом откат — и снова рост. Или чередование «вниз-вверх-вниз», после которого рынок разворачивается. Интуиция подсказывает: здесь что-то есть. Но интуиция — ненадёжный инструмент: она помнит случаи, которые подтвердились, и забывает те, которые нет.
Первый шаг к сигналу — перестать смотреть на свечи и начать смотреть на направления. Каждый бар кодируется как U (закрытие выше предыдущего) или D (закрытие ниже). Последовательность из N таких символов — паттерн. Для N = 5 существует ровно 2⁵ = 32 варианта: «DDDDD», «UDDDD», «UUDDU» и так далее.
Бинаризация теряет информацию об амплитуде — но выигрывает в размере выборки. Паттерн длиной 5 встречается в 1000-баровом окне в среднем 1000/32 ≈ 31 раз — как раз на пороге статистической значимости. Более детальная кодировка (три состояния: большой рост, малый рост, падение) давала бы 3⁵ = 243 паттерна при той же выборке, и большинство из них не набирало бы нужного числа вхождений.
Советник строит полный словарь паттернов в OnInit:
bool GeneratePatterns() { g_pattern_count = (int)MathPow(2, g_pattern_length); ArrayResize(g_patterns, g_pattern_count); for(int i = 0; i < g_pattern_count; i++) { string pattern = ""; for(int j = 0; j < g_pattern_length; j++) { pattern += ((i >> j) & 1) ? "U" : "D"; } g_patterns[i] = pattern; } return true; }
Трюк с побитовым сдвигом (i >> j) & 1 превращает число i в бинарную маску: j-й бит числа i определяет, будет ли j-й символ «U» или «D». Это быстрый обход всех вершин булевского гиперкуба без рекурсии. Словарь строится один раз и не меняется — лишних аллокаций памяти в горячем пути OnTick нет.
Сбор статистики: что происходит после паттерна
Формализовав паттерн как ключ, можно измерить: как часто после него рынок идёт вверх, а как часто — вниз. Именно это делает функция UpdateAssociationRules на каждом новом баре. Она читает закрытые цены за последние InpLookback баров, перекодирует их в строки U/D и подсчитывает исходы.
Исход определяется через InpForecastHorizon баров: если цена через N баров выросла относительно текущей — исход UP, иначе DOWN:
outcomes[i] = (i >= g_forecast_horizon && close[i - g_forecast_horizon] > close[i]) ? "UP" : "DOWN";
Массив close заполнен с флагом ArraySetAsSeries(true), поэтому индекс 0 — последний бар. Индекс (i - g_forecast_horizon) соответствует бару, который будет закрыт через N баров относительно позиции i.
После формирования массивов советник считает базовую вероятность роста p_up и падения p_down по всей выборке. Это нулевая гипотеза: если паттерн ничего не предсказывает, уверенность должна равняться p_up или p_down. Любое отклонение — потенциальный сигнал.
double p_up = (double)outcome_up_count / valid_patterns; double p_down = (double)outcome_down_count / valid_patterns;
Идея заимствована из Data Mining. Метод ассоциативных правил появился в 1993 году в работе Агравала и Сриканта, посвящённой анализу супермаркетных чеков: покупатели, берущие пиво, часто берут чипсы. На финансовых рынках роль «товаров» играют направления баров. Паттерн UUDDU — «антецедент» правила, а «UP» или «DOWN» через N баров — его «консеквент».
Фильтрация: пять метрик значимости
Когда для паттерна набралось достаточно вхождений (InpMinOccurrences, по умолчанию 30), советник вычисляет пять метрик. Каждая отвечает на свой вопрос о природе наблюдаемой закономерности. Только паттерн, прошедший все фильтры, становится торговым правилом.
Структура данных намеренно избыточна:
struct AssociationRule { string antecedent; // паттерн, например "UUDDU" string consequent; // "UP" или "DOWN" double support; // доля баров с этим паттерном double confidence; // P(consequent | antecedent) double lift; // confidence / P(consequent) double chi_square; // χ² статистика double expected_confidence; // P(consequent) — базовая линия double bayes_prob; // байесовская вероятность double p_value; // аппроксимация уровня значимости double mutual_info; // взаимная информация (bits) };
Поддержка и уверенность — базовые метрики Apriori. Поддержка говорит, насколько часто паттерн встречается вообще. Уверенность — насколько часто после него следует нужный исход.
Лифт — отношение уверенности к базовой вероятности. Лифт 1.0 означает, что паттерн ничем не лучше случайного выбора. Лифт 1.3 означает, что с паттерном вы правы на 30% чаще, чем без него. Если рынок после паттерна UUDDU идёт вверх в 68% случаев при случайной вероятности 51%, лифт составит 68/51 ≈ 1.33. Советник выводит в лог только правила с лифтом выше 1.2.
Хи-квадрат и p-value проверяют нулевую гипотезу о независимости паттерна и исхода. Высокий χ² при малом p-value означает: ассоциация не случайна. Советник использует аппроксимацию p ≈ exp(−χ²/2):
double exp_up = count_pattern * p_up; double exp_down = count_pattern * p_down; double chi2 = 0; if(exp_up > 0) chi2 += MathPow(count_up - exp_up, 2) / exp_up; if(exp_down > 0) chi2 += MathPow(count_down - exp_down, 2) / exp_down; double p_value = MathExp(-0.5 * chi2);
Взаимная информация (MI) измеряет, сколько информации (в битах) паттерн несёт об исходе. MI особенно ценна тем, что не зависит от выбора базовой линии и улавливает нелинейные зависимости, которые пропускает лифт:
double mi = 0; if(count_up > 0) mi += ((double)count_up / valid_patterns) * MathLog((double)count_up / (count_pattern * p_up) + 1e-8); if(count_down > 0) mi += ((double)count_down / valid_patterns) * MathLog((double)count_down / (count_pattern * p_down) + 1e-8);
Байесовская вероятность — главный фильтр торговых сигналов (порог InpMinConfidence, по умолчанию 0.6). Классическая уверенность count_up / count_pattern неустойчива при малых выборках: если паттерн встретился 30 раз и все 30 раз дал UP, уверенность равна 100% — но это артефакт малой выборки. Байесовская оценка с лапласовским сглаживанием решает эту проблему:
double alpha = 1.0; // псевдосчёт — мягкий априорный prior double bayes_up = (count_up + alpha) / (count_pattern + 2*alpha); double bayes_down = (count_down + alpha) / (count_pattern + 2*alpha);
При count_pattern = 30 и count_up = 30 байесовская вероятность UP равна 31/32 = 96.9% вместо 100%. При count_pattern = 1000 разница ничтожна — сглаживание работает только там, где оно нужно.
Именно bayesProb является решающей метрикой для входа: она наиболее устойчива к шуму и корректно обрабатывает малые выборки. Лифт и MI оценивают силу ассоциации, хи-квадрат и p-value — её статистическую достоверность. Советник открывает позицию только если все фильтры пройдены одновременно.
Превращение правила в ордер
OnTick выполняет основную работу только при открытии нового бара (проверка IsNewBar) — только на закрытии бара паттерн фиксируется и может быть надёжно сопоставлен с историческими данными.
SL и TP через ATR дневного таймфрейма — независимо от рабочего таймфрейма советника. Дневной ATR отражает реальную волатильность инструмента:
double atr[]; ArraySetAsSeries(atr, true); CopyBuffer(g_atr_handle, 0, 0, 1, atr); double sl = atr[0] * InpATRMultiplier; double tp = atr[0] * InpATRMultiplier;
Динамический лот зависит от силы сигнала — разницы между уверенностью правила и базовой вероятностью, умноженной на 10. Если паттерн даёт UP в 70% случаев при базовых 50%, сила сигнала равна (0.70 − 0.50) × 10 = 2.0, и лот удваивается. Минимальный лот ограничен снизу значением InpLotSize:
double signal_strength = (g_rules[i].confidence - g_rules[i].expected_confidence) * 10; double lot = MathMax(InpLotSize * signal_strength, InpLotSize);
Диагностика в комментарии ордера содержит паттерн, уверенность, байесовскую вероятность и лифт. В терминале MetaTrader это позволяет одним взглядом понять, на каком основании открыта позиция. Лог выводит правила с лифтом > 1.2 и p-value < 0.05 — исследователь видит, что происходит внутри. Это принципиальное отличие от нейросетевых советников, которые работают, но не объясняют почему.
Параметры и настройка
Советник имеет девять входных параметров. InpLookback (размер окна истории, 100–5000 баров) и InpForecastHorizon (горизонт прогноза, 1–20 баров) определяют выборку. Увеличение lookback даёт больше статистики, но снижает адаптивность к текущим условиям. Уменьшение горизонта прогноза делает советника более агрессивным.
InpMinOccurrences (минимальное число вхождений паттерна) — критически важный параметр. При значении 30 и lookback 1000 около трети паттернов не преодолеют порог — это нормально. Слишком низкий порог открывает дорогу случайным правилам, слишком высокий оставляет советника без сигналов.
ATRMultiplier управляет соотношением риска к прибыли. Значение 0.5 означает стоп и тейк на полпути к дневному ATR. Для дневных таймфреймов имеет смысл увеличить его до 1.0–1.5. Ключевое правило: не оптимизируйте ATRMultiplier на истории отдельно от остальных параметров — это прямой путь к переобучению.
Типичные значения для EURUSD H4: PatternLength=5, Lookback=1000, ForecastHorizon=6, MinOccurrences=30, MinSupport=0.05, MinConfidence=0.62, ATRPeriod=14, ATRMultiplier=0.7.
К статье также приложен файл версии без ATR — с фиксированными значениями стопа и тейка.
Результаты бэктестинга и версия v2
Базовые версии советника (с ATR и с фиксированным SL/TP) при тестировании на истории не показали стабильно положительного результата — это ожидаемо для исследовательского инструмента первого уровня.
Для улучшения была разработана версия v2 с автоматическим выбором топ-N% паттернов по композитному скору (bayes_prob × lift), а торговое решение принимается простым большинством голосов этих топ-паттернов. Именно v2 продемонстрировала положительные результаты на бэктестах, хотя коэффициент Шарпа остаётся невысоким:

Коэффициент Шарпа тут прямо скажем, не блещет, поэтому эту систему можно назвать простой стартовой точкой для более сложных модификаций (к примеру, можно собрать нейросимвольную систему, когда нейросеть будет обучаться на массивах паттернов):

Это подтверждает важный вывод: система работает как воспроизводимый исследовательский стенд, а не как готовая торговая система. Её ценность — в прозрачном механизме отбора правил и возможности наращивать сложность.
Ограничения и пути развития
Советник в текущей версии не избегает «утечки данных из будущего» в теоретическом смысле. В UpdateAssociationRules исходы вычисляются на всей истории; поскольку функция вызывается на каждом новом баре, а исход смотрит вперёд на ForecastHorizon баров, последние ForecastHorizon баров не участвуют в подсчёте статистики. Проверка граничных условий в коде требует внимательности при любой модификации.
Советник не учитывает режим рынка. Ассоциативные правила, работающие на трендовом рынке, часто разрушаются во флэте, и наоборот. Добавление фильтра волатильности (ADX, ATR percentile) до входа в логику паттернов — очевидный следующий шаг. Код структурирован так, что этот фильтр вставляется в начало цикла в OnTick одной проверкой.
Среди перспективных направлений — нейросимвольные системы, где нейросеть обучается непосредственно на массивах паттернов. Также интересен подход к сжатию массивов паттернов: сжатие снижает энтропию, что теоретически повышает точность прогнозирования. Оба направления — предмет следующих разработок.
Заключение
Трейдер, открывший эту статью с вопросом «как превратить визуальный паттерн в торговый сигнал», прошёл полный путь от наблюдения до ордера.
Паттерн кодируется как бинарная строка U/D заданной длины — это фиксирует задачу и определяет размер пространства поиска. На окне истории для каждого паттерна собирается статистика исходов UP/DOWN на горизонте N баров, и вычисляются пять независимых метрик: поддержка, уверенность, лифт, хи-квадрат и байесовская вероятность. Только правила, прошедшие все фильтры одновременно, превращаются в условие входа — с динамическим лотом, ATR-уровнями и полной диагностикой в комментарии ордера.
Важно понимать, что перед вами не готовая торговая система. Базовые версии советника на бэктестах не показали стабильно положительного результата, версия v2 с голосованием топ-паттернов выглядит лучше, но коэффициент Шарпа остаётся скромным. Ценность системы в другом: это воспроизводимый исследовательский инструмент, который не является чёрным ящиком — каждый открытый ордер объясняет сам себя.
Именно эта прозрачность открывает дорогу к следующим шагам: добавить фильтр режима рынка, собрать нейросимвольную систему на массивах паттернов, применить сжатие для снижения энтропии. Ассоциативные правила — не финальная архитектура, а надёжная отправная точка, с которой видно, куда двигаться дальше.
| Название файла | Описание файла |
|---|---|
| StatisticalLearningEA.mq5 | Базовая версия, описанная в статье |
| StatisticalLearningEA_fix_sltp.mq5 | Версия с фиксированными SL и TP |
| StatisticalLearningEA_v2.mq5 | Версия с автоматическим выбором топ-N% паттернов по композитному скору |
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Особенности написания Пользовательских Индикаторов
Разработка пробойной торговой системы на основе волатильности
Возможности Мастера MQL5, которые вам нужно знать (Часть 65): Использование паттернов FrAMA и индекса силы
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования