Обновлённый клиентский терминал MetaTrader 4 build 201 - страница 2

 
На картинках:
красным цветом выводится зигзаг, который был в стандартной поставке МТ до лета 2006 года,
оптимизированный зигзаг - первый вариант зигзага Николая Косицына,
исправленный оптимизированный зигзаг - первый вариант зигзага Николая Косицына с исправлением ошибки. Ошибка стандартного зигзага, проявляющаяся в выводе переломов в воздухе, возникает из-за того, что значение максимума (минимума) бара находится на одном баре (бар X), а записывается в индикаторный буфер в ячейку, номер которой отличается от номера бара X.

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

Можно под это подводить философию. Мое мнение - философию под такую работу подводят те, кто реально не торгует на рынке. Реальная торговля быстро убирает излишнюю философию и все расставляет на свои места.

Вся философия идет от того, что сложно найти ошибку в достаточно запутанном алгоритме построения зигзага. Нет отладчика в метаедиторе. И начинаются мистические пассажи на тему философии, вместо упорного поиска ошибки.

===================
Второй вариант зигзага Николая Косицына значительно интереснее первого. В нем осталось исправить ошибку, заключающуюся в выводе переломов зигзага в воздухе.

Считаю, что этот вариант можно поставлять с Метатрейдером. Но обязательно как-то обозначить его как загзаг Николая Косицына. Возможно, дать ему особое название.

И еще. Не помню, есть ли у него в коде исправление вывода загзага при прокрутке истории назад и при подкачке старой истории. Если этого кода нет, то его нужно обязательно вставить. Это тоже ошибка, проявляющаяся в большинстве зигзагоподобных индикаторов. В стандартном зигзаге эта ошибка также была.
 
Вспомнил еще. Самая лучшая оптимизация нагрузки на процессор при расчете зигзага заключается в том, чтобы делать расчет индикатора в следующих случаях:
1) При появлении нового (новых) бара
2) при выходе цены ниже лоу или выше хая нудевого бара.
В остальных случаях расчет не проводить. У меня сейчас так и реализовано в 54 версии индикатора.

На форуме устраиваем мозговой штурм. Поступает предложение обсудить определенную тему. Кто лучшую идею предложит, ту идею и реализую в индикаторе.

Вышеупомянутую оптимизацию предложил micmed.
 
Прежде чем говорить об ошибках, нужно разобраться в самом механизме работы Zigzag'а , иначе все попытки исправления будут сводиться к выстрелам наугад. Эта особенность работы

... стандартного зигзага, проявляющаяся в выводе переломов в воздухе, возникает из-за того, что значение максимума (минимума) бара находится на одном баре (бар X), а записывается в индикаторный буфер в ячейку, номер которой отличается от номера бара X.

не каждому пользователю будет понятна, она как заклинание/мантра его просто будет запутывать. Рассмотрим откуда берется такое поведение Zigzag'а. Возьмем индикатор Price Channel с параметром ChannelPeriod=12 (в Zigzag'е ExtDepth=12 по умолчанию) из Code Base - "MQL4: Price Channel" - и набросим на минутный график EURUSD.
Кроме того, немного изменим индикатор Zigzag из поставки МТ4 build 201 от 10.01.2007
//+------------------------------------------------------------------+
//|                                                   ZigzagHiLo.mq4 |
//|                 Copyright © 2005-2007, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Green
#property indicator_color2 Blue
#property indicator_color3 Orange
//---- indicator parameters
extern int ExtDepth=12;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
//---- indicator buffers
double ZigzagBuffer[];
double HighMapBuffer[];
double LowMapBuffer[];
int level=3; // recounting depth 
bool downloadhistory;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   //IndicatorBuffers(3);
//---- drawing settings
   SetIndexStyle(0,DRAW_SECTION);
//---- indicator buffers mapping
   SetIndexBuffer(0,ZigzagBuffer);
   SetIndexBuffer(1,HighMapBuffer);
   SetIndexLabel(1,"HighMapBuffer");
   SetIndexBuffer(2,LowMapBuffer);
   SetIndexLabel(2,"LowMapBuffer");
   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
   SetIndexEmptyValue(2,0.0);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,108);
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexArrow(2,108);

