Каталог файлов форума

Список вложений в сообщениях, оставленных на этой конференции.

Все файлы форума: 1227

Добавлено: Gerig » 11 апр 2016, 12:49

Тема: Re: ZigZag - индикатор

Текст сообщения:

Хочу представить уважаемым форумчанам некоторые результаты исследований на тему вариаций ZigZag (моей любимой темы, поскольку занимаюсь волновым анализом). Мотивом таких исследований явилось желание сделать индикатор четвертой волны по Эллиотту. Идеи его создания навеял мне изложенный выше пост. Ниже указаны условия при которых формируется это новый ZigZag.
Формирование пика происходит, при выполнении следующих условий:
1. Если имеется такой high свечи в окружении которого, как до него, так и после имеются другие high свечи меньшие на параметр Delta (задается в процентах);
2. Последняя впадина меньше, чем предыдущая.
3. Если второе условие не выполняется, то пик не формируется до тех пор, пока high свечи не будет выше последнего сформированного ранее пика;
Формирование впадины происходит аналогичным образом, при выполнении следующих условий:
1. Если имеется такой low свечи в окружении которого имеются другие свечи с low большим на значение параметр delta(задается в процентах);
2. Последний пик больше, чем предыдущий.
3. Если второе условие не выполняется, то впадина не формируется до тех пор, пока low свечи не будет меньше последней сформированной ранее впадины;
Я полагал, что если таким образом сформированный ZigZag (далее ZigZag_N) наложить, на ZigZag, сформированный по классическому алгоритму, то там, где нет направленного движения цены, а это как правило, четвертая волна (ее можно увидеть по характерному флэту) ZigZag_N не будет формировать пики и впадины, в то время как ZigZag будет отрисовывать флэт.
Изначально мне показалось, что автор идеи, пользователь с ником Pisces, имеет то же представление, что и я. И даже позавидовал его проницательности. Правда потом выяснилось, что автор идеи имел совсем другое в виду и считал, что дельта это разница между пиком и впадиной. Но оставим это в стороне.
Итак, первый прототип индикатора ZigZag_N готов, спасибо огромное Евгению (ник evge), что помог разобраться с механизмом накопления значений по предыдущим пикам и впадинам.

Код: Выделить всё

function Initialize()
{
IndicatorName = "ZigZag_N";   
PriceStudy = true;
AddInput("Input", Inputs.Candle);   
AddSeries("ZZWL", DrawAs.Custom, Color.Blue, true, Axes.Parent); //отображение локального ZigZag
AddSeries("ZZG", DrawAs.Custom, Color.Blue, true, Axes.Parent); //отображение глобального ZigZag
AddSeries("Lh_Ll", DrawAs.Custom, Color.Magenta, true, Axes.Parent);    //отображение последнего плеча
AddSeries("Peak", DrawAs.Custom, Color.Green);   //текуший пик
AddSeries("Trough", DrawAs.Custom, Color.Orange); //текущая впадина
AddSeries("Peak1", DrawAs.Custom, Color.Gray);    //предыдущий пик
AddSeries("Trough1", DrawAs.Custom, Color.Red); //предыдущая впадина
AddSeries("Marker", DrawAs.Custom, Color.Red);   
AddParameter("Delta", 0.2);  //параметр ZigZag задается в процентах
AddGlobalVariable("peakbar", Types.Int,  0);   
AddGlobalVariable("troughbar", Types.Int,  0);   
AddGlobalVariable("Direction", Types.Int,  0);   //направление локального ZigZag
AddGlobalVariable("DirG", Types.Int,  0);   //направление глобального ZigZag
AddGlobalVariable("hi", Types.Double,  0);   
AddGlobalVariable("lo", Types.Double,  0);   
AddGlobalVariable("hibar", Types.Int,  0);   
AddGlobalVariable("lobar", Types.Int,  0);   
AddGlobalVariable("exPkbar", Types.IntList); //процедура записи последних пиков
AddGlobalVariable("exTghbar", Types.IntList); //процедура записи последних впадин
AddGlobalVariable("hiG", Types.Double,  0);   
AddGlobalVariable("loG", Types.Double,  0);   
AddGlobalVariable("hibarG", Types.Int,  0);   
AddGlobalVariable("lobarG", Types.Int,  0);   
AddGlobalVariable("peakbarG", Types.Int,  0);   
AddGlobalVariable("troughbarG", Types.Int,  0);   
}

