тел.: 8 800 200 86 47|+7 (812) 336 61 11Заказать звонок
Admiral Markets UK Admiral Markets UK Choose your country

MQLabs: Зигзаг волатильности

Индикатор VolatilityZigZag

 

Понимание алгоритма работы индикатора ZigZag, входящего в стандартный пакет терминала Meta Trader 4, т.е. осознание факта программной подтасовки конечного результата, лишь немного охлаждает пытливые умы. Точность фиксации вершин и впадин этим индикатором продолжает действовать на трейдеров как взгляд кобры на будущую жертву перед броском. Поэтому нет ничего удивительного в том, что системы, основанные на показаниях индикатора ZigZag, появляются с завидным постоянством. Не будем и мы отставать от общей тенденции, но попробуем подойти к вопросу как можно более взвешенно и аккуратно, избегая ловушек самообмана.

 

Анализ классического и других индикаторов ZigZag

Одним из главных недостатков классического ZigZag является его привязанность к определенному количеству баров, среди которых производится поиск экстремума для отображения очередной точки ломаной прямой. Это количество указывается пользователем в настроечном параметре ExtDepth. Такой подход, как бы, заранее определяет цикличность изменения направления движений рынка. К этому обстоятельству добавляется еще одно - параметр ExtDeviation, который указывает минимальную высоту отрезка индикатора в пунктах. Мало того, что нам необходимо точно определенное количество баров для фиксации экстремума, так мы еще указываем минимальную разность между соседними экстремумами в пунктах. Причем мы не задумываемся, что на одном рынке 5 пунктов - это "один чих", а на другом - целая вечность.

Описанные недостатки ZigZag явно отдают субъективностью восприятия, попыткой описать лишь общие тенденции, не вдаваясь в детали. Первой попыткой исправления ситуации были индикаторы NeoZigZag_HighLow и NeoZigZag_Close, описанные в статье "Новый ZigZag". Индикаторы не имели настроечных параметров, что позволяло надеяться на появление объективной точки зрения на рыночные перипетии. В принципе, так оно и получилось, но в жертву была принесена минимальная высота между соседними экстремумами. В итоге новые индикаторы реагировали на малейшие пробои одних свечей другими, невзирая на размеры пробоя (см. рис. 1).

Рис. 1. Сравнение новых индикаторов ZigZag с классическим индикатором.

Тонкой синей линией показан индикатор NeoZigZag_HighLow, жирной зеленой - NeoZigZag_Close, а тонкой красной линей показан классический индикатор ZigZag. Стойкость последнего упомянутого индикатора видна невооруженным глазом - классический ZigZag успешно фильтрует "шумовые" движения рынка, выделяя из них наиболее существенные составляющие.

Таким образом, приходим к выводу, что регулировать минимальную допустимую разность между соседними экстремумами, все же, необходимо.

 

Определяем минимальное расстояние между соседними экстремумами

Возвращаться к указанию минимальной разности в пунктах - плохое решение. Следует исходить из текущих рыночных реалий, а не задавать параметры рынка один раз "на глазок". Поэтому вспомним подход, который повсеместно культивируется в проектах MQLabs - использование показателя средней волатильности. Но в этом случае получаем другую проблему - за какой период рассчитывать эту волатильность? Ведь мы намеренно ушли от указания всяческих периодов. Ответ достаточно прост - нужно использовать плавающий период, который зависит от расстояния между текущим моментом и последним экстремумом, включая этот экстремум. Причем расчет средней волатильности будет происходить не на основании показаний индикатора ATR, а на основании собственных расчетов программы, из которых будут исключены все свечи, имеющие нулевую единичную волатильность, т.е. свечи с равными максимумом и минимумом.

После расчета средней волатильности нам потребуется сделать вывод о достаточности прошедшего движения цены в обратном направлении от последнего экстремума. Вот здесь и понадобится единственный настроечный параметр, от которого зависят показания индикатора. Это параметр, указывающий степень превышения средней волатильности амплитудой цены. Например, при средней волатильности участка истории, располагающегося за последним экстремумом, равном 2.125 пунктов, и степени превышения, равной 4, для регистрации противоположного экстремума потребуется амплитуда цены не менее 8.5 пунктов (см. рис 2).

Рис. 2. Амплитуда цены превысила среднюю волатильность.

