//+------------------------------------------------------------------+ //| GannZIGZAG_Arrows.mq5 | //| Copyright © 2005, Profi_R | //| http://www.metaquotes.net | //+------------------------------------------------------------------+ //---- авторство индикатора #property copyright "Copyright © 2005, Profi_R" //---- ссылка на сайт автора #property link "http://www.metaquotes.net" #property description "" //---- номер версии индикатора #property version "1.00" //---- отрисовка индикатора в главном окне #property indicator_chart_window //---- для расчёта и отрисовки индикатора использовано 2 буфера #property indicator_buffers 2 //---- использовано всего 2 графических построения #property indicator_plots 2 //+----------------------------------------------+ //| Параметры отрисовки верхнего индикатора | //+----------------------------------------------+ //---- отрисовка индикатора 1 в виде символа #property indicator_type1 DRAW_ARROW //---- в качестве цвета индикатора использован розовый цвет #property indicator_color1 clrMagenta //---- толщина линии индикатора 1 равна 4 #property indicator_width1 4 //---- отображение бычей метки индикатора #property indicator_label1 "Up GannZIGZAG Arrows" //+----------------------------------------------+ //| Параметры отрисовки нижнего индикатора | //+----------------------------------------------+ //---- отрисовка индикатора 2 в виде символа #property indicator_type2 DRAW_ARROW //---- в качестве цвета индикатора использован светло-зелёный цвет #property indicator_color2 clrLimeGreen //---- толщина линии индикатора 2 равна 4 #property indicator_width2 4 //---- отображение метки индикатора #property indicator_label2 "Down GannZIGZAG Arrows" //+----------------------------------------------+ //| Входные параметры индикатора | //+----------------------------------------------+ input uint GSv_range=2; input int Shift=0; // сдвиг индикатора по горизонтали в барах input uint UpLable=170;//значёк верхнего фрактала input uint DnLable=170;//значёк нижнего фрактала //+----------------------------------------------+ //---- объявление динамических массивов, которые будут в дальнейшем использованы в качестве индикаторных буферов double HighestBuffer[]; double LowestBuffer[]; //---- Объявление целых переменных начала отсчёта данных int min_rates_total; //---- double h,l; bool cur_h,cur_l; bool draw_up,draw_dn,initfl; int fPoint_i,sPoint_i,s_up,s_dn,drawf,lb; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { //---- Инициализация переменных начала отсчёта данных min_rates_total=2; //---- превращение динамических массивов в индикаторные буферы SetIndexBuffer(0,LowestBuffer,INDICATOR_DATA); SetIndexBuffer(1,HighestBuffer,INDICATOR_DATA); //---- запрет на отрисовку индикатором пустых значений PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,NULL); PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,NULL); //---- символы для индикатора PlotIndexSetInteger(0,PLOT_ARROW,DnLable); PlotIndexSetInteger(1,PLOT_ARROW,UpLable); //---- установка позиции, с которой начинается отрисовка уровней Боллинджера PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,min_rates_total); PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,min_rates_total); //---- осуществление сдвига индикатора по горизонтали на Shift PlotIndexSetInteger(0,PLOT_SHIFT,Shift); PlotIndexSetInteger(1,PLOT_SHIFT,Shift); //---- индексация элементов в буферах как в таймсериях ArraySetAsSeries(LowestBuffer,true); ArraySetAsSeries(HighestBuffer,true); //--- создание имени для отображения в отдельном подокне и во всплывающей подсказке IndicatorSetString(INDICATOR_SHORTNAME,"GannZIGZAG_Arrows"); //--- определение точности отображения значений индикатора IndicatorSetInteger(INDICATOR_DIGITS,_Digits); //---- } //+------------------------------------------------------------------+ //| 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; // стартовый номер для расчёта всех баров initfl=0; draw_up=0; draw_dn=0; cur_h=0; cur_l=0; } else { limit=rates_total-prev_calculated; // стартовый номер для расчёта новых баров } //---- первоначальная инициализация if(initfl!=1) myInit(rates_total,open,high,low,close); int bars2=rates_total-2; int bars1=rates_total-1; //---- основной цикл расчёта индикатора for(bar=limit; bar>=0 && !IsStopped(); bar--) { bar1=bar+1; count=bars1-bar; HighestBuffer[bar]=NULL; LowestBuffer[bar]=NULL; //---- если на предыдущем баре был отрисован экстремум if((HighestBuffer[bar1]>0 || LowestBuffer[bar1]>0)&& lb!=count) { if(draw_up) s_dn=0; else if(draw_dn) s_up=0; } if(lb!=count) { cur_h=0; cur_l=0; } if(bar>bars2-drawf || (high[bar]<=high[bar1] && low[bar]>=low[bar1])) continue; if(draw_up) { //---- если линия направлена вверх if(high[bar]>h) { //---- если достигнут новый максимум h=high[bar]; cur_h=1; } if(low[bar]bar; i--) { HighestBuffer[i]=NULL; LowestBuffer[i]=NULL; } } else { //---- если свеча бычья sPoint_i=count; HighestBuffer[bar]=h; for(i=bars2-fPoint_i; i>bar; i--) { HighestBuffer[i]=NULL; LowestBuffer[i]=NULL; } } } else { //---- если последний бар только новый максимум if(cur_h==1) { sPoint_i=count; HighestBuffer[bar]=h; l=low[bar]; for(i=bars2-fPoint_i; i>bar; i--) { HighestBuffer[i]=NULL; LowestBuffer[i]=NULL; } } else { if(cur_l==1) { //---- если последний бар только новый минимум draw_up=0; draw_dn=1; fPoint_i=sPoint_i; sPoint_i=count; LowestBuffer[bar]=l; h=high[bar]; for(i=bars2-fPoint_i; i>bar; i--) { HighestBuffer[i]=NULL; LowestBuffer[i]=NULL; } } } } } else { //---- иначе если смены направления нет явно (счетчик Dn свечей не равен GSv_range) //---- если достигнут новый максимум if(cur_h==1) { sPoint_i=count; HighestBuffer[bar]=h; for(i=bars2-fPoint_i; i>bar; i--) { HighestBuffer[i]=NULL; LowestBuffer[i]=NULL; } l=low[bar]; } } } else { //---- если линия направлена вниз if(high[bar]>h) { //---- если достигнут новый максимум h=high[bar]; if(lb!=count || cur_h!=1) s_up++; cur_h=1; //---- если это не тот же самый бар } if(low[bar]bar; i--) { HighestBuffer[i]=NULL; LowestBuffer[i]=NULL; } } else { //---- если свеча бычья draw_up=1; draw_dn=0; fPoint_i=sPoint_i; sPoint_i=count; HighestBuffer[bar]=h; for(i=bars2-fPoint_i; i>bar; i--) { HighestBuffer[i]=NULL; LowestBuffer[i]=NULL; } } } else { //---- если последний бар только новый максимум if(cur_h==1) { draw_up=1; draw_dn=0; fPoint_i=sPoint_i; sPoint_i=count; HighestBuffer[bar]=h; l=low[bar]; for(i=bars2-fPoint_i; i>bar; i--) { HighestBuffer[i]=NULL; LowestBuffer[i]=NULL; } } else { if(cur_l==1) { //---- если последний бар только новый минимум sPoint_i=count; LowestBuffer[bar]=l; h=high[bar]; for(i=bars2-fPoint_i; i>bar; i--) { HighestBuffer[i]=NULL; LowestBuffer[i]=NULL; } } } } } else { //---- иначе если смены направления нет явно (счетчик Up свечей не равен GSv_range) //---- если достигнут новый минимум if(cur_l==1) { sPoint_i=count; LowestBuffer[bar]=l; for(i=bars2-fPoint_i; i>bar; i--) { HighestBuffer[i]=NULL; LowestBuffer[i]=NULL; } h=high[bar]; } } } if(lb!=count) lb=count; } //---- return(rates_total); } //+------------------------------------------------------------------+ // Функция начальной инициализации индикатора | //+------------------------------------------------------------------+ void myInit( const int bars, const double &Open[], const double &High[], const double &Low[], const double &Close[]) { //---- int index,index1; int bars1=bars-1; fPoint_i=0; h=High[bars1]; l=Low[bars1]; for(index=bars-2; index>=0; index--) { index1=index+1; if(High[index]>High[index1] || Low[index]h && High[index]>High[index1]) s_up++; if(Low[index]=Open[index]) { s_dn=0; LowestBuffer[bars1]=Low[bars1]; HighestBuffer[index]=High[index]; draw_up=1; break; } else { s_up=0; HighestBuffer[bars1]=High[bars1]; LowestBuffer[index]=Low[index]; draw_dn=1; break; } } else { h=High[index]; l=Low[index]; sPoint_i=bars1-index; if(s_up==GSv_range) { s_dn=0; LowestBuffer[bars1]=Low[bars1]; HighestBuffer[index]=High[index]; draw_up=1; break; } else { if(s_dn==GSv_range) { s_up=0; HighestBuffer[bars1]=High[bars1]; LowestBuffer[index]=Low[index]; draw_dn=1; break; } } } } initfl=1; drawf=sPoint_i; //---- } //+------------------------------------------------------------------+