Ставь лайки и следи за новостями
Поставь на него ссылку - пусть другие тоже оценят
Оцени его работу в терминале MetaTrader 5
Идеальный ЗигЗаг - индикатор для MetaTrader 5
- Просмотров:
- 10930
- Рейтинг:
- Опубликован:
- 2012.07.11 16:37
- Обновлен:
- 2016.11.22 07:33
- Нужен робот или индикатор на основе этого кода? Закажите его на бирже фрилансеров Перейти на биржу
Ультрабыстрый зигзаг на максимально простом принципе.
Без висящих вершин. С поддержкой оптимизированного по времени нахождения вершин.
Достоинства:
- Самая тяжелая функция в расчетах - iBarShift, которая полностью замещает ненужные циклы для поиска вершин, была заменена на ArrayBSearch, а это значит, индикатор будет работать еще эффективнее аналога на MQL4;
- Вся необходимая информация для каждого бара не только доступна в любой момент истории, но и также доступна советнику для любого момента истории;
- Никаких висящих вершин;
- Возможность эффективного поиска вершин без перебора значений индикатора;
- Очень быстрая работа;
- Корректная обработка вставки истории и переключения таймфреймов;
- Незаменим для работы в советниках.
Недостатки:
- Затраты памяти. Для корректной отрисовки зигзагу надо 2 буфера (1 мало, будут висяки), здесь используется 5. Полностью компенсируется (имхо) достоинством № 6. Ни один быстрый зигзаг по определению не может корректно обрабатывать вставку истории на двух буферах.
- Рисование дополнительных линий. Нужно для того, чтобы они были видны советнику. Значения порядка таких величин, которые не должны быть видны ни при каком раскладе.
Принцип:
Новое колено начинает строиться при откате большем, чем заданный в настройках. Он может задаваться в пунктах (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. По умолчанию выключен. Включать не рекомендуется. Если индикатор используется в советнике, категорически не рекомендуется.
Пользуйте :) . Просьба сообщать обо всех обнаруженных недостатках.
По мотивам участника Pirat на Automated Trading Championship 2011.
Пример работы с функцией IndicatorParameters()Пример использования функции IndicatorParameters для запроса количества входных параметров индикатора, их типа и значений.
Устанавливает виртуальную хеджированную позицию в MetaTrader 5.
Weather VaneИндикатор позволяет рассчитать среднюю величину последних цен по символу и определить направленность движения, что может являться сигналом для совершения торговой операции.