Средняя волатильность участка, ограниченного на рис. 2 синими вертикальными линиями, рассчитывается для восьми свечей, несмотря на то, что свечей на самом деле девять. Из расчета исключается одна свеча, у которой максимум совпадает с минимумом. Суммарная волатильность остальных восьми свечей составляет 4+2+2+2+1+2+1+3 = 17 пунктов. Таким образом, средняя волатильность выходит 17/8 = 2.125 пункта. При степени превышения, равной 4, амплитуда изменения цен между максимумом и потенциальным минимумом должна быть не меньше, чем 2.125 х 4 = 8.5 пунктов, т.е. в реальности - 9 пунктов и больше. К моменту закрытия свечи, обозначенной правой вертикальной линией, амплитуда цен достигла 11 пунктов, что привело к фиксации минимума.

С момента образования нового минимума необходимо искать возможность фиксации максимума. Но если минимум будет обновлен, как показано на рис. 2 (крайняя справа медвежья свеча, которая не вошла в границы рисунка полностью), то отсчет амплитуды изменения цены начнется сначала, т.к. точкой отсчета всегда является последний экстремум цены.

 

Алгоритм первичного определения экстремума

Для того единственного случая, когда ни одного сложившегося экстремума нет, т.е. когда индикатор только запущен и не может опереться на готовые данные, производится назначение экстремума. Им становится максимум или минимум одной из двух, рядом расположенных, свечей. Так, определяется максимум и минимум среди двух свечей: той, с которой начинается расчет, и той, которая находится слева от начальной. Если на исследуемых свечах наблюдается рост цены, то первичным экстремумом становится максимум. Если свечи расположены в порядке падения цены, то первичным экстремумом становится минимум. Если же определить направление цены не удается (экстремумы свечей равны друг другу или движение видится сразу в обе стороны), то начальное направление выбирается по типу последней свечи: медвежья - падение цены (экстремум - минимум), бычья или доджи - рост цены (экстремум - максимум).

Все вышесказанное реализуется в виде функции DoFirstCalc индикатора VolatilityZigZag:

 
//+-------------------------------------------------------------------------------------+
//| Расчет первых значений индикатора                                                   |
//+-------------------------------------------------------------------------------------+
void DoFirstCalc(int index)
{
   g_high[index] = MathMax(High[index+1],          // Первый максимум - это максимум из..
                           High[index]);           // ..двух соседних свечей
   g_low[index] = MathMin(Low[index+1],            // Первый минимум - это минимум из..
                          Low[index]);             // ..двух соседних свечей
                          
   if ((Low[index] < Low[index+1] &&               // Для тех случаев, когда текущая..
        High[index] > High[index+1])               // ..свеча поглощает предыдущую
       ||                                          // ..первичное направление..
       (Low[index] == Low[index+1] &&              // ..определяется по типу свечи
        High[index] == High[index+1]))
   {                                               
      if (Open[index] > Close[index])              // Медвежья свеча - нисходящее..
      {                                            // ..направление
         ChangeoverToDowncast(index);
         return;
      }
      ChangeoverToUpcast(index);                   // А бычья свеча или доджи -..
      return;                                      // ..восходящее направление
   }
   
   if (Low[index] < Low[index+1])                  // Когда текущая свеча пробивает..
   {                                               // ..предыдущую свечу только в одном..
      ChangeoverToDowncast(index);                 // ..направлении, то проблем с..
      return;                                      // ..определением первичного..
   }                                               // ..направления вообще нет
   
   ChangeoverToUpcast(index);
}

Массивы g_high и g_low - это индикаторные буферы, в которых записываются последние максимум и минимум, достигнутые ценой. Аргумент index - индекс свечи, с которой начинается расчет значений индикатора. Функции ChangeoverToDowncast и ChangeoverToUpcast совершают комплекс действий, необходимых для регистрации смены направления движения - с восходящего на нисходящее и с нисходящего на восходящее соответственно.

Код функций выглядит просто:

 
//+-------------------------------------------------------------------------------------+
//| Смена направления движения на восходящее                                            |
//+-------------------------------------------------------------------------------------+
void ChangeoverToUpcast(int index)
{
   g_low[index] = Low[index];
   g_signOfDir[index] = DIRECTION_UP;
   g_dots[index] = g_high[index];
}
//+-------------------------------------------------------------------------------------+
//| Смена направления движения на нисходящее                                            |
//+-------------------------------------------------------------------------------------+
void ChangeoverToDowncast(int index)
{
   g_high[index] = High[index];
   g_signOfDir[index] = DIRECTION_DN;
   g_dots[index] = g_low[index];
}

