
Возможности Мастера MQL5, которые вам нужно знать (Часть 44): Технический индикатор Average True Range (ATR)
Введение
Average True Range (средний истинный диапазон) - распространенный и популярный индикатор волатильности, который, как утверждают форекс-трейдеры, является "наиболее близким" к данным об объеме. Разработанный как индикатор, предназначенный для отслеживания диапазона ценовых баров с учетом изменений цен внутри бара, он стал своего рода опорой в отрасли не только для сортировки сигналов входа, но и для руководства по выбору размера позиции. Мы рассмотрим этот индикатор, разложив его на возможные паттерны, как мы делали это в предыдущих статьях об индикатора. Главное отличие будет заключаться в том, что мы рассмотрим паттерны за пределами класса пользовательских сигналов с учетом пользовательского класса управления капиталом для советников, собранных с помощью Мастера.
Но сначала давайте закончим с паттернами для ADX.
Разворот ADX
Паттерн 6 для ADX — это разворот, который характеризуется падением основного буфера ADX в конце ярко выраженного тренда. Если кратко обобщить информацию об ADX, то он измеряет силу тренда, при этом всплески или подъемы основного буфера осциллятора указывают на силу преобладающего тренда. Кроме того, существуют два дополнительных буфера, DI+ и DI-, которые также количественно определяют силу роста и падения цен соответственно.
Итак, бычий сигнал маркируется сильным медвежьим трендом, который продолжается уже некоторое время, плюс падение показаний основного буфера осциллятора с уровня выше 50 до уровня ниже 4 примерно за 2–3 ценовых бара. Аргумент в пользу этого заключается в том, что поскольку ADX измеряет силу тренда, текущий тренд ослабевает, и поэтому его разворот, который в данном случае является бычьим трендом, вот-вот произойдет. Напротив, медвежий сигнал обозначается сильным бычьим трендом, который также свидетельствует о схожем падении основного буфера ADX с высокого значения до уровня ниже 40. Мы реализуем это в классе сигнала следующим образом:
//+------------------------------------------------------------------+ //| Check for Pattern 6. | //+------------------------------------------------------------------+ bool CSignalADX::IsPattern_6(ENUM_POSITION_TYPE T) { if(Base(X()+3) >= 50 && Base(X()) <= 40) { if(T == POSITION_TYPE_BUY && Close(StartIndex()) > Close(StartIndex() + m_ma_period)) { return(true); } else if(T == POSITION_TYPE_SELL && Close(StartIndex()) < Close(StartIndex() + m_ma_period)) { return(true); } } return(false); }
Тестирование исключительно этого паттерна, при котором входному параметру Patterns Used присвоено целочисленное значение 64, дает нам следующие результаты:
ADX и прорыв уровня поддержки/сопротивления
Паттерн 7 (восьмой и предпоследний из рассматриваемых нами паттернов ADX) сочетает всплески в основном буфере ADX с прорывами уровней поддержки и сопротивления. Поскольку интерпретация линий поддержки и сопротивления в коде более проблематична, чем при ручной торговле, мы будем полагаться на вторичный индикатор — полосы Боллинджера, чтобы лучше их определить. Существуют более тонкие обходные пути, которые я рассмотрел в недавних статьях об RSI и полосах Боллинджера. Читатель может ознакомиться с ними, чтобы переосмыслить то, что мы решили здесь использовать.
Наши прорывы уровней поддержки и сопротивления будут просто отмечаться пробитием нижней и верхней границ полос Боллинджера. Таким образом, бычий сигнал обозначается ростом основного буфера ADX выше уровня 25, а также прорывом цены через верхние полосы Боллинджера, в то время как медвежий сигнал обозначается аналогичным ростом ADX и падением цены ниже нижней полосы. Реализуем это в MQL5 следующим образом:
//+------------------------------------------------------------------+ //| Check for Pattern 7. | //+------------------------------------------------------------------+ bool CSignalADX::IsPattern_7(ENUM_POSITION_TYPE T) { if(Base(X()+2) < 25 && Base(X()) > 25) { if(T == POSITION_TYPE_BUY && Close(StartIndex()) >= Upper(StartIndex())) { return(true); } else if(T == POSITION_TYPE_SELL && Close(StartIndex()) <= Lower(StartIndex())) { return(true); } } return(false); }
Тестирование собранного Мастером советника, который использует только этот паттерн, при установке входного параметра для Patterns Used на значение 128 дает нам следующие результаты:
ADX с подтверждением RSI
Наш последний паттерн 8 объединяет ADX с индикатором RSI, который мы уже рассматривали. Поскольку ADX является индикатором измерения тренда, а RSI часто используется для обозначения точек перекупленности и перепроданности, комбинация этих двух показателей с точки зрения ADX должна учитывать растущие или основные тренды, а не их окончание. На этом этапе мы сосредоточимся на пересечениях RSI на уровне 50, а не на достижении пороговых значений 70/30.
Таким образом, бычий сигнал обозначается пересечением RSI от уровня ниже 50 до уровня выше 50 вместе с ростом основного буфера ADX от уровня ниже 25 до уровня выше 25. Напротив, медвежий сигнал обозначается падением RSI с уровня выше 50 до уровня ниже него, при этом значение ADX снова поднимается выше отметки 25. Реализуем это в MQL5 следующим образом:
//+------------------------------------------------------------------+ //| Check for Pattern 8. | //+------------------------------------------------------------------+ bool CSignalADX::IsPattern_8(ENUM_POSITION_TYPE T) { if(Base(X()+1) < 25 && Base(X()) > 25) { if(T == POSITION_TYPE_BUY && RSI(StartIndex()) > 50 && RSI(StartIndex() + 1) < 50) { return(true); } else if(T == POSITION_TYPE_SELL && RSI(StartIndex()) < 50 && RSI(StartIndex() + 1) > 50) { return(true); } } return(false); }
Тестирование только этого паттерна, при котором входному целому числу используемых шаблонов присвоено значение 256, дает нам следующие результаты:
Оптимизация идеальных паттернов ADX
Сборка с помощью Мастера и приложенного здесь кода описана здесь и здесь. При работе с паттернами ADX не забудьте заменить весовые коэффициенты. Как я уже упоминал ранее, это не обязательно идеальный вариант, поскольку, как правило, различные паттерны нейтрализуют друг друга, то есть в результате оптимизационных прогонов обычно получаются результаты, которые "подгоняются под кривую" и часто не удается воспроизвести их эффективность на данных, отличных от выборки. С учетом вышесказанного, вот некоторые результаты тестирования, полученные путем объединения всех девяти рассмотренных паттернов ADX.
ATR
Осциллятор среднего истинного диапазона, как уже было представлено выше, измеряет волатильность, что имеет решающее значение для Форекс-трейдеров, учитывая отсутствие данных об объеме. Давайте поэтому также рассмотрим его паттерны, некоторые из которых применимы за пределами нашего типичного класса пользовательских сигналов.
Сигнал прорыва волатильности
Когда текущее значение ATR значительно превышает недавнее среднее значение, это может указывать на прорыв волатильности. Это, в свою очередь, подразумевает торговую стратегию, при которой вход в сделку в направлении прорыва при значительном увеличении ATR, сигнализирующем о том, что рынок, вероятно, испытает значительные ценовые движения в этом направлении. Дополнительные индикаторы, такие как скользящая средняя, MACD и так далее, также могут определять направление торговли. Реализуем это в MQL5 следующим образом:
//+------------------------------------------------------------------+ //| Check for Pattern 0. | //+------------------------------------------------------------------+ bool CSignalATR::IsPattern_0(ENUM_POSITION_TYPE T) { if(ATR(X()) > ATR(X() + 1) && ATR(X() + 1) > ATR(X() + 2) && ATR(X() + 2) > ATR(X() + 3)) { if(T == POSITION_TYPE_BUY && Close(X()) > Close(X() + 1) && Close(X() + 1) > Close(X() + 2) && Close(X() + 2) > Close(X() + 3)) { return(true); } else if(T == POSITION_TYPE_SELL && Close(X()) < Close(X() + 1) && Close(X() + 1) < Close(X() + 2) && Close(X() + 2) < Close(X() + 3)) { return(true); } } return(false); }
Тестирование этого конкретного паттерна в одиночку при Used Patterns равном 1 дает нам следующие результаты как один из многих благоприятных результатов короткого периода оптимизации. Мы оптимизируем пару EURUSD на 2022 год на часовом графике.
Порог ATR для подтверждения прорыва
Подтверждения прорыва с помощью ATR имеют решающее значение, учитывая, что ATR является мерой волатильности. Присвоив значение среднему диапазону (максимумы минус минимумы) за установленный период, мы можем определить, насколько цена обычно движется с каждым новым баром. Прорыв происходит, когда цена выходит за пределы определенного уровня поддержки или сопротивления. Таким образом, ATR может служить фильтром ложных пробоев, используя пороговые значения волатильности для подтверждения движения.
Распространенной проблемой прорывов является то, что цены могут ненадолго пробить уровень, а затем откатиться назад. Порог ATR, при добавлении к этим прорывам, помогает осуществлять сортировку, подтверждая прорыв, если цена перемещается на определенный процент выше/ниже ключевого уровня относительно значения ATR. Например, если ATR составляет 20 пунктов, прорыв может считаться действительным, если цена перемещается за пределы уровня поддержки/сопротивления на значение, большее в 1,5-2 раза, тем самым указывая на истинное изменение импульса, а не на шум. Таким образом эти показатели ATR должны быть очень чувствительными, поэтому установка более низкого периода ATR (например, 7 или 10 вместо типичного значения 14) может использоваться для более быстрых рынков или краткосрочных стратегий, обеспечивая лучшую приспособляемость к волатильности. При свинг-трейдинге более длительный период ATR (например, 14 или 20) сглаживает шум и обеспечивает более стабильный сигнал подтверждения пробоя.
Однако наша реализация на языке MQL5 использует несколько иной подход: мы отслеживаем колебания цен относительно абсолютного значения ATR. Если изменения цены в определенном направлении происходят при разумном движении ATR, превышающем оптимизированный порог, то срабатывает новый сигнал в направлении ценового тренда. Код выглядит так:
//+------------------------------------------------------------------+ //| Check for Pattern 1. | //+------------------------------------------------------------------+ bool CSignalATR::IsPattern_1(ENUM_POSITION_TYPE T) { if(ATR(X()) >= m_threshold_points*m_symbol.Point()) { if(T == POSITION_TYPE_BUY && Close(X()) > Close(X() + 1) && Close(X() + 1) > Close(X() + 2) && Close(X() + 2) > Close(X() + 3)) { return(true); } else if(T == POSITION_TYPE_SELL && Close(X()) < Close(X() + 1) && Close(X() + 1) < Close(X() + 2) && Close(X() + 2) < Close(X() + 3)) { return(true); } } return(false); }
Тестовый запуск оптимизаций только с этим паттерном дал нам следующие результаты:
ATR как сигнал выхода
Измерение волатильности рынка с помощью ATR делает его эффективным инструментом для определения динамических точек выхода на основе текущих рыночных условий. В отличие от стратегий выхода с фиксированным пипсом или точкой, выходы на основе ATR адаптируются к волатильности рынка, гарантируя, что выходы происходят на значимых уровнях, а не на произвольных пороговых значениях. Внезапное увеличение значений ATR может указывать на значимое рыночное событие (протоколы ФРС и так далее) или потенциальный разворот. Таким образом, трейдеры могут принять решение о выходе из позиции, когда ATR превышает определенный порог, сигнализируя о повышенной волатильности, которая может привести к истощению тренда или развороту. Таким образом, этот ожидаемый разворот действительно представляет собой сигнал.
Свинг-трейдеры могут дополнительно использовать ATR для выхода из позиций на ключевых известных/идентифицированных уровнях цен, добавляя или вычитая кратное значение ATR к недавним максимумам или минимумам колебаний. Это позволяет им учитывать среднее движение цены и выходить вблизи ключевых точек разворота. Эта форма выхода, основанная на уровнях ATR свинг-трейдерами, снижает подверженность неблагоприятным отклонениям или необоснованным просадкам, особенно в периоды повышенной волатильности, которые могут сигнализировать о надвигающемся развороте или фазе консолидации.
Кроме того, на рынках с ограниченным диапазоном ATR, как правило, низкий, поэтому, когда ATR внезапно растет, это может указывать на потенциальный прорыв или повышенную волатильность. Трейдеры могли бы использовать этот рост как сигнал к выходу, если бы они находились в пределах диапазона. Главное правило здесь заключается в том, что постоянный отказ от выхода из позиций при низкой волатильности помогает трейдерам избегать попадания в ловушку изменчивых, боковых рынков, тем самым поддерживая благоприятный профиль риска/прибыли в своих сделках. Однако наша реализация на MQL5 немного упрощена, поскольку мы создаем пользовательский класс сигнала и ищем вход. Код паттерна 2:
//+------------------------------------------------------------------+ //| Check for Pattern 2. | //+------------------------------------------------------------------+ bool CSignalATR::IsPattern_2(ENUM_POSITION_TYPE T) { if(ATR(X()) >= 2.0 * m_threshold_points*m_symbol.Point()) { if(T == POSITION_TYPE_SELL && Close(X()) > Close(X() + 1) && Close(X() + 1) > Close(X() + 2) && Close(X() + 2) > Close(X() + 3)) { return(true); } else if(T == POSITION_TYPE_BUY && Close(X()) < Close(X() + 1) && Close(X() + 1) < Close(X() + 2) && Close(X() + 2) < Close(X() + 3)) { return(true); } } return(false); }
Наш подход по сути предполагает разворот тренда, когда значения ATR становятся слишком высокими, более чем в два раза превышая оптимизированный порог. Это, безусловно, не лучший подход к использованию этого фактора, поскольку читатели, возможно, уже заметили, что выше мы упомянули "более интересные" способы извлечения выгоды из выходов. Однако, как всегда, прилагаемый исходный код можно изменить, чтобы реализовать альтернативный подход. Тестовый прогон краткой оптимизации для пары EUR CHF на 2022 год на часовом таймфрейме дает нам следующие результаты:
Сигнал сокращения волатильности
Сокращение ATR также может служить сигналом к подготовке к росту волатильности — затишью перед бурей. Периоды низкой волатильности обычно предшествуют резкому росту цен или всплеску волатильности. Некоторые трейдеры часто отслеживают сокращение ATR, чтобы предвидеть вероятность прорыва и подготовиться к предстоящему движению. Внезапный рост ATR после такого периода часто является убедительным подтверждением того, что произошел прорыв. Таким образом, трейдеры могут использовать сокращение ATR для входа в сделки, как только волатильность снова начнет расти, тем самым следуя тренду.
Еще одно преимущество сокращений ATR касается ограниченных по времени выходов. Некоторые трейдеры выходят из позиций после определенного периода времени, поэтому использование ATR для определения того, когда закрывать позиции, которые стагнируют, может быть в этом случае очень полезным. Если ATR низкий или снижается с течением времени, это может быть сигналом о снижении импульса, что имеет смысл для выхода, поскольку удержание позиции не даст значительного движения. В стратегиях следования за трендом сокращение ATR также может быть полезным. При сильном тренде начало сокращения может быть сигналом о том, что тренд теряет импульс и, возможно, входит в консолидацию. То есть следует подготовиться к потенциальным разворотам, либо зафиксировать прибыль. Для трейдеров, торгующих по тренду, имеет смысл временно выйти.
Для свинг-трейдеров сокращение ATR может быть сигналом того, что цена застряла в фазе консолидации и пришло время выходить из позиций, чтобы не оказаться в боковом движении. И наоборот, как только сокращение закончится, свинг-трейдеры могут искать точки входа, когда волатильность снова начнет расти. В качестве альтернативы, свинг-трейдеры могут использовать сокращение ATR для определения рынков с ограниченным диапазоном и торговли в этом диапазоне, покупая на уровне поддержки и продавая на уровне сопротивления до тех пор, пока не произойдет прорыв или пробой.
Также стоит отметить, что сокращение ATR часто происходит одновременно со снижением объемов торгов, особенно на непрозрачных форекс-рынках, что обычно свидетельствует о нерешительности участников. Увеличение объема и расширение ATR указывает на потенциальный прорыв, поскольку на рынок поступает новая ликвидность. Объединение сокращения ATR с последующим ростом объема является полезным подтверждением для трейдеров, рассчитывающих на прорыв и желающих войти во время расширения волатильности. В этой статье сокращение волатильности как сигнал входа используется для обнаружения разворотов. Эти ожидаемые развороты затем определяют наше предполагаемое направление цены. Если ATR снижается после нисходящего тренда, мы ожидаем отката и, следовательно, имеем бычий сигнал. Если же падение ATR произойдет ближе к концу бычьего тренда, мы воспринимаем это как медвежий сигнал. Необходимый код приведен ниже:
//+------------------------------------------------------------------+ //| Check for Pattern 3. | //+------------------------------------------------------------------+ bool CSignalATR::IsPattern_3(ENUM_POSITION_TYPE T) { if(ATR(X()) < ATR(X() + 1) && ATR(X() + 1) < ATR(X() + 2) && ATR(X() + 2) < ATR(X() + 3)) { if(T == POSITION_TYPE_SELL && Close(X() + 3) > Close(X() + 4) && Close(X() + 4) > Close(X() + 5) && Close(X() + 5) > Close(X() + 6)) { return(true); } else if(T == POSITION_TYPE_BUY && Close(X() + 3) < Close(X() + 4) && Close(X() + 4) < Close(X() + 5) && Close(X() + 5) < Close(X() + 6)) { return(true); } } return(false); }
Тестовый прогон некоторых результатов оптимизации, в которых используется только паттерн 3 (при этом входным параметром для Patterns Used является 8) дает нам следующие результаты:
Канал ATR (диапазоны ATR)
Каналы ATR (также известные как полосы ATR) — это динамические полосы, основанные на волатильности, которые можно построить выше и ниже цены, используя кратное среднего истинного диапазона (ATR). Как и полосы Боллинджера, они помогают создать канал вокруг цены, который в этом конкретном случае может быть полезен для отражения волатильности рынка.
И так же, как и полосы, они расширяются и сужаются в зависимости от волатильности цен, предоставляя трейдерам представление о том, насколько цена обычно отклоняется от своего среднего значения в течение заданного периода времени. Кроме того, верхняя и нижняя полосы действуют как динамические уровни поддержки и сопротивления соответственно, поскольку цена имеет тенденцию колебаться в пределах этих полос. Касание или пробитие этих "уровней" может подавать сигналы о потенциальном развороте или продолжении. В отличие от статических уровней поддержки/сопротивления, они, несомненно, более динамичны, что делает их более восприимчивыми к преобладающим рыночным условиям.
Таким образом, сигналы от этих полос возникают, когда цена прорывается выше верхней полосы ATR, что свидетельствует о бычьем тренде или повышенном давлении покупателей, в то время как прорыв ниже нижней полосы может указывать на медвежий тренд или давление продавцов. Для ручного трейдера необходимо реализовать пользовательский индикатор, который физически отображает эти полосы, но в нашем случае, поскольку мы используем советники, собранные в Мастере (новички могут почитать об этом здесь и здесь), нам не нужно беспокоиться об этом. Поскольку мы автоматизируем наш торговый процесс, мы можем взять два отдельных показания индикатора — скользящую среднюю цены и ATR — и суммировать их, чтобы определить эти полосы на каждом новом баре. Реализуем паттерн на MQL5 следующим образом:
//+------------------------------------------------------------------+ //| Check for Pattern 4. | //+------------------------------------------------------------------+ bool CSignalATR::IsPattern_4(ENUM_POSITION_TYPE T) { if(T == POSITION_TYPE_BUY && Close(X()) > MA(X()) + 2.0 * ATR(X())) { return(true); } else if(T == POSITION_TYPE_SELL && Close(X()) < MA(X()) - 2.0 * ATR(X())) { return(true); } return(false); }
Такие полосы могут выполнять дополнительные функции, например, фильтровать ложные прорывы при использовании с другими индикаторами, такими как полосы Боллинджера или каналы Кельтнера, подтверждая, что прорыв достаточно значительный. Другие приложения для канала ATR немного пересекаются с тем, что мы упомянули выше, однако их все равно стоит упомянуть. Каналы ATR могут помочь определить силу и направление тренда. Когда цена постоянно движется вблизи верхней полосы ATR, это указывает на сильный бычий тренд. Аналогично, движение цены вдоль нижней полосы указывает на сильный медвежий тренд. Такое выявление трендов может оказаться полезным на некоторых рынках, которые на больших временных интервалах демонстрируют резкие колебания. И наоборот, если цена с трудом вырывается из полос ATR или часто касается полос без дальнейшего развития, это может быть признаком истощения тренда или снижения импульса.
Трейдеры также используют полосы ATR для определения возможностей возврата к среднему значению, особенно на рынках с ограниченным диапазоном. Когда цена касается верхней или нижней полосы, это может быть сигналом того, что актив перекуплен или перепродан, и вероятен разворот к среднему значению (средней цене). Поэтому, в зависимости от рассматриваемого таймфрейма, когда цена отскакивает от верхней или нижней полосы ATR, не прорывая ее, это может быть сигналом для трейдеров зафиксировать прибыль или развернуть свои позиции.
При использовании тейк-профита на основе волатильности эти полосы могут обеспечивать динамические уровни, основанные на волатильности. Тейк-профит, размещенный сразу за пределами полосы ATR, может помочь защитить сделки от обычного рыночного шума, оставляя место для колебаний цен в пределах полосы. Это не было учтено в нашей реализации паттерна 4, поскольку мы создаем пользовательский класс сигнала, однако он может быть включен в пользовательский трейлинг-класс другого советника, собранного Мастером. Тестовые прогоны из периода оптимизации с настройками, аналогичными тем, что мы использовали выше (EURCHF H1, 2022 год), выглядят следующим образом:
Затем мы выполняем оптимизацию по всем этим сигналам, объединяя их в один с различными весами. В результате одного из благоприятных прогонов оптимизации мы получаем следующие тестовые прогоны.
ATR в трейлинг-классе
Мы рассмотрели, как можно использовать ATR для генерации сигналов входа и выхода для советника, хотя это не всегда является основной целью или применением. В первую очередь ATR используется для размещения стоп-ордеров или, в крайнем случае, для определения размера позиции, поэтому мы рассмотрим их в пользовательских классах, которые по-прежнему можно собрать в советнике с помощью Мастера MQL5.
Мы придерживаемся простой реализации: для определения уровня трейлинг-стопа мы просто увеличиваем эталонный показатель на величину, кратную ATR. Для наших целей бенчмарк может иметь три формы. Уровни необработанной цены, скользящей средней и индикатора SAR. Каждый из них, в своей части, предоставляет нам паттерн, который мы индексируем 0, 1 и 2 и кодируем следующим образом:
//+------------------------------------------------------------------+ //| Check for Pattern 0. | //+------------------------------------------------------------------+ void CTrailingATR::IsPattern_0(double &Price, ENUM_POSITION_TYPE T) { if(T == POSITION_TYPE_BUY) { Price -= (m_stop_level * ATR(StartIndex())); } else if(T == POSITION_TYPE_SELL) { Price += (m_stop_level * ATR(StartIndex())); } } //+------------------------------------------------------------------+ //| Check for Pattern 1. | //+------------------------------------------------------------------+ void CTrailingATR::IsPattern_1(double &Price, ENUM_POSITION_TYPE T) { if(T == POSITION_TYPE_BUY) { Price = (MA(StartIndex()) - (m_stop_level * ATR(StartIndex()))); } else if(T == POSITION_TYPE_SELL) { Price = (MA(StartIndex()) + (m_stop_level * ATR(StartIndex()))); } } //+------------------------------------------------------------------+ //| Check for Pattern 2. | //+------------------------------------------------------------------+ void CTrailingATR::IsPattern_2(double &Price, ENUM_POSITION_TYPE T) { if(T == POSITION_TYPE_BUY && SAR(StartIndex()) < Low(StartIndex())) { Price = (SAR(StartIndex()) - (m_stop_level * ATR(StartIndex()))); } else if(T == POSITION_TYPE_SELL && SAR(StartIndex()) > High(StartIndex())) { Price = (SAR(StartIndex()) + (m_stop_level * ATR(StartIndex()))); } }
Оптимизацию и тестовые прогоны можно выполнять последовательно, как мы это делали выше, однако для краткости мы выполним только один прогон, который попытается оптимизировать использование всех паттернов с разными весами. Результаты представлены ниже:
ATR в управлении капиталом
Разрывы стоп-лосса могут быть полезны при определении размера позиции. Если у трейдера открыта позиция, то стоп-лосс — это то, что ограничит максимальный убыток, который он может понести по этой позиции, если сделка пойдет не в его пользу. Таким образом, измеряя тиковое значение разрыва стоп-лосса, можно получить условную величину размера позиции в лотах, которая не будет активировать более установленного процента от свободной маржи на тот момент времени.
Вооружившись уровнем стоп-лосса и максимальным процентом риска, мы можем получить лоты, которые теоретически ограничат наши потери. Это в теории, поскольку стопы не гарантируют цену. Они срабатывают только в том случае, если эта цена доступна, поэтому январь 2015 года оказался катастрофическим для трейдеров с позициями по CHF. Какая же страховка самая лучшая? Минимальный и продуманный размер позиции. Если мы применим те же 3 различных возможных метода стоп-лосса, которые мы использовали выше с трейлинг-стопом, вот как мы реализуем 3 параллельных паттерна для пользовательского класса управления капиталом:
//+------------------------------------------------------------------+ //| Getting lot size for open long position. | //+------------------------------------------------------------------+ double CMoneyATR::CheckOpenLong(double price, double sl) { if(m_symbol == NULL) return(0.0); //--- select lot size double lot; if(price == 0.0) lot = m_account.MaxLotCheck(m_symbol.Name(), ORDER_TYPE_BUY, m_symbol.Ask(), m_percent); else lot = m_account.MaxLotCheck(m_symbol.Name(), ORDER_TYPE_BUY, price, m_percent); //--- double result = 0.0, results = 0.0; price =m_symbol.Bid(); //--- if the model 0 is used and "ATR-Based Stop Loss" if(((m_patterns_usage & 0x01) != 0)) { IsPattern_0(price, POSITION_TYPE_BUY); result += m_pattern_0 * price; results += m_pattern_0; } //--- if the model 1 is used and "ATR-MA-Channel Stop Loss" if(((m_patterns_usage & 0x02) != 0)) { IsPattern_1(price, POSITION_TYPE_BUY); result += m_pattern_1 * price; results += m_pattern_1; } //--- if the model 2 is used and "ATR-SAR-Channel Stop Loss" if(((m_patterns_usage & 0x04) != 0)) { IsPattern_2(price, POSITION_TYPE_BUY); result += m_pattern_2 * price; results += m_pattern_2; } //--- if(results > 0) { result /= results; double _risk = (fabs(m_symbol.Bid()-result)/m_symbol.Point())*(m_symbol.TickSize()/m_symbol.Point())*m_symbol.TickValue(); _risk /= m_account.FreeMargin(); _risk *= 100.0; double _risk_lots = m_percent/_risk;// where m_percent is also max risk lot = fmin(2.0*lot, fmax(_risk_lots, m_symbol.LotsMin())); } //--- return trading volume return(Optimize(lot)); } //+------------------------------------------------------------------+ //| Getting lot size for open short position. | //+------------------------------------------------------------------+ double CMoneyATR::CheckOpenShort(double price, double sl) { if(m_symbol == NULL) return(0.0); //--- select lot size double lot; //--- if(price == 0.0) lot = m_account.MaxLotCheck(m_symbol.Name(), ORDER_TYPE_SELL, m_symbol.Bid(), m_percent); else lot = m_account.MaxLotCheck(m_symbol.Name(), ORDER_TYPE_SELL, price, m_percent); //--- double result = 0.0, results = 0.0; price =m_symbol.Ask(); //--- if the model 0 is used and "ATR-Based Stop Loss" if(((m_patterns_usage & 0x01) != 0)) { IsPattern_0(price, POSITION_TYPE_SELL); result += m_pattern_0 * price; results += m_pattern_0; } //--- if the model 1 is used and "ATR-MA-Channel Stop Loss" if(((m_patterns_usage & 0x02) != 0)) { IsPattern_1(price, POSITION_TYPE_SELL); result += m_pattern_1 * price; results += m_pattern_1; } //--- if the model 2 is used and "ATR-SAR-Channel Stop Loss" if(((m_patterns_usage & 0x04) != 0)) { IsPattern_2(price, POSITION_TYPE_SELL); result += m_pattern_2 * price; results += m_pattern_2; } //--- if(results > 0) { result /= results; double _risk = (fabs(result-m_symbol.Ask())/m_symbol.Point())*(m_symbol.TickSize()/m_symbol.Point())*m_symbol.TickValue(); _risk /= m_account.FreeMargin(); _risk *= 100.0; double _risk_lots = m_percent/_risk;// where m_percent is also max risk lot = fmin(2.0*lot, fmax(_risk_lots, m_symbol.LotsMin())); } //--- return trading volume return(Optimize(lot)); }
Помимо того, что этот подход имеет недостаток, заключающийся в чрезмерной зависимости от доступности цены стоп-лосса, время от времени он сопряжен с риском установки слишком больших размеров лотов в случаях, когда разрыв стоп-лосса очень мал. Вот почему мы нормализуем лоты так, чтобы они не превышали в два раза лоты, которые мы получили бы при проценте риска по умолчанию от свободной маржи. Таким образом, этот процент риска (m_percent) служит двум целям: во-первых, он определяет потолок наших лотов, если мы собираемся покупать лоты, используя его в качестве процента от свободной маржи, во-вторых, он также определяет условный максимальный процент свободной маржи, который мы потеряем, если наш стоп-лосс будет на установленном уровне.
Тестовые прогоны с лучшими результатами оптимизации, опять же с настройками, аналогичными указанным выше, дают нам следующие результаты:
И снова мы не проводили тестовые прогоны для каждого паттерна, а просто оптимизировали наш советник для использования всех паттернов, хотя и с разным весом, как это было в случае с трейлинг-стопами выше.
Заключение
В этой статье было предложено довольно много различных идей и реализаций ATR, однако для краткости они не были реализованы в коде и протестированы. Поэтому читатель может продолжить работу над ними, самостоятельно реализуя и тестируя их, в идеале на еще более широком наборе символов и на большем количестве исторических данных, чтобы лучше понять, что подходит лично для него.
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/16213





- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования