Индикаторы: Идеальный зигзаг

 

Идеальный зигзаг:

Ультрабыстрый зигзаг на максимально простом принципе. Без висящих вершин. С поддержкой оптимизированного по времени нахождения вершин.

Author: Андрей

 
Хотелось бы провести очную ставку на скорость советника с использованием этого ЗигЗага и другим кодом. В тестере. На реале, конечно, индикатор сможет (в отличие от безындикаторного советника - нет IndicatorCounted() ) обновляться при коррективах истории. Но интересны именно его скоростные характеристики в советнике. Возможно, вы придумаете советник для такого соревнования. Со своей стороны попробую тогда повторить его без использования индикатора.
 
hrenfx:

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

Я вообще не претендую на лидерство по скорости, "очень быстрая работа" значит лишь то, индикатор использует приемы эффективного построения зигзага.

Но, в принципе, против теста ничего не имею.

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

Т.е. с меня советник? Хорошо, быстро не обещаю, когда будет готов, стукну в личку. Можно остановиться на анализе трех первых сформированных вершин.
 
Спасибо за разработку, а можно сделать так чтобы он на истории показывал где находил макс и мин?
 
Darkside:
Спасибо за разработку, а можно сделать так чтобы он на истории показывал где находил макс и мин?
Автор такой ерундой вряд ли будет заниматься. Но можно корявыми ручками втихаря поковыряться в высоких материях и дописать пару строк в авторский код.

//+------------------------------------------------------------------+
//|                                               XLab_ZZ_oldpic.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2012, TheXpert"
#property link      "theforexpert@gmail.com"
#property indicator_chart_window
extern int ChannelPoints = 50;
// attention! when used, this option can lead to incorrect visualization of last ZZ ray at 0 bar
// incorrect visualization will be redrawn when new bar appears
// use it carefully and don't expect complete correctness
// never(!) use this indicator values from 0 bar in your automated strategies.
// never(!) use this option if this indicator is used in automated strategy.
// if used, this option can lead to incorrect extremum parsing in your EA
/* extern */ bool DrawZeroBar = false;
#property indicator_buffers 7 //5
#property indicator_color1 LightGray
#property indicator_color2 LightGray
#property indicator_color6 Red
#property indicator_color7 Aqua
#property indicator_width6 3
#property indicator_width7 3
double Maxs[];
double Mins[];
double MaxsOld[];
double MinsOld[];
double Direction[];
double MaxTime[];
double MinTime[];
string symbol;
#define UP 0.0001
#define DN -0.0001
#define NONE 0
bool Inited;
datetime LastTime;
int init()
{
   SetIndexBuffer(0, Maxs);
   SetIndexBuffer(1, Mins);
   
   SetIndexBuffer(2, MinTime);
   SetIndexBuffer(3, MaxTime);
   
   SetIndexBuffer(4, Direction);
   
   SetIndexBuffer(5, MaxsOld);
   SetIndexBuffer(6, MinsOld);
   SetIndexStyle(0, DRAW_ZIGZAG);
   SetIndexStyle(1, DRAW_ZIGZAG);
   SetIndexStyle(2, DRAW_NONE);
   SetIndexStyle(3, DRAW_NONE);
   SetIndexStyle(4, DRAW_NONE);
   
   SetIndexStyle(5, DRAW_ARROW);
   SetIndexStyle(6, DRAW_ARROW);
   SetIndexArrow(5, 159);
   SetIndexArrow(6, 159);
   symbol = Symbol();
   
   Inited = false;
   LastTime = 0;
   
   return(0);
}
int start()
{
   if (!Inited)
   {
      ArrayInitialize(Mins, EMPTY_VALUE);
      ArrayInitialize(Maxs, EMPTY_VALUE);
      ArrayInitialize(MinTime, EMPTY_VALUE);
      ArrayInitialize(MaxTime, EMPTY_VALUE);
      ArrayInitialize(Direction, EMPTY_VALUE);
      
      ArrayInitialize(MinsOld, EMPTY_VALUE);
      ArrayInitialize(MaxsOld, EMPTY_VALUE);
   }
   
   int ToCount = Bars - IndicatorCounted();
   
   // DON'T fix to >= 0. For the 0 bar the logic is in DrawZeroBar block
   for (int i = ToCount - 1; i > 0; i--)
   {
      if (i < Bars - 1)
      {
         MinTime[i] = MinTime[i + 1];
         MaxTime[i] = MaxTime[i + 1];
         Direction[i] = Direction[i + 1];
         Maxs[i] = EMPTY_VALUE;
         Mins[i] = EMPTY_VALUE;
      }
      
      Check(i);
      MaxsOld[i]=Maxs[i];
      MinsOld[i]=Mins[i];
   }
   
   if (DrawZeroBar)
   {
      if (LastTime != Time[0])
      {
         LastTime = Time[0];
         MinTime[0] = MinTime[1];
         MaxTime[0] = MaxTime[1];
         Direction[0] = Direction[1];
         Maxs[0] = EMPTY_VALUE;
         Mins[0] = EMPTY_VALUE;
      }
      
      CheckPrice(0, Close[0]);
   }
   else
   {
      Maxs[0] = EMPTY_VALUE;
      Mins[0] = EMPTY_VALUE;
   }
   
   return(0);
}
void Check(int offset)
{
   double o = Open[offset];
   double h = High[offset];
   double l = Low[offset];
   double c = Close[offset];
   if (c < o)
   {
      CheckPrice(offset, h);
      CheckPrice(offset, l);
   }
   else
   {
      CheckPrice(offset, l);
      CheckPrice(offset, h);
   }
}
void CheckPrice(int offset, double p)
{
   if (!Inited)
   {
      CheckInit(offset, p);
      Inited = true;
   }
   else
   {
      if (Direction[offset] == UP) CheckUp(offset, p);
      else if (Direction[offset] == DN) CheckDn(offset, p);
   }
}
void CheckInit(int offset, double c)
{
   MaxTime[offset] = Time[offset];
   MinTime[offset] = Time[offset];
   
   Maxs[offset] = c;
   Mins[offset] = c;
 
   Direction[offset] = UP;
}
void CheckUp(int offset, double c)
{
   int lastOffset = iBarShift(symbol, 0, MaxTime[offset]);
   if (Maxs[lastOffset] == EMPTY_VALUE)
   {
      Maxs[lastOffset] = High[lastOffset];
   }
   
   if (c > Maxs[lastOffset])
   {
      Maxs[lastOffset] = EMPTY_VALUE;
      Maxs[offset] = c;
      MaxTime[offset] = Time[offset];
      lastOffset = offset;
   }
   
   if (c + ChannelPoints*Point < Maxs[lastOffset])
   {
      Direction[offset] = DN;
      
      Mins[offset] = c;
      MinTime[offset] = Time[offset];
   }
}
void CheckDn(int offset, double c)
{
   int lastOffset = iBarShift(symbol, 0, MinTime[offset]);
   if (Mins[lastOffset] == EMPTY_VALUE)
   {
      Mins[lastOffset] = Low[lastOffset];
   }
   
   if (c < Mins[lastOffset])
   {
      Mins[lastOffset] = EMPTY_VALUE;
      Mins[offset] = c;
      MinTime[offset] = Time[offset];
      lastOffset = offset;
   }
   
   if (c - ChannelPoints*Point > Mins[lastOffset])
   {
      Direction[offset] = UP;
      Maxs[offset] = c;
      MaxTime[offset] = Time[offset];
   }
}
 

