//+------------------------------------------------------------------+
//|                        MultiZigZag           MZZ9_trendLine.mq4  |
//+------------------------------------------------------------------+
/*

  29 января 2012 г.


Большинство внешних параметров - строковые переменные. 
В каждую переменную записываются параметры для девяти зигзагов. 
Первая цифра - для первого зигзага, вторая - для второго, третья - для третьего, четвертая - для четвертого и т.д.. Через запятую.

Выводится четыре первых зигзага, считая от текущего таймфрейма. Рассчитывается максимум 9 зигзагов.

ExtDepth,  ExtBackstep - параметры для зигзага.
Если задать ExtDepth=0, то соответствующий зигзаг выводиться не будет.
ExtMaxBar      - количество баров, на которых рассчитывается зигзаг.
GrossPeriod    - периоды графиков, выраженные в минутах, по данным с которых строится зигзаг. При записи 0 зигзаг выводится на текущем таймфрейме.
zzVisible 0    - соответствующий зигзаг не рассчитывается и не выводится на график, 1 - зигзаг рассчитывается.
zzColor        - задаются цвета для каждого таймфрейма.
extColor       - дополнительные цвета, если на одном таймфрейме выводится несколько зигзагов.

ExtProcedureOfPayments - последовательность рассчета зигзагов: true - в порядке возрастания таймфрейма, false - в порядке убывания.

showZigZag     - варианты показа зигзагов. 0 - в виде ломаной линии. 1 - в виде ромбиков на экстремумах. 2 - в виде рядов точек на участке, 
                 принадлежащем бару того таймфрейма, по данным которого рассчитывается зигзаг, Как в DT-ZigZag
ExtFirstPoint  - выбор места первой точки привязки трендовой. false - на переломе зигзага, true - на последнем из баров равных бару на переломе зигзага
TrendLineType  - вариант построения трендовых линий. 0 - по данным таймфрейма, на котором построен зигзаг с привязкой к барам текущего тф. 
                                                     1 - по данным текущего таймфрейма.
                                                     2 - по данным таймфрейма, на котором построен зигзаг без привязки к барам текущего тф.

LevelVisible   - 1 - разрешает вывод уровней пересечения трендовых. 0 - запрещает.
vLineVisible   - 1 - разрешает вывод вертикальной линии от экстремума, где начинается правая трендовая. 0 - запрещает.
numbervLine    - задает номер экстремума зигзага, на котором выводится вертикальная линия. Можно задать только 0 или 1.

LineStyle      - задает стиль линий
LineWidth      - задает толщину линий

hLevelVisible  - 1 - разрешает вывод горизонтальных уровней. 0 - запрещает.
hLabelVisible  - 1 - разрешает вывод значений горизонтальных уровней. 0 - запрещает.
hLevelFree     - этим параметром задаются значения горизонтальных уровней. Уровней может быть произвольное количество.
                 Значения уовней разделяются между собой запятой. Значения уровней задаются в виде десятичных дробей.
                 Точка разделяет целую и дробную часть значения уровня.
hLineStyle     - задает стиль линий
hLineWidth     - задает толщину линий

FiboLevelVisible - задает, на каких зигзагах выводить фибо уровни от пересечения трендовой и вертикали.
FiboLevel        - задает значения фибо уровней
VisibleCenaFibo  - разрешает показ ценовых значений уровней фибо


ExtReCalculate - количество экстремумов зигзага, начиная с 0, пересчитываемых в режиме реального времени.
                 Применяется для расчета зигзагов со старших таймфреймов.

ExtComplect - у нескольких индикаторов, запущенных на одной валютной паре в одном окне должны быть разные значения этого параметра.
              Это необходимо, чтобы линии, создаваемые разными экземплярами индикаторов, имели уникальные назвиния.
              Каждый экземпляр индикатора может управлять линиями, которые он создал.
              
*/

#property link   "nen"

//  Отрисовка индикатора в основном окне
#property indicator_chart_window
//  Количество индикаторных буфферов
#property indicator_buffers  8

//  ВХОДНЫЕ ПАРАМЕТРЫ ИНДИКАТОРА 
extern string ExtDepth      = "12,12,12,12,12,12,12,12,12";
extern string ExtBackstep   = "3,3,3,3,3,3,3,3,3";
extern string ExtMaxBar     = "5000,1000,350,350,350,350,350,350,350,350";    // Количество обсчитываемых баров (0-все)
extern string GrossPeriod   = "1,5,15,30,60,240,1440,10080,43200";            // Таймфреймы, на которых рассчитываются зигзаги, 0 - текущий таймфрейм
extern string zzVisible     = "1,1,1,0,1,1,1,1,1";
extern string zzColor       = "Tan,RoyalBlue,Aqua,SaddleBrown,Red,Yellow,Magenta,Purple,MediumSpringGreen";
extern string extColor      = "Indigo,Olive,Teal";

extern bool   ExtProcedureOfPayments = true;
extern int    showZigZag    = 0;
extern bool   ExtFirstPoint = true;
extern int    TrendLineType = 1;
extern string LevelVisible  = "1,1,1,1,1,1,1,1,1";
extern string vLineVisible  = "1,1,1,1,1,1,1,1,1";
extern int    numbervLine   = 0;
//extern string vLineVisible  = "0,0,0,0,0,0,0,0,0";
extern string LineStyle     = "2,2,2,2,2,2,2,2,2";
extern string LineWidth     = "0,0,0,0,0,0,0,0,0";

//extern string hLevelVisible = "1,1,1,1,1,1,1,1,1";
extern string hLevelVisible = "0,0,0,0,0,0,0,0,0";
extern string hLabelVisible = "1,1,1,1,1,1,1,1,1";
extern string hLevelFree    = "-1.0,0.0,0.618,1.0,1.618,2.0,2.618,3.0,4.0";
extern string hLineStyle    = "1,1,1,1,1,1,1,1,1";
extern string hLineWidth    = "0,0,0,0,0,0,0,0,0";
extern string FiboLevelVisible  = "1,1,1,1,1,1,1,1,1";
extern string FiboLevel     = "0.0,0.146,0.236,0.382,0.618,1.0,1.618,2.618,4.236,6.853";
extern bool   VisibleCenaFibo = true;
extern int    ExtReCalculate = 3;              // Количество экстремумов зигзага старшего таймфрейма, начиная с 0, пересчитываемых
                                               // в режиме реального времени
extern int    ExtComplect   = 0;

int ExtDepth_[]={0,0,0,0,0,0,0,0,0}, ExtBackstep_[]={0,0,0,0,0,0,0,0,0}, ExtMaxBar_[]={0,0,0,0,0,0,0,0,0}, GrossPeriod_[]={0,0,0,0,0,0,0,0,0}, zzVisible_[]={0,0,0,0,0,0,0,0,0};
int zzColor_[]={0,0,0,0,0,0,0,0,0}, extColor_[]={0,0,0}, currentBars_[]={0,0,0,0,0,0,0,0,0}, LineStyle_[]={0,0,0,0,0,0,0,0,0}, LineWidth_[]={0,0,0,0,0,0,0,0,0};
int LevelVisible_[]={0,0,0,0,0,0,0,0,0}, vLineVisible_[]={0,0,0,0,0,0,0,0,0}, hLevelVisible_[]={0,0,0,0,0,0,0,0,0}, hLabelVisible_[]={0,0,0,0,0,0,0,0,0}, hLineStyle_[]={0,0,0,0,0,0,0,0,0}, hLineWidth_[]={0,0,0,0,0,0,0,0,0}, FiboLevelVisible_[]={0,0,0,0,0,0,0,0,0};
//  Индикаторные буферы
double LowestBuffer1[],HighestBuffer1[],LowestBuffer2[],HighestBuffer2[],LowestBuffer3[],HighestBuffer3[],LowestBuffer4[],HighestBuffer4[];
//  Вспомогательные буферы
double LowestBufferGross1[],HighestBufferGross1[],LowestBufferGross2[],HighestBufferGross2[],LowestBufferGross3[],HighestBufferGross3[],LowestBufferGross4[],HighestBufferGross4[];
double LowestBufferGross5[],HighestBufferGross5[],LowestBufferGross6[],HighestBufferGross6[],LowestBufferGross7[],HighestBufferGross7[],LowestBufferGross8[],HighestBufferGross8[];
double LowestBufferGross9[],HighestBufferGross9[];
//  Флаги, показывающие, что со старшего тф первоначальное преобразование зигзага произведено
bool Grosstf_DT[]={false, false, false, false, false, false, false, false, false};
//  Флаги, показывающие, что на истории зигзаг построен
bool ZZ_tf[]     ={false, false, false, false, false, false, false, false, false};
//  Значение времени начала и конца третьего луча
datetime L2LTime[]={0,0,0,0,0,0,0,0,0},L2HTime[]={0,0,0,0,0,0,0,0,0};
//  При выходе за значения переменных lBar, hBar и tiZZ производится расчет зигзага
//  То есть только при выходе за пределы уже посчитанного бара производится расчет. 
//  Это позволяет рассчитывать не на каждом тике.
double lBar[]={0,0,0,0,0,0,0,0,0}, hBar[]={0,0,0,0,0,0,0,0,0};
datetime tiZZ[]={0,0,0,0,0,0,0,0,0}, tiP2ZZ[]={0,0,0,0,0,0,0,0,0};
//  Координаты первых трех экстремумов зигзагов и вертикальных линий
int      nbar[9][3], vLine[9];
datetime t3[9][3], tvLine[9];
double   h3[9][3], l3[9][3], vFibo[9];
//  Флаги пересчета трендовых
int recount[9]; // 0 - трендовые не пересчитываются, 1 пересчитывается трендовая от первого луча,
                // 2 - пересчитываются две трендовые