//---- indicator short name
   IndicatorShortName("ZigZag("+ExtDepth+","+ExtDeviation+","+ExtBackstep+")");
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int i, counted_bars = IndicatorCounted();
   int limit,counterZ,whatlookfor;
   int    shift, back,lasthighpos,lastlowpos;
   double val,res;
   double curlow,curhigh,lasthigh,lastlow;

   if (counted_bars==0 && downloadhistory) // history was downloaded
     {
      ArrayInitialize(ZigzagBuffer,0.0);
      ArrayInitialize(HighMapBuffer,0.0);
      ArrayInitialize(LowMapBuffer,0.0);
     }
   if (counted_bars==0) 
     {
      limit=Bars-ExtDepth;
      downloadhistory=true;
     }
   if (counted_bars>0) 
     {
      while (counterZ<3 && i<100)
        {
         res=ZigzagBuffer[i];
         if (res!=0) counterZ++;
         i++;
        }
      i--;   
      limit=i;
      if (LowMapBuffer[i]!=0) 
        {
         curlow=LowMapBuffer[i];
         whatlookfor=1;
        }
      else
        {
         curhigh=HighMapBuffer[i];
         whatlookfor=-1;
        }
      for (i=limit-1;i>=0;i--)  
        {
         ZigzagBuffer[i]=0.0;  
         LowMapBuffer[i]=0.0;
         HighMapBuffer[i]=0.0;
        }
     }
      
   for(shift=limit; shift>=0; shift--)
      {
      val=Low[Lowest(NULL,0,MODE_LOW,ExtDepth,shift)];
      if(val==lastlow) val=0.0;
      else 
        { 
         lastlow=val; 
         if((Low[shift]-val)>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=LowMapBuffer[shift+back];
               if((res!=0)&&(res>val)) LowMapBuffer[shift+back]=0.0; 
              }
           }
        } 
      LowMapBuffer[shift]=val;
      //--- high
      val=High[Highest(NULL,0,MODE_HIGH,ExtDepth,shift)];
      if(val==lasthigh) val=0.0;
      else 
        {
         lasthigh=val;
         if((val-High[shift])>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=HighMapBuffer[shift+back];
               if((res!=0)&&(res<val)) HighMapBuffer[shift+back]=0.0; 
              } 
           }
        }
      HighMapBuffer[shift]=val;
      }

   // final cutting 
   if (whatlookfor==0)
     {
      lastlow=0;
      lasthigh=0;  
     }
   else
     {
      lastlow=curlow;
      lasthigh=curhigh;
     }
   for (shift=limit;shift>=0;shift--)
     {
      res=0.0;
      switch(whatlookfor)
        {
         case 0: // look for peak or lawn 
            if (lastlow==0 && lasthigh==0)
              {
               if (HighMapBuffer[shift]!=0)
                 {
                  lasthigh=High[shift];
                  lasthighpos=shift;
                  whatlookfor=-1;
                  ZigzagBuffer[shift]=lasthigh;
                  res=1;
                 }
               if (LowMapBuffer[shift]!=0)
                 {
                  lastlow=Low[shift];
                  lastlowpos=shift;
                  whatlookfor=1;
                  ZigzagBuffer[shift]=lastlow;
                  res=1;
                 }
              }
             break;  
         case 1: // look for peak
            if (LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow && HighMapBuffer[shift]==0.0)
              {
               ZigzagBuffer[lastlowpos]=0.0;
               lastlowpos=shift;
               lastlow=LowMapBuffer[shift];
               ZigzagBuffer[shift]=lastlow;
               res=1;
              }
            if (HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
              {
               lasthigh=HighMapBuffer[shift];
               lasthighpos=shift;
               ZigzagBuffer[shift]=lasthigh;
               whatlookfor=-1;
               res=1;
              }   
            break;               
         case -1: // look for lawn
            if (HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh && LowMapBuffer[shift]==0.0)
              {
               ZigzagBuffer[lasthighpos]=0.0;
               lasthighpos=shift;
               lasthigh=HighMapBuffer[shift];
               ZigzagBuffer[shift]=lasthigh;
              }
            if (LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
              {
               lastlow=LowMapBuffer[shift];
               lastlowpos=shift;
               ZigzagBuffer[shift]=lastlow;
               whatlookfor=1;
              }   
            break;               
         default: return; 
        }
     }

   return(0);
  }
//+------------------------------------------------------------------+



и также набросим с параметрами по умолчанию.

 
Следующий код для записи в буферы индикатора исключает запись найденных значений в другую ячейку.

      if (Low[shift]==val) ZigZagBuffer[shift]=val; else ZigZagBuffer[shift]=0.0;
...
      if (High[shift]==val) TempBuffer[shift]=val; else TempBuffer[shift]=0.0;
...


В стандартном зигзаге было так

      ZigZagBuffer[shift]=val;
...
      TempBuffer[shift]=val;
...



В приведенном выше коде надо заменить

     LowMapBuffer[shift]=val;



на

   if (Low[shift]==val)   LowMapBuffer[shift]=val;



Также и для хая. И переломы в воздухе рисоваться не будут.

 
Мы увидим, что все переломы Zigzag'a (даже те, что висят в воздухе) взялись не откуда то с потолка, а лежат четко на линиях PriceChannel. Конечно, в самом алгоритме этого Zigzag'a есть внутреннее противоречие - из двух равных по значению экстремумов вырезается более поздний, но если более поздний отличается хотя бы на один пункт, то часто вырезается именно старый экстремум, а рисуется новый - вот и получаем перелом в воздухе. Но простое изменение этого места ничего не даст, так как в этом случае Zigzag станет даже более спорным.

Вот картинка, объясняющая все это.



Если посмотреть внимательно, то видно, что предлагаемый вариант исправления (простое изменение номера индекса для записи эктремума) не решает этой проблемы. Так что думайте и предлагайте четко формализированные варианты. По поводу внешнего бара думать надо только после решения этой ситуации (мое мнение).
 
Логично же когда найденный экстремум найден на баре номер X и потом это значение помещается в индикаторный буфер в ячейку с номером X.

А если найденное значение помещается в ячейку с другим номером, то это будет уже не зигзаг, а какой-то другой индикатор.

Зигзаг должен находить максимумы и минимумы рынка в тех местах, где они действительно имеются. И однозначно указывать нам это место с точность до пункта и в соответствующий момент времени.
 
Вот Вам неразмеченный рисунок. Покажите на нем то, что хотите изменить.

 
Rosh, похоже мы говорим о разных вещах. И не понимаем друг друга.

Если надо находить экстремумы на значениях другого индикатора (на прайсканале, например), то это уже другой инструмент.
Загзаг нам должен показывать существующие на рынке экстремумы, а не произвольные точки.

Экстремумы существуют там, где реально была рыночная цена. Где цены не было - не было и экстремума.

Ответьте на простой вопрос. Трейдеру нужно реально сущестующий экстремум на рынке найти или непонятно откуда взявшуюся точку на графике, которую кто-то посчитал за экстремум?

Вот ответите мне на этот простой вопрос, после этого я буду готов обсуждать далее.

Следующий простой вопрос такой. Вы торгуете на реальном счете (не на демо) на собственные деньги или только программируете?
 
Rosh, похоже мы говорим о разных вещах. И не понимаем друг друга.

Если надо находить экстремумы на значениях другого индикатора (на прайсканале, например), то это уже другой инструмент.
Загзаг нам должен показывать существующие на рынке экстремумы, а не произвольные точки.

Экстремумы существуют там, где реально была рыночная цена. Где цены не было - не было и экстремума.


Ну так дайте ответ - формализируйте алгоритм, покажите механизм поиска экстремумов. Иначе действительно обсуждать нечего, посты в стиле " работает неправильно, сами знаете почему" ни к какому конструктивизму не ведут. Не хотите обсуждать - не стоит поднимать тему.

Следующий простой вопрос такой. Вы торгуете на реальном счете (не на демо) на собственные деньги или только программируете?
Я бы назвал такой вопрос неприличным, не находите? Даже если Вы являетесь общепризнанным гуру, разногласия в понимании правильности алгоритма не дает права для таких подковырок. Мне вот никогда не приходило в голову - торгует nen на реальном счету или нет. То , что я не использую индикатор Zigzag в своем анализе рынка (также как и вилы Эндрюса и бабочку Гартли и порследовательность Демарка и что-то там еще с Пессавенто) не делает меня человеком второго сорта и не говорит о моем уровне IQ. Вопрос закрыт. Можете сами поставить любой ответ на свой вопрос.
 
To nen

Расскажите, пожалуйста, о всех возможностях своего ZigZag ( встроенные уровни Фибо мы уже видели ). Спасибо.