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

 

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


Расшифруйте , пожалуйста, выделенную фразу.
По поводу стиля DRAW_ZIGZAG - именно поэтому и не стал делать, во-первых, опять же будет спорный алгоритм рассчета, и во-вторых - большинство сразу и не поймет как им пользоваться, а уж тупая замена в советниках или индикаторах будет грозить народными волнениями :)

Пример: DT-ZigZag - индикатор, который написал klot, через iCustom использует данные от внешнего ZigZag. Есть индикаторы по поиску различных паттернов, Gartley, в частности, также берут данные от внешнего зигзага. Есть и другие индикаторы, работающие через через iCustom с внешним ZigZag'ом.

Ко мне часто обращаются трейдеры с просьбой заменить в том или ином индикаторе в тексте кода индикатора встроенный стандартный ZigZag на ZigZag с исмправленными ошибками. Эти индикаторы работают с встроенным "однобуферным" зигзагом. Наверняка могут поступать предложения и для встраивания в текст вместо "однобуферного" "двухбуферного" зигзага, если "двухбуферный" будет активно продвигаться. А такое встраивание уже сложнее сделать.

Мое мнение - надо продвигать оба варианта ZigZag'a.
=====================

В тексте выложенного выше индикатора необходимо заменить строчку
   if (Bars-IndicatorCounted()>3) for (shift=Bars-1;shift>=0; shift--) {ExtMapBuffer[shift]=0; ExtMapBuffer2[shift]=0;}


на следующую строчку

   if (Bars-IndicatorCounted()>3) for (shift=Bars-1;shift>=0; shift--) {ExtMapBuffer[shift]=0; ExtMapBuffer2[shift]=0; tiBar_0=0;}



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

 
Rosh, чуть раньше ты упоминал о нескольких алгоритмах ZZ, которые тебе известны. Очень ценю твой глубокий "въезд" в тему и был бы очень признателен тебе, если бы ты хотя бы вкратце о них рассказал (не считая стандартного).

ZZ - один из самых сложных индикаторов в стандартном пакете МТ4, и в нем используются три последовательных прохода по полной истории. Явный перебор в сложности! Мне кажется, суть проблемы в том, что сам по себе стандартный алгоритм, зашитый в МТ4, навязывает и соответствующие параметры индикатора, которые, вообще говоря, кажутся крайне искусственными - все три параметра!

Самый логичный вариант - найти такой алгоритм, в котором остались бы только параметры, которые имеют для трейдера ясный смысл, а не легкий шок при попытке понять, как они влияют на его внешний вид. Прошу воспринимать это замечание не как критику именно твоего или стандартного варианта ZZ; это просто общее впечатление, вполне естественное для человека, не знающего его логики.

Для меня единственный естественный параметр - это минимальная разница в пунктах между соседними экстремумами индикатора, которая должна быть неким пороговым значением, задающим необходимость отрисовки его вершин. Это моя бритва Оккама. Например, если мы задаем 50 пунктов, то это означает, что на нарисованном ZZ не должно быть соседних вершин с разницей уровней менее 50. Довольно любопытно, что в стандартном алгоритме этого важнейшего параметра вообще нет...

Честно говоря, у меня пока четко оформленного алгоритма нет, но несколько дней назад я об этом очень крепко задумался и намерен создать абсолютно другой алгоритм. Подход к решению видится в рекурсии и только в ней, а не в последовательном многопроходном алгоритме. Рекурсия кажется здесь самым естественным подходом, автоматически учитывающим фрактальность чарта. На каждом этапе рекурсии предполагается искать по одному минимуму и максимуму ZZ и проверять, соответствуют ли они нашей бритве Оккама. Границы каждого самостоятельного отрезка проходят по точкам экстремумов.

Как только появится что-то работающее - выложу (если меня не опередят :)).
 
Один из вариантов Zigzag'а - это свинги Ганна, которые делались на пауке Profi_R, kaizer'ом и мною. Profi_R в конце концов добил эту тему (индикатор стал рисовать не только историю, но и корректно работать в онлайне). В качестве консультанат по этой теме вытсупал AVlad.

Второй вариант Zigzag'а - это построение эктремумов по системе окруженных вершин и донышков, описанный в книге Ларри Вильямса "Долгосрочные секреты краткосрочной торговли". В какой-то мере пересекается с Ганном.

Третий способ - нахождение экстремумов цены на определенных областях какого-либо индикатора. Этот способ мне показал один знакомый, точнее по его алгоритму я сделал такой Zigzag (еще в МТ3).