//  Массив для хранения значений Bars
int saveBars[]={0,0,0,0,0,0,0,0,0};
int currentBars;
//  Массив для хранения порядка рассчета зигзагов. Какой зигзаг за каким рассчитывается.
int ProcedureOfPayments[9][3];
//  Переменная, хранящая количество баров, на которых рассчитывается зигзаг
int limit;
//  Массивы и переменные для задания уровней
double fi[], fif[];
string fitxt[], fiftxt[];
string fitxt100[], fiftxt100[];
int    Sizefi=0, Sizefif=0;
//+------------------------------------------------------------------+
//| Initialization function. Начало.                                 |
//+------------------------------------------------------------------+
int init()
  {
   string aa,aa1,str="";
   int aa2;
   int i,j,k,m,n,q;

// Использовано по два индикаторных буффера для вывода на график каждого зигзага
   SetIndexBuffer(0,LowestBuffer1);
   SetIndexBuffer(1,HighestBuffer1);
   SetIndexBuffer(2,LowestBuffer2);
   SetIndexBuffer(3,HighestBuffer2);
   SetIndexBuffer(4,LowestBuffer3);
   SetIndexBuffer(5,HighestBuffer3);
   SetIndexBuffer(6,LowestBuffer4);
   SetIndexBuffer(7,HighestBuffer4);

// Установка значений индикатора, которые не будут видимы на графике
   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
   SetIndexEmptyValue(2,0.0);
   SetIndexEmptyValue(3,0.0);
   SetIndexEmptyValue(4,0.0);
   SetIndexEmptyValue(5,0.0);
   SetIndexEmptyValue(6,0.0);
   SetIndexEmptyValue(7,0.0);

   _stringtointarray (ExtDepth,     ExtDepth_,     9);
   _stringtointarray (ExtBackstep,  ExtBackstep_,  9);
   _stringtointarray (ExtMaxBar,    ExtMaxBar_,    9);
   _stringtointarray (GrossPeriod,  GrossPeriod_,  9);
   _stringtointarray (zzVisible,    zzVisible_,    9);
   _stringtointarray (LineStyle,    LineStyle_,    9);
   _stringtointarray (LineWidth,    LineWidth_,    9);
   _stringtointarray (LevelVisible, LevelVisible_, 9);
   _stringtointarray (vLineVisible, vLineVisible_, 9);
   _stringtointarray (hLevelVisible,hLevelVisible_,9);
   _stringtointarray (hLabelVisible,hLabelVisible_,9);
   _stringtointarray (hLineStyle,   hLineStyle_,   9);
   _stringtointarray (hLineWidth,   hLineWidth_,   9);
   _stringtointarray (FiboLevelVisible, FiboLevelVisible_, 9);
   _stringtocolorarray (zzColor,    zzColor_,      9);
   _stringtocolorarray (extColor,   extColor_,     3);

   ArrayInitialize(t3,0); ArrayInitialize(h3,0); ArrayInitialize(l3,0); ArrayInitialize(recount,2);
   ArrayInitialize(nbar,0); ArrayInitialize(vLine,0); ArrayInitialize(tvLine,0); ArrayInitialize(vFibo,0);

   if (TrendLineType<0) TrendLineType=0;
   if (TrendLineType>2) TrendLineType=2;

   if (numbervLine<0) numbervLine=0;
   if (numbervLine>1) numbervLine=1;

   // Подготовка списка фиб, заданных пользователем. Начало.
   i=-1; aa2=0;
   while (aa2>=0)
     {
      aa2=StringFind(hLevelFree, ",",i+1);
      if (aa2>=0)
        {i=aa2;Sizefi++;}
      else
        {
         if (StringLen(hLevelFree)-i>0)
           {
            if (StrToDouble(StringSubstr(hLevelFree,i+1))>0) Sizefi++;
            ArrayResize(fi,Sizefi);
            ArrayResize(fitxt,Sizefi);
            ArrayResize(fitxt100,Sizefi);
            aa1=hLevelFree;
            for (i=0;i<Sizefi;i++)
              {
               aa2=StringFind(aa1, ",", 0);

               fitxt[i]=StringTrimLeft(StringTrimRight(StringSubstr(aa1,0,aa2)));
               fi[i]=StrToDouble(fitxt[i]);
               if (fi[i]<1) fitxt[i]=StringSubstr(fitxt[i],1);
               fitxt100[i]=DoubleToStr(100*fi[i],1);

               if (aa2>=0) aa1=StringSubstr(aa1,aa2+1);
              }
           }
        }
     }

   i=-1; aa2=0;
   while (aa2>=0)
     {
      aa2=StringFind(FiboLevel, ",",i+1);
      if (aa2>=0)
        {i=aa2;Sizefif++;}
      else
        {
         if (StringLen(FiboLevel)-i>0)
           {
            if (StrToDouble(StringSubstr(FiboLevel,i+1))>0) Sizefif++;
            ArrayResize(fif,Sizefif);
            ArrayResize(fiftxt,Sizefif);
            ArrayResize(fiftxt100,Sizefif);
            aa1=FiboLevel;
            for (i=0;i<Sizefif;i++)
              {
               aa2=StringFind(aa1, ",", 0);

               fiftxt[i]=StringTrimLeft(StringTrimRight(StringSubstr(aa1,0,aa2)));
               fif[i]=StrToDouble(fiftxt[i]);
               if (fif[i]<1) fitxt[i]=StringSubstr(fiftxt[i],1);
               fiftxt100[i]=DoubleToStr(100*fif[i],1);

               if (aa2>=0) aa1=StringSubstr(aa1,aa2+1);
              }
           }
        }
     }
   // Подготовка списка фиб, заданных пользователем. Конец.

   for (i=0;i<9;i++)
     {
      Grosstf_DT[i]=false; ZZ_tf[i]=false;
      j=GrossPeriod_[i];
      GrossPeriod_[i]=_period(i,j);

      if (ExtDepth_[i]<=0) zzVisible_[i]=0;
      if (zzVisible_[i]>0)
        {
         m=ExtBackstep_[i]+ExtDepth_[i];
         if ((ExtMaxBar_[i]>iBars(NULL,GrossPeriod_[i])-m) || (ExtMaxBar_[i]==0)) limit=iBars(NULL,GrossPeriod_[i])- m; else limit=ExtMaxBar_[i];

         if (i==0) arr_resize(LowestBufferGross1, HighestBufferGross1, limit+m, i);
         else if (i==1) arr_resize(LowestBufferGross2, HighestBufferGross2, limit+m, i);
         else if (i==2) arr_resize(LowestBufferGross3, HighestBufferGross3, limit+m, i);
         else if (i==3) arr_resize(LowestBufferGross4, HighestBufferGross4, limit+m, i);
         else if (i==4) arr_resize(LowestBufferGross5, HighestBufferGross5, limit+m, i);
         else if (i==5) arr_resize(LowestBufferGross6, HighestBufferGross6, limit+m, i);
         else if (i==6) arr_resize(LowestBufferGross7, HighestBufferGross7, limit+m, i);
         else if (i==7) arr_resize(LowestBufferGross8, HighestBufferGross8, limit+m, i);
         else if (i==8) arr_resize(LowestBufferGross9, HighestBufferGross9, limit+m, i);
        }

      ProcedureOfPayments[i][0]=GrossPeriod_[i];
      ProcedureOfPayments[i][1]=i;
     }

   ArraySort(ProcedureOfPayments,WHOLE_ARRAY,0,MODE_ASCEND);

   if (showZigZag<0) showZigZag=0;
   if (showZigZag>2) showZigZag=2;

   j=1;k=0;q=-1;
   for (n=0;n<9;n++)
     {
      i=ProcedureOfPayments[n][1];
      if (zzVisible_[i]==0 || j>4) ProcedureOfPayments[n][2]=0;
      else if (GrossPeriod_[i]==0 || GrossPeriod_[i]>Period())
        {
         if (GrossPeriod_[i]==q)
           {
            zzColor_[i]=extColor_[k];
            k++;
           }

         q=GrossPeriod_[i];

         if (j==1)
           {
            if (showZigZag==0)
              {
               SetIndexStyle(0,DRAW_ZIGZAG, EMPTY, 0, zzColor_[i]);
               SetIndexStyle(1,DRAW_ZIGZAG, EMPTY, 0, zzColor_[i]);
              }
            else
              {
               SetIndexStyle(0,DRAW_ARROW, EMPTY, 0, zzColor_[i]);
               SetIndexStyle(1,DRAW_ARROW, EMPTY, 0, zzColor_[i]);
               if (showZigZag==1)
                 {
                  SetIndexArrow(0, 116); 
                  SetIndexArrow(1, 116);
                 }
               else
                 {
                  SetIndexArrow(0, 159); 
                  SetIndexArrow(1, 159);
                 }
              }
           }
         else if (j==2)
           {
            if (showZigZag==0)
              {
               SetIndexStyle(2,DRAW_ZIGZAG, EMPTY, 0, zzColor_[i]);
               SetIndexStyle(3,DRAW_ZIGZAG, EMPTY, 0, zzColor_[i]);
              }
            else
              {
               SetIndexStyle(2,DRAW_ARROW, EMPTY, 0, zzColor_[i]);
               SetIndexStyle(3,DRAW_ARROW, EMPTY, 0, zzColor_[i]);
               if (showZigZag==1)
                 {
                  SetIndexArrow(2, 116); 
                  SetIndexArrow(3, 116);
                 }
               else
                 {
                  SetIndexArrow(2, 159); 
                  SetIndexArrow(3, 159);
                 }
              }
           }
         else if (j==3)
           {
            if (showZigZag==0)
              {
               SetIndexStyle(4,DRAW_ZIGZAG, EMPTY, 0, zzColor_[i]);
               SetIndexStyle(5,DRAW_ZIGZAG, EMPTY, 0, zzColor_[i]);
              }
            else
              {
               SetIndexStyle(4,DRAW_ARROW, EMPTY, 0, zzColor_[i]);
               SetIndexStyle(5,DRAW_ARROW, EMPTY, 0, zzColor_[i]);
               if (showZigZag==1)
                 {
                  SetIndexArrow(4, 116); 
                  SetIndexArrow(5, 116);
                 }
               else
                 {
                  SetIndexArrow(4, 159); 
                  SetIndexArrow(5, 159);
                 }
              }
           }
         else if (j==4)
           {
            if (showZigZag==0)
              {
               SetIndexStyle(6,DRAW_ZIGZAG, EMPTY, 0, zzColor_[i]);
               SetIndexStyle(7,DRAW_ZIGZAG, EMPTY, 0, zzColor_[i]);
              }
            else
              {
               SetIndexStyle(6,DRAW_ARROW, EMPTY, 0, zzColor_[i]);
               SetIndexStyle(7,DRAW_ARROW, EMPTY, 0, zzColor_[i]);
               if (showZigZag==1)
                 {
                  SetIndexArrow(6, 116); 
                  SetIndexArrow(7, 116);
                 }
               else
                 {
                  SetIndexArrow(6, 159); 
                  SetIndexArrow(7, 159);
                 }
              }
           }
         ProcedureOfPayments[n][2]=j; j++;
        }
     }

   if (ExtProcedureOfPayments) ArraySort(ProcedureOfPayments,WHOLE_ARRAY,0,MODE_ASCEND); else ArraySort(ProcedureOfPayments,WHOLE_ARRAY,0,MODE_DESCEND);

// Имена для окон данных и лэйбы для субъокон
   for (n=0;n<9;n++)
     {
      if (GrossPeriod_[ProcedureOfPayments[n][1]]==0) str=""+Period(); else str=""+GrossPeriod_[ProcedureOfPayments[n][1]];
      if (ProcedureOfPayments[n][2]==1)
        {
         SetIndexLabel(0,"Low1_"+str );
         SetIndexLabel(1,"High1_"+str);
        }
      else if (ProcedureOfPayments[n][2]==2)
        {
         SetIndexLabel(2,"Low2_"+str );
         SetIndexLabel(3,"High2_"+str);
        }
      else if (ProcedureOfPayments[n][2]==3)
        {
         SetIndexLabel(4,"Low3_"+str );
         SetIndexLabel(5,"High3_"+str);
        }
      else if (ProcedureOfPayments[n][2]==4)
        {
         SetIndexLabel(6,"Low4_"+str );
         SetIndexLabel(7,"High4_"+str);
        }
     }

   currentBars=0;
// Завершение инициализации

   return(0);
  }