Не помешало бы FIBO-шку набросить на последние вершинки.


Хорошая работа!

 
Darkside:
Спасибо за разработку, а можно сделать так чтобы он на истории показывал где находил макс и мин?

Так макс и мин можно найти двумя строчками через iHighest iLowest. Зачем это делать в отдельно взятом индикаторе?

TarasBY:

Не помешало бы FIBO-шку набросить на последние вершинки.

Это можно сделать отдельно, код для взятия вершин есть. Я вообще планирую все дополнения (если получится) делать через дополнительные индикаторы.
 

Скачал, проверил, пока всё нормально.

Автору Спасибо.

=)

 

В чем может быть проблема? Индикатор показывает 4 знака поле запятой, а график-то с 5 знаками.

Хотел использовать в советнике. Но при сравнении значений с High[n] или Low[n] всегда "false"

 
Altarius:

В чем может быть проблема? Индикатор показывает 4 знака поле запятой, а график-то с 5 знаками.

Добавьте в init строчку

IndicatorDigits(Digits);

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

Спасибо, что приметили, я как-то зевнул.

 
Вчер добрый. Использую данный индикатор для работы. Смущала задержка обрисовки 0-бара. Решение выполнил правкой следущего кода
if (DrawZeroBar)
   {
      if (LastTime != Time[0])
      {
         LastTime = Time[0];
 
         MinTime[0] = MinTime[1];
         MaxTime[0] = MaxTime[1];
         Direction[0] = Direction[1];
         Maxs[0] = EMPTY_VALUE;
         Mins[0] = EMPTY_VALUE;
      }
      if (Direction[offset] == UP) CheckPrice(0, High[0]);
      else if (Direction[offset] == DN) CheckPrice(0, Low[0]);
      
   }