//+------------------------------------------------------------------+ //| ZigZagPointer.mq5 | //| Copyright © 2005, Dr. Gaines | //| dr_richard_gaines@yahoo.com | //+------------------------------------------------------------------+ /* | //Version: Final, November 01, 2008 | Editing: Nikolay Kositsin farria@mail.redcom.ru | //+------------------------------------------------------------------+ Этот вариант индикатора ZigZag, в отличие от оригинала, на каждом тике пересчитывается только на ещё непосчитанных барах и поэтому совсем не грузит компьютер. Помимо этого в данном индикаторе отрисовка линии происходит именно в стиле ZIGZAG, и поэтому индикатор корректно изображает одновременно две своих верщины(Хай и Лоу) на одном и том же баре! //----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ Depth - это минимальное кол-во баров, на котором не будет второго максимума (минимума) меньше (больше) на Deviation пипсов, чем предыдущего, то есть расходиться ZigZag может всегда, а сходится (либо сдвинуться целиком) больше, чем на Deviation, ZigZag может только после Depth баров. Backstep - это минимальное количество баров между максимумами (минимумами). //----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ Индикатор Зигзаг — ряд линий тренда, которые соединяют существенные вершины и основания на ценовом графике. Параметр минимального изменения цен определяет процент, на который цена должна переместить, чтобы сформировать новую "Зиг" или "Заг" линию. Этот индикатор отсеивает изменения на анализируемом графике, величина которых меньше заданной. Таким образом, зигзаг отражает только существенные изменения. Зигзаг используется, главным образом, для облегченного восприятия графиков, так как он показывает только наиболее значимые изменения и развороты. Также с его помощью можно выявлять Волны Эллиота и различные фигуры на графике. Важно усвоить, что последний отрезок индикатора может меняться в зависимости от изменений анализируемых данных. Это один из немногих индикаторов, у которого изменение цены бумаги может вызвать изменение предыдущего значения. Подобная способность корректировки своих значений по последующим изменениям цены делает Зигзаг прекрасным инструментом для анализа уже произошедших ценовых изменений. Поэтому не следует пытаться создать торговую систему на основе Зигзага: он лучше подходит для анализа исторических данных, чем для прогнозирования. Copyright © 2005, MetaQuotes Software Corp. */ //+------------------------------------------------------------------+ //--- авторство индикатора #property copyright "Copyright © 2005, Dr. Gaines" //--- ссылка на сайт автора #property link "dr_richard_gaines@yahoo.com" //--- номер версии индикатора #property version "1.01" #property description "Интерпретация зигзага" //--- отрисовка индикатора в главном окне #property indicator_chart_window //--- для расчёта и отрисовки индикатора использовано два буфера #property indicator_buffers 2 //--- использовано всего два графических построения #property indicator_plots 2 //+----------------------------------------------+ //| Параметры отрисовки нижнего индикатора | //+----------------------------------------------+ //--- отрисовка индикатора 1 в виде символа #property indicator_type1 DRAW_ARROW //--- в качестве цвета индикатора использован салатовый цвет #property indicator_color1 clrLime //--- толщина линии индикатора 1 равна 4 #property indicator_width1 4 //--- отображение метки индикатора #property indicator_label1 "ZigZagPointer Lower" //+----------------------------------------------+ //| Параметры отрисовки верхнего индикатора | //+----------------------------------------------+ //--- отрисовка индикатора 2 в виде символа #property indicator_type2 DRAW_ARROW //--- в качестве цвета индикатора использован розовый цвет #property indicator_color2 clrMagenta //--- толщина линии индикатора 2 равна 4 #property indicator_width2 4 //--- отображение метки индикатора #property indicator_label2 "ZigZagPointer Upper" //+----------------------------------------------+ //| объявление констант | //+----------------------------------------------+ #define RESET 0 // Константа для возврата терминалу команды на пересчет индикатора //+----------------------------------------------+ //| Входные параметры индикатора | //+----------------------------------------------+ input uint ExtDepth=12; input uint ExtDeviation=5; input uint ExtBackstep =3; //+----------------------------------------------+ //--- объявление динамических массивов, которые в дальнейшем //--- будут использованы в качестве индикаторных буферов double HighestBuffer[]; double LowestBuffer[]; //--- объявление переменных памяти для пересчёта индикатора только на непосчитанных барах int LASTlowpos,LASThighpos; double LASTlow0,LASTlow1,LASThigh0,LASThigh1,dExtDeviation; //--- объявление целочисленных переменных начала отсчёта данных int min_rates_total; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- инициализация переменных начала отсчёта данных min_rates_total=int(ExtDepth+ExtBackstep); dExtDeviation=ExtDeviation*_Point; //--- превращение динамических массивов в индикаторные буферы SetIndexBuffer(0,LowestBuffer,INDICATOR_DATA); SetIndexBuffer(1,HighestBuffer,INDICATOR_DATA); //--- запрет на отрисовку индикатором пустых значений PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0); //--- индексация элементов в буферах как в таймсериях ArraySetAsSeries(LowestBuffer,true); ArraySetAsSeries(HighestBuffer,true); //--- установка позиции, с которой начинается отрисовка уровней Боллинджера PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,min_rates_total); PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,min_rates_total); //--- установка формата точности отображения индикатора IndicatorSetInteger(INDICATOR_DIGITS,_Digits); //--- имя для окон данных и метка для подокон string shortname; StringConcatenate(shortname,"ZigZagPointer(ExtDepth=",ExtDepth, "ExtDeviation = ",ExtDeviation,"ExtBackstep = ",ExtBackstep,")"); IndicatorSetString(INDICATOR_SHORTNAME,shortname); //--- завершение инициализации return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- проверка количества баров на достаточность для расчёта if(rates_totalrates_total || prev_calculated<=0)// проверка на первый старт расчёта индикатора { limit=rates_total-min_rates_total; // стартовый номер для расчёта всех баров lastlow1=-1; lasthigh1=-1; lastlowpos=-1; lasthighpos=-1; } else { limit=rates_total-prev_calculated; // стартовый номер для расчёта новых баров //--- восстанавливаем значения переменных lastlow0=LASTlow0; lasthigh0=LASThigh0; lastlow1=LASTlow1; lasthigh1=LASThigh1; lastlowpos=LASTlowpos+limit; lasthighpos=LASThighpos+limit; } //--- индексация элементов в массивах как в таймсериях ArraySetAsSeries(high,true); ArraySetAsSeries(low,true); //--- первый большой цикл расчёта индикатора for(bar=limit; bar>=0 && !IsStopped(); bar--) { //--- запоминаем значения переменных перед прогонами на текущем баре if(rates_total!=prev_calculated && bar==0) { LASTlow0=lastlow0; LASThigh0=lasthigh0; } //--- low val=low[ArrayMinimum(low,bar,ExtDepth)]; if(val==lastlow0) val=0.0; else { lastlow0=val; if(low[bar]-val>ExtDeviation*_Point) val=0.0; else { for(back=1; back<=int(ExtBackstep); back++) { res=LowestBuffer[bar+back]; if(res && res>val) LowestBuffer[bar+back]=0.0; } } } LowestBuffer[bar]=val; //--- high val=high[ArrayMaximum(high,bar,ExtDepth)]; if(val==lasthigh0) val=0.0; else { lasthigh0=val; if(val-high[bar]>ExtDeviation*_Point) val=0.0; else { for(back=1; back<=int(ExtBackstep); back++) { res=HighestBuffer[bar+back]; if(res && res=0; bar--) { //--- запоминаем значения переменных перед прогонами на текущем баре if(rates_total!=prev_calculated && !bar) { LASTlow1=lastlow1; LASThigh1=lasthigh1; LASTlowpos=lastlowpos; LASThighpos=lasthighpos; } //--- curlow=LowestBuffer[bar]; curhigh=HighestBuffer[bar]; //--- if(!curlow && !curhigh) continue; //--- if(curhigh!=0) { if(lasthigh1>0) { if(lasthigh10) { if(lastlow1>curlow) LowestBuffer[lastlowpos]=0; else LowestBuffer[bar]=0; } //--- if(curlow