function Evaluate()
{
// Alfadirect4.ru Gerig
// ZigZag
// Новый минимум, если Close бара вырос от текущего Low на % и при этом
// последний Peak выше предыдущего Peak1
// Новый максимум, если Close бара снизился от текущего High на % и при этом
// последняя впадина Trough меньше предыдущей впадины Trough1
  if (CurrentIndex < 2)
  {
   lo = Input.Low[0];    //Впервые присваиваемые значения для локального минимума
   hi = Input.High[0];   //Впервые присваиваемые значения для локального максимума
    loG = Input.Low[0];    //Впервые присваиваемые значения для глобального минимума
   hiG = Input.High[0];   //Впервые присваиваемые значения для глобального максимума
  }
  else
  {
   double delta = 0.01*Delta;
  //Задаем значения локальному минимуму lo и локальному максимуму hi
   if(Input.High[0] > hi)   
   {
   hi = Input.High[0];
   hibar = CurrentIndex;
   }
   if(Input.Low[0] < lo)
   {
   lo = Input.Low[0];
   lobar = CurrentIndex;
   }             
       if(Direction >= 0)
        {
               if((Input.Low[0] > (1 + delta)*lo))
                {
               Direction = -1; //нашли впадину локального ZigZag
               hi = Input.High[0]; //локальный максимум
               hibar = CurrentIndex; //номер бара локального максимума
                    troughbar = lobar; //номер бара впадины       
                    exTghbar.Add(troughbar); //добавляем номер бара впадины в перечень
                    if ( exTghbar.Count > 2 ) //записываем номера баров последних впадин.
                    exTghbar.RemoveAt(0);
                    ZZWL[lobar-CurrentIndex] = lo;
               Marker[lobar-CurrentIndex] = lo;           
            } 
           }
        if(Direction <= 0)   
        {
         if(Input.High[0] <(1 - delta)*hi)
           {
              Direction = 1; // нашли пик локального ZigZag
              lo = Input.Low[0]; //локальный минимум
               lobar = CurrentIndex; //мер бара локального минимума
                   peakbar = hibar; //номер бара пика
                   exPkbar.Add(peakbar); //добавляем номер пика в перечень
                   if (exPkbar.Count > 2 ) //записываем номера баров последних пиков.
                   exPkbar.RemoveAt(0);
                   ZZWL[hibar-CurrentIndex] = hi;
                   Marker[hibar-CurrentIndex] = hi;
          }   
         }
         Trough = Input.Low[troughbar-CurrentIndex]; //впадина 
         Peak = Input.High[peakbar-CurrentIndex]; //пик
         if (exTghbar.Count > 1)
         {
         Trough1 = Input.Low[exTghbar[0]-CurrentIndex]; //предыдущая впадина локального ZigZag
         }
         if(exPkbar.Count > 1)
         {
         Peak1 = Input.High[exPkbar[0]-CurrentIndex]; //предыдущий пик локального ZigZag
         //ShowMessage(peakbar-CurrentIndex);  //Для отладки использовали
         }
            Marker.DrawCircle();
         Peak.DrawDash();
         Trough.DrawDash();
         Peak1.DrawDash();
         Trough1.DrawDash();
         ZZWL.DrawLine(Color.Blue, Line.Dot, 2); //отрисовка локального ZigZag цвета Blue
         //Задаем значения глобальному минимуму loG и глобального максимуму hiG
         if(Input.High[0] > hiG)   
         {
         hiG = Input.High[0];
         hibarG = CurrentIndex;
         }
         if(Input.Low[0] < loG)
         {
         loG = Input.Low[0];
         lobarG = CurrentIndex;
         }             
         if(DirG >= 0)
         {
               if((Input.Low[0] > (1 + delta)*loG))
                {
                   if ((Peak>Peak1)||((Peak<Peak1)&&(Input.Low[0]<Trough)))
                   {
               DirG = -1; //нашли впадину глобального ZigZag
               hiG = Input.High[0]; //глобального максимум
               hibarG = CurrentIndex; //номер бара глобального максимума
                    troughbarG = lobarG; //номер бара впадины       
                    ZZG[lobarG-CurrentIndex] = loG;
             //  Marker[lobarG-CurrentIndex] = loG;
                   }         
            } 
           }
        if(DirG <= 0)   
        {
         if(Input.High[0] <(1 - delta)*hiG)
           {
                  if((Trough1>Trough)||((Trough1<Trough)&&(Input.High[0]>Peak)))
                  {
              DirG = 1; // нашли пик глобального ZigZag
              loG = Input.Low[0]; //глобального минимум
               lobarG = CurrentIndex; //мер бара глобального минимума
                   peakbarG = hibar; //номер бара пика
                   ZZG[hibarG-CurrentIndex] = hiG;
                //   Marker[hibarG-CurrentIndex] = hiG;
                 }
          }   
         }
         ZZG.DrawLine(Color.Blue, Line.Solid, 3); //отрисовка глобального ZigZag цвета Blue
         // Последнее плечо, где отображаются локальные экстремумы (не зафиксированно)
         // отображается пунктирной линией цвета Magenta
         if (CurrentIndex == MaxIndex)
          {
             if (troughbar > peakbar)
              {
                Lh_Ll[troughbar-CurrentIndex]=ZZWL[troughbar-CurrentIndex];
                Lh_Ll[hibar-CurrentIndex] = hi;
              }
             if (troughbar < peakbar)
              {
                Lh_Ll[peakbar-CurrentIndex]=ZZWL[peakbar-CurrentIndex];
                Lh_Ll[lobar-CurrentIndex] = lo;
              }       
          }
          Lh_Ll.DrawLine(Color.Magenta, Line.Dot, 2);   
    }
}



Что же можно увидеть? Есть некоторая неточность в отображении некоторых пиков и впадин ZigZag_N, связанная с тем, что если в условиях большой волатильности будет сформирован пик или впадина в ZigZag, то ZigZag_N ее не будет считать, а рассчитает новую рядом стоящую свечу. Я хотел было усовершенствовать алгоритм и предусмотреть правило пересчета вершин в таких случаях, но решил на график вывести еще один ZigZag, но с другой величиной Delta. Я был очень удивлен, но ZigZag c параметром delta увеличенным в 2,5 раза практически совпадает с ZigZag_N.

Получается, что мое предположение об отображении четвертой волны таким способом полностью ошибочно. И действительно был прав пользователь с ником Геннадий, предложивший просто увеличить параметр delta.
Вложения
Скриншот 2016-04-11 12.26.38.png