Смотри, как бесплатно скачать роботов
Ищи нас в Twitter!
Ставь лайки и следи за новостями
Интересный скрипт?
Поставь на него ссылку - пусть другие тоже оценят
Понравился скрипт?
Оцени его работу в терминале MetaTrader 5
Индикаторы

Идеальный ЗигЗаг - индикатор для MetaTrader 5

Просмотров:
10899
Рейтинг:
(61)
Опубликован:
2012.07.11 16:37
Обновлен:
2016.11.22 07:33
Нужен робот или индикатор на основе этого кода? Закажите его на бирже фрилансеров Перейти на биржу

Ультрабыстрый зигзаг на максимально простом принципе.

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

Идеальный ЗигЗаг

Достоинства:

  1. Самая тяжелая функция в расчетах - iBarShift, которая полностью замещает ненужные циклы для поиска вершин, была заменена на ArrayBSearch, а это значит, индикатор будет работать еще эффективнее аналога на MQL4;
  2. Вся необходимая информация для каждого бара не только доступна в любой момент истории, но и также доступна советнику для любого момента истории;
  3. Никаких висящих вершин;
  4. Возможность эффективного поиска вершин без перебора значений индикатора;
  5. Очень быстрая работа;
  6. Корректная обработка вставки истории и переключения таймфреймов;
  7. Незаменим для работы в советниках.

Недостатки:

  1. Затраты памяти. Для корректной отрисовки зигзагу надо 2 буфера (1 мало, будут висяки), здесь используется 5. Полностью компенсируется (имхо) достоинством № 6. Ни один быстрый зигзаг по определению не может корректно обрабатывать вставку истории на двух буферах.
  2. Рисование дополнительных линий. Нужно для того, чтобы они были видны советнику. Значения порядка таких величин, которые не должны быть видны ни при каком раскладе.

Принцип:

Новое колено начинает строиться при откате большем, чем заданный в настройках. Он может задаваться в пунктах (IdealZZ) или в процентах (IdealZZP)

Взятие вершин:

input int ChannelWidth=100;

#property indicator_chart_window

datetime LastTime;
int ZZHandle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
   LastTime = 0;
   ZZHandle = iCustom(_Symbol, Period(), "IdealZZ", ChannelWidth);
  }
//+------------------------------------------------------------------+
//| GetValue                                                         |
//+------------------------------------------------------------------+
bool GetValue(double dir,int bar,int prevBar,double &peak,
             int &peakBar,datetime &peakTime,const datetime &T[])
  {
   if(dir<0)
     {
      double t[1];
      if(0>=CopyBuffer(ZZHandle,2,bar,1,t)) return false;
      int i= ArrayBsearch(T, (datetime)t[0]);

      if(i==prevBar)
        {
         if(0>=CopyBuffer(ZZHandle,2,bar+1,1,t)) return false;
         i=ArrayBsearch(T,(datetime)t[0]);
        }

      double v[1];
      if(0>=CopyBuffer(ZZHandle,1,i,1,v)) return false;

      if(v[0]==EMPTY_VALUE)
        {
         if(0>=CopyBuffer(ZZHandle,2,bar+1,1,t)) return false;
         i=ArrayBsearch(T,(datetime)t[0]);
         if(0>=CopyBuffer(ZZHandle,1,i,1,v)) return false;
        }

      peak=v[0];
      peakBar=i;
      peakTime=(datetime)t[0];
     }
   else if(dir>0)
     {
      double t[1];
      if(0>=CopyBuffer(ZZHandle,3,bar,1,t)) return false;
      int i= ArrayBsearch(T, (datetime)t[0]);

      if(i==prevBar)
        {
         if(0>=CopyBuffer(ZZHandle,3,bar+1,1,t)) return false;
         i=ArrayBsearch(T,(datetime)t[0]);
        }

      double v[1];
      if(0>=CopyBuffer(ZZHandle,0,i,1,v)) return false;

      if(v[0]==EMPTY_VALUE)
        {
         if(0>=CopyBuffer(ZZHandle,3,bar+1,1,t)) return false;
         i=ArrayBsearch(T,(datetime)t[0]);
         if(0>=CopyBuffer(ZZHandle,0,i,1,v)) return false;
        }

      peak=v[0];
      peakBar=i;
      peakTime=(datetime)t[0];
     }
   else
     {
      return(false);
     }

   return(true);
  }
//+------------------------------------------------------------------+
//| GetValue                                                         |
//+------------------------------------------------------------------+
void SetPt(string name,double price,datetime time)
  {
   ObjectCreate(0,name,OBJ_ARROW,0,time,price);
   ObjectSetInteger(0,name,OBJPROP_ARROWCODE,108);
   ObjectSetDouble(0,name,OBJPROP_PRICE,price);
   ObjectSetInteger(0,name,OBJPROP_TIME,time);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &T[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   if(LastTime==T[0]) return(rates_total);
   LastTime=T[0];

   ArraySetAsSeries(T,true);

   double dir_[1];
   if(0>=CopyBuffer(ZZHandle,4,1,1,dir_)) return rates_total;
   double dir=dir_[0];
   double rdir=-dir;

   if(dir==EMPTY_VALUE) return(rates_total);

   double v1,v2,v3,v4,v5;
   int    i1,i2,i3,i4,i5;
   datetime t1,t2,t3,t4,t5;

   if(
      GetValue(dir,1,0,v1,i1,t1,T) && 
      GetValue(rdir,i1,0,v2,i2,t2,T) && 
      GetValue(dir,i2,i1,v3,i3,t3,T) && 
      GetValue(rdir,i3,i2,v4,i4,t4,T) && 
      GetValue(dir,i4,i3,v5,i5,t5,T)
      )
     {
      SetPt("1",v1,t1);
      SetPt("2",v2,t2);
      SetPt("3",v3,t3);
      SetPt("4",v4,t4);
      SetPt("5",v5,t5);
      Print(v1,"   ",v2,"  ",v3,"  ",v4," ",v5," ",i1,"  ",i2,"  ",i3," ",i4," ",i5);
     }
   else
     {
      Print("Seems to be error available...");
     }

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

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

Внимание! Код может работать некорректно, если включен режим нулевого бара

Режим нулевого бара:

Включается в коде переменной DrawZeroBar. По умолчанию выключен. Включать не рекомендуется. Если индикатор используется в советнике, категорически не рекомендуется.

Пользуйте :) . Просьба сообщать обо всех обнаруженных недостатках.

Версия советника Jolly Roger Версия советника Jolly Roger

По мотивам участника Pirat на Automated Trading Championship 2011.

Пример работы с функцией IndicatorParameters() Пример работы с функцией IndicatorParameters()

Пример использования функции IndicatorParameters для запроса количества входных параметров индикатора, их типа и значений.

Triangle Hedge Triangle Hedge

Устанавливает виртуальную хеджированную позицию в MetaTrader 5.

Weather Vane Weather Vane

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