По поводу этого:
Для меня единственный естественный параметр - это минимальная разница в пунктах между соседними экстремумами индикатора, которая должна быть неким пороговым значением, задающим необходимость отрисовки его вершин. Это моя бритва Оккама. Например, если мы задаем 50 пунктов, то это означает, что на нарисованном ZZ не должно быть соседних вершин с разницей уровней менее 50. Логично?

как видишь в этой ветке, не все так считают, многим хочется абсолютной точности как в аптеке, fuzzi logic вызывает иногда даже ярость :)
Как учитывать фрактальность цен - я пока не знаю, например, индикатор FRAMA я написал но больше к нему так и не возврашался. А как твои успехи с ним? :)
Насчет этого:

Честно говоря, у меня пока четко оформленного алгоритма нет, но несколько дней назад я об этом очень крепко задумался и намерен создать абсолютно другой алгоритм. Подход к решению видится в рекурсии и только в ней, а не в последовательном многопроходном алгоритме. Рекурсия кажется здесь самым естественным подходом, автоматически учитывающим фрактальность чарта. На каждом этапе рекурссии предполагается искать по одному минимуму и максмуму ZZ и проверять, соответствуют ли они нашей бритве Оккама. Границы каждого самостоятельного отрезка проходят по точкам экстремумов.
\
у меня пока есть только смутный алгоритм, предложенный Владиславом в самой длинной ветке на этом форуме. Необходимо найти критерии слома одной тенденции и возможное начало другой. Тут необходимо провести статистические исследования, хотя не факт, что это что-то даст. В общем такой мой расплывчатый ответ, грубо говоря - не знаю .
 
Говоря о фрактальности, я имел в виду самоподобие, а не "хаотичность" графика. Это самоподобие должно естественно отражаться и в самом алгоритме, диктуя иерархию экстремумов (ни в коем случае не говорю об Эллиотте, хотя и тут можно что-нибудь придумать с разметкой, которая на эллиоттовскую уже не будет похожа, но вполне может оказаться полезной). Эта иерархия естественно вырисовывается по мере выполнения рекурсивного алгоритма, как фотография при проявлении. Поясню более подробно.

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

Второй уровень рекурсии: внутри каждого отрезка снова ищем экстремумы и проверяем бритвой. Соответствие бритве для соседних отрезков выполняется автоматически, так что не нужно вырезать что-то лишнее, как это сделано во втором проходе стандартного алгоритма. И так далее.

Понятно, что дробить до бесконечности мы не сможем. Для каждого из отрезков определим в качестве критерия окончания рекурсии нашу бритву Оккама. Никаких дополнительных параметров, они не нужны!

И где тут у нас фаззи, не пойму... Все однозначно, никаких экстремумов, висящих в воздухе: у нас же нет параметра ExtDeviation.

Вероятно, этот алгоритм аналогичен алгоритму Ларри Вильямса (с добавлением нашей бритвы), так как тот тоже по сути рекурсивен, но в сторону укрупнения экстремумов.

P.S. За FRAMA - большое спасибо. Я тоже с ним немного повозился и пока отложил. Надеюсь, скоро снова пригодится...
 
Примерно такой алгоритм я и думаю. Только по рецепту Владислава:
1. Строим аппроксимацию на всей истории по ЛР.
2. Строим распределение остатков от ЛР.
3. Задаем критерий в % нормального распределения для поиска макисмальных размахов от ЛР.
4. Находим эти экстремуму и на полученных интервалах ... идем по пункту 1 .2.3 и 4.

Критерием окончания рекерсии служит то, что дисперсия на всей ломанной линии меньше дисперсии от Yi-Yi+1.

Таким образом, у нас есть как-то обоснованный Zigzag, теперь начинаем отслеживать некий критерий при движении по истории с привязкой к известным (теперь априори) точкам привязки Zigzag'а(экстремумам) . Набираем статисику слома любого удобного критерия при подходе к точке перелома Zigzag'а, например, это может быть показатель Херста или размер сигмы. Если статистика работает, пытаемся создать алгоритм для работы уже в он-лайн. Надеюсь, понятно описал.
 
А как вам мой вариант зигзага?
не сложный, но достаточно стабильный и скоростной алгоритм.
Экстремумы в функциях iLowest и iHighest расчитываются по MODE_CLOSE можно заменить на MODE_LOW и MODE_HIGH соответственно, но стабильность незначительно потеряется на "внешних" барах.
Единственный внешний параметр - это ExtDepth - временной диапазон для поиска экстремумов.