//+------------------------------------------------------------------+
//| Initialization function. Конец.                                  |
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//| Custom indicator deinitialization function. Начало.              |
//+------------------------------------------------------------------+
int deinit()
  {
   _delete_line ();
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function. Конец.               |
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//| Расчет индикатора. Начало.                                       |
//+------------------------------------------------------------------+
int start()
  {
   int i, m, n;
   bool calculate;

   if (Bars-currentBars>1)
     {
      for (n=0;n<9;n++)
        {
         if (ProcedureOfPayments[n][2]>0) {i=ProcedureOfPayments[n][1]; saveBars[i]=0; currentBars_[i]=0;}
        }
     }

   currentBars=Bars;

   for (n=0;n<9;n++)
     {
      i=ProcedureOfPayments[n][1];

      if (zzVisible_[i]==0) continue;

      if (iBars(NULL, GrossPeriod_[i])-currentBars_[i]>1) {saveBars[i]=0;}
      currentBars_[i]=iBars(NULL, GrossPeriod_[i]);

      m=ExtBackstep_[i]+ExtDepth_[i];
      if ((currentBars_[i]-1<m) || (m<=0)) continue;

      calculate=false;

      limit=iBars(NULL,GrossPeriod_[i])-saveBars[i]+1;

      if (limit>2)
        {
         calculate=true;
         Grosstf_DT[i]=false;
         ZZ_tf[i]=false;

         if ((ExtMaxBar_[i]>iBars(NULL,GrossPeriod_[i])-m) || (ExtMaxBar_[i]==0)) limit=iBars(NULL,GrossPeriod_[i])- m; else limit=ExtMaxBar_[i];

         if      (i==0) arr_resize(LowestBufferGross1, HighestBufferGross1, limit+m, i);
         else if (i==1) arr_resize(LowestBufferGross2, HighestBufferGross2, limit+m, i);
         else if (i==2) arr_resize(LowestBufferGross3, HighestBufferGross3, limit+m, i);
         else if (i==3) arr_resize(LowestBufferGross4, HighestBufferGross4, limit+m, i);
         else if (i==4) arr_resize(LowestBufferGross5, HighestBufferGross5, limit+m, i);
         else if (i==5) arr_resize(LowestBufferGross6, HighestBufferGross6, limit+m, i);
         else if (i==6) arr_resize(LowestBufferGross7, HighestBufferGross7, limit+m, i);
         else if (i==7) arr_resize(LowestBufferGross8, HighestBufferGross8, limit+m, i);
         else if (i==8) arr_resize(LowestBufferGross9, HighestBufferGross9, limit+m, i);

         if (ProcedureOfPayments[n][2]==1)
           {
            ArrayInitialize(LowestBuffer1,0); ArrayInitialize(HighestBuffer1,0);
           }
         else if (ProcedureOfPayments[n][2]==2)
           {
            ArrayInitialize(LowestBuffer2,0); ArrayInitialize(HighestBuffer2,0); 
           }
         else if (ProcedureOfPayments[n][2]==3)
           {
            ArrayInitialize(LowestBuffer3,0); ArrayInitialize(HighestBuffer3,0); 
          }
         else if (ProcedureOfPayments[n][2]==4)
           {
            ArrayInitialize(LowestBuffer4,0); ArrayInitialize(HighestBuffer4,0); 
          }

        }
      else
        {
         if (lBar[i]>iLow(NULL,GrossPeriod_[i],0) || hBar[i]<iHigh(NULL,GrossPeriod_[i],0) || tiZZ[i]!=iTime(NULL,GrossPeriod_[i],0))
           {
            calculate=true;
           }
        }

      if (calculate)
        {

         if      (i==0) _Gross(LowestBufferGross1, HighestBufferGross1, limit, n);
         else if (i==1) _Gross(LowestBufferGross2, HighestBufferGross2, limit, n);
         else if (i==2) _Gross(LowestBufferGross3, HighestBufferGross3, limit, n);
         else if (i==3) _Gross(LowestBufferGross4, HighestBufferGross4, limit, n);
         else if (i==4) _Gross(LowestBufferGross5, HighestBufferGross5, limit, n);
         else if (i==5) _Gross(LowestBufferGross6, HighestBufferGross6, limit, n);
         else if (i==6) _Gross(LowestBufferGross7, HighestBufferGross7, limit, n);
         else if (i==7) _Gross(LowestBufferGross8, HighestBufferGross8, limit, n);
         else if (i==8) _Gross(LowestBufferGross9, HighestBufferGross9, limit, n);

        }

     }

 // Завершение вычислений индикатора
   return(0);
  }
//+------------------------------------------------------------------+
//| Расчет индикатора. Конец.                                        |
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|               Подпрограммы и функции                             |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Подбор массивов для расчета Grossperiod. Начало.                 |
//+------------------------------------------------------------------+

int _Gross(double& GLB[],double& GHB[],int limit,int n)
  {
   int x=ProcedureOfPayments[n][1];

   if (GrossPeriod_[x]==0)
    {
     if      (ProcedureOfPayments[n][2]==1) ZigZag_(LowestBuffer1, HighestBuffer1, x);
     else if (ProcedureOfPayments[n][2]==2) ZigZag_(LowestBuffer2, HighestBuffer2, x);
     else if (ProcedureOfPayments[n][2]==3) ZigZag_(LowestBuffer3, HighestBuffer3, x);
     else if (ProcedureOfPayments[n][2]==4) ZigZag_(LowestBuffer4, HighestBuffer4, x);
     else
      {
       if (limit==2) Shift_elements(GLB,GHB);
       ZigZag_(GLB, GHB, x);
      }
    }
   else
    {
     if (limit==2) Shift_elements(GLB,GHB);
     if (ZigZag_(GLB, GHB, x)==0)
       {
        if      (ProcedureOfPayments[n][2]==1) ZigZagDT (LowestBuffer1, HighestBuffer1, GLB, GHB, x);
        else if (ProcedureOfPayments[n][2]==2) ZigZagDT (LowestBuffer2, HighestBuffer2, GLB, GHB, x);
        else if (ProcedureOfPayments[n][2]==3) ZigZagDT (LowestBuffer3, HighestBuffer3, GLB, GHB, x);
        else if (ProcedureOfPayments[n][2]==4) ZigZagDT (LowestBuffer4, HighestBuffer4, GLB, GHB, x);
       }
    }

   if (TrendLineType!=1)
     {
      if (GrossPeriod_[x]==0)
        {
         if      (ProcedureOfPayments[n][2]==1) _drawline (LowestBuffer1, HighestBuffer1, x, false);
         else if (ProcedureOfPayments[n][2]==2) _drawline (LowestBuffer2, HighestBuffer2, x, false);
         else if (ProcedureOfPayments[n][2]==3) _drawline (LowestBuffer3, HighestBuffer3, x, false);
         else if (ProcedureOfPayments[n][2]==4) _drawline (LowestBuffer4, HighestBuffer4, x, false);
         else
           {
            _drawline (GLB, GHB, x, false);
           }
        }
      else _drawline (GLB, GHB, x, true);
     }
   else
     {
      if (showZigZag<2 && recount[x]>0)
        {
         if      (ProcedureOfPayments[n][2]==1) _drawline (LowestBuffer1, HighestBuffer1, x, false);
         else if (ProcedureOfPayments[n][2]==2) _drawline (LowestBuffer2, HighestBuffer2, x, false);
         else if (ProcedureOfPayments[n][2]==3) _drawline (LowestBuffer3, HighestBuffer3, x, false);
         else if (ProcedureOfPayments[n][2]==4) _drawline (LowestBuffer4, HighestBuffer4, x, false);
         else
           {
            _drawline (GLB, GHB, x, true);
           }
        }
     }

   return(0);
  }
//+------------------------------------------------------------------+
//| Подбор массивов для расчета Grossperiod. Конец.                  |
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//|  Основной ZigZag. Начало.                                        |
//+------------------------------------------------------------------+

int ZigZag_(double& LB[],double& HB[],int x)
  {
   int j, jl, jh, jc, bar_l, bar_h, limit1, maxbar_;

   int    bar,back,lasthighpos=-1,lastlowpos=-1;
   double curlow,curhigh,lasthigh,lastlow,val;
   
   datetime wrt;
   double   wrh, wrl;

   if (ZZ_tf[x]) // Режим реального времени.
     {
      // Определение бара, с которого начинается расчет
      bar_l=iBarShift(NULL,GrossPeriod_[x],L2LTime[x],true);
      bar_h=iBarShift(NULL,GrossPeriod_[x],L2HTime[x],true);

      if ((bar_l<0) || (bar_h<0)) {saveBars[x]=0; return (-1);}
      if (L2LTime[x]<=L2HTime[x]) limit=bar_l; else limit=bar_h;

      limit1=limit-1;

      // Восстановление переменных
      lastlow=iLow(NULL,GrossPeriod_[x],bar_l);
      lasthigh=iHigh(NULL,GrossPeriod_[x],bar_h);

     }
   else // Построение зигзага на истории.
     {
      ZZ_tf[x]=true;
      bar_l=limit;
      bar_h=limit;

      limit1=limit;
     }

   // Начало первого большого цикла
   for(bar=limit1; bar>=0; bar--)
     {
      //--- low
      if (bar<bar_l)
        {
         j=iLowest(NULL,GrossPeriod_[x],MODE_LOW,ExtDepth_[x],bar);
         val=iLow(NULL,GrossPeriod_[x],j);

         if(val==lastlow) val=0.0;
         else 
           { 
            lastlow=val; 
            for(back=1; back<=ExtBackstep_[x]; back++)
              {
               if(val<LB[j+back])LB[j+back]=0.0; 
              }
           } 

         if (j==bar) LB[j]=val;
        }

      //--- high
      if (bar<bar_h)
        {
         j=iHighest(NULL,GrossPeriod_[x],MODE_HIGH,ExtDepth_[x],bar);
         val=iHigh(NULL,GrossPeriod_[x],j);

         if(val==lasthigh) val=0.0;
         else 
           {
            lasthigh=val;
            for(back=1; back<=ExtBackstep_[x]; back++)
              {
               if(val>HB[j+back])HB[j+back]=0.0; 
              } 
           }

         if (j==bar) HB[j]=val;
        }
     }
   // Конец первого большого цикла

   // Начало второго большого цикла
   lasthigh=-1; lastlow=-1;

   for(bar=limit; bar>=0; bar--)
     {
      curlow=LB[bar];
      curhigh=HB[bar];

      if((curlow==0)&&(curhigh==0)) continue;

      if(curhigh!=0)
        {
         if(lasthigh>0) 
           {
            if(lasthigh<curhigh) HB[lasthighpos]=0;
            else HB[bar]=0;
           }

         if(lasthigh<curhigh || lasthigh<0)
           {
            lasthigh=curhigh;
            lasthighpos=bar;
           }
         lastlow=-1;
        }

      if(curlow!=0)
        {
         if(lastlow>0)
           {
            if(lastlow>curlow) LB[lastlowpos]=0;
            else LB[bar]=0;
           }

         if((curlow<lastlow)||(lastlow<0))
           {
            lastlow=curlow;
            lastlowpos=bar;
           } 
         lasthigh=-1;
        }
     } 
   // Конец второго большого цикла

   // Обновление переменных
   saveBars[x]=iBars(NULL,GrossPeriod_[x]);
   lBar[x]=iLow(NULL,GrossPeriod_[x],0); hBar[x]=iHigh(NULL,GrossPeriod_[x],0); tiZZ[x]=iTime(NULL,GrossPeriod_[x],0);

   jl=0;jh=0;jc=0;recount[x]=0;
   for (bar=0;bar<saveBars[x];bar++)
     {
      // Определение необходимости пересчета трендовых
      if (jc<3)
        {
         if (LB[bar]>0 || HB[bar]>0)
           {
            wrt=iTime(NULL,GrossPeriod_[x],bar);
            wrh=iHigh(NULL,GrossPeriod_[x],bar);
            wrl=iLow (NULL,GrossPeriod_[x],bar);

            if (jc==2)
              {
               if (t3[x][jc]!=wrt || h3[x][jc]!=wrh || l3[x][jc]!=wrl) {t3[x][jc]=wrt; h3[x][jc]=wrh; l3[x][jc]=wrl; recount[x]=2;}
              }
            else 
              {
               if (jc==numbervLine)
                 {
                  vLine[x]=0; tvLine[x]=iTime(NULL,GrossPeriod_[x],bar);
                  if (HB[bar]>0) vFibo[x]=HB[bar]; else vFibo[x]=LB[bar];
                  if (t3[x][jc]!=wrt || h3[x][jc]!=wrh || l3[x][jc]!=wrl) vLine[x]=1;
                 }

               if (t3[x][jc]!=wrt || h3[x][jc]!=wrh || l3[x][jc]!=wrl) {t3[x][jc]=wrt; h3[x][jc]=wrh; l3[x][jc]=wrl; recount[x]=1; if (jc==1) recount[x]=2;}
              }

            nbar[x][jc]=bar;
            jc++;
           }
        }

      // Сохранение времени начала и окончания третьего луча или последнего луча, меньше третьего
      if (LB[bar]>0) {if (jl<=1) {L2LTime[x]=iTime(NULL,GrossPeriod_[x],bar);} jl++;}
      if (HB[bar]>0) {if (jh<=1) {L2HTime[x]=iTime(NULL,GrossPeriod_[x],bar);} jh++;}
      if (jl>1 && jh>1) break;
     }

   if (jc<3) recount[x]=0;

   if (numbervLine==0)
     {
      if (LB[nbar[x][0]]>0 && HB[nbar[x][0]]==0) vFibo[x]=LB[nbar[x][0]];
      else if (HB[nbar[x][0]]>0 && LB[nbar[x][0]]==0) vFibo[x]=HB[nbar[x][0]];
      else if (LB[nbar[x][0]]>0 && HB[nbar[x][0]]>0)
        {
         if ((LB[nbar[x][2]]>0 && HB[nbar[x][2]]==0) || (HB[nbar[x][1]]>0 && LB[nbar[x][1]]==0)) vFibo[x]=LB[nbar[x][0]];
         if ((HB[nbar[x][2]]>0 && LB[nbar[x][2]]==0) || (LB[nbar[x][1]]>0 && HB[nbar[x][1]]==0)) vFibo[x]=HB[nbar[x][0]];
        }
     }
   else
     {
      if (LB[nbar[x][1]]>0 && HB[nbar[x][1]]==0) vFibo[x]=LB[nbar[x][0]];
      else if (HB[nbar[x][1]]>0 && LB[nbar[x][1]]==0) vFibo[x]=HB[nbar[x][0]];
      else if (LB[nbar[x][1]]>0 && HB[nbar[x][1]]>0)
        {
         if ((LB[nbar[x][0]]==0 && HB[nbar[x][0]]>0) || (HB[nbar[x][2]]>0 && LB[nbar[x][2]]==0)) vFibo[x]=LB[nbar[x][0]];
         if ((HB[nbar[x][0]]==0 && LB[nbar[x][0]]>0) || (LB[nbar[x][2]]>0 && HB[nbar[x][2]]==0)) vFibo[x]=HB[nbar[x][0]];
        }
     }

   return(0);
  }
//+------------------------------------------------------------------+
//|  Основной ZigZag. Конец.                                         |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Преобразование зигзага со старшего таймфрейма на текущий. Начало.|
//+------------------------------------------------------------------+
int ZigZagDT (double& LB[], double& HB[], double& LBG[], double& HBG[], int x)
  {
   int i=0, j, jl, jh, ext3=0, end, k;
   double el=-1, eh=-1;
   datetime t1, t2, t3=GrossPeriod_[x]*60-1;
   bool tdelta=false;
   int ni;  // номер бара
   int jc;  // счетчик экстремумов зигзага

   if (TrendLineType==1) {nbar[x][0]=-1; nbar[x][1]=-1; nbar[x][2]=-1;}

   ni=-1; jc=-1;
   if (Grosstf_DT[x]) // Режим реального времени.
     {
      end=ExtReCalculate+1;

      t1=iTime(NULL, GrossPeriod_[x],i);
      for (j=0;ext3<end && j<Bars;j++)
        {

         if (Period()==10080)
           {
            if (el<0 && eh<0) tdelta=Time[j]<t1;
            else tdelta=Time[j]+t3<t1;
           }
         else
           {
            tdelta=Time[j]<t1;
           }

         if (tdelta) {i++; if (showZigZag==2) {t2=t1+GrossPeriod_[x]*60;} t1=iTime(NULL, GrossPeriod_[x],i);}

         LB[j]=0;
         HB[j]=0;

         if (LBG[i]>0)
           {
            if (el>=Low[j] || el<0) {el=Low[j]; jl=j;}
           }
         else
           {
            if (el>0)
              {
               if (showZigZag==2)
                 {
                  for (k=j-1;Time[k]<t2;k--)
                    {
                     if (k<0) break;
                     LB[k]=el;
                    }
                 }

               LB[jl]=el; el=-1; ext3++;

               if (jc<3)
                 {
                  if (TrendLineType==1) nbar[x][jc]=jl;
                  if (jc==numbervLine)
                    {
                     tvLine[x]=Time[jl];
                     vFibo[x]=LB[jl];
                    }
                 }
              }
           }

         if  (HBG[i]>0)
           {
            if (eh<=High[j]) {eh=High[j]; jh=j;}
           }
         else
           {
            if (eh>0)
              {
               if (showZigZag==2)
                 {
                  for (k=j-1;Time[k]<t2;k--)
                    {
                     if (k<0) break;
                     HB[k]=eh;
                    }
                 }

               HB[jh]=eh; eh=-1; ext3++;

               if (jc<3)
                 {
                  if (TrendLineType==1) nbar[x][jc]=jh;
                  if (jc==numbervLine)
                    {
                     tvLine[x]=Time[jh];
                     vFibo[x]=HB[jl];
                    }
                 }
              }
           } 

         if  (jc<3)
           {
            if (ni!=i) {ni=i; if (LBG[i]>0 || HBG[i]>0) jc++;}
           }

        }
     }
   else // Построение зигзага на истории.
     {
      if (limit<=ExtDepth_[x]+ExtBackstep_[x]) {saveBars[x]=0; return (-1);}
      end=iBarShift(NULL,Period(),iTime(NULL, GrossPeriod_[x],limit),false);

      if (end<=0) {saveBars[x]=0; return (-1);}

      Grosstf_DT[x]=true;

      t1=iTime(NULL, GrossPeriod_[x],i);
      for (j=0;j<end;j++)
        {

         if (Period()==10080)
           {
            if (el<0 && eh<0) tdelta=Time[j]<t1;
            else tdelta=Time[j]+t3<t1;
           }
         else
           {
            tdelta=Time[j]<t1;
           }

         if (tdelta) {i++; if (showZigZag==2) {t2=t1+GrossPeriod_[x]*60;} t1=iTime(NULL, GrossPeriod_[x],i);}

         if (LBG[i]>0)
           {
            if (el>=Low[j] || el<0) {el=Low[j]; jl=j;}
           }
         else
           {
            if (el>0)
              {
               if (showZigZag==2)
                 {
                  for (k=j-1;Time[k]<t2;k--)
                    {
                     if (k<0) break;
                     LB[k]=el;
                    }
                 }

               LB[jl]=el; el=-1;

               if (jc<3)
                 {
                  if (TrendLineType==1) nbar[x][jc]=jl;
                  if (jc==numbervLine)
                    {
                     tvLine[x]=Time[jl];
                     vFibo[x]=LB[jl];
                    }
                 }
              }
           }

         if  (HBG[i]>0)
           {
            if (eh<=High[j]) {eh=High[j]; jh=j;}
           }
         else
           {
            if (eh>0)
              {
               if (showZigZag==2)
                 {
                  for (k=j-1;Time[k]<t2;k--)
                    {
                     if (k<0) break;
                     HB[k]=eh;
                    }
                 }

               HB[jh]=eh; eh=-1;

               if (jc<3)
                 {
                  if (TrendLineType==1) nbar[x][jc]=jh;
                  if (jc==numbervLine)
                    {
                     tvLine[x]=Time[jh];
                     vFibo[x]=HB[jl];
                    }
                 }
              }
           } 

         if  (jc<3)
           {
            if (ni!=i) {ni=i; if (LBG[i]>0 || HBG[i]>0) jc++;}
           }

        }
     }

   return (0);
  }
//+------------------------------------------------------------------+
//| Преобразование зигзага со старшего таймфрейма на текущий. Конец. |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Рисование трендовых и других линий. Начало.                      |
//+------------------------------------------------------------------+
void _drawline (double& LB[],double& HB[], int x, bool y)
  {
   int  i=0, j, k, ray, wr0, wr1, jh, jl, jc, ni, j1, n;
   double el=-1, eh=-1;
   string nameObj, nameObjTL, per_, txtcenafibo;
   double p1,p2, tangens, tangens1, f1, f2;
   int    np[2];
   datetime t1,t2;
   bool   newname=false, hl=false; // hl= false - первый экстремум на минимуме; = true - на максимуме
   double tangens_[2], p_[2], cenafibo;

   if (HB[nbar[x][0]]>0) hl=true;

   if (y && TrendLineType==0) {np[0]=-1; np[1]=-1; k=GrossPeriod_[x]*60;}
            
   if (TrendLineType!=1)
     {
      for (ray=2;ray>0;ray--)
        {
         j=nbar[x][ray];
         j1=nbar[x][ray-1];

         if ((!hl && ray==2) || (hl && ray==1))
           {
            p1=iLow(NULL,GrossPeriod_[x],j); 
            if (ExtFirstPoint)
              {
               for (i=j;i>=0;i--)
                 {
                  if (iLow(NULL,GrossPeriod_[x],i)==iLow(NULL,GrossPeriod_[x],j)) j=i;
                  if (i==j1) break;
                 }
              }

            t1=iTime(NULL,GrossPeriod_[x],j); np[ray-1]=j;
            tangens=iLow(NULL,GrossPeriod_[x],j-1)-iLow(NULL,GrossPeriod_[x],j); p2=iLow(NULL,GrossPeriod_[x],j-1); t2=iTime(NULL,GrossPeriod_[x],j-1);

            for (i=j-1;i>=0;i--)
              {
               tangens1=(iLow(NULL,GrossPeriod_[x],i)-iLow(NULL,GrossPeriod_[x],j))/(j-i);
               if (tangens>=tangens1) {tangens=tangens1; p2=iLow(NULL,GrossPeriod_[x],i); t2=iTime(NULL,GrossPeriod_[x],i);}
               if (i==j1) break;
              }
           }
         else if ((hl && ray==2) || (!hl && ray==1))
           {
            p1=iHigh(NULL,GrossPeriod_[x],j);
            if (ExtFirstPoint)
              {
               for (i=j;i>=0;i--)
                 {
                  if (iHigh(NULL,GrossPeriod_[x],i)==iHigh(NULL,GrossPeriod_[x],j)) j=i;
                  if (i==j1) break;
                 }
              }

            t1=iTime(NULL,GrossPeriod_[x],j); np[ray-1]=j;
            tangens=iHigh(NULL,GrossPeriod_[x],j-1)-iHigh(NULL,GrossPeriod_[x],j); p2=iHigh(NULL,GrossPeriod_[x],j-1); t2=iTime(NULL,GrossPeriod_[x],j-1);
            for (i=j-1;i>=0;i--)
              {
               tangens1=(iHigh(NULL,GrossPeriod_[x],i)-iHigh(NULL,GrossPeriod_[x],j))/(j-i);
               if (tangens<=tangens1) {tangens=tangens1; p2=iHigh(NULL,GrossPeriod_[x],i); t2=iTime(NULL,GrossPeriod_[x],i);}
               if (i==j1) break;
              }
           }

         if (y && TrendLineType==0)
           {

            if ((!hl && ray==2) || (hl && ray==1))
              {
               i=iBarShift(NULL,Period(),t2+k,false);
               while (Time[i]>t2+k) {i++; if (i>=Bars) {recount[x]=0; return;}}

               j=i;
               while (Time[i]>=t2) {if (Low[i]<Low[j]) {j=i;} i++; if (i>=Bars) {recount[x]=0; return;}}
               t2=Time[j]; n=j;

               i=iBarShift(NULL,Period(),t1+k,false);
               while (Time[i]>t1+k) {i++; if (i>=Bars) {recount[x]=0; return;}}

               j=i;
               while (Time[i]>=t1) {if (Low[i]<Low[j]) {j=i;} i++; if (i>=Bars) {recount[x]=0; return;}}
               t1=Time[j]; np[ray-1]=j;

              }
            else if ((hl && ray==2) || (!hl && ray==1))
              {
               i=iBarShift(NULL,Period(),t2+k,false);
               while (Time[i]>t2+k) {i++; if (i>=Bars) {recount[x]=0; return;}}

               j=i;
               while (Time[i]>=t2) {if (High[i]>High[j]) {j=i;} i++; if (i>=Bars) {recount[x]=0; return;}}
               t2=Time[j]; n=j;

               i=iBarShift(NULL,Period(),t1+k,false);
               while (Time[i]>t1+k) {i++; if (i>=Bars) {recount[x]=0; return;}}

               j=i;
               while (Time[i]>=t1) {if (High[i]>High[j]) {j=i;} i++; if (i>=Bars) {recount[x]=0; return;}}
               t1=Time[j]; np[ray-1]=j;

              }

            tangens=(p2-p1)/(j-n);
           }

         wr0=nbar[x][0]; wr1=nbar[x][1];
         if ((LB[wr0]>0 && HB[wr0]>0) || (LB[wr1]>0 && HB[wr1])) {recount[x]=0; return;}

         if (t1==t2) continue;
         tangens_[ray-1]=tangens; p_[ray-1]=p1;
         if (GrossPeriod_[x]==0) per_=""+Period();
         else if (GrossPeriod_[x]>0) per_=""+GrossPeriod_[x];
         nameObjTL="#"+ExtComplect+"_"+ray+"_"+x+"_"+per_;

         ObjectDelete(nameObjTL);
         ObjectCreate(nameObjTL, OBJ_TREND, 0, t1, p1, t2, p2);
         ObjectSet(nameObjTL, OBJPROP_COLOR, zzColor_[x]);
         ObjectSet(nameObjTL, OBJPROP_STYLE, LineStyle_[x]);
         ObjectSet(nameObjTL, OBJPROP_WIDTH, LineWidth_[x]);

         if (ray==1 && vLineVisible_[x]==1 && vLine[x]==1)
           {
            nameObj="#"+ExtComplect+"_vLine"+"_"+x+"_"+per_;
            ObjectDelete(nameObj);
            ObjectCreate(nameObj,OBJ_VLINE,0, tvLine[x],p1);
            ObjectSet(nameObj, OBJPROP_COLOR, zzColor_[x]);
            ObjectSet(nameObj, OBJPROP_STYLE, LineStyle_[x]);
            ObjectSet(nameObj, OBJPROP_WIDTH, LineWidth_[x]);

            if (FiboLevelVisible_[x]==1)
              {
               nameObj="#"+ExtComplect+"_fibo"+"_"+x+"_"+per_;

               ObjectDelete(nameObj);
               ObjectCreate(nameObj,OBJ_FIBO,0,tvLine[x],ObjectGetValueByShift(nameObjTL,nbar[x][numbervLine]),tvLine[x],vFibo[x]);
               ObjectSet(nameObj, OBJPROP_LEVELCOLOR, zzColor_[x]);
               ObjectSet(nameObj, OBJPROP_COLOR, CLR_NONE);
               ObjectSet(nameObj, OBJPROP_LEVELSTYLE, hLineStyle_[x]);
               ObjectSet(nameObj, OBJPROP_LEVELWIDTH, hLineWidth_[x]);
               ObjectSet(nameObj,OBJPROP_FIBOLEVELS,Sizefif);

               for (i=0;i<Sizefif;i++)
                 {
                  if (VisibleCenaFibo)
                    {
                     cenafibo=vFibo[x]+(ObjectGetValueByShift(nameObjTL,nbar[x][numbervLine])-vFibo[x])*fif[i];
                     txtcenafibo="  " + DoubleToStr(cenafibo,Digits);
                    }
                  else txtcenafibo="";
                  ObjectSet(nameObj,OBJPROP_FIRSTLEVEL+i,fif[i]);
                  ObjectSetFiboDescription(nameObj, i, fiftxt100[i]+txtcenafibo); 
                 }
              }
           }

        }

      if (np[1]>=0 && np[0]>=0 && (LevelVisible_[x]==1  || hLevelVisible_[x]==1))
        {
         if (TrendLineType==2) {if (hl) f1=iHigh(NULL,GrossPeriod_[x],np[1])+(np[1]-np[0])*tangens_[1]; else f1=(np[1]-np[0])*tangens_[1]+iLow(NULL,GrossPeriod_[x],np[1]);}
         else {if (hl) f1=High[np[1]]+(np[1]-np[0])*tangens_[1]; else f1=(np[1]-np[0])*tangens_[1]+Low[np[1]];}
//         f2=(((p_[1]-p_[0]+(np[1]-np[0])*tangens_[1])/(tangens_[0]-tangens_[1]))*tangens_[0]+p1);
         f2=(np[1] - (p_[0]-p_[1]+np[0]*tangens_[0]-np[1]*tangens_[1])/(tangens_[0]-tangens_[1]))*tangens_[1]+p_[1];
        }

      if (np[1]>=0 && np[0]>=0 && LevelVisible_[x]==1)
        {

         nameObj="#"+ExtComplect+"_level"+"_"+x+"_"+per_;

         ObjectDelete(nameObj);
         ObjectCreate(nameObj,OBJ_HLINE,0,t1,f2);
         ObjectSet(nameObj, OBJPROP_COLOR, zzColor_[x]);
         ObjectSet(nameObj, OBJPROP_STYLE, LineStyle_[x]);
         ObjectSet(nameObj, OBJPROP_WIDTH, LineWidth_[x]);
        }

      if (np[1]>=0 && np[0]>=0 && hLevelVisible_[x]==1)
        {
         if (TrendLineType==2) {t1=iTime(NULL,GrossPeriod_[x],nbar[x][0]); t2=iTime(NULL,GrossPeriod_[x],nbar[x][1]);}
         else {t1=Time[nbar[x][0]]; t2=Time[nbar[x][1]];}

         nameObj="#"+ExtComplect+"_hLevel"+"_"+x+"_"+per_;

         ObjectDelete(nameObj);
         ObjectCreate(nameObj,OBJ_FIBO,0,t1,f1,t2,f2);
         ObjectSet(nameObj, OBJPROP_LEVELCOLOR, zzColor_[x]);
         ObjectSet(nameObj, OBJPROP_COLOR, CLR_NONE);
         ObjectSet(nameObj, OBJPROP_LEVELSTYLE, hLineStyle_[x]);
         ObjectSet(nameObj, OBJPROP_LEVELWIDTH, hLineWidth_[x]);
         ObjectSet(nameObj,OBJPROP_FIBOLEVELS,Sizefi);

         for (i=0;i<Sizefi;i++)
           {
            ObjectSet(nameObj,OBJPROP_FIRSTLEVEL+i,fi[i]);
            if (hLabelVisible_[x]==1) ObjectSetFiboDescription(nameObj, i, fitxt100[i]); 
           }
        }
     }
   else // TrendLineType=1
     {
      if (y)
        {
         ni=-1; jc=-1;
         nbar[x][0]=-1; nbar[x][1]=-1; nbar[x][2]=-1;
         t1=iTime(NULL, GrossPeriod_[x],i);

         for (j=0;(jc<3 && j<Bars);j++)
           {
            if (Time[j]<t1)
              {
               i++; t1=iTime(NULL, GrossPeriod_[x],i);
              }

            if (LB[i]>0)
              {
               if (el>=Low[j] || el<0) {el=Low[j]; jl=j;}
              }
            else
              {
               if (el>0)
                 {
                  el=-1;
                  nbar[x][jc]=jl;
                  if (jc==numbervLine)
                    {
                     tvLine[x]=Time[jl];
                    }
                 }
              }

            if  (HB[i]>0)
              {
               if (eh<=High[j]) {eh=High[j]; jh=j;}
              }
            else
              {
               if (eh>0)
                 {
                  eh=-1;
                  if (nbar[x][jc]==jh) {recount[x]=0; return;}
                  nbar[x][jc]=jh;
                  if (jc==numbervLine)
                    {
                     tvLine[x]=Time[jh];
                    }
                 }
              } 

            if (ni!=i) {ni=i; if (LB[i]>0 || HB[i]>0) jc++;}
           }

         if (jc<3 || nbar[x][2]>=Bars) {recount[x]=0; return;}
        }

      wr0=nbar[x][0]; wr1=nbar[x][1];
      if (y) {if (nbar[x][0]<0 || nbar[x][1]<0 || nbar[x][2]<0) {recount[x]=0; return;}}
      else {if ((LB[wr0]>0 && HB[wr0]>0) || (LB[wr1]>0 && HB[wr1])) {recount[x]=0; return;}}

      for (ray=2;ray>0;ray--)
        {
         j=nbar[x][ray];
         j1=nbar[x][ray-1];

         if ((!hl && ray==2) || (hl && ray==1))
           {
            p1=Low[j]; 
            if (ExtFirstPoint)
              {
               for (i=j;i>=0;i--)
                 {
                  if (Low[i]==Low[j]) j=i;
                  if (i==j1) break;
                 }
              }

            t1=Time[j]; np[ray-1]=j;
            tangens=Low[j-1]-Low[j]; p2=Low[j-1]; t2=Time[j-1];

            for (i=j-1;i>=0;i--)
              {
               tangens1=(Low[i]-Low[j])/(j-i);
               if (tangens>=tangens1) {tangens=tangens1; p2=Low[i]; t2=Time[i];}
               if (i==j1) break;
              }
           }
         else if ((hl && ray==2) || (!hl && ray==1))
           {
            p1=High[j];
            if (ExtFirstPoint)
              {
               for (i=j;i>=0;i--)
                 {
                  if (High[i]==High[j]) j=i;
                  if (i==j1) break;
                 }
              }

            t1=Time[j]; np[ray-1]=j;
            tangens=High[j-1]-High[j]; p2=High[j-1]; t2=Time[j-1];
            for (i=j-1;i>=0;i--)
              {
               tangens1=(High[i]-High[j])/(j-i);
               if (tangens<=tangens1) {tangens=tangens1; p2=High[i]; t2=Time[i];}
               if (i==j1) break;
              }
           }

         if (t1==t2) continue;

         if (GrossPeriod_[x]==0) per_=""+Period();
         else if (GrossPeriod_[x]>0) per_=""+GrossPeriod_[x];
         nameObjTL="#"+ExtComplect+"_"+ray+"_"+x+"_"+per_;

         ObjectDelete(nameObjTL);
         ObjectCreate(nameObjTL, OBJ_TREND, 0, t1, p1, t2, p2);
         ObjectSet(nameObjTL, OBJPROP_COLOR, zzColor_[x]);
         ObjectSet(nameObjTL, OBJPROP_STYLE, LineStyle_[x]);
         ObjectSet(nameObjTL, OBJPROP_WIDTH, LineWidth_[x]);

         if (ray==1 && vLineVisible_[x]==1 && vLine[x]==1)
           {
            nameObj="#"+ExtComplect+"_vLine"+"_"+x+"_"+per_;
            ObjectDelete(nameObj);
            ObjectCreate(nameObj,OBJ_VLINE,0, tvLine[x],p1);
            ObjectSet(nameObj, OBJPROP_COLOR, zzColor_[x]);
            ObjectSet(nameObj, OBJPROP_STYLE, LineStyle_[x]);
            ObjectSet(nameObj, OBJPROP_WIDTH, LineWidth_[x]);

            if (FiboLevelVisible_[x]==1)
              {
               nameObj="#"+ExtComplect+"_fibo"+"_"+x+"_"+per_;

               ObjectDelete(nameObj);
               ObjectCreate(nameObj,OBJ_FIBO,0,tvLine[x],ObjectGetValueByShift(nameObjTL,nbar[x][numbervLine]),tvLine[x],vFibo[x]);
               ObjectSet(nameObj, OBJPROP_LEVELCOLOR, zzColor_[x]);
               ObjectSet(nameObj, OBJPROP_COLOR, CLR_NONE);
               ObjectSet(nameObj, OBJPROP_LEVELSTYLE, hLineStyle_[x]);
               ObjectSet(nameObj, OBJPROP_LEVELWIDTH, hLineWidth_[x]);
               ObjectSet(nameObj,OBJPROP_FIBOLEVELS,Sizefif);

               for (i=0;i<Sizefif;i++)
                 {
                  if (VisibleCenaFibo)
                    {
                     cenafibo=vFibo[x]+(ObjectGetValueByShift(nameObjTL,nbar[x][numbervLine])-vFibo[x])*fif[i];
                     txtcenafibo="  " + DoubleToStr(cenafibo,Digits);
                    }
                  else txtcenafibo="";
                  ObjectSet(nameObj,OBJPROP_FIRSTLEVEL+i,fif[i]);
                  ObjectSetFiboDescription(nameObj, i, fiftxt100[i]+txtcenafibo); 
                 }
              }
           }

         tangens_[ray-1]=tangens; p_[ray-1]=p1;
        }

      if (LevelVisible_[x]==1  || hLevelVisible_[x]==1)
        {
         if (hl) f1=High[np[1]]+(np[1]-np[0])*tangens_[1]; else f1=(np[1]-np[0])*tangens_[1]+Low[np[1]];
//         f2=(((p_[1]-p_[0]+(np[1]-np[0])*tangens_[1])/(tangens_[0]-tangens_[1]))*tangens_[0]+p1);
         f2=(np[1] - (p_[0]-p_[1]+np[0]*tangens_[0]-np[1]*tangens_[1])/(tangens_[0]-tangens_[1]))*tangens_[1]+p_[1];
// Print("GrossPeriod = "+GrossPeriod_[x]+"   f2 = "+f2+"  np[0] = "+np[0]+"  np[1] = "+np[1]+"   p1 = "+p1+"   p2 = "+p2+"   tangens_[0] = "+tangens_[0]+"   tangens_[1] = "+tangens_[1]);
        }

      if (LevelVisible_[x]==1)
        {

         nameObj="#"+ExtComplect+"_level"+"_"+x+"_"+per_;

         ObjectDelete(nameObj);
         ObjectCreate(nameObj,OBJ_HLINE,0,t1,f2);
         ObjectSet(nameObj, OBJPROP_COLOR, zzColor_[x]);
         ObjectSet(nameObj, OBJPROP_STYLE, LineStyle_[x]);
         ObjectSet(nameObj, OBJPROP_WIDTH, LineWidth_[x]);
        }

      if (hLevelVisible_[x]==1)
        {
         t1=Time[nbar[x][0]]; t2=Time[nbar[x][1]];

         nameObj="#"+ExtComplect+"_hLevel"+"_"+x+"_"+per_;

         ObjectDelete(nameObj);
         ObjectCreate(nameObj,OBJ_FIBO,0,t1,f1,t2,f2);
         ObjectSet(nameObj, OBJPROP_LEVELCOLOR, zzColor_[x]);
         ObjectSet(nameObj, OBJPROP_COLOR, CLR_NONE);
         ObjectSet(nameObj, OBJPROP_LEVELSTYLE, hLineStyle_[x]);
         ObjectSet(nameObj, OBJPROP_LEVELWIDTH, hLineWidth_[x]);
         ObjectSet(nameObj,OBJPROP_FIBOLEVELS,Sizefi);

         for (i=0;i<Sizefi;i++)
           {
            ObjectSet(nameObj,OBJPROP_FIRSTLEVEL+i,fi[i]);
            if (hLabelVisible_[x]==1) ObjectSetFiboDescription(nameObj, i, fitxt100[i]); 
           }
        }
     }

  }
//+------------------------------------------------------------------+
//| Рисование трендовых и других линий. Конец.                       |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Проверка корректности задания таймфрейма. Начало.                |
//+------------------------------------------------------------------+
int _period(int x, int tf)
  {
   if (tf<Period() && tf>0) ExtDepth_[x]=0;
   if (tf==Period()) return (0);
   return (tf);
  }
//+------------------------------------------------------------------+
//| Проверка корректности задания таймфрейма. Конец.                 |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Сдвиг элементов массива на 1 от 0 элемента в сторону увеличения  |
//| индекса. Начало.                                                 |
//+------------------------------------------------------------------+
void Shift_elements (double& arr[], double& arr1[])
  {
   int i,j;

   j=ArraySize(arr)-1;
   for (i=j;i>0;i--)
     {
      arr[i]=arr[i-1];
      arr1[i]=arr1[i-1];
     }
   arr[0]=0;
   arr1[0]=0;
  }
//-------------------------------------------------------------------+
//| Сдвиг элементов массива на 1 от 0 элемента в сторону увеличения  |
//| индекса. Конец.                                                  |
//-------------------------------------------------------------------+


//+------------------------------------------------------------------+
//| Изменение размера массивов и присвоение всем элементам значения 0|
//| Начало.                                                          |
//+------------------------------------------------------------------+
void arr_resize (double& arr[], double& arr1[], int size, int x)
  {
   if (GrossPeriod_[x]>0)
     {
      ArrayResize(arr,size); ArrayResize(arr1,size);
      ArrayInitialize(arr,0); ArrayInitialize(arr1,0);
     }
  }
//+------------------------------------------------------------------+
//| Изменение размера массивов и присвоение всем элементам значения 0|
//| Конец.                                                           |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Перенос значений параметров из строки в числовой массив. Начало. |
//+------------------------------------------------------------------+
void _stringtointarray (string str, int& arr[], int x)
  {
   int i,j,k=0;
   for (i=0;i<x;i++)
     {
      j=StringFind(str,",",k);
      if (j<0) {arr[i]=StrToInteger(StringSubstr(str,k)); break;}
      arr[i]=StrToInteger(StringSubstr(str,k,j-k));
      k=j+1;
     }
  }
//+------------------------------------------------------------------+
//| Перенос значений параметров из строки в числовой массив.Конец.   |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Перенос значений параметров из строки в числовой массив. Начало. |
//+------------------------------------------------------------------+
void _stringtocolorarray (string str, int& arr[], int x)
  {
   int i,j,k=0;
   for (i=0;i<x;i++)
     {
      j=StringFind(str,",",k);
      if (j<0) {arr[i]=fStrToColor(StringSubstr(str,k)); break;}
      arr[i]=fStrToColor(StringSubstr(str,k,j-k));
      k=j+1;
     }
  }
//+------------------------------------------------------------------+
//| Перенос значений параметров из строки в числовой массив.Конец.   |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Удаление линий. Начало.                                          |
//+------------------------------------------------------------------+
void _delete_line ()
  {
   int i;
   string txt;

   for (i=ObjectsTotal(); i>=0; i--)
     {
      txt=ObjectName(i);
      if (StringFind(txt,"#"+ExtComplect+"_")>-1) ObjectDelete (txt);
     }
  }
//+------------------------------------------------------------------+
//| Удаление линий. Конец.                                           |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Преобразование строки в цвет. Начало.                            |
//| Функцию написал Integer.  http://forum.mql4.com/ru/7134          |
//+------------------------------------------------------------------+
color fStrToColor(string aName)
  {
 
   color tColor[]={  Black, DarkGreen, DarkSlateGray, Olive, Green, Teal, Navy, Purple, 
                     Maroon, Indigo, MidnightBlue, DarkBlue, DarkOliveGreen, SaddleBrown, 
                     ForestGreen, OliveDrab, SeaGreen, DarkGoldenrod, DarkSlateBlue, 
                     Sienna, MediumBlue, Brown, DarkTurquoise, DimGray, LightSeaGreen, 
                     DarkViolet, FireBrick, MediumVioletRed, MediumSeaGreen, Chocolate, 
                     Crimson, SteelBlue, Goldenrod, MediumSpringGreen, LawnGreen, 
                     CadetBlue, DarkOrchid, YellowGreen, LimeGreen, OrangeRed, DarkOrange, 
                     Orange, Gold, Yellow, Chartreuse, Lime, SpringGreen, Aqua, DeepSkyBlue, 
                     Blue, Magenta, Red, Gray, SlateGray, Peru, BlueViolet, LightSlateGray, 
                     DeepPink, MediumTurquoise, DodgerBlue, Turquoise, RoyalBlue, SlateBlue, 
                     DarkKhaki, IndianRed, MediumOrchid, GreenYellow, MediumAquamarine, 
                     DarkSeaGreen, Tomato, RosyBrown, Orchid, MediumPurple, PaleVioletRed, 
                     Coral, CornflowerBlue, DarkGray, SandyBrown, MediumSlateBlue, Tan, 
                     DarkSalmon, BurlyWood, HotPink, Salmon, Violet, LightCoral, SkyBlue, 
                     LightSalmon, Plum, Khaki, LightGreen, Aquamarine, Silver, LightSkyBlue, 
                     LightSteelBlue, LightBlue, PaleGreen, Thistle, PowderBlue, PaleGoldenrod, 
                     PaleTurquoise, LightGray, Wheat, NavajoWhite, Moccasin, LightPink, 
                     Gainsboro, PeachPuff, Pink, Bisque, LightGoldenrod, BlanchedAlmond, 
                     LemonChiffon, Beige, AntiqueWhite, PapayaWhip, Cornsilk, LightYellow, 
                     LightCyan, Linen, Lavender, MistyRose, OldLace, WhiteSmoke, Seashell, 
                     Ivory, Honeydew, AliceBlue, LavenderBlush, MintCream, Snow, White
                  };  
   string tName[]={   "Black", "DarkGreen", "DarkSlateGray", "Olive", "Green", "Teal", "Navy", "Purple", 
                     "Maroon", "Indigo", "MidnightBlue", "DarkBlue", "DarkOliveGreen", "SaddleBrown", 
                     "ForestGreen", "OliveDrab", "SeaGreen", "DarkGoldenrod", "DarkSlateBlue", 
                     "Sienna", "MediumBlue", "Brown", "DarkTurquoise", "DimGray", "LightSeaGreen", 
                     "DarkViolet", "FireBrick", "MediumVioletRed", "MediumSeaGreen", "Chocolate", 
                     "Crimson", "SteelBlue", "Goldenrod", "MediumSpringGreen", "LawnGreen", 
                     "CadetBlue", "DarkOrchid", "YellowGreen", "LimeGreen", "OrangeRed", "DarkOrange", 
                     "Orange", "Gold", "Yellow", "Chartreuse", "Lime", "SpringGreen", "Aqua", "DeepSkyBlue", 
                     "Blue", "Magenta", "Red", "Gray", "SlateGray", "Peru", "BlueViolet", "LightSlateGray", 
                     "DeepPink", "MediumTurquoise", "DodgerBlue", "Turquoise", "RoyalBlue", "SlateBlue", 
                     "DarkKhaki", "IndianRed", "MediumOrchid", "GreenYellow", "MediumAquamarine", 
                     "DarkSeaGreen", "Tomato", "RosyBrown", "Orchid", "MediumPurple", "PaleVioletRed", 
                     "Coral", "CornflowerBlue", "DarkGray", "SandyBrown", "MediumSlateBlue", "Tan", 
                     "DarkSalmon", "BurlyWood", "HotPink", "Salmon", "Violet", "LightCoral", "SkyBlue", 
                     "LightSalmon", "Plum", "Khaki", "LightGreen", "Aquamarine", "Silver", "LightSkyBlue", 
                     "LightSteelBlue", "LightBlue", "PaleGreen", "Thistle", "PowderBlue", "PaleGoldenrod", 
                     "PaleTurquoise", "LightGray", "Wheat", "NavajoWhite", "Moccasin", "LightPink", 
                     "Gainsboro", "PeachPuff", "Pink", "Bisque", "LightGoldenrod", "BlanchedAlmond", 
                     "LemonChiffon", "Beige", "AntiqueWhite", "PapayaWhip", "Cornsilk", "LightYellow", 
                     "LightCyan", "Linen", "Lavender", "MistyRose", "OldLace", "WhiteSmoke", "Seashell", 
                     "Ivory", "Honeydew", "AliceBlue", "LavenderBlush", "MintCream", "Snow", "White"
                  };

   aName=StringTrimLeft(StringTrimRight(aName));      
   for(int i=0;i<ArraySize(tName);i++)
     {
      if(aName==tName[i])return(tColor[i]);
     }

  return(Red);                                     
                
 }
//+------------------------------------------------------------------+
//| Преобразование строки в цвет. Конец.                             |
//| Функцию написал Integer.  http://forum.mql4.com/ru/7134          |
//+------------------------------------------------------------------+

/*
функция для вывода отладочной информации от ForexTools

http://forum.mql4.com/ru/23069
ForexTools 08.06.2009 10:06

  я вот такой функцией пользуюсь

void Debug(string p1="", string p2="", string p3="", string p4="", string p5="", string p6="", string p7="", string p8="", string p9="")
{
  Print(p1+" "+p2+" "+p3+" "+p4+" "+p5+" "+p6+" "+p7+" "+p8+" "+p9);
}можно писать простые и понятные конструкции в тексте вроде такой:

Debug ( "Lot =",Lot, " Stop =",stop * Point )и в журнале увидеть читабельную строку:

Lot = 0.2 Stop = 0.0054

Для отладки под визуализатором Print меняется на Comment

сорри. упростил текст получилось действительно непонятно. на самом деле полный вариант был такой:

void Debug(int PrintMode, string p1="", string p2="", string p3="", string p4="", string p5="", string p6="", string p7="", string p8="", string p9="")
{
  if(PrintMode == 1) Print(p1+" "+p2+" "+p3+" "+p4+" "+p5+" "+p6+" "+p7+" "+p8+" "+p9);
  if(PrintMode == 2) Comment(p1+"\n"+p2+"\n"+p3+"\n"+p4+"\n"+p5+"\n"+p6+"\n"+p7+"\n"+p8+"\n"+p9);
}PrintMode задается в параметрах и позволяет переключать один и тотже отладочный вывод в журнал либо в коментарий. Бывает весьма полезно при прогонах в режиме визуализатора. При = 0 отладка откулючается



*/