
Возможности Мастера MQL5, которые вам нужно знать (Часть 27): Скользящие средние и угол атаки
Введение
Мы продолжаем серию статей о торговых настройках и идеях, которые можно быстро протестировать и защитить от ошибок с помощью Мастера MQL5. Сегодня рассмотрим угол атаки (angle of attack). В широком смысле фраза "угол атаки" означает идеальный угол, под которым должен взлетать истребитель для достижения максимальной подъемной силы и минимального расхода топлива.
Для трейдеров эта фраза обычно относится к траектории движения цены актива в период тренда. Считается, что крутой угол указывает на сильный тренд. Мы начнем с изучения инструментов для измерения индикатора. Затем мы подвергнем этот подход критике, указав на некоторые связанные с ним проблемы, предложим потенциально лучшую альтернативу и, как всегда, завершим результатами тестирования и отчетами.
Мы, как всегда, используем экземпляр пользовательского класса сигнала для проверки наших гипотез о том, как измерить угол атаки, и измерим этот угол не по необработанной цене, а по скользящей средней. Мы используем затухающую скользящую среднюю в качестве индикатора для измерения и отслеживания значимости угла атаки. Для мониторинга углов атаки также можно использовать необработанные цены, однако, поскольку они неизбежно будут более волатильными, чем индикаторный буфер, мы применим именно скользящую среднюю. Можно было бы использовать любую скользящую среднюю, но мы выбрали затухающую, поскольку она относительно новая и может быть незнакома большинству трейдеров.
Современные подходы к использованию угла атаки
Простейший подход к определению угла атаки начинается с определения двух ценовых точек в пределах ценового или индикаторного буфера, от которого будет измеряться угол. Таким буфером могут быть необработанные цены активов, но они, как правило, очень волатильны, поэтому чаще используют сглаженный буфер, например буфер скользящей средней. Таким образом на дневном таймфрейме мы получим скользящую среднюю за сегодня и скользящую среднюю за N дней назад.
За этим следует определение изменения скользящей средней за период, что в нашем случае равно N периодам, за которые получены два значения скользящей средней. Первое, что обычно определяется, — это наклон m, который можно вычислить с помощью формулы, представленной ниже:
где:
- MA (today) — скользящее среднее на сегодняшний день.
- MA (N days ago) — скользящее среднее N дней назад.
- N — количество дней между двумя точками.
Возвращаемое значение m из нашей формулы выше представляет собой наклон и пропорционально углу атаки скользящей средней. В его нынешнем формате его можно использовать в качестве индикатора крутизны и, следовательно, ценовой динамики. Однако для многих людей понятие угла относится к чему-то на бумаге, что для целей данного ценового действия будет находиться в диапазоне от 0 до 90 градусов.
Если вы хотите представить этот наклон как угол, вы должны использовать функцию арктангенса (обратного тангенса) для преобразования наклона в градусы:
Возвращаемое значение θ — это угол в радианах. Чтобы перевести его в градусы, нужно умножить его на:
Чтобы увидеть это в действии, давайте рассмотрим очень простой пример применения. Предположим, у вас есть следующие данные за 10-дневный период:
- 10 дней назад скользящая средняя была равна 100
- Сегодня она равна 110
Исходя из нашей простой формулы выше, наклон m будет равен:
Отсюда угол θ (тета) в радианах будет равен:
А если перевести это в градусы:
В конечном итоге мы получим значение, которое, по мнению многих людей, находится на грани очень высокого. 45 градусов. Если бы рассматриваемая ценная бумага была валютной парой с иеной, такое значение было бы оправдано. Однако рассмотрим ситуацию, когда цена акций технологической компании растет на ту же величину, но за один день. Если мы проделаем те же вычисления, что и выше, наш угол составит 84 градуса, что близко к 90! Однако базовая интерпретация "угла атаки" при таком подходе, который не является стандартным термином в финансовом анализе, приводит к интерпретации наклона скользящей средней как показателя силы и направления тренда. Чем круче угол (или наклон), тем сильнее тренд.
Проблемы с текущим подходом и методами
Как упоминалось выше, при применении текущих измерений угла атаки существует ряд проблем, в первую очередь связанных с чрезмерной чувствительностью к шкале цен и непостоянными результатами измерения угла в различных временных рамках. Чтобы проиллюстрировать это, начнем с проблемы чувствительности к ценам.
Если бы нашим торгуемым активом была валютная пара, не включающая иену, например GBPUSD, то сопоставимое 10-дневное изменение цены, которое для этой пары составило бы около 0,10, дало бы значение m, равное 0,01. Если умножить это значение на 180, а затем разделить результат на число Пи, то получим угол 0,57 градуса. Из наших наблюдений мы знаем, что 45 градусов и 0,57 градуса — это огромная разница по величине, и тем не менее обе валюты, пара с иеной и GBPUSD, совершили движение на 10 000 пунктов! Можно было бы предположить, что эта разница в углах объясняется большей волатильностью пар с иеной, но соотношение двух углов составляет 90!! Большинство трейдеров согласятся, что иена вряд ли в 90 раз более волатильна, чем не-иеновые пары, такие как GBPUSD. Очевидно, это связано с тем, что для правильной оценки изменения цен валютных пар необходимо учитывать значение тика движения пункта. И если верить forex.com самые волатильные пары в 2023 году — AUDUSD и NZDUSD!
Самая волатильная пара с иеной находится на 3-м месте, и это несмотря на то, что и AUDUSD, и NZDUSD торгуются с пятью знаками после запятой, что означает, что наше движение на 0,10 пункта выше даст тот же угол в 0,57 градуса.
Согласно списку forex.com, пара AUDUSD оказалась на первом месте по волатильности из-за среднего дневного изменения в 1,04%. При приблизительной цене 0,68150 движение за 10 дней со скоростью 1,04% в день составит 0,070876. Это даст нам m, или наклон, равный 0,0070876, и угол за 10 дней, равный 0,406 градуса. Меньше, чем 0,507, которые мы оценили для GBPUSD выше, но ближе к GBPJPY, которая заняла 7-е местов списке со средним изменением цены 0,81%. Такое изменение цены за аналогичные 10 дней при базовой цене 147,679 составит угол в 50,1 градуса!
Конечно, угол атаки не предназначен для измерения волатильности как таковой, однако большинство читателей и трейдеров, я думаю, ожидают, что величина предполагаемого угла атаки будет в некотором роде мерой размера возможного движения цены актива. Тот факт, что это явно не так, ставит под угрозу такой подход к измерению угла. В дополнение к этим несоответствиям, связанным с чувствительностью к цене, изменения в графике/временном интервале анализа могут существенно повлиять на размер угла атаки.
Рассмотрим, например, приведенные выше случаи, если бы мы перешли с дневного таймфрейма, скажем, на 4-часовой. На самой первой иллюстрации, где у нас был угол 45 градусов, это значение изменится до 0,95 градуса! Возникает вопрос: почему при простой "детализации" периода, в течение которого мы измеряем угол, не внося никаких изменений в шкалу цен, мы внезапно получаем очень плоский угол, составляющий менее одного градуса? Навскидку на этот вопрос можно ответить так: у нас удлиненное основание, и поэтому угол поднимается меньше по сравнению с той же высотой, но поскольку длина основания на самом деле одинакова при измерении во времени, этого искажения быть не должно.
Представляем альтернативный метод
Более детальное изучение проблем, вызванных изменениями временных рамок, действительно открывает возможное решение. В любом треугольнике, когда мы ищем величину угла и нам представлены как высота, так и основание для этого прямоугольного треугольника, арктангенс основания, деленный на высоту, должен дать нам один из углов в градусах.
Итак, на изображении выше основание большего прямоугольного треугольника на самом деле равно 1 (оно больше cosθ), поэтому наша противоположная сторона имеет высоту tanθ. Ключевым моментом является то, что единицы измерения смежной стороны (основания) аналогичны единицам измерения противоположной стороны (высоты). В этом случае вы получаете значимые значения градуса для тета, когда находите арктангенс или арккосинус угла тета.
Приведенный выше рисунок хоть и содержит "слишком много информации", подчеркивает определение тангенса как коэффициента. Синус к косинусу. Или подобное к подобному. Чтобы угол тета имел смысл, горизонтальная ось должна иметь те же единицы измерения, что и вертикальная. Тогда возникает вопрос: как можно гармонизировать две оси цены и времени, чтобы они имели одинаковые единицы измерения?
При этой нормализации можно сделать выбор: либо обе оси — временную и ценовую — преобразовать в единицы времени, либо обе — в единицы цены. Поначалу идея преобразования может показаться радикальной, но как только мы начнем изучать и сравнивать результаты, все станет понятно. Поскольку цена имеет решающее значение, а движение цены в неправильном направлении приведет к просадке, у нас будут как "вертикальная", так и "горизонтальная" оси нашего ценового действия, отмеченные в единицах цены. Возникает вопрос: как нам перемасштабировать ось времени в цену?
Для этого можно использовать ряд подходов. Цель данной статьи не в том, чтобы перечислить их все или обязательно использовать "лучший" из них. Однако мы будем использовать переменную шкалу. При представлении любых двух ценовых точек, находящихся на расстоянии D друг от друга во времени, расстояние D будет преобразовано в ценовые единицы диапазона цен по сравнению с предыдущим расстоянием D. Всё кажется довольно простым, но при этом мы получаем относительно стабильные результаты для величины угла атаки. Реализация в MQL5 может выглядеть так:
//+------------------------------------------------------------------+ //| Get Angle function //+------------------------------------------------------------------+ double CSignalAA::Angle(int Index) { double _angle = 0.0; double _price = DM(Index) - DM(Index+m_length_period); double _max = DM(Index+m_length_period+1); double _min = DM(Index+m_length_period+1); for(int i=Index+m_length_period+2;i<Index+(2*m_length_period);i++) { double _dm = DM(i); _max = fmax(_max, _dm); _min = fmin(_min, _dm); } double _time = fmax(m_symbol.Point(), _max - _min); _angle = (180.0 / M_PI) * MathArctan(fabs(_price) / _time); if(_price < 0.0) { _angle *= -1.0; } return(_angle); }
Наша функция просто берет два индексных заполнителя и использует их для определения того, откуда измерять угол атаки, а также, как упоминалось выше, насколько далеко в историю следует зайти в поисках ценового диапазона, который служит нашей мерой времени или значением горизонтальной оси. Диапазон цен в выбранной истории может быть равен нулю, поэтому у нас есть точка, определяемая минимальным размером ценовой точки торгуемого актива, которая служит минимальным диапазоном. Читатели могут изменить это значение на текущий спред или на любое другое значение, если нет деления на ноль. Мы имеем в виду функцию затухающей скользящей средней (DM), которая представлена ниже.
Затухающая скользящая средняя (DMA)
Эта скользящая средняя дает экспоненциально затухающие веса, которые уменьшаются быстрее, чем в традиционных экспоненциальных скользящих средних. Определяется по следующей формуле:
где
- n - размер усредненной выборки
- i - индекс положения в выборке
- P - цена в момент времени i
Как и некоторые новые скользящие средние, которые мы рассматривали в недавних статьях этой серии, эту можно реализовать как функцию или пользовательский индикатор, если вы хотите торговать вручную с ее помощью. Пользовательские индикаторы хорошо справляются с буферизацией, что может обеспечить дополнительную эффективность даже советнику. Однако в целях тестирования мы придерживаемся функционального подхода, поскольку пользовательский индикатор подразумевает, что к нашему скомпилированному советнику будут предъявляться дополнительные требования.
Существует множество экспоненциальных средних, которые придают больший вес недавним ценам, но я думаю, что затухающая скользящая средняя делает это наилучшим образом. Реализация в MQL5 выглядит так:
//+------------------------------------------------------------------+ //| Decaying Mean | //+------------------------------------------------------------------+ double CSignalAA::DM(int Index, int Mask = 8) { double _dm = 0.0; vector _r; if(_r.CopyRates(m_symbol.Name(), m_period, Mask, Index, m_length_period)) { //vectors are not series double _weight = 0.0; for(int i = 0; i < m_length_period; i++) { _dm += (1.0/pow(2.0, m_length_period-i))*_r[i]; _weight += (1.0/pow(2.0, m_length_period-i)); } if(_weight != 0.0) { _dm /= _weight; } } return(_dm); }
Мы просто применяем вес к каждой цене в выборке, которая усредняется, при этом следует учитывать, что векторы не копируют цены как ряды. Это означает, что нам необходимо знать, что самая высокая цена индекса — это последняя цена или цена, наиболее близкая к индексу, с которого мы начали копирование. Это означает, что наше взвешивание (показатель степени, заданный для знаменателя 2) будет изменено на противоположное, поскольку мы выполняем подсчет в цикле for.
Класс сигналов
Чтобы объединить все это в класс, мы добавляем функции затухания среднего (decay-mean) и угла (angle) к экземпляру класса сигнала и, конечно, вносим изменения в условия покупки и продажи:
//+------------------------------------------------------------------+ //| "Voting" that price will grow. | //+------------------------------------------------------------------+ int CSignalAA::LongCondition(void) { int result = 0; double _angle = Angle(StartIndex()); if(_angle >= m_threshold) { result = int(round(100.0 * ((_angle) / (90.0)))); } return(result); } //+------------------------------------------------------------------+ //| "Voting" that price will fall. | //+------------------------------------------------------------------+ int CSignalAA::ShortCondition(void) { int result = 0; double _angle = Angle(StartIndex()); if(_angle <= -m_threshold) { result = int(round(100.0 * (fabs(_angle) / (90.0)))); } return(result); }
Наши условия действительно просты, и все, что они проверяют, — это то, превышает ли угол, измеренный от входного расстояния, или равен ли он входному пороговому значению по величине. Это означает, что наши условия по своей сути являются следствием тренда. Функция Angle возвращает положительное или отрицательное значение, проверяемое условиями на покупку и продажу перед открытием позиции. Подход следования за трендом можно перевернуть в ситуациях, когда угол слишком крутой. Предлагаю читателям самостоятельно разобраться и посмотреть, есть ли в этом какие-либо достоинства. Еще один интересный момент - это то, как мы определили размер значения result в условиях. Поскольку наша функция Angle теперь возвращает более "постоянные" значения по сравнению с теми, которые дает классический подход, мы можем быть уверены, что не получим угол, превышающий или даже близкий к 90 градусам по величине.
Вот почему мы нормализуем абсолютное значение угла, разделив его на 90 и изменив масштаб так, чтобы оно находилось в требуемом диапазоне от 0 до 100. Опять же, можно изучить альтернативные подходы к нормализации, но именно этот подход, как правило, придает наибольший вес значению угла атаки, который является основной темой данной статьи.
Тестирование стратегии и отчеты для обоих подходов
При проведении тестов на 4-часовом временном интервале для пары GBPCHF за 2023 год (с 01.01.2023 по 01.01.2024) мы получаем следующие результаты:
Они указывают на некоторый потенциал, однако сделок совершается недостаточно. И, конечно же, помимо того, что эти прогоны ограничены всего лишь годом, они не используют функцию прогнозирования стратегии, которая может служить быстрым фильтром для определения того, что сработает, а что нет. Однако мы использовали затухающий наклон скользящей средней в качестве нашего приближения к наклону цены, и поскольку эта конкретная средняя сильно смещена в сторону самых последних цен, мы обязательно получим множество резких колебаний сигналов.
Критический угол атаки
Понятие критического угла позаимствовано из аэродинамики. До сих пор мы искали условия покупки и продажи, основываясь исключительно на величине затухающего угла скользящей средней. Критический угол атаки наводит на мысль о том, что этот угол, на котором мы основываем наши решения об открытии, на самом деле лучше определить как находящийся в пределах полосы или определенного диапазона, а не единичного порогового значения. Чтобы протестировать и использовать эту особенность, мы изменим наш пользовательский класс сигнала, введя дополнительный параметр.
Параметр, который мы добавляем в наш класс сигнала, — это double-значение m_band, которое помогает установить внешний диапазон угла срабатывания, поскольку у нас уже есть пороговое значение. Это изменение будет отражено следующим образом в функциях условий на покупку и продажу:
//+------------------------------------------------------------------+ //| "Voting" that price will grow. | //+------------------------------------------------------------------+ int CSignalAA::LongCondition(void) { int result = 0; double _angle = Angle(StartIndex()); if(_angle >= m_threshold && _angle <= m_threshold+m_band) { result = int(round(100.0 * ((_angle) / (90.0)))); } return(result); } //+------------------------------------------------------------------+ //| "Voting" that price will fall. | //+------------------------------------------------------------------+ int CSignalAA::ShortCondition(void) { int result = 0; double _angle = Angle(StartIndex()); if(_angle <= -m_threshold && _angle >= -(m_threshold+m_band)) { result = int(round(100.0 * (fabs(_angle) / (90.0)))); } return(result); }
Главное изменение — это проверка того, что угол больше порогового значения, как это было в случае с нашим первым сигналом, но также и того, что он ниже верхнего предела, который определяется параметром полосы (band). Если мы проведем тесты с этим сигнальным файлом, собранным в советник (руководства по этому вопросу для новичков можно найти здесь и здесь), мы получаем следующие результаты в результате аналогичного тестового запуска, который мы провели выше:
Быстрое сравнение с нашими предыдущими результатами ясно показывает, что мы не торгуем так часто, и, возможно, этого следовало ожидать, поскольку теперь нам требуется, чтобы угол не только превышал пороговое значение, но и оставался в пределах определенного диапазона. Общая производительность улучшилась по большинству показателей, таких как фактор прибыли, фактор восстановления, процент просадки и т. д. Поэтому этот метод можно было бы изучить более подробно, проведя тестирование в течение более длительных периодов времени с использованием тиковых данных, прежде чем можно будет сделать выводы о его эффективности.
Заключение
Итак, мы рассмотрели угол атаки в качестве метрики для финансовых временных рядов как с традиционной точки зрения, когда угол определяется на основе ценовых и необработанных временных изменений, так и с точки зрения нового подхода, заключающегося в преобразовании временной оси временного ряда в ценовые единицы. Тестирование с использованием предыдущего подхода не было продемонстрировано в этой статье, поскольку мы обнаружили так много несоответствий в том, как измеряется угол атаки, что попытки выполнить прогоны тестера стратегий показались пустой тратой вычислительных ресурсов.
Однако тестирование с использованием нашего нового подхода, при котором горизонтальная или временная ось разграничивается в единицах времени до вычисления угла атаки, дало некоторые многообещающие результаты. Мы провели тесты с использованием этого подхода в двух режимах. Во-первых, мы просто использовали пороговое значение угла, чтобы отсеять, какие позиции нам следует открыть, а во-вторых, задействовали концепцию критического угла, согласно которой для открытия позиции угол атаки должен был не просто превышать пороговое значение, но и быть достаточно близким к пороговому значению, находясь в определенном диапазоне.
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/15241





- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Стивен,
Я просматриваю эту статью, так как она, кажется, дополняет идеи, которые у меня были в прошлом. Кажется, что код, на который ссылается статья, отсутствует. Символы включения <code:.../> присутствуют, но метка, похоже, ссылается на неизвестный исходный файл. Является ли исходным файлом файл, включенный как Attack_Angle_cr.mq5 & Signalwz_c.mqh?
Спасибо, CapeCoddah
Стивен,
Я просматриваю эту статью, так как она, кажется, дополняет идеи, которые у меня были в прошлом. Кажется, что код, на который ссылается статья, отсутствует. Символы включения <code:.../> присутствуют, но метка, похоже, ссылается на неизвестный исходный файл. Является ли исходным файлом файл, включенный как Attack_Angle_cr.mq5 & Signalwz_c.mqh?
Спасибо, CapeCoddah
Здравствуйте,
Код был частью прикрепленного файла. Он был включен в текст и отправлен на публикацию.
Опубликована статья Возможности Мастера MQL5, которые вам нужно знать (Часть 27): Скользящие средние и угол атаки:
Автор: Stephen Njuki