Аллигатор, который не спит: как фракталы и хаос легли в основу FractalEA
Есть расхожая фраза, которую любят повторять на семинарах по трейдингу: «рынок непредсказуем». Формально это правда. Но теория хаоса, откуда Билл Вильямс в своё время позаимствовал вдохновение для своих индикаторов, говорит о вещи более тонкой: хаотическая система непредсказуема в деталях, но не бесструктурна. У неё есть фазы, есть повторяющиеся паттерны перехода от порядка к беспорядку и обратно. Вопрос не в том, можно ли предсказать конкретную свечу. Вопрос в том, можно ли распознать момент, когда система переходит из одной фазы в другую — и оказаться на правильной стороне этого перехода чуть раньше толпы.
Именно из этой идеи выросла связка «Аллигатор + фракталы», а из неё, спустя немало итераций, — торговый советник FractalEA для MetaTrader 5, о механике которого я и хочу рассказать. Не как рекламный буклет, а как разбор инженерных решений — с кодом, с граблями, на которые я наступил, и с объяснением логики там, где она достаточно универсальна, чтобы её показывать.
1. Спящий и просыпающийся рынок
Индикатор Аллигатор — это три сглаженные скользящие средние со сдвигом вперёд: «челюсть» (самая медленная), «зубы» (средняя) и «губы» (самая быстрая). Когда все три линии сплетены в один узел — рынок находится в фазе равновесия, во флэте. Вильямс называл это «сон Аллигатора», и метафора здесь на удивление точная: в такой фазе цена буквально топчется на месте, свечи то и дело перекрывают друг друга телами, а любой резкий вылет вверх или вниз почти сразу выкупается обратно — рынок как будто сам себя одёргивает.
Проблема в том, что визуально флэт от начала тренда отличить непросто именно в момент перехода: первые один-два импульсных бара нового тренда выглядят почти так же, как обычный выброс волатильности во флэте, который через пару свечей схлопнется назад. Разница проявляется только чуть позже — когда линии Аллигатора начинают равномерно расходиться, а не просто дёргаются в разные стороны. Гнаться за самым первым баром движения — значит ловить львиную долю ложных пробоев. Ждать, пока линии разойдутся окончательно и очевидно всем участникам рынка — значит регулярно опаздывать к уже наполовину отыгранному движению. Задача не в том, чтобы предсказать пробой заранее, а в том, чтобы поймать его достаточно рано, но при этом иметь формальный критерий, отсекающий львиную долю шума.
В FractalEA роль такого критерия играет условие «тело свечи закрылось за пределами зубов Аллигатора» — оно жёстко зашито в логику сигнала и не выключается ни при каких настройках. Это не опциональный фильтр, а фундамент: если тело свечи не вышло за зубы, о сигнале речи вообще не идёт, вне зависимости от того, что показывают остальные шесть фильтров.
2. Фрактал как точка отсчёта
Второй кирпичик — фракталы. В классическом определении Вильямса фрактал — это группа из пяти последовательных баров, где центральный имеет самый высокий Хай (бычий фрактал) или самый низкий Лоу (медвежий фрактал) среди всех пяти:
// Классическое определение фрактала (Trading Chaos, Б. Вильямс) bool IsBullishFractal(int shift, int wing) { double centerHigh = iHigh(_Symbol, tf, shift); for(int i = 1; i <= wing; i++) { if(iHigh(_Symbol, tf, shift - i) >= centerHigh) return false; if(iHigh(_Symbol, tf, shift + i) >= centerHigh) return false; } return true; }
Само определение — не ноу-хау, это первая глава учебника, а число баров подтверждения с каждой стороны у меня и вовсе вынесено в настраиваемый параметр — при желании можно собрать и более широкий, и более узкий фрактал. Интересный инженерный вопрос начинается там, где учебник заканчивается: что делать с фракталом, тень которого коснулась уровня, а тело свечи ещё не закрылось за ним?
Тут возможны две наивные крайности. Первая — реагировать по касанию тенью: тогда система ловит колоссальное количество шума, потому что тень достаёт до уровня в разы чаще, чем туда доходит тело. Вторая — требовать закрытия тела строго на том же баре, где сформировался фрактал: тогда система регулярно упускает движения, которые запоздали буквально на один бар и добрались до уровня телом свечи только следующей. Я решаю это через промежуточное состояние «отложенный фрактал»: если тень достала до уровня, а тело — нет, фрактал не отбрасывается сразу, а переводится в режим ожидания до следующего бара. Если на следующем баре тело всё-таки закрывается за уровнем — сигнал формируется с небольшой задержкой в один бар; если нет — фрактал считается отработанным и больше не рассматривается вовсе, даже если позже цена вернётся к этому же уровню.
А вот что происходит дальше — как система выбирает между несколькими одновременно готовыми фракталами (а такое на волатильном рынке случается чаще, чем кажется), в каком порядке проверяются шесть фильтров относительно этого состояния, и какая математика стоит за самими фильтрами — это уже зона, где живёт статистический эдж системы, а не в самом определении фрактала, поэтому здесь код я не привожу целиком.
3. Стоп-лосс: три философии одной задачи
Что делать со стопом после входа — вопрос почти философский. Можно привязать его к структуре рынка (фракталу), можно привязать его к самому индикатору (зубам Аллигатора), а можно вообще отказаться от адаптивности и зафиксировать его в пунктах. В FractalEA реализованы все три режима, потому что ни один из них не универсален — каждый ведёт себя по-своему в зависимости от инструмента, таймфрейма и текущей волатильности, и я не нашёл ни одного режима, который побеждал бы во всех условиях одновременно.
Стоп «за фракталом» — самый органичный вариант: он подтягивается только тогда, когда рынок сам формирует новую структурную точку в выгодную сторону, то есть трейлинг идёт синхронно с реальным изменением структуры цены, а не по расписанию. У этого подхода есть обратная сторона: на инструментах, где фракталы формируются редко (плавный, вялый тренд без резких откатов), стоп может подолгу вообще не двигаться, оставляя избыточный риск открытым дольше, чем хотелось бы.
Стоп «за зубами Аллигатора» тралится каждый новый бар вслед за индикатором, но только в выгодную сторону, никогда не отодвигаясь от цены. Он реагирует чаще и плотнее прижат к текущей цене — но именно поэтому чувствительнее к обычным коррекциям внутри тренда: слишком тесный трейлинг на инструменте с рваным движением рискует выбить позицию раньше времени, до того как основное движение вообще успело начаться.
Фиксированный стоп в пунктах не подстраивается вообще ни под что — и в этой глухоте к структуре рынка есть своё преимущество: предсказуемость риска на входе, без зависимости от того, насколько «удачно» ляжет ближайший фрактал. На спокойных инструментах это, пожалуй, самый скучный из трёх вариантов. А вот на резких, рывками движущихся инструментах — и здесь я забегу немного вперёд, к следующему разделу — именно эта скучная предсказуемость неожиданно начинает работать в плюс.
4. Гонка за тейком: история одного открытия
Расскажу историю, которая случилась у меня во время оптимизации параметров на золоте (XAUUSD) и которая неплохо иллюстрирует, почему бэктест никогда не заменит понимания архитектуры платформы.
В советнике реализована связка «тейк-профит + безубыток + ступенчатый трейлинг»: как только прибыль достигает заданного порога, стоп переносится в безубыток, а если задан шаг трейлинга — фиксированный тейк-профит снимается с ордера вовсе, и дальше позиция ведётся исключительно ступенчатым стопом. Логика на бумаге выглядела железобетонно: зачем держать фиксированный тейк, если дальше позицию сопровождает более гибкий и потенциально более прибыльный механизм?
// Переход в фазу ступенчатого трейлинга после безубытка if(profitPts >= InpBEPts && !beApplied) { double newSL = entryPrice + compensation; // безубыток + комиссия/своп/спред double newTP = (InpBETrailPts > 0) ? 0 : currentTP; // тейк снимается, если задан шаг трала trade.PositionModify(ticket, newSL, newTP); beApplied = true; }
На одном из тестовых прогонов я сравнивал связку «тейк-профит 1200 пунктов, безубыток 640, шаг трейлинга 900» с той же связкой, но без тейка вовсе. Казалось бы, раз тейк всё равно снимается сразу после безубытка на 640 пунктах, его конкретное значение вообще не должно иметь значения — трал должен полностью его заменить. На практике вариант с включённым тейком в 1200 пунктов неожиданно дал результат заметно лучше, и первое время я списывал это на статистический шум выборки. Пересчёт на разных отрезках истории показал, что разница устойчивая, а не случайная — и тогда я полез разбираться, откуда она берётся.
Причина оказалась в задержке между решением советника и его исполнением на сервере. Тейк-профит — это ордер, который физически лежит на стороне сервера брокера и исполняется им напрямую, без участия советника, в момент касания цены. Команда «убери тейк, подвинь стоп» — это запрос, требующий сетевого round-trip до сервера и обратно. На спокойном рынке эта задержка не имеет значения: цена просто не успевает никуда убежать за миллисекунды обработки запроса. А вот на золоте, в моменты резких импульсных движений на новостях, цена вполне может пролететь дистанцию от точки активации безубытка до уровня тейка быстрее, чем сервер обработает команду на его отмену. В таком случае позиция закрывается по старому фиксированному тейку — и, как выяснилось на статистике, это чаще оказывается удачным исходом: ступенчатый трал фиксирует прибыль лишь дискретными шагами, а резкий разворот сразу после импульса, не успевшего дойти до первого такого шага, отдаёт рынку почти всю набежавшую прибыль, которую фиксированный тейк успел бы забрать заранее.
Вывод получился не совсем тот, что я закладывал на этапе проектирования: фиксированный тейк на волатильных инструментах — не запасной вариант на случай, если трал не настроен, а самостоятельный механизм страховки от резких импульсов, который стоит держать включённым сознательно, а не по остаточному принципу. Забавно, что к этому выводу привела не теория, а конкретная гонка миллисекунд между двумя серверными запросами.
5. Шесть фильтров: не гарантия, а смещение вероятностей
Готовый сигнал — это ещё не команда на вход. Прежде чем выставить ордер, сигнальная свеча проходит через систему из шести независимых фильтров: по спреду, по направлению Аллигатора на старшем таймфрейме, по размеру тела свечи относительно волатильности, по ширине самого Аллигатора, по индексу относительной силы и по близости к ещё не пробитому структурному уровню на старшем таймфрейме.
Каждый из этих фильтров в отдельности отсекает довольно скромную долю сигналов. Интереснее то, что они не дублируют друг друга: фильтр по спреду реагирует на состояние ликвидности прямо сейчас, фильтр по старшему таймфрейму — на контекст более крупного масштаба, фильтр по ширине Аллигатора — на то, насколько сам тренд уже «созрел» к моменту сигнала. Пороги для части фильтров я привязал не к фиксированным пунктам, а к волатильности конкретного инструмента и таймфрейма — так система сама подстраивается под изменение рынка вместо того, чтобы требовать ручного пересчёта при каждой смене актива. Конкретные пороговые значения и то, как именно шесть фильтров взаимодействуют друг с другом при одновременной проверке, я оставляю за скобками — это уже не про принцип, а про калибровку, и именно она отличает готовую систему от статьи в блоге.
Общий же принцип таков: ни один из фильтров не гарантирует исход отдельной сделки. Каждый лишь немного смещает распределение вероятностей в пользу системы — как в казино, где отдельный спин рулетки непредсказуем, но зеро на колесе сдвигает математическое ожидание на длинной дистанции. Разница лишь в том, что в трейдинге «зеро» приходится калибровать вручную и заново для каждого инструмента.
6. Человек в контуре системы
Полностью автоматическая торговля — это красиво на бумаге, но на практике трейдеру периодически хочется вмешаться руками: закрыть позицию раньше времени, войти на своё усмотрение, увидеть, что происходит «под капотом» прямо сейчас, а не просто верить алгоритму на слово. Для этого в советнике есть полуавтоматическая панель с кнопками входа и отдельная панель статуса всех шести фильтров — с цветовой индикацией в реальном времени.
// Цвет строки фильтра на панели статуса if(!filterEnabled) rowColor = clrGray; // фильтр выключен в настройках else if(noTrendToEvaluate) rowColor = clrGray; // для направленных фильтров: нет чёткого тренда else if(filterBlocksEntryNow) rowColor = clrLightPink; else rowColor = clrLimeGreen;
Идея простая: даже если решение о входе принимает человек, а не автоматика, ему полезно видеть тот же самый «светофор», которым руководствуется алгоритм. Это не костыль для новичков и не попытка подстраховать нерешительного трейдера — это способ синхронизировать интуицию с формальной логикой системы, не отключая ни то, ни другое. Опытный трейдер часто чувствует разворот раньше, чем это подтвердит формальный фрактал; панель в этом случае не мешает довериться собственному опыту, но честно показывает, что по формальным критериям сигнала пока ещё нет — а дальше решение всё равно остаётся за человеком.
7. Что делать после серии неудач
Ни одна система не выигрывает каждую сделку подряд — и это нормально, статистика убытков распределена не равномерно, а сериями: могут быть недели ровной, скучной прибыли, а потом три-четыре стопа подряд без видимой причины. Вопрос в том, как на эти серии реагировать. В FractalEA есть опциональный режим восстановления: советник считает подряд идущие «настоящие» стоп-лоссы — то есть закрытия по стопу с убытком, произошедшие до того, как по позиции был активирован безубыток, — и при достижении заданной длины серии отправляет следующую сделку удвоенным объёмом. Но только если запаса свободной маржи хватает не просто на открытие такой позиции, а с запасом на покрытие потенциального убытка вплоть до стоп-лосса — иначе удвоение попросту не применяется, и сделка уходит обычным объёмом.
Важная оговорка: это не мартингейл в классическом понимании — здесь нет бесконечного удвоения после каждого следующего проигрыша. Механизм срабатывает один раз за накопленную серию и сразу «разряжается» независимо от исхода этой одной удвоенной сделки — даже если она тоже закроется стопом, система не станет удваивать объём ещё раз; ей придётся заново, с нуля, накопить полную серию убытков. По сути это статистическая ставка на простое наблюдение: рынок не «помнит» предыдущие сделки конкретного советника, а значит вероятность рабочего сигнала после неудачной серии не становится ниже сама по себе. Риск-менеджмент здесь лишь аккуратно использует это наблюдение в свою пользу, не превращая обычную просадку в фатальную.
8. Инфраструктура тоже часть стратегии
Одни и те же входные параметры совершенно по-разному работают на разных условиях исполнения — спред, своп, глубина стакана и задержка обработки ордеров у конкретного брокера или биржи накладывают свой отпечаток, и история из четвёртого раздела — прямое тому подтверждение: без учёта задержки round-trip на сервер оптимальные настройки тейка выглядели бы совсем иначе. Наборы параметров, которые я публикую вместе с советником, изначально готовились не «под усреднённого брокера вообще», а под конкретную инфраструктуру — мастер-аккаунты Bybit TradeFi на платформе MT5 (CFD-инструменты). Если вы копируете сделки с подобного мастер-аккаунта или запускаете советник в схожих условиях исполнения, поведение системы будет ближе к ожидаемому по бэктестам. При переносе на другого брокера с иной структурой спреда и свопа сеты имеет смысл пересчитывать заново, а не использовать как есть — это касается любой торговой системы, не только этой.
Вместо заключения
Мне кажется, главный урок из всей этой работы не в конкретных настройках Аллигатора или в том, сколько баров должно быть у фрактала. Урок в том, что теория хаоса как метафора для рынка работает ровно потому, что не обещает предсказуемости — она честно признаёт непредсказуемость отдельного события и предлагает работать с фазами и вероятностями. Хорошая торговая система — это не оракул, а дисциплинированный процесс, который отсеивает часть шума, снимает часть эмоций и время от времени преподносит инженеру неожиданные уроки вроде истории с гонкой за тейком на золоте — уроки, которые ни один учебник по теории хаоса заранее не предскажет.
Советник опубликован на MQL5 Market под названием FraceaFull — там же выкладываются патчноуты по каждой версии. Если у вас есть свои наблюдения по поведению Аллигатора и фракталов на других инструментах — буду рад обсудить в комментариях.


