//+---------------------------------------------------------------------+ //| Zigzag2_R_Color_Fibo_Grand_xN_Stat_HTF.mq5 | //| Copyright © 2019, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+---------------------------------------------------------------------+ //| Для работы индикатора файл Zigzag2_R_Color.mq5 следует положить | //| в папке: каталог_данных_терминала\MQL5\Indicators и откомпилировать | //+---------------------------------------------------------------------+ #property copyright "Copyright © 2019, Nikolay Kositsin" #property link "farria@mail.redcom.ru" //---- номер версии индикатора #property version "1.61" //---- отрисовка индикатора в главном окне #property indicator_chart_window //---- для расчёта и отрисовки индикатора использовано три буфера #property indicator_buffers 3 //---- использовано всего 1 графическое построение #property indicator_plots 1 //+----------------------------------------------+ //| Объявление констант | //+----------------------------------------------+ #define RESET 0 // константа для возврата терминалу команды на пересчет индикатора #define INDICATOR_NAME "Zigzag2_R_Color" // константа для имени индикатора #define FIBO_LINES_TOTAL 7 // Константа для количества уровней фибо //+----------------------------------------------+ //| Параметры отрисовки верхнего индикатора | //+----------------------------------------------+ //---- в качестве индикатора использован ZIGZAG #property indicator_type1 DRAW_COLOR_ZIGZAG //---- в качестве цвета линии индикатора использованы #property indicator_color1 clrMediumVioletRed,clrMediumSeaGreen //---- толщина линии индикатора 1 равна 4 #property indicator_width1 4 //---- отображение бычей метки индикатора #property indicator_label1 "Zigzag2_R_Color" //+----------------------------------------------+ //| Входные параметры индикатора | //+----------------------------------------------+ input ENUM_TIMEFRAMES TimeFrame=PERIOD_H4; // Период графика //+----------------------------------------------+ //| Входные параметры индикатора | //+----------------------------------------------+ input int ExtDepth=12; input int ExtDeviation=5; input int ExtBackstep=3; input string FiboName="Fibo_Grand_xN"; //Имя Фибо-объекта input double FiboRatio =1.000; //Коэффициент домножения всех фибоуровней input double FiboLevelsShift=0.000; //Сдвиг по вертикали всех фибоуровней в Фибах от нулевого уровня input uint FiboTotal=3; //Количество дополнительных секторов Фибо сверху или снизу input color FiboColor=clrRed; //Цвет Фибо input uint FiboWidth=5; //толщина линии Фибо input int Shift=0; // сдвиг зигзага по горизонтали в барах //---- input double FiboLevel1 =0.000; //значение фибоуровня 1 input ENUM_LINE_STYLE StyleLevel1=STYLE_SOLID; //стиль линии фибоуровня 1 input uint WidthLevel1=4; //толщина линии фибоуровня 1 input color Color_Level1 = clrDarkTurquoise; //цвет фибоуровня 1 //---- input double FiboLevel2=0.236; //значение фибоуровня 2 input ENUM_LINE_STYLE StyleLevel2=STYLE_SOLID; //стиль линии фибоуровня 2 input uint WidthLevel2=1; //толщина линии фибоуровня 2 input color Color_Level2= clrRosyBrown; //цвет фибоуровня 2 //---- input double FiboLevel3 =0.382; //значение фибоуровня 3 input ENUM_LINE_STYLE StyleLevel3=STYLE_DASH; //стиль линии фибоуровня 3 input uint WidthLevel3=1; //толщина линии фибоуровня 3 input color Color_Level3 = clrOrange; //цвет фибоуровня 3 //---- input double FiboLevel4 =0.500; //значение фибоуровня 4 input ENUM_LINE_STYLE StyleLevel4=STYLE_SOLID; //стиль линии фибоуровня 4 input uint WidthLevel4=2; //толщина линии фибоуровня 4 input color Color_Level4 = clrDarkViolet; //цвет фибоуровня 4 //---- input double FiboLevel5 =0.618; //значение фибоуровня 5 input ENUM_LINE_STYLE StyleLevel5=STYLE_DASH; //стиль линии фибоуровня 5 input uint WidthLevel5=1; //толщина линии фибоуровня 5 input color Color_Level5 = clrBlue; //цвет фибоуровня 5 //---- input double FiboLevel6=0.764; //значение фибоуровня 6 input ENUM_LINE_STYLE StyleLevel6=STYLE_SOLID; //стиль линии фибоуровня 6 input uint WidthLevel6=1; //толщина линии фибоуровня 6 input color Color_Level6 = clrGray; //цвет фибоуровня 6 //---- input double FiboLevel7 = 1.000; //значение фибоуровня 7 input ENUM_LINE_STYLE StyleLevel7=STYLE_SOLID; //стиль линии фибоуровня 7 input uint WidthLevel7=4; //толщина линии фибоуровня 7 input color Color_Level7 = clrDarkTurquoise; //цвет фибоуровня 7 //---- input bool Fibo_AsRay=true; //отрисовка луча //+----------------------------------------------+ #define FIBO_LINES_TOTAL_XN_FULL FIBO_LINES_TOTAL*(1+FiboTotal*2)-FiboTotal*2 // Константа для количества уровней фибо //---- массивы переменных для линий Фибо double Values[]; color Colors[]; ENUM_LINE_STYLE Styles[]; uint Widths[]; //---- объявление динамических массивов, которые в дальнейшем будут использованы в качестве индикаторных буферов double HighBuffer[]; double LowBuffer[]; double ColorBuffer[]; //---- объявление целочисленных переменных начала отсчета данных int min_rates_total,LimitShift; //---- объявление целочисленных переменных для хендлов индикаторов int ZigZag_Handle; //+------------------------------------------------------------------+ //| Получение таймфрейма в виде строки | //+------------------------------------------------------------------+ string GetStringTimeframe(ENUM_TIMEFRAMES timeframe) {return(StringSubstr(EnumToString(timeframe),7,-1));} //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //---- инициализация переменных double timeratio=PeriodSeconds(TimeFrame)/PeriodSeconds(PERIOD_CURRENT); min_rates_total=int(2*timeratio); LimitShift=min_rates_total; //---- получение хендла индикатора Zigzag2_R_Color ZigZag_Handle=iCustom(NULL,TimeFrame,"Zigzag2_R_Color",ExtDepth,ExtDeviation,ExtBackstep); if(ZigZag_Handle==INVALID_HANDLE) { Print(" Не удалось получить хендл индикатора Zigzag2_R_Color"); return(INIT_FAILED); } //---- превращение динамического массива LowBuffer[] в индикаторный буфер SetIndexBuffer(0,LowBuffer,INDICATOR_DATA); //---- индексация элементов в буфере, как в таймсерии ArraySetAsSeries(LowBuffer,true); //---- превращение динамического массива HighBuffer[] в индикаторный буфер SetIndexBuffer(1,HighBuffer,INDICATOR_DATA); //---- индексация элементов в буфере, как в таймсерии ArraySetAsSeries(HighBuffer,true); //---- превращение динамического массива ColorBuffer[] в индикаторный буфер SetIndexBuffer(2,ColorBuffer,INDICATOR_COLOR_INDEX); //---- индексация элементов в буфере, как в таймсерии ArraySetAsSeries(ColorBuffer,true); //---- запрет на отрисовку индикатором пустых значений PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,NULL); //---- установка позиции, с которой начинается отрисовка PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,min_rates_total); //---- осуществление сдвига индикатора по горизонтали на Shift PlotIndexSetInteger(0,PLOT_SHIFT,Shift); //---- создание имени для отображения в отдельном подокне и во всплывающей подсказке string shortname; StringConcatenate(shortname,INDICATOR_NAME,"(",Symbol(),GetStringTimeframe(_Period),")"); IndicatorSetString(INDICATOR_SHORTNAME,shortname); //---- определение точности отображения значений индикатора IndicatorSetInteger(INDICATOR_DIGITS,_Digits); //---- ArrayResize(Values,FIBO_LINES_TOTAL_XN_FULL); ArrayResize(Colors,FIBO_LINES_TOTAL_XN_FULL); ArrayResize(Styles,FIBO_LINES_TOTAL_XN_FULL); ArrayResize(Widths,FIBO_LINES_TOTAL_XN_FULL); //---- Values[0]=FiboLevel1*FiboRatio; Values[1]=FiboLevel2*FiboRatio; Values[2]=FiboLevel3*FiboRatio; Values[3]=FiboLevel4*FiboRatio; Values[4]=FiboLevel5*FiboRatio; Values[5]=FiboLevel6*FiboRatio; Values[6]=FiboLevel7*FiboRatio; //---- Colors[0]=Color_Level1; Colors[1]=Color_Level2; Colors[2]=Color_Level3; Colors[3]=Color_Level4; Colors[4]=Color_Level5; Colors[5]=Color_Level6; Colors[6]=Color_Level7; //---- Styles[0]=StyleLevel1; Styles[1]=StyleLevel2; Styles[2]=StyleLevel3; Styles[3]=StyleLevel4; Styles[4]=StyleLevel5; Styles[5]=StyleLevel6; Styles[6]=StyleLevel7; //---- Widths[0]=WidthLevel1; Widths[1]=WidthLevel2; Widths[2]=WidthLevel3; Widths[3]=WidthLevel4; Widths[4]=WidthLevel5; Widths[5]=WidthLevel6; Widths[6]=WidthLevel7; //---- for(int count=1; count<=int(FiboTotal); count++) for(int lev=1; lev<7; lev++) { int kkk=lev+6*(2*count-1); Values[kkk]=Values[lev]+count; Colors[kkk]=Colors[lev]; Styles[kkk]=Styles[lev]; Widths[kkk]=Widths[lev]; //---- kkk=lev+6*(2*count); Values[kkk]=-Values[7-lev]-count+1; Colors[kkk]=Colors[lev-1]; Styles[kkk]=Styles[lev-1]; Widths[kkk]=Widths[lev-1]; } //--- создадим объект if(!FiboLevelsCreate(0,FiboName,0,0,0,0,0,FiboColor,STYLE_SOLID,FiboWidth,false,false,false,Fibo_AsRay,false,0)) { Print("Не удалось создать Фибо!"); return(INIT_FAILED); } if(!FiboLevelsSet(FIBO_LINES_TOTAL_XN_FULL,Values,Colors,Styles,Widths,0,FiboName)) { Print("Не удалось настроить Фибо!"); return(INIT_FAILED); } //--- завершение инициализации return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Поиск первого экстремума по его значению в таймсерии | //+------------------------------------------------------------------+ int FindMax(double Value,int start,int end,const double &Array[]) { //---- for(int bar=start; bar>=end; bar--) if(Array[bar]>=Value) return(bar); //---- return(ArrayMaximum(Array,end,start-end)); } //+------------------------------------------------------------------+ //| Поиск первого экстремума по его значению в таймсерии | //+------------------------------------------------------------------+ int FindMin(double Value,int start,int end,const double &Array[]) { //---- for(int bar=start; bar>=end; bar--) if(Array[bar]<=Value) return(bar); //---- return(ArrayMinimum(Array,end,start-end)); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //---- FiboLevelsDelete(0,FiboName); Comment(""); //---- ChartRedraw(0); } //+------------------------------------------------------------------+ //| Custom 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(!TimeFramesCheck(INDICATOR_NAME,TimeFrame)) return(RESET); //---- проверка количества баров на достаточность для расчета if(rates_totalrates_total || prev_calculated<=0)// проверка на первый старт расчета индикатора { limit=rates_total-min_rates_total-1; // стартовый номер для расчета всех баров maxbar=0; minbar=0; } else limit=LimitShift+rates_total-prev_calculated; // стартовый номер для расчета новых баров //---- индексация элементов в массивах, как в таймсериях ArraySetAsSeries(time,true); ArraySetAsSeries(high,true); ArraySetAsSeries(low,true); //---- обнулим содержимое индикаторных буферов до расчета for(bar=limit; bar>=0 && !IsStopped(); bar--) { LowBuffer[bar]=NULL; HighBuffer[bar]=NULL; } //---- основной цикл расчета индикатора for(bar=limit; bar>=0 && !IsStopped(); bar--) { //---- копируем вновь появившиеся данные в массивы if(CopyTime(NULL,TimeFrame,time[bar],1,ZigZagTime)<=0) return(RESET); if(time[bar+1]=ZigZagTime[0]) { //---- копируем вновь появившиеся данные в массивы if(CopyBuffer(ZigZag_Handle,1,time[bar],1,UpZigZag)<=0) return(RESET); if(CopyBuffer(ZigZag_Handle,0,time[bar],1,DnZigZag)<=0) return(RESET); if(CopyBuffer(ZigZag_Handle,2,time[bar],1,ColZigZag)<=0) return(RESET); ColorBuffer[bar]=ColZigZag[0]; if(UpZigZag[0]) { maxbar=FindMax(UpZigZag[0],bar,0,high); HighBuffer[maxbar]=UpZigZag[0]; LimitShift=bar; } if(DnZigZag[0]) { minbar=FindMin(DnZigZag[0],bar,0,low); LowBuffer[minbar]=DnZigZag[0]; LimitShift=bar; } } else ColorBuffer[bar]=ColorBuffer[bar+1]; } //---- объявления локальных переменных для построения фиб int bar1,bar2,sign; double price1,price2; //---- Построение Фибо bar1=FindFirstExtremum(0,rates_total,HighBuffer,LowBuffer,sign,price1); bar1=FindSecondExtremum(sign,bar1,rates_total,HighBuffer,LowBuffer,sign,price1); bar2=FindSecondExtremum(sign,bar1,rates_total,HighBuffer,LowBuffer,sign,price2); double vertShift=MathAbs(price2-price1)*FiboLevelsShift; //---- if(!FiboLevelsPointChange(0,FiboName,0,time[bar1],price1+vertShift)) return(rates_total); if(!FiboLevelsPointChange(0,FiboName,1,time[bar2],price2+vertShift)) return(rates_total); //---- ChartRedraw(0); return(rates_total); } //+------------------------------------------------------------------+ //| Cоздает "Уровни Фибоначчи" по заданным координатам | //+------------------------------------------------------------------+ bool FiboLevelsCreate(const long chart_ID=0, // ID графика const string name="FiboLevels", // имя объекта const int sub_window=0, // номер подокна datetime time1=0, // время первой точки double price1=0, // цена первой точки datetime time2=0, // время второй точки double price2=0, // цена второй точки const color clr=clrLimeGreen, // цвет объекта const ENUM_LINE_STYLE style=STYLE_SOLID, // стиль линии объекта const int width=1, // толщина линии объекта const bool back=false, // на заднем плане const bool selection=true, // выделить для перемещений const bool ray_left=false, // продолжение объекта влево const bool ray_right=false, // продолжение объекта вправо const bool hidden=true, // скрыт в списке объектов const long z_order=0) // приоритет на нажатие мышью { //--- установим координаты точек привязки, если они не заданы ChangeFiboLevelsEmptyPoints(time1,price1,time2,price2); //--- сбросим значение ошибки ResetLastError(); //--- создадим "Уровни Фибоначчи" по заданным координатам if(!ObjectCreate(chart_ID,name,OBJ_FIBO,sub_window,time1,price1,time2,price2)) { Print(__FUNCTION__, ": не удалось создать \"Уровни Фибоначчи\"! Код ошибки = ",GetLastError()); return(false); } //--- установим цвет ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); //--- установим стиль линии ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style); //--- установим толщину линии ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width); //--- отобразим на переднем (false) или заднем (true) плане ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); //--- включим (true) или отключим (false) режим выделения объекта для перемещений //--- при создании графического объекта функцией ObjectCreate, по умолчанию объект //--- нельзя выделить и перемещать. Внутри же этого метода параметр selection //--- по умолчанию равен true, что позволяет выделять и перемещать этот объект ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); //--- включим (true) или отключим (false) режим продолжения отображения объекта влево ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left); //--- включим (true) или отключим (false) режим продолжения отображения объекта вправо ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right); //--- скроем (true) или отобразим (false) имя графического объекта в списке объектов ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); //--- установи приоритет на получение события нажатия мыши на графике ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); //--- успешное выполнение return(true); } //+------------------------------------------------------------------+ //| Задает количество уровней и их параметры | //+------------------------------------------------------------------+ bool FiboLevelsSet(int levels, // количество линий уровня double &values[], // значения линий уровня color &colors[], // цвет линий уровня ENUM_LINE_STYLE &styles[], // стиль линий уровня int &widths[], // толщина линий уровня const long chart_ID=0, // ID графика const string name="FiboLevels") // имя объекта { //--- проверим размеры массивов if(levels!=ArraySize(colors) || levels!=ArraySize(styles) || levels!=ArraySize(widths) || levels!=ArraySize(widths)) { Print(__FUNCTION__,": длина массива не соответствует количеству уровней, ошибка!"); return(false); } //--- установим количество уровней ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels); //--- установим свойства уровней в цикле for(int i=0;i=Rates_total)StartPos=Rates_total-1; for(int bar=StartPos; bar=Rates_total)StartPos=Rates_total-1; if(Direct==-1) for(int bar=StartPos; bar