При регистрации нового экстремума значение противоположного экстремума теряется. Отсчет противоположного движения цены начинается с бара index и с соответствующего экстремума.

Массив g_signOfDir - это еще один индикаторный буфер, в котором запоминается направление тренда на каждом, пройденном индикатором, баре.

В общем случае, когда первичная информация для индикатора собрана, за дело принимается функция DoCommonCalc:

 
//+-------------------------------------------------------------------------------------+
//| Расчет данных, когда существуют первичные данные                                    |
//+-------------------------------------------------------------------------------------+
void DoCommonCalc(int index)
{
   if (IsExtremumRefresh(index))                   // Если обновлен экстремум текущего..
      return;                                      // ..направления, то определение..
                                                   // ..развития противоположного..
                                                   // ..движения не производится
      
   if (!IsHighPriceRange(index))                   // Если ценовая амплитуда недостаточна
      return;                                      // ..то смена тенденции не происходит

   CurrentDirectionChange(index);
}

Сначала проверяется момент обновления существующего экстремума (функция IsExtremumRefresh), т.е. пробой минимума вниз при нисходящем движении или пробой максимума вверх при восходящем движении. В этом случае противоположный экстремум принимает значение экстремума свечи index, а последующие проверки возможности смены направления не производятся.

Если же действующий экстремум не обновлен, то производится сравнение амплитуды изменения цены и средней волатильности, умноженной на значение параметра индикатора, отвечающего за степень превышения средней волатильности. Достаточное значение амплитуды цены переводит выполнение к вызову функции смены направления движения - CurrentDirectionChange.

Итог работы функций первичного и последующего определения экстремумов, т.е. итог работы индикатора VolatilityZigZag, показан на рис. 3.

Рис. 3. Определение экстремумов индикатором VolatilityZigZag.

Синими линиями показаны отрезки, отображаемые индикатором VolatilityZigZag, а красными линиями - отрезки индикатора ZigZag. Классический индикатор располагается на один слой выше. Поэтому в местах совпадения показаний индикаторов виден только индикатор ZigZag.

 

Момент смены направления движения цены

В мечтах трейдеров показания индикатора ZigZag истолковываются следующим образом: как только появился новый экстремум, отрывается сделка в противоположном от него направлении, т.е. при появлении максимума совершается продажа, а при появлении минимума - покупка. Если бы ZigZag показывал окончательные экстремумы, то такой подход являлся бы единственно верным. Но, поскольку это не так, то наиболее правильным было бы следование наметившемуся тренду. Для этого в момент фиксации очередного экстремума нужно открывать сделку в направлении экстремума: появление максимума - покупка, появление минимума - продажа.

Насколько такой подход верен в случае с классическим ZigZag, еще нужно проверять, но вот в случае с индикатором VolatilityZigZag озвученная тактика более чем уместна. Ведь новый экстремум фиксируется тогда, когда амплитуда изменения цены возрастает выше среднего значения волатильности, рассчитанного среди свечей, находящихся справа по графику от последнего экстремума. Иными словами, коррекция направленного движения переросла те пределы, которые можно считать коррекцией. Поэтому и следует регистрировать противоположный экстремум, чем обозначать новое направление тренда. Такие моменты индикатор VolatilityZigZag обозначает стрелками соответствующего направления (см. рис. 4).

Рис. 4. Моменты регистрации нового тренда.

Исходя из вышесказанного, при использовании показаний индикатора VolatilityZigZag следует стремиться к уменьшению количества участков перегиба линии с целью как можно более продолжительного следования тренду. Это достигается путем увеличения значения настроечного параметра i_cntOfAverages, которым задается степень превышения средней волатильности. Тем не менее, бесконечное увеличение этого коэффициента приводит к увеличению времени реакции на изменение направления тренда, т.е. красные и синие стрелки будут располагаться все дальше и дальше от противоположных экстремумов.

 

Настроечные параметры индикатора

  • i_cntOfAverages - коэффициент, на который необходимо умножить среднюю волатильность последних свечей, расположенных справа от экстремума, чтобы получить минимальную амплитуду изменения цены, которая позволит зарегистрировать противоположный экстремум. Иными словами, насколько резким должно быть движение в противоположном от последнего экстремума направлении, чтобы был зарегистрирован новый тренд. Чем больше значение параметра, тем позже будет подан сигнал о смене направления тренда.

  • i_indBarsCount - количество баров, на которых отображается индикатор.

 

Игорь Герасько

Октябрь 2012

Специально для компании Admiral Markets

3.545455
 
 
X
Loading