//+------------------------------------------------------------------+
//|                                                        DT_ZZ.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, klot."
#property link      "klot@mail.ru"

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Aqua
#property indicator_color2 Blue
#property indicator_color3 Red
//---- indicator parameters
extern int ExtDepth=21;
extern bool HLBuf=false;
//---- indicator buffers
double zzL[];
double zzH[];
double zz[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
  int cod;
  if (!HLBuf) cod=12; else cod=3;
 //  IndicatorBuffers(3);
//---- drawing settings
   SetIndexStyle(2,cod);
   SetIndexStyle(1,cod);
   SetIndexStyle(0,DRAW_SECTION);
   SetIndexArrow(2,159);
   SetIndexArrow(1,159);
//---- indicator buffers mapping
   SetIndexBuffer(0,zz);
   SetIndexBuffer(1,zzH);
   SetIndexBuffer(2,zzL);
   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
   SetIndexEmptyValue(2,0.0);
     
//---- indicator short name
   IndicatorShortName("DT_ZZ("+ExtDepth+")");
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int    i,shift,pos,lasthighpos,lastlowpos,curhighpos,curlowpos;
   double curlow,curhigh,lasthigh,lastlow;
   double min, max;
   ArrayInitialize(zz,0.0);
   ArrayInitialize(zzL,0.0);
   ArrayInitialize(zzH,0.0);
   
   lasthighpos=Bars; lastlowpos=Bars;
   lastlow=Low[Bars];lasthigh=High[Bars];
  for(shift=Bars-ExtDepth; shift>=0; shift--)
    {
      curlowpos=iLowest(NULL,0,MODE_CLOSE,ExtDepth,shift);
      curlow=Close[curlowpos];
      curhighpos=iHighest(NULL,0,MODE_CLOSE,ExtDepth,shift);
      curhigh=Close[curhighpos];
      //------------------------------------------------
      //--- high
      if( curhigh<=lasthigh )  { lasthigh=curhigh;}
      else
         {  
            // Новая макушка оразовалась
            if( lastlowpos>curhighpos ) 
            {  
            zzH[curhighpos]=curhigh;
           // Убираем лишние макушки на промежутке от новой макушки до старого донышка
               max=-100000; pos=lastlowpos;
               for(i=lastlowpos; i>=curhighpos; i--)
                  { 
                    if (zzH[i]==0.0) continue;
                    if (zzH[i]>max) { max=zzH[i]; pos=i; }
                    zz[i]=0.0;
                  } 
               zz[pos]=High[pos];//max;
           //*/     
            }  
         lasthighpos=curhighpos;
         lasthigh=curhigh;    
         }
      //------------------------------------------------
      //--- low
      if( curlow>=lastlow ) { lastlow=curlow; }
      else
         { 
            //Новое донышко
            if( lasthighpos>curlowpos  ) 
            { 
            zzL[curlowpos]=curlow;
              //Убираем лишние донышки на промежутке от нового донышка до макушки
              min=100000; pos=lasthighpos;
               for(i=lasthighpos; i>=curlowpos; i--)
                  { 
                    if (zzL[i]==0.0) continue;
                    if (zzL[i]<min) { min=zzL[i]; pos=i; }
                    zz[i]=0.0;
                  } 
               zz[pos]=Low[pos];//min;
               //*/
            } 
          lastlowpos=curlowpos;
          lastlow=curlow; 
         }   
    //----------------------------------------------------------------------
    }
 return(0);
}
//+------------------------------------------------------------------+
 
--Ищем два глобальных экстремума.

Это какие два экстремума? Два соседних хая или два соседних противоположных экстремума? (пара хай-лоу?). Собственно весь алгоритм из таких вот загадок состоит.
 
--Ищем два глобальных экстремума.

Это какие два экстремума? Два соседних хая или два соседних противоположных экстремума? (пара хай-лоу?). Собственно весь алгоритм из таких вот загадок состоит.


Ищем два экстремума на участке в ExtDepth баров (данный вариант по клозе)

curlowpos=iLowest(NULL,0,MODE_CLOSE,ExtDepth,shift);
curlow=Close[curlowpos];
curhighpos=iHighest(NULL,0,MODE_CLOSE,ExtDepth,shift);
curhigh=Close[curhighpos];

далее сравниваем
//--- high
if( curhigh<=lasthigh ) { lasthigh=curhigh;}
и
//--- low
if( curlow>=lastlow ) { lastlow=curlow; }

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

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

2 klot: твоя версия намноооого короче стандартной. Надо на него посмотреть, что он рисует...

2 Rosh: мне надо ознакомиться с методом Владислава, есть непонятные термины. Это в большой эллиоттовской ветке здесь же?
 

2 klot: твоя версия намноооого короче стандартной. Надо на него посмотреть, что он рисует...

Стараюсь :)