//+------------------------------------------------------------------+ //| Hans_Indicator.mq5 | //| Copyright © 2014, Shimodax | //| http://www.strategybuilderfx.com/forums/showthread.php?t=15439 | //+------------------------------------------------------------------+ /* Introduction: Draw ranges for "Simple Combined Breakout System for EUR/USD and GBP/USD" thread (see http://www.strategybuilderfx.com/forums/showthread.php?t=15439) LocalTimeZone: TimeZone for which MT5 shows your local time, e.g. 1 or 2 for Europe (GMT+1 or GMT+2 (daylight savings time). Use zero for no adjustment. The MetaQuotes demo server uses GMT +2. Enjoy :-) Markus */ #property copyright "Copyright © 2014, Shimodax" #property link "http://www.strategybuilderfx.com/forums/showthread.php?t=15439" #property description "Индикатор расширяющихся коридоров временных зон. Сформированный коридор равен четырём часам, расширение коридора - шестнадцать часов." //---- номер версии индикатора #property version "1.02" //---- отрисовка индикатора в главном окне #property indicator_chart_window //---- количество индикаторных буферов 4 #property indicator_buffers 4 //---- использовано четыре графических построения #property indicator_plots 4 //+-----------------------------------------+ //| объявление констант | //+-----------------------------------------+ #define RESET 0 // Константа для возврата терминалу команды на пересчёт индикатора //+-----------------------------------------+ //| Параметры отрисовки индикатора 1 | //+-----------------------------------------+ //---- отрисовка индикатора в виде линии #property indicator_type1 DRAW_LINE //---- в качестве цвета линии индикатора использован Blue цвет #property indicator_color1 clrBlue //---- линия индикатора - сплошная #property indicator_style1 STYLE_SOLID //---- толщина линии индикатора равна 1 #property indicator_width1 1 //---- отображение метки индикатора #property indicator_label1 "Upper Hans_Indicator 1" //+-----------------------------------------+ //| Параметры отрисовки индикатора 2 | //+-----------------------------------------+ //---- отрисовка индикатора в виде линии #property indicator_type2 DRAW_LINE //---- в качестве цвета линии индикатора использован Magenta цвет #property indicator_color2 clrMagenta //---- линия индикатора - сплошная #property indicator_style2 STYLE_SOLID //---- толщина линии индикатора равна 1 #property indicator_width2 1 //---- отображение метки индикатора #property indicator_label2 "Lower Hans_Indicator 1" //+-----------------------------------------+ //| Параметры отрисовки индикатора 3 | //+-----------------------------------------+ //---- отрисовка индикатора в виде линии #property indicator_type3 DRAW_LINE //---- в качестве цвета линии индикатора использован Lime цвет #property indicator_color3 clrLime //---- линия индикатора - сплошная #property indicator_style3 STYLE_SOLID //---- толщина линии индикатора равна 3 #property indicator_width3 3 //---- отображение метки индикатора #property indicator_label3 "Upper Hans_Indicator 2" //+-----------------------------------------+ //| Параметры отрисовки индикатора 4 | //+-----------------------------------------+ //---- отрисовка индикатора в виде линии #property indicator_type4 DRAW_LINE //---- в качестве цвета линии индикатора использован Red цвет #property indicator_color4 clrRed //---- линия индикатора - сплошная #property indicator_style4 STYLE_SOLID //---- толщина линии индикатора равна 3 #property indicator_width4 3 //---- отображение метки индикатора #property indicator_label4 "Lower Hans_Indicator 2" //+-----------------------------------------+ //| ВХОДНЫЕ ПАРАМЕТРЫ ИНДИКАТОРА | //+-----------------------------------------+ input uint LocalTimeZone=0; // час начала отсчёта исходного коридора input uint DestTimeZone=4; // сдвиг коридора влево в барах input uint PipsForEntry=100; // расширение границ сформированного коридора в пунктах input int Shift=0; // Сдвиг индикатора по горизонтали в барах //+-----------------------------------------+ //---- Объявление целых переменных начала отсчёта данных int min_rates_total; //---- объявление динамических массивов, которые будут в дальнейшем использованы в качестве индикаторных буферов double Zone1Upper[],Zone2Upper[]; double Zone1Lower[],Zone2Lower[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //---- Инициализация переменных начала отсчёта данных min_rates_total=100; //---- превращение динамического массива в индикаторный буфер SetIndexBuffer(0,Zone1Upper,INDICATOR_DATA); //---- осуществление сдвига начала отсчёта отрисовки индикатора PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,min_rates_total); //---- установка значений индикатора, которые не будут видимы на графике PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,NULL); //---- осуществление сдвига индикатора по горизонтали PlotIndexSetInteger(0,PLOT_SHIFT,Shift); //---- запрет на отображение значений индикатора в левом верхнем углу окна индикатора PlotIndexSetInteger(0,PLOT_SHOW_DATA,false); //---- индексация элементов в буфере как в таймсерии ArraySetAsSeries(Zone1Upper,true); //---- превращение динамического массива в индикаторный буфер SetIndexBuffer(1,Zone1Lower,INDICATOR_DATA); //---- осуществление сдвига начала отсчёта отрисовки индикатора PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,min_rates_total); //---- установка значений индикатора, которые не будут видимы на графике PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,NULL); //---- осуществление сдвига индикатора по горизонтали PlotIndexSetInteger(1,PLOT_SHIFT,Shift); //---- запрет на отображение значений индикатора в левом верхнем углу окна индикатора PlotIndexSetInteger(1,PLOT_SHOW_DATA,false); //---- индексация элементов в буфере как в таймсерии ArraySetAsSeries(Zone1Lower,true); //---- превращение динамического массива в индикаторный буфер SetIndexBuffer(2,Zone2Upper,INDICATOR_DATA); //---- осуществление сдвига начала отсчёта отрисовки индикатора PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,min_rates_total); //---- установка значений индикатора, которые не будут видимы на графике PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,NULL); //---- осуществление сдвига индикатора по горизонтали PlotIndexSetInteger(2,PLOT_SHIFT,Shift); //---- запрет на отображение значений индикатора в левом верхнем углу окна индикатора PlotIndexSetInteger(2,PLOT_SHOW_DATA,false); //---- индексация элементов в буфере как в таймсерии ArraySetAsSeries(Zone2Upper,true); //---- превращение динамического массива в индикаторный буфер SetIndexBuffer(3,Zone2Lower,INDICATOR_DATA); //---- осуществление сдвига начала отсчёта отрисовки индикатора PlotIndexSetInteger(3,PLOT_DRAW_BEGIN,min_rates_total); //---- установка значений индикатора, которые не будут видимы на графике PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,NULL); //---- осуществление сдвига индикатора по горизонтали PlotIndexSetInteger(3,PLOT_SHIFT,Shift); //---- запрет на отображение значений индикатора в левом верхнем углу окна индикатора PlotIndexSetInteger(3,PLOT_SHOW_DATA,false); //---- индексация элементов в буфере как в таймсерии ArraySetAsSeries(Zone2Lower,true); //--- создание имени для отображения в отдельном подокне и во всплывающей подсказке IndicatorSetString(INDICATOR_SHORTNAME,"Hans_Indicator("+string(LocalTimeZone)+","+ string(DestTimeZone)+","+string(PipsForEntry)+","+string(Shift)+")"); //--- определение точности отображения значений индикатора IndicatorSetInteger(INDICATOR_DIGITS,_Digits); //---- завершение инициализации 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-1; // стартовый номер для расчета всех баров } else limit=rates_total-prev_calculated; // стартовый номер для расчета новых баров //---- индексация элементов в массивах как в таймсериях ArraySetAsSeries(Time,true); ArraySetAsSeries(High,true); ArraySetAsSeries(Low,true); //---- основной цикл расчёта индикатора BreakoutRanges(0,limit,LocalTimeZone,DestTimeZone,rates_total,Time,High,Low); //---- return(rates_total); } //+------------------------------------------------------------------+ //| Compute index of first/last bar of yesterday and today | //+------------------------------------------------------------------+ int BreakoutRanges(int offset,int &lastbar,int tzlocal,int tzdest, const int rates_total_,const datetime &Time_[],const double &High_[],const double &Low_[]) { //---- int i,j,k, tzdiff=tzlocal-tzdest, tzdiffsec=tzdiff*3600, tidxstart[2]={ 0,0}, tidxend[2]={ 0,0 }; double thigh[2]= { 0.0, 0.0 }, tlow[2]= { DBL_MAX }; string tfrom[3]= { "04:00", "08:00" , /*rest of day: */ "12:00"}, tto[3]= { "08:00", "12:00", /*rest of day: */ "24:00" }, tday; bool inperiod=-1; datetime timet; // // search back for the beginning of the day // tday=TimeToString(Time_[lastbar]-tzdiffsec,TIME_DATE); for(; lastbar=offset; i--) { timet=Time_[i]-tzdiffsec; // time of this bar string timestr= TimeToString(timet, TIME_MINUTES), // current time HH:MM thisday= TimeToString(timet, TIME_DATE); // current date // // for all three periods (first period, second period, rest of day) // for(j=0; j<2; j++) { if(tfrom[j]<=timestr && timestr0) { // now draw high/low back over the recently completed period for(k=tidxstart[j-1]; k>=tidxend[j-1]; k--) { if(j-1==0) { Zone1Upper[k]= thigh[j-1]; Zone1Lower[k]= tlow[j-1]; } if(j-1==1) { Zone2Upper[k]= thigh[j-1]; Zone2Lower[k]= tlow[j-1]; } } } inperiod=j; // remember current period } if(inperiod==2) // inperiod==2 (end of day) is just to check completion of zone 2 break; // for the current period find idxstart, idxend and compute high/low if(tidxstart[j]==0) { tidxstart[j]=i; tday=thisday; } tidxend[j]=i; thigh[j]=MathMax(thigh[j],High_[i]); tlow[j]=MathMin(tlow[j],Low_[i]); } } // // carry forward the periods for which we have definite high/lows // if(inperiod>=1 && tday==thisday) { // first time period completed Zone1Upper[i]= thigh[0]+PipsForEntry*_Point; Zone1Lower[i]= tlow[0]-PipsForEntry*_Point; Zone2Upper[i]=Zone2Lower[i]=NULL; Zone2Upper[i]= thigh[0]+PipsForEntry*_Point; Zone2Lower[i]= tlow[0]-PipsForEntry*_Point; if(inperiod>=2) { // second period completed Zone2Upper[i]= thigh[1]+PipsForEntry*_Point; Zone2Lower[i]= tlow[1]-PipsForEntry*_Point; } } else { // none yet to carry forward (zero to clear old values, e.g. from switching timeframe) Zone1Upper[i]=Zone1Lower[i]=Zone2Upper[i]=Zone2Lower[i]=NULL; } // // at the beginning of a new day reset everything // if(tday!="XXX" && tday!=thisday) { //Print("#",i,"new day ",thisday,"/",tday); tday="XXX"; inperiod=-1; for(j=0; j<2; j++) { tidxstart[j]=0; tidxend[j]=0; thigh[j]=0; tlow[j]=99999; } } } //---- return (0); } //+------------------------------------------------------------------+