//+------------------------------------------------------------------+
//|                                                   i-DayRange.mq4 |
//|                                           Ким Игорь В. aka KimIV |
//|                                              http://www.kimiv.ru |
//|                                                                  |
//|  17.11.2005  Индикатор дневного диапазона                        |
//|  09.10.2006  По просьбе CW добавил параметр MaxRange, который    |
//|              ограничивает диапазон изменения индикатора.         |
//|  28.03.2007  По просьбе avtotorg@list.ru добавил продолжение     |
//|              линий до конца дня и ценовые уровни.                |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 SteelBlue
#property indicator_style1 1
#property indicator_width1 2
#property indicator_color2 SteelBlue
#property indicator_style2 1
#property indicator_width2 2
#property indicator_color3 LightSlateGray
#property indicator_style3 0
#property indicator_width3 1

//------- Внешние параметры индикатора -------------------------------
extern int   NumberOfDays = 5;      // Количество дней (0-все)
extern int   MaxRange     = 300;    // Максимальный диапазон
extern bool  ShowContinue = True;   // Показывать продолжение линий
extern bool  ShowPrice    = True;   // Показывать ценовые уровни
extern color clFont       = Green;  // Цвет шрифта
extern int   SizeFont     = 8;      // Размер шрифта
extern int   OffSet       = 10;     // Смещение

double shifthigh[];
double shiftlow[];
double shiftaver[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void init() {
  SetIndexBuffer   (0, shifthigh);
  SetIndexDrawBegin(0, 0);
  SetIndexLabel    (0, "Up Channel");
  SetIndexStyle    (0, DRAW_LINE);

  SetIndexBuffer   (1, shiftlow);
  SetIndexDrawBegin(1, 0);
  SetIndexLabel    (1, "Down Channel");
  SetIndexStyle    (1, DRAW_LINE);

  SetIndexBuffer   (2, shiftaver);
  SetIndexDrawBegin(2, 0);
  SetIndexLabel    (2, "Average Channel");
  SetIndexStyle    (2, DRAW_LINE, 0,1);
}

//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
void deinit() {
  ObjectDelete("UpPrice");
  ObjectDelete("DnPrice");
  Comment("");
}

//+------------------------------------------------------------------+ 
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+ 
void start() {
  datetime dt=CurTime();
  double   HighLine=0, LowLine=0, AverLine=0;
  int      i, j, kb;

  for (i=NumberBar(); i>=0; i--) {
    if (TimeHour(Time[i])==0 && TimeMinute(Time[i])==0) {
      HighLine=iHigh(Symbol(),0,i);
      LowLine=iLow(Symbol(),0,i);
    } else {
      if (MaxRange<=0 || MaxRange*Point>HighLine-LowLine) {
        if (iHigh(NULL,0,i)>HighLine) HighLine=iHigh(NULL,0,i);
        if (iLow(NULL,0,i)<LowLine) LowLine=iLow(NULL,0,i);
      }
    }
    AverLine=LowLine+(HighLine-LowLine)/2;

    kb=(StrToTime(TimeToStr(Time[0], TIME_DATE)+" 23:59")-Time[0])/Period()/60;
    if (i==0 && ShowContinue) {
      SetIndexShift(0, kb);
      SetIndexShift(1, kb);
      SetIndexShift(2, kb);
      for (j=kb; j>=0; j--) {
        shifthigh[j]=HighLine;
        shiftlow [j]=LowLine;
        shiftaver[j]=AverLine;
      }
    }
    shifthigh[i+kb]=HighLine;
    shiftlow [i+kb]=LowLine;
    shiftaver[i+kb]=AverLine;

    if (i==0 && ShowPrice) {
      DrawPrices(dt, "Price", HighLine, LowLine);
    }
  }
  Comment("Текущий дневной диапазон: "+DoubleToStr((HighLine-LowLine)/Point,0)+" п.");
}

//+------------------------------------------------------------------+
//| Прорисовка ценовых меток на графике                              |
//| Параметры:                                                       |
//|   dt - дата торгового дня                                        |
//|   no - наименование объекта                                      |
//|   up - верхний ценовой уровень                                   |
//|   dn - нижний ценовой уровень                                    |
//+------------------------------------------------------------------+
void DrawPrices(datetime dt, string no, double up, double dn) {
  if (ObjectFind("Up"+no)<0) ObjectCreate("Up"+no, OBJ_TEXT, 0, 0,0);
  ObjectSet("Up"+no, OBJPROP_TIME1   , dt);
  ObjectSet("Up"+no, OBJPROP_PRICE1  , up+(OffSet+SizeFont)*Point);
  ObjectSet("Up"+no, OBJPROP_COLOR   , clFont);
  ObjectSet("Up"+no, OBJPROP_FONTSIZE, SizeFont);
  ObjectSetText("Up"+no, DoubleToStr(up, Digits));

  if (ObjectFind("Dn"+no)<0) ObjectCreate("Dn"+no, OBJ_TEXT, 0, 0,0);
  ObjectSet("Dn"+no, OBJPROP_TIME1   , dt);
  ObjectSet("Dn"+no, OBJPROP_PRICE1  , dn-OffSet*Point);
  ObjectSet("Dn"+no, OBJPROP_COLOR   , clFont);
  ObjectSet("Dn"+no, OBJPROP_FONTSIZE, SizeFont);
  ObjectSetText("Dn"+no, DoubleToStr(dn, Digits));
}

//+------------------------------------------------------------------+ 
//| Возвращает номер бара                                            |
//+------------------------------------------------------------------+ 
int NumberBar() {
  int nd=0, i=0;

  while (nd<NumberOfDays) {
    i++;
    if (TimeHour(Time[i])==0 && TimeMinute(Time[i])==0) nd++;
  }
  return(i);
}
//+------------------------------------------------------------------+

