//+------------------------------------------------------------------+
//|                                                  Konstruktor.mq4 |
//|                                                              nen |
//|                                                               "" |
//+------------------------------------------------------------------+
#property copyright "nen"
#property link      "http://www.onix-trade.net/forum/index.php?showtopic=89331&view=findpost&p=412823"

// Отрисовка индикатора в основном окне
#property indicator_chart_window

// Количество индикаторных буфферов
#property indicator_buffers  8

#define up  1
#define dn  -1

// ВХОДНЫЕ ПАРАМЕТРЫ ИНДИКАТОРА 
extern string ___0___ = "Parameters for primary selection of extremums";      // разделитель групп параметров
extern int PrimarySelectionOfExtremums = 0;  // Выбор алгоритма первичного отбора экстремумов
                                             // 0 - алгоритм стандартного зигзага
                                             // 1 - по фракталам
                                             // 2 - свинги Ганна
                                             // 3 - свинги Ганна в варианте matrica
                                             // 4 - zigzag_Dow
                                             // 5 - двухбаровый фильтр
                                             // 6 - усреднение баров
extern int filterZigZag = 0;      // 0 - зигзаговая фильтрация до расчета следующего уровня
                                  // 1 - зигзаговая фильтрация после построения следующего уровня - сейчас отключено
                                  // 2 - без зигзаговой фильтрации
// Параметры для алгоритма стандартного зигзага
extern int ExtDepth     = 8;     // количество баров, на которых ищется экстремум - примерно соответствует периоду MA
extern int ExtBackstep  = 13;
// Параметры фрактального индикатора для первичного отбора экстремумов
extern int ExtBarLeft   = 2;      // количество баров слева ниже максимума
extern int ExtBarRight  = 2;      // количество баров справа ниже максимума

// Свинги Ганна
extern int externalBar  = 2;      // 0 - луч от предыдущего бара идет к ближайшему экстремуму внешнего бара
                                  // 1 - на внешнем баре продолжается тренд предыдущего бара. 
                                  // 2 - луч идет к тому экстремуму внешнего бара, к которому ближе цена открытия бара.
                                  //     Если цена открытия находится на одинаковом расстроянии от максимума и минимума,
                                  //     то будет вариант 1.

// усреднение баров
extern int bars_average = 0;      // Алгоритм выбора усреднения баров
                                  // 0 - (H+L)/2
                                  // 1 - (H+L+O+C)/4 
                                  // 2 - (H+L+C+C)/4

extern string ___1___ = "Parameters for next selection of extremums";         // разделитель групп параметров
extern int NextSelectionOfExtremums = 1;     // Выбор алгоритма для отбора экстремумов второго и следующих уровней
                                             // 0 - отсутствует построение второго и следующих уровней
                                             // 1 - по фракталам
                                             // 2 - свинги Ганна
                                             // 3 - zigzag_alf
                                             // 4 - zigzag_Dow

extern string ___2___ = "Common Parameters";                                  // разделитель групп параметров
// Общие параметры
extern int VariantShow  = 0;       // выбор варианта вывода информации на график
                                   // 0 - DRAW_ZIGZAG, 1 - DRAW_ARROW, 2 - две линии, одна линия соединяет минимумы, вторая - максимумы.
                                   // 3 - зарезервировано 
extern int ShowPrimaryLevel  = 0;  // номер уровня, начиная с которого производится вывод экстремумов на график
extern int QuantityExtremums = 20; // задание количества экстремумов старшего уровня, для которых будут сохраняться в массивах 
                                   // экстремумы младшего уровня. 0 - все экстремумы, от 1 до 10 - 10 экстремумов
extern string ColorLevels    = "Tan,RoyalBlue,Aqua,SaddleBrown,Red,Yellow,Magenta,Purple,MediumSpringGreen,Chocolate,LightGray"; // цвет уровня
extern string StyleLevels    = "0,0,0,0,0,0,0,0,0,0,0"; // задаем стиль линий для каждого уровня
extern string WidthLevels    = "0,0,0,0,0,0,0,0,0,0,0"; // задаем толщину линий для каждого уровня
extern int Statistica        = 0;  // вывод статистики во вкладку Эксперты метатрейдера после расчета истории
                                   // 1 - выводится количество баров с экстремумами на каждом уровне
                                   // 2 - 
                                   //
                                   //


extern int ExtComplekt       = 0;    // номер комплекта. Если на график выведено несколько индикаторов, то у каждого индикатора должен быть 
                                     // уникальный параметр ExtComplekt, чтобы отличать графические построения, относящиеся к конкретному индикатору

// Глобальные переменные
// Индикаторные буферы
double LowestBuffer1[],HighestBuffer1[],LowestBuffer2[],HighestBuffer2[],LowestBuffer3[],HighestBuffer3[],LowestBuffer4[],HighestBuffer4[];

/*
В массивы tL-cL-cH записываем первичные подборки экстремумов.
Далее их, если задано, фильтруем зигзагом. Проводим прополку зигзаговым алгоритмом.
Следующим шагом для отображения четырех уровней найденных экстремумов переносим значения экстремумов в массивы LowestBuffer-HighestBuffer.
Если применяется второй вариант зигзаговой фильтрации, то из нафильтрованных массивов tL-cL-cH после зигзаговой фильтрации переносим
значения экстремумов в масивы tLz-cLz-cHz и уже из этих массивов переносим значения экстремумов в масиивы LowestBuffer-HighestBuffer 
для их отображения на графике.
*/
// массивы для хранения времени экстремумов соответствующего уровня
datetime tL1[1],tL2[1],tL3[1],tL4[1],tL5[1],tL6[1],tL7[1],tL8[1],tL9[1],tL10[1],tL11[1];            // filterZigZag = 0 или filterZigZag = 2
// массивы для хранения цены экстремумов соответствующего уровня
double   cL1[1],cL2[1],cL3[1],cL4[1],cL5[1],cL6[1],cL7[1],cL8[1],cL9[1],cL10[1],cL11[1];            // filterZigZag = 0 или filterZigZag = 2
double   cH1[1],cH2[1],cH3[1],cH4[1],cH5[1],cH6[1],cH7[1],cH8[1],cH9[1],cH10[1],cH11[1];
// массивы для хранения времени экстремумов соответствующего уровня для второго варианта зигзага 
datetime tLz1[1],tLz2[1],tLz3[1],tLz4[1],tLz5[1],tLz6[1],tLz7[1],tLz8[1],tLz9[1],tLz10[1],tLz11[1]; // filterZigZag = 1
// массивы для хранения цены экстремумов соответствующего уровня для второго варианта зигзага
double   cLz1[1],cLz2[1],cLz3[1],cLz4[1],cLz5[1],cLz6[1],cLz7[1],cLz8[1],cLz9[1],cLz10[1],cLz11[1]; // filterZigZag = 1
double   cHz1[1],cHz2[1],cHz3[1],cHz4[1],cHz5[1],cHz6[1],cHz7[1],cHz8[1],cHz9[1],cHz10[1],cHz11[1];
// массивы для сохранения значения цены и времени последнего экстремума
double   last_h[11], last_l[11];
datetime last_t[11];
int      gtf;                   // рабочий таймфрейм
bool     gnextlevel;            // =true - возможно создание следующего уровня

int      gColorLevels_[11], gStyleLevels_[]={0,0,0,0,0,0,0,0,0,0,0}, gWidthLevels_[]={0,0,0,0,0,0,0,0,0,0,0};

double   gH[], gL[];            // массивы максимумов и минимумов для первичной выборки экстремумов
datetime gT[];
int      gbar;                  // номер бара, с которого начинается поиск экстремумов

int      _PrimarySelectionOfExtremums, _NextSelectionOfExtremums, _VariantShow;
double   glowBar, ghighBar;     // значение минимума и максимума нулевого бара припоследнем расчета
datetime gtimelast;             // время нулевого бара при последнем расчете
datetime gtime_gbar[11];        // время, с которого начнется расчет при поступлении нового тика
int      gcurrentBars=0;        // количество расчитанных баров
datetime gtimedinamic;          // время бара, с которого проверяем изменившиеся экстремумы
datetime gL2LTime[11],gL2HTime[11];  // значение времени начала и конца второго (третьего) луча зигзага или последнего минимума и максимума

int      glevel;                // номер обрабатываемого уровня
bool     history;               // =true - сделать первоначальный расчет всех уровнией

bool     g_addnewextremum;      // определяет необходимость расчета следующих уровней

// переменные для двухбарового фильтра
double ups, dws, ups_, dws_;
datetime gsave_tgi, gsave_tb1;
// переменные для сохранения значений, с которых необходимо подолжить расчет на следующем тике
double gsave_lastlow[11], gsave_lasthigh[11], gsave_lastlow_[11], gsave_lasthigh_[11], gsave_wr0;
datetime gsave_tLast[11], gt_hi[11], gt_li[11], gt_end[11];
int gsave_hl[11];

bool gTheExternalBar;            // для внешнего бара в свингах Ганна

int  gRecalculation;             // полный пересчет на текущем тике

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   int i, j;
// При выводе на график используется для каждого уровня два индикаторных буфера.
// Один буфер для вывода минимумов, второй уровень для вывода максимумов.
   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);

   _stringtocolorarray(ColorLevels, gColorLevels_, 11);
   _stringtointarray  (StyleLevels, gStyleLevels_, 11);
   _stringtointarray  (WidthLevels, gWidthLevels_, 11);

   if(PrimarySelectionOfExtremums<0 || PrimarySelectionOfExtremums>6) _PrimarySelectionOfExtremums=0;
   else _PrimarySelectionOfExtremums=PrimarySelectionOfExtremums;

   if(NextSelectionOfExtremums<0 || NextSelectionOfExtremums>4) _NextSelectionOfExtremums=0;
   else _NextSelectionOfExtremums=NextSelectionOfExtremums;

   if(filterZigZag<2) filterZigZag=0;
   if(filterZigZag>2) filterZigZag=2;

   if(ExtBarLeft<0)  ExtBarLeft=1;
   if(ExtBarRight<0) ExtBarRight=1;

   if(bars_average<0 || bars_average>2) bars_average=0;

   if(VariantShow<0) VariantShow=0;
   if(VariantShow>2) VariantShow=2;
   _VariantShow=VariantShow;
   if(_VariantShow==0 && filterZigZag>1) _VariantShow=1;

   if(ShowPrimaryLevel<0) ShowPrimaryLevel=0;
   if(ShowPrimaryLevel>10) ShowPrimaryLevel=10;

   if(QuantityExtremums<0) QuantityExtremums=0;
   if(QuantityExtremums>0 && QuantityExtremums<10) QuantityExtremums=10;

   j=0;
   for(i=0;i<4;i++)
     {
      if(i+ShowPrimaryLevel>9) break;
      if(_VariantShow==0)
        {
         SetIndexStyle(j, DRAW_ZIGZAG, gStyleLevels_[i+ShowPrimaryLevel], gWidthLevels_[i+ShowPrimaryLevel], gColorLevels_[i+ShowPrimaryLevel]);
         j++;
         SetIndexStyle(j, DRAW_ZIGZAG, gStyleLevels_[i+ShowPrimaryLevel], gWidthLevels_[i+ShowPrimaryLevel], gColorLevels_[i+ShowPrimaryLevel]);
         j++;
        }
      else if(_VariantShow==1)
        {
         SetIndexStyle(j, DRAW_ARROW, gStyleLevels_[i+ShowPrimaryLevel], gWidthLevels_[i+ShowPrimaryLevel], gColorLevels_[i+ShowPrimaryLevel]);
         SetIndexArrow(j, 117); 
         j++;
         SetIndexStyle(j, DRAW_ARROW, gStyleLevels_[i+ShowPrimaryLevel], gWidthLevels_[i+ShowPrimaryLevel], gColorLevels_[i+ShowPrimaryLevel]);
         SetIndexArrow(j, 117);
         j++;
        }
      else if(_VariantShow==2)
        {
         SetIndexStyle(j, DRAW_SECTION, gStyleLevels_[i+ShowPrimaryLevel], gWidthLevels_[i+ShowPrimaryLevel], gColorLevels_[i+ShowPrimaryLevel]);
         j++;
         SetIndexStyle(j, DRAW_SECTION, gStyleLevels_[i+ShowPrimaryLevel], gWidthLevels_[i+ShowPrimaryLevel], gColorLevels_[i+ShowPrimaryLevel]);
         j++;
        }
      else if(_VariantShow==3)    // резерв
        {
        }
     }

   gcurrentBars=0;

   return(0);
  }

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   delete_objects();
   Comment("");
//----
   return(0);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int i;

   gtf=Period();
   gRecalculation=1;

   while(gRecalculation>0)
     {
      if(gcurrentBars<iBars(NULL, gtf)-1)
        {
         Print("Время полного пересчета = ",TimeToStr(Time[0],TIME_DATE|TIME_MINUTES));
         glowBar=0; ghighBar=0; gtimelast=0; gsave_wr0=0;
         ArrayInitialize(gsave_tLast,0);ArrayInitialize(gsave_hl,0);ArrayInitialize(gsave_lastlow,0);ArrayInitialize(gsave_lasthigh,0);
         ArrayInitialize(gt_hi,0);ArrayInitialize(gt_li,0);ArrayInitialize(gt_end,0);

         gTheExternalBar=false; 
         history=true;
//      if(_PrimarySelectionOfExtremums==2 || _PrimarySelectionOfExtremums==3) delete_objects();
         delete_objects();
         g_addnewextremum=true;
         gbar=iBars(NULL, gtf);

         ArrayInitialize(gtime_gbar,0); ArrayInitialize(gL2LTime,0); ArrayInitialize(gL2HTime,0); 

         ArrayInitialize(LowestBuffer1,0);ArrayInitialize(HighestBuffer1,0);
         ArrayInitialize(LowestBuffer2,0);ArrayInitialize(HighestBuffer2,0); 
         ArrayInitialize(LowestBuffer3,0);ArrayInitialize(HighestBuffer3,0); 
         ArrayInitialize(LowestBuffer4,0);ArrayInitialize(HighestBuffer4,0); 

         ArrayInitialize(last_h,0);ArrayInitialize(last_l,0);ArrayInitialize(last_t,0);

         ArrayInitialize(tL1,0);ArrayInitialize(tL2,0);ArrayInitialize(tL3,0);ArrayInitialize(tL4,0);ArrayInitialize(tL5,0);
         ArrayInitialize(tL6,0);ArrayInitialize(tL7,0);ArrayInitialize(tL8,0);ArrayInitialize(tL9,0);ArrayInitialize(tL10,0);
         ArrayInitialize(tL11,0);

         ArrayInitialize(cL1,0);ArrayInitialize(cL2,0);ArrayInitialize(cL3,0);ArrayInitialize(cL4,0);ArrayInitialize(cL5,0);
         ArrayInitialize(cL6,0);ArrayInitialize(cL7,0);ArrayInitialize(cL8,0);ArrayInitialize(cL9,0);ArrayInitialize(cL10,0);
         ArrayInitialize(cL11,0);
         ArrayInitialize(cH1,0);ArrayInitialize(cH2,0);ArrayInitialize(cH3,0);ArrayInitialize(cH4,0);ArrayInitialize(cH5,0);
         ArrayInitialize(cH6,0);ArrayInitialize(cH7,0);ArrayInitialize(cH8,0);ArrayInitialize(cH9,0);ArrayInitialize(cH10,0);
         ArrayInitialize(cH11,0);
         if(filterZigZag==1)
           {
            ArrayResize(cLz1,gbar);ArrayResize(cHz1,gbar);ArrayResize(tLz1,gbar);

            ArrayInitialize(tLz1,0);ArrayInitialize(tLz2,0);ArrayInitialize(tLz3,0);ArrayInitialize(tLz4,0);ArrayInitialize(tLz5,0);
            ArrayInitialize(tLz6,0);ArrayInitialize(tLz7,0);ArrayInitialize(tLz8,0);ArrayInitialize(tLz9,0);ArrayInitialize(tLz10,0);
            ArrayInitialize(tLz11,0);

            ArrayInitialize(cLz1,0);ArrayInitialize(cLz2,0);ArrayInitialize(cLz3,0);ArrayInitialize(cLz4,0);ArrayInitialize(cLz5,0);
            ArrayInitialize(cLz6,0);ArrayInitialize(cLz7,0);ArrayInitialize(cLz8,0);ArrayInitialize(cLz9,0);ArrayInitialize(cLz10,0);
            ArrayInitialize(cLz11,0);
            ArrayInitialize(cHz1,0);ArrayInitialize(cHz2,0);ArrayInitialize(cHz3,0);ArrayInitialize(cHz4,0);ArrayInitialize(cHz5,0);
            ArrayInitialize(cHz6,0);ArrayInitialize(cHz7,0);ArrayInitialize(cHz8,0);ArrayInitialize(cHz9,0);ArrayInitialize(cHz10,0);
            ArrayInitialize(cHz11,0);
           }
         Print("");
        }
      else
        {
         if(_PrimarySelectionOfExtremums<2)
           {
            gbar=iBarShift(NULL, gtf, gtime_gbar[0], true)+2;
           }
        }

      if(_PrimarySelectionOfExtremums==4 && gtimelast==iTime(NULL, gtf, 0)) return(0);
      if(tL1[0]>0)
        {
         if(glowBar<=iLow(NULL, gtf, 0) && ghighBar>=iHigh(NULL, gtf, 0) && gtimelast==iTime(NULL, gtf, 0)) return (0);
         if(gtimelast<iTime(NULL, gtf, 0) &&(_PrimarySelectionOfExtremums==2 || _PrimarySelectionOfExtremums==3))
           {
            gTheExternalBar=false; delete_objects();
           }
        }
      glowBar=iLow(NULL, gtf, 0); ghighBar=iHigh(NULL, gtf, 0);                  // обновляем сразу, а не после длительного расчета

      // Поиск экстремумов для первого уровня
      glevel=0;
      SamplingCreationExtremums();

      if(history)
        {

         if(ShowPrimaryLevel==0)
           {
            VisiblePrimarySelections(cL1, cH1, tL1, cLz1, cHz1, tLz1, LowestBuffer1, HighestBuffer1); // визуализация
           }

         // Создание следующих уровней и визуализация
         SelectionArrayForNextLevels();
         gtimelast=iTime(NULL, gtf, 0); // эта переменная используется в промежуточных расчетах, поэтому ее обновляем после расчетов
         history=false;

         // Обрезка массивов
         if(QuantityExtremums>0)
           {
            for(i=1;i<11;i++)
             {
              int k=ScrapOfArrays(i);
//              if(k!=0) Print("размер массива уровня ",i-1," = ",k);
              if(k==0) break;
//              if(ScrapOfArrays(i)==0) break;
             }
          }
        }
      else
        {
         WriteNewExtremums(cL1, cH1, tL1, cLz1, cHz1, tLz1);

         // Создание следующих уровней и визуализация
         SelectionArrayForNextLevels();

         gtimelast=iTime(NULL, gtf, 0); // эта переменная используется в промежуточных расчетах, поэтому ее обновляем после расчетов
        }
      if(gRecalculation>0) gRecalculation--;
     }

   gcurrentBars=iBars(NULL, gtf);       // обновляем в конце, чтобы не накапливались непосчитанные бары за время расчета
                                        // и не срабатывал полный пересчет на следующем тике в случае длительного расчета

   return(0);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|    Подпрограммы                                                  |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Обрезка массивов. Начало.                                        |
//+------------------------------------------------------------------+
/*
// массивы для хранения времени экстремумов соответствующего уровня
datetime tL1[1],tL2[1],tL3[1],tL4[1],tL5[1],tL6[1],tL7[1],tL8[1],tL9[1],tL10[1],tL11[1];            // filterZigZag = 0 или filterZigZag = 2
// массивы для хранения цены экстремумов соответствующего уровня
double   cL1[1],cL2[1],cL3[1],cL4[1],cL5[1],cL6[1],cL7[1],cL8[1],cL9[1],cL10[1],cL11[1];            // filterZigZag = 0 или filterZigZag = 2
double   cH1[1],cH2[1],cH3[1],cH4[1],cH5[1],cH6[1],cH7[1],cH8[1],cH9[1],cH10[1],cH11[1];
// массивы для хранения времени экстремумов соответствующего уровня для второго варианта зигзага 
datetime tLz1[1],tLz2[1],tLz3[1],tLz4[1],tLz5[1],tLz6[1],tLz7[1],tLz8[1],tLz9[1],tLz10[1],tLz11[1]; // filterZigZag = 1
// массивы для хранения цены экстремумов соответствующего уровня для второго варианта зигзага
double   cLz1[1],cLz2[1],cLz3[1],cLz4[1],cLz5[1],cLz6[1],cLz7[1],cLz8[1],cLz9[1],cLz10[1],cLz11[1]; // filterZigZag = 1
double   cHz1[1],cHz2[1],cHz3[1],cHz4[1],cHz5[1],cHz6[1],cHz7[1],cHz8[1],cHz9[1],cHz10[1],cHz11[1];
*/

int ScrapOfArrays(int j)
  {
   int i, k=0;
   switch(j)
     {
      case 1:
             if(ArraySize(tL2)>QuantityExtremums)
               {
                k=ArraySize(tL1);
                for(i=0;i<ArraySize(tL1);i++)
                  {
                   if(tL2[QuantityExtremums-1]==tL1[i]) {k=i+1; break;}
                  }
                 ArrayResize(tL1,k); ArrayResize(cL1,k); ArrayResize(cH1,k);
               }
             break;
      case 2:
             if(ArraySize(tL3)>QuantityExtremums)
               {
                k=ArraySize(tL2);
                for(i=0;i<ArraySize(tL2);i++)
                  {
                   if(tL3[QuantityExtremums-1]==tL2[i]) {k=i+1; break;}
                  }
                 ArrayResize(tL2,k); ArrayResize(cL2,k); ArrayResize(cH2,k);
               }
             break;
      case 3:
             if(ArraySize(tL4)>QuantityExtremums)
               {
                k=ArraySize(tL3);
                for(i=0;i<ArraySize(tL3);i++)
                  {
                   if(tL4[QuantityExtremums-1]==tL3[i]) {k=i+1; break;}
                  }
                 ArrayResize(tL3,k); ArrayResize(cL3,k); ArrayResize(cH3,k);
               }
             break;
      case 4:
             if(ArraySize(tL5)>QuantityExtremums)
               {
                k=ArraySize(tL4);
                for(i=0;i<ArraySize(tL4);i++)
                  {
                   if(tL5[QuantityExtremums-1]==tL4[i]) {k=i+1; break;}
                  }
                 ArrayResize(tL4,k); ArrayResize(cL4,k); ArrayResize(cH4,k);
               }
             break;
      case 5:
             if(ArraySize(tL6)>QuantityExtremums)
               {
                k=ArraySize(tL5);
                for(i=0;i<ArraySize(tL5);i++)
                  {
                   if(tL6[QuantityExtremums-1]==tL5[i]) {k=i+1; break;}
                  }
                 ArrayResize(tL5,k); ArrayResize(cL5,k); ArrayResize(cH5,k);
               }
             break;
      case 6:
             if(ArraySize(tL7)>QuantityExtremums)
               {
                k=ArraySize(tL6);
                for(i=0;i<ArraySize(tL6);i++)
                  {
                   if(tL7[QuantityExtremums-1]==tL6[i]) {k=i+1; break;}
                  }
                 ArrayResize(tL6,k); ArrayResize(cL6,k); ArrayResize(cH6,k);
               }
             break;
      case 7:
             if(ArraySize(tL8)>QuantityExtremums)
               {
                k=ArraySize(tL7);
                for(i=0;i<ArraySize(tL7);i++)
                  {
                   if(tL8[QuantityExtremums-1]==tL7[i]) {k=i+1; break;}
                  }
                 ArrayResize(tL7,k); ArrayResize(cL7,k); ArrayResize(cH7,k);
               }
             break;
      case 8:
             if(ArraySize(tL9)>QuantityExtremums)
               {
                k=ArraySize(tL8);
                for(i=0;i<ArraySize(tL8);i++)
                  {
                   if(tL9[QuantityExtremums-1]==tL8[i]) {k=i+1; break;}
                  }
                 ArrayResize(tL8,k); ArrayResize(cL8,k); ArrayResize(cH8,k);
               }
             break;
      case 9:
             if(ArraySize(tL10)>QuantityExtremums)
               {
                k=ArraySize(tL9);
                for(i=0;i<ArraySize(tL9);i++)
                  {
                   if(tL10[QuantityExtremums-1]==tL9[i]) {k=i+1; break;}
                  }
                 ArrayResize(tL9,k); ArrayResize(cL9,k); ArrayResize(cH9,k);
               }
             break;
      case 10:
             if(ArraySize(tL11)>QuantityExtremums)
               {
                k=ArraySize(tL10);
                for(i=0;i<ArraySize(tL10);i++)
                  {
                   if(tL11[QuantityExtremums-1]==tL10[i]) {k=i+1; break;}
                  }
                 ArrayResize(tL10,k); ArrayResize(cL10,k); ArrayResize(cH10,k);
               }
     }

   return (k);
  }
//+------------------------------------------------------------------+
//| Обрезка массивов. Конец.                                         |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Создание первичной выборки экстремумов. Начало.                  |
//+------------------------------------------------------------------+
int SamplingCreationExtremums()
  {
   if(tL1[0]==0)
     {
      gbar--;

      switch(_PrimarySelectionOfExtremums)
        {
         case 0: {
                  standart();
                  if(filterZigZag==0) ZigZag(cL1, cH1, tL1);
                  else if(filterZigZag==1) ZigZag(cLz1, cHz1, tLz1);
                  break;
                 }
         case 1: {
                  fractals();
                  if(filterZigZag==0) ZigZag(cL1, cH1, tL1); // Print("2  gbar = ",gbar);
                  else if(filterZigZag==1) {ZigZag(cLz1, cHz1, tLz1);}

                  break;
                 }
         case 2: swing(); break; // gann
         case 3: swing(); break; // matrica
         case 4: zigzag_Dow(); break;
         case 5: _2barsFiltr(); break;
         case 6: AverageBars();
        }
     }
   else
     {
      gbar--;

      switch(_PrimarySelectionOfExtremums)
        {
         case 0: {
                  standart();
                  if(filterZigZag==0) ZigZag(gL, gH, gT);
                  break;
                 }
         case 1: {
                  fractals();
                  if(filterZigZag==0) ZigZag(gL, gH, gT);
                  break;
                 }
         case 2: swing(); break; // gann
         case 3: swing(); break; // matrica
         case 4: {
                  if(gtimelast!=iTime(NULL, gtf, 0)) zigzag_Dow(); 
                  break;
                 }
         case 5: _2barsFiltr(); break;
         case 6: AverageBars();
        }
     }

   return (0);
  }
//+------------------------------------------------------------------+
//| Создание первичной выборки экстремумов. Конец.                   |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Подбор массивов для создания второго и следующих уровней.        |
//| Начало.                                                          |
//+------------------------------------------------------------------+
int SelectionArrayForNextLevels()
  {
   int i;

   glevel=1;
   for(i=0;i<10;i++)
     {
      // проверка необходимости создания следующего уровня
      if(ArraySize(gT)>0) gnextlevel=true; else {gnextlevel=false;} // break;}

      if(g_addnewextremum)
        {
         g_addnewextremum=false;
//if(glevel>0) {glevel=0; return(0);}
         switch(i)
           {
            case 0: CreationExtremumsNextLevels(cL1,  cH1,  tL1,  cL2,   cH2,  tL2,  cLz2,  cHz2,  tLz2);  break; // создание 2-го  уровня
            case 1: CreationExtremumsNextLevels(cL2,  cH2,  tL2,  cL3,   cH3,  tL3,  cLz3,  cHz3,  tLz3);  break; // создание 3-го  уровня
            case 2: CreationExtremumsNextLevels(cL3,  cH3,  tL3,  cL4,   cH4,  tL4,  cLz4,  cHz4,  tLz4);  break; // создание 4-го  уровня
            case 3: CreationExtremumsNextLevels(cL4,  cH4,  tL4,  cL5,   cH5,  tL5,  cLz5,  cHz5,  tLz5);  break; // создание 5-го  уровня
            case 4: CreationExtremumsNextLevels(cL5,  cH5,  tL5,  cL6,   cH6,  tL6,  cLz6,  cHz6,  tLz6);  break; // создание 6-го  уровня
            case 5: CreationExtremumsNextLevels(cL6,  cH6,  tL6,  cL7,   cH7,  tL7,  cLz7,  cHz7,  tLz7);  break; // создание 7-го  уровня
            case 6: CreationExtremumsNextLevels(cL7,  cH7,  tL7,  cL8,   cH8,  tL8,  cLz8,  cHz8,  tLz8);  break; // создание 8-го  уровня
            case 7: CreationExtremumsNextLevels(cL8,  cH8,  tL8,  cL9,   cH9,  tL9,  cLz9,  cHz9,  tLz9);  break; // создание 9-го  уровня
            case 8: CreationExtremumsNextLevels(cL9,  cH9,  tL9,  cL10,  cH10, tL10, cLz10, cHz10, tLz10); break; // создание 10-го уровня
            case 9: CreationExtremumsNextLevels(cL10, cH10, tL10, cLz11, cH11, tL11, cLz11, cHz11, tLz11);        // создание 11-го уровня
           }
        }
      glevel++;
      if(!gnextlevel) break;
     }

   glevel=0;
   return (0);
  }
//+------------------------------------------------------------------+
//| Подбор массивов для создания второго и следующих уровней.        |
//| Конец.                                                           |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Создание выборки экстремумов для второго и следующих уровней.    |
//| И визуализация.                                                  |
//| Начало.                                                          |
//+------------------------------------------------------------------+
int CreationExtremumsNextLevels(double& cl[], double& ch[], datetime& t[], double& cl_[], double& ch_[], datetime& t_[], double& clz[], double& chz[], datetime& tz[])
  {
   int k;

   switch(_NextSelectionOfExtremums)
     {
      case 0: break; // резерв
      case 1: {
               if(fractals_nextlevel(cl, ch, t, cl_, ch_, t_, clz, chz, tz)<0) return(0);
               break;
              }
      case 2: {
               if(swing_nextlevel(cl, ch, t, cl_, ch_, t_)<0) return(0);
               break;
              }
      case 3: {
               if(zigzag_alf(cl, ch, t, cl_, ch_, t_)<0) return(0);
               break;
              }
      case 4: {
               if(zigzag_Dow_nextlevel(cl, ch, t, cl_, ch_, t_)<0) return(0);
               break;
              }
     }

   // визуализация
   if(history)
     {
      k=glevel-ShowPrimaryLevel;
      if(k>=0 && k<4)
        {
         switch(k)
           {
            case 0: VisiblePrimarySelections(cl_, ch_, t_, clz, chz, tz, LowestBuffer1, HighestBuffer1); break;
            case 1: VisiblePrimarySelections(cl_, ch_, t_, clz, chz, tz, LowestBuffer2, HighestBuffer2); break;
            case 2: VisiblePrimarySelections(cl_, ch_, t_, clz, chz, tz, LowestBuffer3, HighestBuffer3); break;
            case 3: VisiblePrimarySelections(cl_, ch_, t_, clz, chz, tz, LowestBuffer4, HighestBuffer4);
           }
        }
     }
   else
     {
      WriteNewExtremums(cl_, ch_, t_, clz, chz, tz);
     }

   return (0);
  }
//+------------------------------------------------------------------+
//| Создание выборки экстремумов для второго и следующих уровней.    |
//| И визуализация.                                                  |
//| Конец.                                                           |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Создание первичной выборки экстремумов.                          |
//| Двухбаровый фильтр. Начало.                                      |
//+------------------------------------------------------------------+
int _2barsFiltr()
  {
   int i, hl, limit, gi, b1, b2, end;
   if(history)
     {
      limit=iBars(NULL, gtf)-2;
      b1=iBars(NULL, gtf)-1;
      gi=b1;
      hl=up;
      end=iBars(NULL, gtf);
      ArrayResize(gL, end); ArrayResize(gH, end); ArrayResize(gT, end);
      ArrayInitialize(gL, 0); ArrayInitialize(gH, 0); ArrayInitialize(gT, 0);
      if(iLow(NULL, gtf, limit+1)<=iLow(NULL, gtf, limit))
        {
         gL[limit+1]=iLow(NULL, gtf, limit+1); gT[limit+1]=iTime(NULL, gtf, limit+1);
        }
      else
        {
         gL[limit]=iLow(NULL, gtf, limit); gT[limit]=iTime(NULL, gtf, limit);
        }
     }
   else
     {
      limit=iBarShift(NULL, gtf, gsave_tLast[0], false);
      gi=iBarShift(NULL, gtf, gsave_tgi, false);
      b1=iBarShift(NULL, gtf, gsave_tb1, false);
      hl=gsave_hl[0];
      end=iBarShift(NULL, gtf, tL1[1], false);
      ArrayResize(gL, end+1); ArrayResize(gH, end+1); ArrayResize(gT, end+1);
      ArrayInitialize(gL, 0); ArrayInitialize(gH, 0); ArrayInitialize(gT, 0);
      gL[end]=cL1[1]; gH[end]=cH1[1]; gT[end]=tL1[1];
      end=iBarShift(NULL, gtf, tL1[0], false);
      gL[end]=cL1[0]; gH[end]=cH1[0]; gT[end]=tL1[0];
      gtimedinamic=tL1[1];
    }

   for(i=limit; i>=0; i--)
     {
      if(iHigh(NULL, gtf, i+1)>ups || iLow(NULL, gtf, i+1)<dws)
        {
         b2=b1; b1=i+1;
         ups=MathMax(iHigh(NULL, gtf, b2),iHigh(NULL, gtf, b1));
         dws=MathMin(iLow(NULL, gtf, b2),iLow(NULL, gtf, b1));
         if(hl==up)
           {
            if(ups>ups_)
              {
               gH[gi]=0;
               gi=b1;
               gH[gi]=ups; gT[gi]=iTime(NULL, gtf, gi);
              }
            else if(dws<dws_ && ups<ups_)
              {
               hl=dn;
               gi=b1;
               gL[gi]=dws; gT[gi]=iTime(NULL, gtf, gi);
              }
           }
         else
           {
            if(dws<dws_)
              {
               gL[gi]=0;
               gi=b1;
               gL[gi]=dws; gT[gi]=iTime(NULL, gtf, gi);
              }
            else if(ups>ups_ && dws>dws_)
              {
               hl=up;
               gi=b1;
               gH[gi]=ups; gT[gi]=iTime(NULL, gtf, gi);
              }
           }
        }
      ups_=ups; dws_=dws;
     }

   gsave_tLast[0]=iTime(NULL, gtf, 0);
   gsave_tgi=iTime(NULL, gtf, gi);
   gsave_tb1=iTime(NULL, gtf, b1);
   gsave_hl[0]=hl;

   press_arr(cL1, cH1, tL1, cLz1, cHz1, tLz1);

   // определение необходимости проверки следующего уровня на наличие нового экстремума
   if(history || gT[0]!=tL1[0] || gL[0]!=cL1[0] || gH[0]!=cH1[0]) g_addnewextremum=true;

   return (0);
  }
//+------------------------------------------------------------------+
//| Создание первичной выборки экстремумов.                          |
//| Двухбаровый фильтр. Конец.                                       |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Создание первичной выборки экстремумов.                          |
//| Усреднение баров. Начало.                                        |
//+------------------------------------------------------------------+
int AverageBars()
  {
   int i, hl=0, limit, gi, end=iBars(NULL, gtf);
   double b1=0, b2=0;
   if(history)
     {
      limit=iBars(NULL, gtf)-2;
      ArrayResize(gL, end); ArrayResize(gH, end); ArrayResize(gT, end);
      ArrayInitialize(gL, 0); ArrayInitialize(gH, 0); ArrayInitialize(gT, 0);
     }
   else
     {
      limit=iBarShift(NULL, gtf, tL1[2], false);
      end=limit+1;
      ArrayResize(gL, end); ArrayResize(gH, end); ArrayResize(gT, end);
      ArrayInitialize(gL, 0); ArrayInitialize(gH, 0); ArrayInitialize(gT, 0);
      if(cH1[2]>0) {hl=up; gH[limit]=cH1[2];}
      if(cL1[2]>0) {hl=dn; gL[limit]=cL1[2];}
      gT[limit]=tL1[2]; gi=limit;
      limit--;
      gtimedinamic=tL1[2];
     }

   b2=av_bars(limit+1);
   for(i=limit; i>0; i--)
     {
      b1=b2;
      b2=av_bars(i);

      if(hl==0)
        {
         if(b2>b1) {hl=up; gH[i]=av_bars(i); gT[i]=iTime(NULL, gtf, i);}
         else  {hl=dn; gL[i]=av_bars(i); gT[i]=iTime(NULL, gtf, i);}
         gi=i;
        }
      else
        {
         if(hl==up)
           {
            if(b2>b1) gi=i;
            else if(b2<b1) {gH[gi]=av_bars(gi); gT[gi]=iTime(NULL, gtf, gi); hl=dn; gi=i;}
           }
         else
           {
            if(b2<b1) gi=i;
            else if(b2>b1) {gL[gi]=av_bars(gi); gT[gi]=iTime(NULL, gtf, gi); hl=up; gi=i;}
           }
        }
     }

   if(hl==up) {gH[gi]=av_bars(gi); gT[gi]=iTime(NULL, gtf, gi);}
   else if(hl==dn) {gL[gi]=av_bars(gi); gT[gi]=iTime(NULL, gtf, gi);}

   press_arr(cL1, cH1, tL1, cLz1, cHz1, tLz1);

   // определение необходимости проверки следующего уровня на наличие нового экстремума
   if(history || gT[0]!=tL1[0] || gL[0]!=cL1[0] || gH[0]!=cH1[0]) g_addnewextremum=true;

   return (0);
  }
//+------------------------------------------------------------------+
//| Создание первичной выборки экстремумов.                          |
//| Усреднение баров. Конец.                                         |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Вычисление среднего для бара. Начало.                            |
//+------------------------------------------------------------------+
double av_bars(int i)
  {
   switch(bars_average)
     {
      case 0: return ((iHigh(NULL, gtf, i)+iLow(NULL, gtf, i))/2);
      case 1: return ((iHigh(NULL, gtf, i)+iLow(NULL, gtf, i)+iOpen(NULL, gtf, i)+iClose(NULL, gtf, i))/4);
      case 2: return ((iHigh(NULL, gtf, i)+iLow(NULL, gtf, i)+iClose(NULL, gtf, i)+iClose(NULL, gtf, i))/4);
     }
   return (0);
  }
//+------------------------------------------------------------------+
//| Вычисление среднего для бара. Конец.                             |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Создание второго и следующих уровней экстремумов.                |
//| Трендовый алгоритм (alf). Начало.                                |
//+------------------------------------------------------------------+
int zigzag_alf(double& cl[], double& ch[], datetime& t[], double& cl_[], double& ch_[], datetime& t_[])
  {
   int i, j, k, hl=gsave_hl[glevel], limit, gi=-1, pi=-1;
   double stop=-1, stop1=-1;

   if(ArraySize(t)<4) {g_addnewextremum=false; return(-1);}
   if(history || ArraySize(t_)<3)
     {
      limit=ArraySize(t);
      ArrayResize(gL, limit); ArrayResize(gH, limit); ArrayResize(gT, limit);
      ArrayInitialize(gL, 0); ArrayInitialize(gH, 0); ArrayInitialize(gT, 0);

      if(cl[limit-1]>0 && ch[limit-1]==0)
        {
         hl=up; stop=cl[limit-1];
         for(i=limit-1;i>=0;i--)
           {
            if(ch[i]>0)
              {
               if(gi<0) gi=i;
               else if(ch[i]>ch[gi]) gi=i;
              }
            if(cl[i]>0 && gi>=0) break;
           }
         if(gi<0) {g_addnewextremum=false; return(-1);}
         gH[gi]=ch[gi]; gT[gi]=t[gi];
        }
      else if(cl[limit-1]>0 && ch[limit-1]>0 && cl[limit-2]>0) {hl=up; stop=cl[limit-1]; gi=limit-1;}
      else if(cl[limit-1]>0 && ch[limit-2]>0 && ch[limit-1]>0) {hl=dn; stop=ch[limit-1]; gi=limit-1;}
      else if(cl[limit-1]==0 && ch[limit-1]>0)
        {
         hl=dn; stop=ch[limit-1];
         for(i=limit-1;i>=0;i--)
           {
            if(cl[i]>0)
              {
               if(gi<0) gi=i;
               else if(cl[i]<cl[gi]) gi=i;
              }
            if(ch[i]>0 && gi>=0) break;
           }
         if(gi<0) {g_addnewextremum=false; return(-1);}
         gL[gi]=cl[gi]; gT[gi]=t[gi];
        }
     }
   else
     {
      for(i=0;i<ArraySize(t)-1;i++)
        {
         if(t[i]==t_[1]) break;
        }

      gi=i;
      if(ch_[1]>0) hl=up; else hl=dn;
      for(i=gi;i<ArraySize(t)-1;i++)
        {
         if(hl==up)
           {
            if(cl[i]>0) {stop=cl[i]; break;}
           }
         else
           {
            if(ch[i]>0) {stop=ch[i]; break;}
           }
        }

      for(i=gi;i<ArraySize(t)-1;i++)
        {
         if(t[i]==t_[2]) break;
        }
      limit=i+1;
      ArrayResize(gL, limit); ArrayResize(gH, limit); ArrayResize(gT, limit);
      ArrayInitialize(gL, 0); ArrayInitialize(gH, 0); ArrayInitialize(gT, 0);
      gH[i]=ch[i]; 
      gL[i]=cl[i];
      gT[i]=t[i];

      gH[gi]=ch[gi]; 
      gL[gi]=cl[gi];
      gT[gi]=t[gi];

      gtimedinamic=t_[1];
     }

   for(i=limit-1;i>=0;i--)
     {
      if(hl==up)
        {
         if(ch[i]>0)
           {
            if(ch[i]>ch[gi])
              {
               gH[gi]=0; gi=i; gH[gi]=ch[gi]; gT[gi]=t[gi]; pi=-1;
               if(stop1>0) {stop=stop1; stop1=-1;}
              }
            else if(stop1==stop) {pi=-1; stop1=-1;}
            else if(stop1>stop)
              {
               if(pi>0)
                 {
                  gH[gi]=0; gi=pi; gH[gi]=ch[gi]; gT[gi]=t[gi];
                  if(ch[i]>ch[gi])
                    {
                     gH[gi]=0; gi=i; gH[gi]=ch[gi]; gT[gi]=t[gi]; pi=-1;
                     if(stop1>0) {stop=stop1; stop1=-1;}
                    }
                 }
               if(stop1>0) {pi=i; stop=stop1; stop1=-1;}
              }
            else if(pi>0) if(ch[i]>ch[pi]) {gH[gi]=0; gi=pi; gH[gi]=ch[gi]; gT[gi]=t[gi]; pi=-1;}
           }

         if(cl[i]>=stop && stop>0)
           {
            if(stop1<0) stop1=cl[i];
            else if(cl[i]<stop1) stop1=cl[i];
           }

         if(cl[i]>0 && cl[i]<stop)
           {
            if(pi<0) stop=ch[gi]; else stop=ch[pi];
            pi=-1;
            stop1=-1;
            hl=dn;
            gi=i;
            gL[gi]=cl[gi];
            gT[gi]=t[gi];
           }
        }
      else
        {
         if(cl[i]>0)
           {
            if(cl[i]<cl[gi])
              {
               gL[gi]=0; gi=i; gL[gi]=cl[gi]; gT[gi]=t[gi]; pi=-1;
               if(stop1>0) {stop=stop1; stop1=-1;}
              }
            else if(stop1==stop) {pi=-1; stop1=-1;}
            else if(stop1<stop && stop1>0)
              {
               if(pi>0)
                 {
                  gL[gi]=0; gi=pi; gL[gi]=cl[gi]; gT[gi]=t[gi];
                  if(cl[i]<cl[gi])
                    {
                     gL[gi]=0; gi=i; gL[gi]=cl[i]; gT[gi]=t[gi]; pi=-1;
                     if(stop1>0) {stop=stop1; stop1=-1;}
                    }
                 }
               if(stop1>0) {pi=i; stop=stop1; stop1=-1;}
              }
            else if(pi>0) if(cl[i]<cl[pi] || stop1<0) {gL[gi]=0; gi=pi; gL[gi]=cl[gi]; gT[gi]=t[gi]; pi=-1;}
           }

         if(ch[i]>0 && ch[i]<=stop)
           {
            if(stop1<0) stop1=ch[i];
            else if(ch[i]>stop1) stop1=ch[i];
           }

         if(ch[i]>stop && stop>0)
           {
            if(pi<0) stop=cl[gi]; else stop=cl[pi];
            stop1=-1;
            pi=-1;
            hl=up;
            gi=i;
            gH[gi]=ch[gi];
            gT[gi]=t[gi];
           }
        }

     }

   k=ArraySize(gT);

   if(history)
     {
      ArrayResize(cl_,k); ArrayResize(ch_,k); ArrayResize(t_,k);
     }
   // Сжатие массивов
   //---
   j=0;
   for(i=0;i<ArraySize(gT);i++)
     {
      if(gL[i]>0 || gH[i]>0)
        {
         if(history)  // только при первом проходе заполняются массивы cl_-ch_-t_
           {
            cl_[j]=gL[i]; ch_[j]=gH[i]; t_[j]=gT[i];
           }

         gL[j]=gL[i]; gH[j]=gH[i]; gT[j]=gT[i];
         j++;
        }
     }

   ArrayResize(gL,j); ArrayResize(gH,j); ArrayResize(gT,j);

   if(ArraySize(t_)<3) gtimedinamic=gT[ArraySize(gT)-1];

   if(history)
     {
      ArrayResize(cl_,j); ArrayResize(ch_,j); ArrayResize(t_,j);
     }

   if(history && t[0]>0 && Statistica>0) Statistika(cl, ch, t, cl_, ch_, t_);   // вывод статистики

   if(j==0) {g_addnewextremum=false; return(-1);}

   // определение необходимости проверки следующего уровня на наличие нового экстремума
   if(history || gT[0]!=t_[0] || gL[0]!=cl_[0] || gH[0]!=ch_[0]) g_addnewextremum=true;

   return (0);
  }
//+------------------------------------------------------------------+
//| Создание второго и следующих уровней экстремумов.                |
//| Трендовый алгоритм (alf). Конец.                                 |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Визуализация первой выборки экстремумов. Начало.                 |
//+------------------------------------------------------------------+
int VisiblePrimarySelections(double& cl[], double& ch[], datetime& t[], double& clz[], double& chz[], datetime& tz[], double& LB[], double& HB[])
  {
   int i, j;
   if(filterZigZag==1)
     {
      for(i=ArraySize(tz)-1;i>=0;i--)
        {
         j=iBarShift(NULL, gtf, tz[i], false); 
         LB[j]=clz[i];
         HB[j]=chz[i];
        }
     }
   else
     {
      for(i=ArraySize(t)-1;i>=0;i--)
        {
         j=iBarShift(NULL, gtf, t[i], false); 
         LB[j]=cl[i];
         HB[j]=ch[i];
        }
     }

   return (0);
  }
//+------------------------------------------------------------------+
//| Визуализация первой выборки экстремумов. Конец.                  |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Подбор массивов для визуализации новых экстремумов. Начало.      |
//+------------------------------------------------------------------+
int SelectBufferForNewExtremums(double cl, double ch, datetime t, datetime t_)
  {
   int k=glevel-ShowPrimaryLevel;
   if(k>=0 && k<4)
     {
      switch(k)
        {
         case 0: VisibleNewExtremums(cl, ch, t, t_, LowestBuffer1, HighestBuffer1); break;
         case 1: VisibleNewExtremums(cl, ch, t, t_, LowestBuffer2, HighestBuffer2); break;
         case 2: VisibleNewExtremums(cl, ch, t, t_, LowestBuffer3, HighestBuffer3); break;
         case 3: VisibleNewExtremums(cl, ch, t, t_, LowestBuffer4, HighestBuffer4);
        }
     }

   return (0);
  }
//+------------------------------------------------------------------+
//| Подбор массивов для визуализации новых экстремумов. Конец.       |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Визуализация новых экстремумов. Начало.                          |
//+------------------------------------------------------------------+
/*
t_ - время предыдущего экстремума
t  - время следующего экстремума
*/
int VisibleNewExtremums(double cl, double ch, datetime t, datetime t_, double& LB[], double& HB[])
  {
   int i, j;

   i=iBarShift(NULL, gtf,t,true);

   if(t==t_)
     {
      LB[i]=cl; HB[i]=ch;
     }
   else
     {
      j=iBarShift(NULL, gtf,t_,true);

      if(LB[j]>0) LB[j]=0; 
      if(HB[j]>0) HB[j]=0;
      LB[i]=cl; HB[i]=ch;
     }

   return (0);
  }
//+------------------------------------------------------------------+
//| Визуализация новых экстремумов. Конец.                           |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Запись новых экстремумов в массивы. Начало.                      |
//+------------------------------------------------------------------+
int WriteNewExtremums(double& cl[], double& ch[], datetime& t[], double& clz[], double& chz[], datetime& tz[])
  {
   int i, j, k, m, n, p, arr_size;
   datetime q=0;

   m=ArraySize(gT);
   if(m<1) {g_addnewextremum=false; return(-1);}
   if(gT[0]==0) {g_addnewextremum=false; return(-1);}                         // отсутствуют новые экстремумы
   // поиск неизменившихся фракталов
   i=0;
   if(ArraySize(t)==1 && t[0]==0)
     {
      k=m-1;
     }
   else
     {
      for(j=0;j<m-1;j++) if(gT[j]==gtimedinamic) break;
      for(i=0;i<ArraySize(t)-1;i++) if(t[i]==gtimedinamic) break;

      k=j;
     }  

   for(j=k;j>=0;j--)
     {
      if(i<0)
        {
         arr_size=ArraySize(t)+1;
         ArrayResize(cl,arr_size); ArrayResize(ch,arr_size); ArrayResize(t,arr_size);
         q=gT[j];
         for(p=ArraySize(t)-1;p>0;p--)
           {
            cl[p]=cl[p-1]; ch[p]=ch[p-1]; t[p]=t[p-1];
           }
         if(QuantityExtremums>0) ScrapOfArrays(glevel);                      // Обрезка массивов
         i++;
        }
      else q=t[i];

      if(i+1<ArraySize(t)) if(q==t[i+1]) {q=gT[j]; t[i]=gT[j];}
      if(q==0 && i==0) {q=gT[j]; t[i]=gT[j];}
      SelectBufferForNewExtremums(gL[j], gH[j], gT[j], q);                    // визуализация

      cl[i]=gL[j]; ch[i]=gH[j]; t[i]=gT[j];
      i--;
     }

   // сжатие массива
   if(i>=0)
     {
      SelectBufferForNewExtremums(0, 0, t[0], t[0]);                          // визуализация
      for(p=0;p<ArraySize(t)-1;p++)
        {
         cl[p]=cl[p+1]; ch[p]=ch[p+1]; t[p]=t[p+1];
        }
      ArrayResize(cl,p); ArrayResize(ch,p); ArrayResize(t,p);
     }

   if(filterZigZag==1)
     {
      ZigZag(gL, gH, gT);// Print("5  gbar = ",gbar);
      press_arr(cl, ch, t, clz, chz, tz);

      n=gT[arr_size-1];
      for(i=0;i<ArraySize(tz);i++) if(n>=tz[i]) break;

      for(j=arr_size-1;j>=0;j--)
        {
         if(i<0)
           {
            if(ArraySize(tz)<arr_size)
              {
               ArrayResize(clz,arr_size); ArrayResize(chz,arr_size); ArrayResize(tz,arr_size);
              }
            q=gT[j];
            for(p=ArraySize(t);p>0;p--) {clz[p]=clz[p-1]; chz[p]=chz[p-1]; tz[p]=tz[p-1];}
            i++;
           }
         else q=tz[i];
         SelectBufferForNewExtremums(gL[j], gH[j], gT[j], tz[i]);
         q=0;
         clz[i]=gL[j]; chz[i]=gH[j]; tz[i]=gT[j];
         i--;
       }
     }

   return (0);
  }
//+------------------------------------------------------------------+
//| Запись новых экстремумов в массивы. Конец.                       |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Создание первичной выборки экстремумов.                          |
//| Поиск экстремумов с помощью алгоритма стандартного               |
//| для Metatrader зигзага. Без зигзаговой фильтрации.               |
//| Начало.                                                          |
//+------------------------------------------------------------------+
int standart() // переопределить переменные gL2LTime gL2HTime
  {
   int i, back, shift, limit, bar_l=-1, bar_h=-1, end;
   double val, lastlow=0, lasthigh=0;
   int jl=0,jh=0;

   if(history)
     {
      bar_l=gbar;
      bar_h=gbar;
      limit=gbar-ExtBackstep-ExtDepth-1;
      end=iBars(NULL, gtf);
     }
   else
     {
      // Определение бара, с которого начинается расчет
      for(i=0; i<ArraySize(tL1)-1; i++)
        {
         if(cL1[i]>0) {bar_l=iBarShift(NULL, gtf, tL1[i], true); jl++;}
         if(cH1[i]>0) {bar_h=iBarShift(NULL, gtf, tL1[i], true); jh++;}
         if(jl>=2 && jh>=2) break;
        }
      gtime_gbar[0]=tL1[i];
      gtimedinamic=tL1[i];

      bar_l++; bar_h++;

      // Восстановление переменных
      lastlow=iLow(NULL, gtf, bar_l);
      lasthigh=iHigh(NULL, gtf, bar_h);

      limit=iBarShift(NULL, gtf, tL1[i], true)+1;
      end=limit+ExtDepth+ExtBackstep;
     }

   ArrayResize(gL, end); ArrayResize(gH, end); ArrayResize(gT, end);
   ArrayInitialize(gL, 0); ArrayInitialize(gH, 0); ArrayInitialize(gT, 0);
   for(shift=limit; shift>=0; shift--)
     {
      // поиск минимумов
      if(shift<bar_l)
        {
         i=iLowest(NULL, gtf, MODE_LOW, ExtDepth, shift);
         val=iLow(NULL, gtf, i);

         if(val==lastlow) val=0.0;
         else 
           { 
            lastlow=val; 
            for(back=1; back<=ExtBackstep; back++)
              {
               if(val<gL[i+back]) gL[i+back]=0.0; 
              }
           } 

         if(i==shift) {gL[i]=val; gT[i]=iTime(NULL, gtf, i);}
        }

      // поиск максимумов
      if(shift<bar_h)
        {
         i=iHighest(NULL, gtf, MODE_HIGH, ExtDepth, shift);
         val=iHigh(NULL, gtf, i);

         if(val==lasthigh) val=0.0;
         else 
           {
            lasthigh=val;
            for(back=1; back<=ExtBackstep; back++)
              {
               if(val>gH[i+back]) gH[i+back]=0.0; 
              }
           }

         if(i==shift) {gH[i]=val; gT[i]=iTime(NULL, gtf, i);}
        }
     }

   // сжатие массивов
   press_arr(cL1, cH1, tL1, cLz1, cHz1, tLz1);

   // определение необходимости проверки следующего уровня на наличие нового экстремума
   if(history || gT[0]!=tL1[0] || gL[0]!=cL1[0] || gH[0]!=cH1[0]) g_addnewextremum=true;

   return (0);
  }
//+------------------------------------------------------------------+
//| Создание первичной выборки экстремумов.                          |
//| Поиск экстремумов с помощью алгоритма стандартного               |
//| для Metatrader зигзага. Без зигзаговой фильтрации.               |
//| Конец.                                                           |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Создание первичной выборки экстремумов.                          |
//| Фрактальный алгоритм. Начало.                                    |
//+------------------------------------------------------------------+
//| В данном случае ФРАКТАЛ - название условное. В Метатрейдере есть |
//| индикатор фракталов. Данный алгоритм является расширенной версией|
//| индикатора фракталов. Название прижилось. Хотя и не соответствует|
//| понятию ФРАКТАЛ.                                                 |
//+------------------------------------------------------------------+
int fractals()
  {
   int i, j, k, m, lastlowpos=0, lasthighpos=0, end, jl=0, jh=0, arr_size;
   double lastlow=iLow(NULL, gtf, 0), lasthigh=iHigh(NULL, gtf, 0);
   bool frl=true, frh=true;
   datetime timeend=0; // время окончания поиска новых фракталов

   if(history)
     {
      end=iBars(NULL, gtf);
     }
   else
     {
      // определение точки окончания поиска новых и измененных фракталов
      //---
      gtimedinamic=0;
      arr_size=ArraySize(tL1);
      for(i=0;i<arr_size-1;i++)
        {
         if(gtimedinamic==0)
           {
            if(jl>1 && jh>1)
              {
               gtimedinamic=tL1[i]; j=i;
              }
           }
         else
           {
            if(cL1[i]>0 && cH1[i]>0) continue;
            if(lastlowpos>0 && lasthighpos>0) {k=i; break;}
            if(cL1[i]>0 && lastlowpos==0) lastlowpos++;
            else if(cH1[i]>0 && lasthighpos==0) lasthighpos++;
           }
         if(cL1[i]>0) jl++;
         if(cH1[i]>0) jh++;
        }
      timeend=tL1[i];
      if(gtimedinamic==0) gtimedinamic=timeend;

      end=iBarShift(NULL, gtf, timeend, false)+1;
      //---
     }

   ArrayResize(gL, end); ArrayResize(gH, end); ArrayResize(gT, end);
   ArrayInitialize(gL, 0); ArrayInitialize(gH, 0); ArrayInitialize(gT, 0);

   m=0; 
   for(i=0; i<iBars(NULL, gtf); i++)
     {
      // поиск минимумов
      if(!frl)
        {
         if(iLow(NULL, gtf, i)<lastlow) frl=true;
         lastlowpos=i; lastlow=iLow(NULL, gtf, i);
        }
      else
        {
         if(lastlow>=iLow(NULL, gtf, i))
           {
            lastlow=iLow(NULL, gtf, i); lastlowpos=i;
           }
         else
           {
            k=ExtBarLeft;
            for(j=lastlowpos+1; (j<end-1 && k>0); j++)
              {
               if(iLow(NULL, gtf, j)<=lastlow && k>0) {frl=false; break;}
               if(iLow(NULL, gtf, j)>lastlow) k--;
              }

            if(frl)
              {
               k=ExtBarRight;
               for(j=lastlowpos-1; (j>0 && k>0); j--)
                 {
                  if(iLow(NULL, gtf, j)==lastlow) {k=ExtBarRight; continue;}
                  if(iLow(NULL, gtf, j)<lastlow && k>0) {frl=false; break;}
                  if(iLow(NULL, gtf, j)>lastlow) k--;
                 }
              }

            if(frl)
              {
               if(gT[m]>0 && gT[m]>iTime(NULL, gtf, lastlowpos)) m++;
               gL[m]=lastlow; gT[m]=iTime(NULL, gtf, lastlowpos); frl=false;
              }
            lastlowpos=i; lastlow=iLow(NULL, gtf, i);
           }
        }    

      // поиск максимумов
      if(!frh)
        {
         if(iHigh(NULL, gtf, i)>lasthigh) frh=true;
         lasthighpos=i; lasthigh=iHigh(NULL, gtf, i);
        }
       else
        {
         if(lasthigh<=iHigh(NULL, gtf, i))
           {
            lasthigh=iHigh(NULL,gtf,i); lasthighpos=i;
           }
         else
           {
            k=ExtBarLeft;
            for(j=lasthighpos+1; (j<end-1 && k>0); j++)
              {
               if(iHigh(NULL, gtf, j)>=lasthigh && k>0) {frh=false; break;}
               if(iHigh(NULL, gtf, j)<lasthigh) k--;
              }

            if(frh)
              {
               k=ExtBarRight;
               for(j=lasthighpos-1; (j>=0 && k>0); j--)
                 {
                  if(iHigh(NULL, gtf, j)==lasthigh) {k=ExtBarRight; continue;}
                  if(iHigh(NULL, gtf, j)>lasthigh && k>0) {frh=false; break;}
                  if(iHigh(NULL, gtf, j)<lasthigh) k--;
                 }
              }

            if(frh)
              {
               if(gT[m]>0 && gT[m]>iTime(NULL, gtf, lasthighpos)) m++;
               gH[m]=lasthigh; gT[m]=iTime(NULL, gtf, lasthighpos); frh=false;
              }
            lasthighpos=i; lasthigh=iHigh(NULL, gtf, i);
           }
        }

      if(!history) if(gT[m]==timeend) break;
     }    

   m++;
   ArrayResize(gL, m); ArrayResize(gH, m); ArrayResize(gT, m);

   if(history)  // только при первом проходе заполняются массивы cl-ch-t / clz-chz-tz
     {
      ArrayResize(cL1, m); ArrayResize(cH1, m); ArrayResize(tL1, m);
      ArrayCopy(cL1, gL, 0, 0, WHOLE_ARRAY); ArrayCopy(cH1, gH, 0, 0, WHOLE_ARRAY); ArrayCopy(tL1, gT, 0, 0, WHOLE_ARRAY); 
      if(filterZigZag==1)
        {
         ArrayResize(cLz1, m); ArrayResize(cHz1, m); ArrayResize(tLz1, m);
         ArrayCopy(cLz1, gL, 0, 0, WHOLE_ARRAY); ArrayCopy(cHz1, gH, 0, 0, WHOLE_ARRAY); ArrayCopy(tLz1, gT, 0, 0, WHOLE_ARRAY); 
        }
      g_addnewextremum=true;
     }
   else
     {
      // определение необходимости проверки следующего уровня на наличие нового экстремума
      if(gT[0]!=tL1[0] || gL[0]!=cL1[0] || gH[0]!=cH1[0]) g_addnewextremum=true;
     }

   return (0);
  }
//+------------------------------------------------------------------+
//| Создание первичной выборки экстремумов.                          |
//| Фрактальный алгоритм. Конец.                                     |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Создание второго и следующих уровней экстремумов.                |
//| Фрактальный алгоритм. Начало.                                    |
//+------------------------------------------------------------------+
int fractals_nextlevel(double& cl[], double& ch[], datetime& t[], double& cl_[], double& ch_[], datetime& t_[], double& clz[], double& chz[], datetime& tz[])
  {
   int i, j, k, m, lastlowpos=0, lasthighpos=0, end, jl=0, jh=0, arr_size;
   double lastlow, lasthigh;
   if(PrimarySelectionOfExtremums==1) {lastlow=iLow(NULL, gtf, 0); lasthigh=iHigh(NULL, gtf, 0);}
   else {lastlow=10000; lasthigh=0;}
   bool frl=true, frh=true, t_end=true;
   datetime timeend=t_[ArraySize(t_)-1];

   if(ArraySize(t)<3) return(-1);

   if(history)
     {
      end=ArraySize(t);
     }
   else
     {
      // определение точки окончания поиска новых и измененных фракталов
      //---
      gtimedinamic=0;
      arr_size=ArraySize(t_);
      if(arr_size==1 && t_[0]==0)
        {
         gtimedinamic=t[ArraySize(t)-1];
         timeend=gtimedinamic;
         end=ArraySize(t);
        }
      else
        {
         for(i=0;i<arr_size;i++)
           {
            if(gtimedinamic==0)
              {
               if(jl>1 && jh>1) gtimedinamic=t_[i];
              }
            else
              {
               if(cl_[i]>0 && ch_[i]>0) continue;
               if(lastlowpos>0 && lasthighpos>0) break;
               if(cl_[i]>0 && lastlowpos==0) lastlowpos++;
               else if(ch_[i]>0 && lasthighpos==0) lasthighpos++;
              }
            if(cl_[i]>0) jl++;
            if(ch_[i]>0) jh++;
           }
         if(i<arr_size)
           {
            timeend=t_[i];
            for(i=0; i<ArraySize(t)-1; i++) if(t[i]==timeend) break;
            if(i==0) end=1; else end=i;
           }
         else
           {
            timeend=t[ArraySize(t)-1];
            end=ArraySize(t)-1;
           }
         if(gtimedinamic==0) gtimedinamic=timeend;
        }
      }

   ArrayResize(gL, end); ArrayResize(gH, end); ArrayResize(gT, end);
   ArrayInitialize(gL, 0); ArrayInitialize(gH, 0); ArrayInitialize(gT, 0);

   lastlowpos=0; lasthighpos=0;
   m=0; 
   for(i=0; i<ArraySize(t); i++)
     {
      // поиск минимумов
      if(cl[i]>0)
        {
         if(!frl)
           {
            if(cl[i]<lastlow) frl=true;
            lastlowpos=i; lastlow=cl[i];
           }
         else
           {
            if(lastlow>=cl[i])
              {
               lastlow=cl[i]; lastlowpos=i;
              }
            else
              {
               k=ExtBarLeft;
               for(j=lastlowpos+1;(j<ArraySize(cl) && k>0);j++)
                 {
                  if(cl[j]>0)
                    {
                     if(cl[j]<=lastlow && k>0) {frl=false; break;}
                     if(cl[j]>lastlow) k--;
                    }
                 }

               if(frl)
                 {
                  k=ExtBarRight;
                  for(j=lastlowpos-1; (j>=0 && k>0); j--)
                    {
                     if(cl[j]>0)
                       {
                        if(cl[j]==lastlow) {k=ExtBarRight; continue;}
                        if(cl[j]<lastlow && k>0) {frl=false; break;}
                        if(cl[j]>lastlow) k--;
                       }
                    }
                 }

               if(frl)
                 {
                  if(gT[m]>0 && gT[m]>t[lastlowpos])
                    {
                     m++;
                     if(ArraySize(gT)==m) {ArrayResize(gL,m+1); ArrayResize(gH,m+1); ArrayResize(gT,m+1);}
                     gL[m]=lastlow; gT[m]=t[lastlowpos]; frl=false;
                    }
                  else if(gT[m]>0 && gT[m]<t[lastlowpos])
                    {
                     if(ArraySize(gT)==m+1) {ArrayResize(gL,m+1); ArrayResize(gH,m+1); ArrayResize(gT,m+1);}
                     gT[m+1]=gT[m]; gL[m+1]=gL[m]; gH[m+1]=gH[m]; gH[m]=0;
                     gL[m]=lastlow; gT[m]=t[lastlowpos]; frl=false;
                     m++;
                    }
                  else
                    {
                     gL[m]=lastlow; gT[m]=t[lastlowpos]; frl=false;
                    }
                 }
               lastlowpos=i; lastlow=cl[i];
              }
           }
        }

      // поиск максимумов
      if(ch[i]>0)
        {
         if(!frh)
           {
            if(ch[i]>lasthigh) frh=true;
            lasthighpos=i; lasthigh=ch[i];
           }
          else
           {
            if(lasthigh<=ch[i])
              {
               lasthigh=ch[i]; lasthighpos=i;
              }
            else
              {
               k=ExtBarLeft;
               for(j=lasthighpos+1;(j<ArraySize(ch) && k>0);j++)
                 {
                  if(ch[j]>0)
                    {
                     if(ch[j]>=lasthigh && k>0) {frh=false; break;}
                     if(ch[j]<lasthigh) k--;
                    }
                 }

               if(frh)
                 {
                  k=ExtBarRight;
                  for(j=lasthighpos-1; (j>=0 && k>0); j--)
                    {
                     if(ch[j]>0)
                       {
                        if(ch[j]==lasthigh) {k=ExtBarRight; continue;}
                        if(ch[j]>lasthigh && k>0) {frh=false; break;}
                        if(ch[j]<lasthigh) k--;
                       }
                    }
                 }

               if(frh)
                 {
                  if(gT[m]>0 && gT[m]>t[lasthighpos])
                    {
                     m++;
                     if(ArraySize(gT)==m) {ArrayResize(gL,m+1); ArrayResize(gH,m+1); ArrayResize(gT,m+1);}
                     gH[m]=lasthigh; gT[m]=t[lasthighpos]; frh=false;
                    }
                  else if(gT[m]>0 && gT[m]<t[lasthighpos])
                    {
                     if(ArraySize(gT)==m+1) {ArrayResize(gL,m+1); ArrayResize(gH,m+1); ArrayResize(gT,m+1);}
                     gT[m+1]=gT[m]; gL[m+1]=gL[m]; gH[m+1]=gH[m]; gL[m]=0;
                     gH[m]=lasthigh; gT[m]=t[lasthighpos]; frh=false;
                     m++;
                    }
                  else
                    {
                     gH[m]=lasthigh; gT[m]=t[lasthighpos]; frh=false;
                    }
                 }
               lasthighpos=i; lasthigh=ch[i];
              }
           }
        }
      if(!history) if(gT[m]>0 && gT[m]<=timeend) break;
     }    

   m++;

   ArrayResize(gL, m); ArrayResize(gH, m); ArrayResize(gT, m);
   
   if(history)  // только при первом проходе заполняются массивы cl-ch-t / clz-chz-tz
     {
      ArrayResize(cl_, m); ArrayResize(ch_, m); ArrayResize(t_, m);
      ArrayCopy(cl_, gL, 0, 0, WHOLE_ARRAY); ArrayCopy(ch_, gH, 0, 0, WHOLE_ARRAY); ArrayCopy(t_, gT, 0, 0, WHOLE_ARRAY); 
      if(filterZigZag==1)
        {
         ArrayResize(clz, m); ArrayResize(chz, m); ArrayResize(tz, m);
         ArrayCopy(clz, gL, 0, 0, WHOLE_ARRAY); ArrayCopy(chz, gH, 0, 0, WHOLE_ARRAY); ArrayCopy(tz, gT, 0, 0, WHOLE_ARRAY); 
        }
      g_addnewextremum=true;
     }
   else
     {
      // определение необходимости проверки следующего уровня на наличие нового экстремума
      if(gT[0]!=t_[0] || gL[0]!=cl_[0] || gH[0]!=ch_[0]) g_addnewextremum=true;
     }

   if(history)
     {
      if(filterZigZag==0) ZigZag(cl_, ch_, t_);// Print("7  gbar = ",gbar);
      else if(filterZigZag==1) ZigZag(clz, chz, tz);
     }
   else
     {
      if(filterZigZag==0) ZigZag(gL, gH, gT);
     }

   if(history && t[0]>0 && Statistica>0) Statistika(cl, ch, t, cl_, ch_, t_);   // вывод статистики

   return (0);
  }
//+------------------------------------------------------------------+
//| Создание второго и следующих уровней экстремумов.                |
//| Фрактальный алгоритм. Конец.                                     |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Заполнение и сжатие массивов. Начало.                            |
//+------------------------------------------------------------------+
int press_arr(double& cl[], double& ch[], datetime& t[], double& clz[], double& chz[], datetime& tz[])
  {
   int i, j, k;

   k=ArraySize(gT);

   if(history)
     {
      ArrayResize(cl,k); ArrayResize(ch,k); ArrayResize(t,k);
      if(filterZigZag==1)
        {
         ArrayResize(clz,k); ArrayResize(chz,k); ArrayResize(tz,k);
        }
     }
   // Сжатие массивов
   //---
   j=0;
   for(i=0;i<k;i++)
     {
      if(gL[i]>0 || gH[i]>0)
        {
         if(history)  // только при первом проходе заполняются массивы cl-ch-t / clz-chz-tz
           {
            cl[j]=gL[i]; ch[j]=gH[i]; t[j]=gT[i];
            if(filterZigZag==1)
              {
               clz[j]=gL[i]; chz[j]=gH[i]; tz[j]=gT[i];
              }
           }

         gL[j]=gL[i]; gH[j]=gH[i]; gT[j]=gT[i];
         j++;
        }
     }
   ArrayResize(gL,j); ArrayResize(gH,j); ArrayResize(gT,j);
   if(history)
     {
      ArrayResize(cl,j); ArrayResize(ch,j); ArrayResize(t,j);
      if(filterZigZag==1)
        {
         ArrayResize(clz,j); ArrayResize(chz,j); ArrayResize(tz,j);
        }
     }
   //---

   return(0);
  }
//+------------------------------------------------------------------+
//| Заполнение и сжатие массивов. Конец.                             |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Создание первичной выборки экстремумов. Начало.                  |
//| Трендовый алгоритм (Dow). Начало.                                |
//+------------------------------------------------------------------+
int zigzag_Dow()
  {
   int i, hi, li, hl, end, n;
   double lastlow=0, lasthigh=0;
   
   hl=gsave_hl[0];
   if(history)  // полный пересчет
     {
      gbar=iBars(NULL, gtf);
      end=gbar;
      li=gbar-1; hi=gbar-1;
      lastlow=iLow(NULL, gtf, li); lasthigh=iHigh(NULL, gtf, hi);
      ArrayResize(gL,end); ArrayResize(gH,end); ArrayResize(gT,end);
      ArrayInitialize(gL,0); ArrayInitialize(gH,0); ArrayInitialize(gT,0);
     }
   else  // расчет последних баров, не расчитанных на предыдущем цикле (обработка нулевого бара)
     {
      gbar=iBarShift(NULL, gtf, gtime_gbar[glevel], false);
      hi=iBarShift(NULL, gtf, gt_hi[0], true);
      li=iBarShift(NULL, gtf, gt_li[0], true);
      if(hi<0 || li<0) {gcurrentBars=0; return(-1);}
      if(hi<li) n=li; else n=hi;
      gtimedinamic=iTime(NULL, gtf, n);
      n++;
      ArrayResize(gL,n); ArrayResize(gH,n); ArrayResize(gT,n);
      ArrayInitialize(gL,0); ArrayInitialize(gH,0); ArrayInitialize(gT,0);

      gL[li]=iLow(NULL, gtf, li);  gT[li]=iTime(NULL, gtf, li);  // gT[n-1]=iTime(NULL, gtf, n-1);
      gH[hi]=iHigh(NULL, gtf, hi); gT[hi]=iTime(NULL, gtf, hi);
      lastlow=gsave_lastlow[0]; lasthigh=gsave_lasthigh[0];
     }
   
   end=1;
   for(i=gbar-1;i>=end;i--)
     {
      if(i==0) break;
      if(hl==0)                                                               // начальное определение направление тренда
        {
         if(lastlow>iLow(NULL, gtf, i) && lasthigh>=iHigh(NULL, gtf, i))           // тренд Down
           {
            hl=dn; li=i; //li=searchbarcur(Period(), dn, lastlow, lasthigh, tLast); 
            lastlow=iLow(NULL, gtf, i); 
            gH[hi]=lasthigh; gT[hi]=iTime(NULL, gtf, hi);
            gL[li]=lastlow; gT[li]=iTime(NULL, gtf, li);
            lasthigh=iHigh(NULL, gtf, i);
           }
         else if(lastlow<=iLow(NULL, gtf, i) && lasthigh<iHigh(NULL, gtf, i))      // тренд Up
           {
            hl=up; hi=i; //hi=searchbarcur(Period(), up, lastlow, lasthigh, tLast); 
            lasthigh=iHigh(NULL, gtf, i); 
            gL[li]=lastlow; gT[li]=iTime(NULL, gtf, li);
            gH[hi]=lasthigh; gT[hi]=iTime(NULL, gtf, hi);
            lastlow=iLow(NULL, gtf, i);
           }
         else
           {
            if(lastlow>iLow(NULL, gtf, i) && lasthigh<iHigh(NULL, gtf, i)) {li=i; hi=i;}
            lastlow=iLow(NULL, gtf, i); lasthigh=iHigh(NULL, gtf, i);
           }
        }
      else
        {
         if(lastlow==iLow(NULL, gtf, i) && lasthigh==iHigh(NULL, gtf, i)) continue; // 

         if(lastlow>iLow(NULL, gtf, i) && lasthigh<iHigh(NULL, gtf, i))            // на внешнем баре продолжение предыдущего тренда
           {
            if(hl==dn)
              {
               gL[li]=0;
               lastlow=iLow(NULL, gtf, i); //lasthigh=iHigh(NULL, gtf, i); tLast=iTime(NULL, gtf, i);
               li=i; //li=searchbarcur(Period(), dn, lastlow, lasthigh, tLast); 
               gL[li]=lastlow; gT[li]=iTime(NULL, gtf, li);
              }
            else
              {
               gH[hi]=0;
               lasthigh=iHigh(NULL, gtf, i); //lastlow=iLow(NULL, gtf, i); tLast=iTime(NULL, gtf, i);
               hl=up; hi=i; //hi=searchbarcur(Period(), up, lastlow, lasthigh, tLast); 
               gH[hi]=lasthigh; gT[hi]=iTime(NULL, gtf, hi);
              }
            continue;
           }

         if(hl==dn)
           {
            if(lasthigh>iHigh(NULL, gtf, i) || (lasthigh==iHigh(NULL, gtf, i) && lastlow>iLow(NULL, gtf, i)))    // продолжение тренда
              {
               gL[li]=0;
               lastlow=iLow(NULL, gtf, i); lasthigh=iHigh(NULL, gtf, i);
               li=i;
               gL[li]=lastlow; gT[li]=iTime(NULL, gtf, li);
              }
            else                                                              // разворот
              {
               lastlow=iLow(NULL, gtf, i); lasthigh=iHigh(NULL, gtf, i);
               hl=up; hi=i;
               gH[hi]=lasthigh; gT[hi]=iTime(NULL, gtf, hi);
              }
           }
         else
           {
            if(lastlow<iLow(NULL, gtf, i) || (lastlow==iLow(NULL, gtf, i) && lasthigh<iHigh(NULL, gtf, i)))       // продолжение тренда
              {
               gH[hi]=0;
               lastlow=iLow(NULL, gtf, i); lasthigh=iHigh(NULL, gtf, i);
               hi=i;
               gH[hi]=lasthigh; gT[hi]=iTime(NULL, gtf, hi);
              }
            else                                                              // разворот
              {
               lastlow=iLow(NULL, gtf, i); lasthigh=iHigh(NULL, gtf, i);
               hl=dn; li=i;
               gL[li]=lastlow; gT[li]=iTime(NULL, gtf, li);
              }
           }
        }
     }

   press_arr(cL1, cH1, tL1, cLz1, cHz1, tLz1);

   // сохраняем переменные
   gsave_hl[0]=hl;
   gt_hi[0]=iTime(NULL, gtf, hi); gt_li[0]=iTime(NULL, gtf, li);
   gsave_lastlow[0]=lastlow; gsave_lasthigh[0]=lasthigh;
   gtime_gbar[0]=iTime(NULL, gtf, 1);
   if(history)  // только при первом проходе заполняются массивы cl-ch-t / clz-chz-tz
     {
      g_addnewextremum=true;
     }
   else
     {

      if(gT[0]>0 && gT[0]<tL1[0])
        {
         gcurrentBars=0; gRecalculation++; return(-1);
        }

      // определение необходимости проверки следующего уровня на наличие нового экстремума
      if(gT[0]!=tL1[0] || gL[0]!=cL1[0] || gH[0]!=cH1[0]) g_addnewextremum=true;
     }

   return (0);
  }
//+------------------------------------------------------------------+
//| Создание первичной выборки экстремумов.                          |
//| Трендовый алгоритм. (Dow) Конец.                                 |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Создание второго и следующих уровней экстремумов.                |
//| Трендовый алгоритм (Dow). Начало.                                |
//+------------------------------------------------------------------+
int zigzag_Dow_nextlevel(double& cl[], double& ch[], datetime& t[], double& cl_[], double& ch_[], datetime& t_[])
  {
   int i, hi, li, hl=0, hi_, li_, j, k, end;
   double lastlow=1000000, lastlow_=1000000, lasthigh=0, lasthigh_=0;

   int hl_wr[]={0,0};
   datetime thi_wr[]={0,0}, tli_wr[]={0,0}, tend_wr[]={0,0};
   double lastlow_wr[]={0,0}, lastlow__wr[]={0,0}, lasthigh_wr[]={0,0}, lasthigh__wr[]={0,0};

   if(ArraySize(gT)==0 || ArraySize(t)<3) {g_addnewextremum=false; return(-1);}
   if(history || ArraySize(t_)<5)
     {
      end=ArraySize(t);
      ArrayResize(gL, end); ArrayResize(gH, end); ArrayResize(gT, end);
      ArrayInitialize(gL, 0); ArrayInitialize(gH, 0); ArrayInitialize(gT, 0);
      end--;
     }
   else
     {
      hl_wr[0]=gsave_hl[glevel]; thi_wr[0]=gt_hi[glevel]; tli_wr[0]=gt_li[glevel]; tend_wr[0]=gt_end[glevel];
      lastlow_wr[0]=gsave_lastlow[glevel]; lastlow__wr[0]=gsave_lastlow_[glevel]; 
      lasthigh_wr[0]=gsave_lasthigh[glevel]; lasthigh__wr[0]=gsave_lasthigh_[glevel];
      // восстанавливаем переменные
      hl=gsave_hl[glevel];
      lastlow=gsave_lastlow[glevel]; lasthigh=gsave_lasthigh[glevel];
      lastlow_=gsave_lastlow_[glevel]; lasthigh_=gsave_lasthigh_[glevel];
      for(i=0;i<ArraySize(t);i++) {if(t[i]==gt_hi[glevel]) {hi=i; break;}}
      for(i=0;i<ArraySize(t);i++) {if(t[i]==gt_li[glevel]) {li=i; break;}}
      for(i=0;i<ArraySize(t);i++) {if(t[i]==gt_end[glevel]) {end=i; break;}}
      for(j=0;j<ArraySize(t_);j++) {if(t_[j]<gt_end[glevel]) break;}
      gtimedinamic=t_[j];
      for(i=0;i<ArraySize(t);i++) {if(t[i]==t_[j]) break;}
      ArrayResize(gL, i+1); ArrayResize(gH, i+1); ArrayResize(gT, i+1);
      ArrayInitialize(gL, 0); ArrayInitialize(gH, 0); ArrayInitialize(gT, 0);
      gT[i]=t[i]; gL[i]=cl[i]; gH[i]=ch[i];

      end--;
     }

   j=0;
   for(i=end; i>=0; i--)
     {
      if(hl==0)   // определение направления тренда
        {
         if(cl[i]>0) // выявляем минимум
           {
            if(lastlow_>cl[i]) {lastlow_=cl[i]; li_=i;}

            if(li>0 && hi>0)   // определение направления тренда
              {
               if(lastlow<=lastlow_ &&((li>li_ && hi!=li) || lasthigh<lasthigh_)) {hl=up; gL[li]=cl[li]; gT[li]=t[li]; lasthigh=lasthigh_; lasthigh_=0; hi=hi_; continue;}
               if(((li>li_ && hi!=li) || lastlow>lastlow_) && lasthigh>=lasthigh_) {hl=dn; gH[hi]=ch[hi]; gT[hi]=t[hi]; lasthigh=lasthigh_; lasthigh_=0; hi=hi_; continue;}
              }

            lasthigh=lasthigh_; lasthigh_=0; hi=hi_;
           }

         if(ch[i]>0) // выявляем максимум
           {
            if(lasthigh_<ch[i]) {lasthigh_=cl[i]; hi_=i;}

            if(li>0 && hi>0)   // определение направления тренда
              {
               if(lastlow<=lastlow_ &&((li>li_ && hi!=li) || lasthigh<lasthigh_)) {hl=up; gL[li]=cl[li]; gT[li]=t[li]; lastlow=lastlow_; lastlow_=1000000; li=li_; continue;}
               if(((li>li_ && hi!=li) || lastlow>lastlow_) && lasthigh>=lasthigh_) {hl=dn; gH[hi]=ch[hi]; gT[hi]=t[hi]; lastlow=lastlow_; lastlow_=1000000; li=li_; continue;}
              }

            lastlow=lastlow_; lastlow_=1000000; li=li_;
           }
        }
      else
        {
         if(hl==dn)
           {
            if(ch[i]>0)
              {
               if(ch[i]>lasthigh_) {lasthigh_=ch[i]; hi=i;}
               lastlow=lastlow_; lastlow_=1000000;
               if(lasthigh<lasthigh_)                          // разворот
                 {
                  hl=up; gL[li]=cl[li]; gT[li]=t[li];
                  // сохраняем переменные
                  hl_wr[1]=hl_wr[0]; thi_wr[1]=thi_wr[0]; tli_wr[1]=tli_wr[0]; tend_wr[1]=tend_wr[0]; 
                  lastlow_wr[1]=lastlow_wr[0]; lastlow__wr[1]=lastlow__wr[0]; lasthigh_wr[1]=lasthigh_wr[0]; lasthigh__wr[1]=lasthigh__wr[0];
                  hl_wr[0]=hl; thi_wr[0]=t[hi]; tli_wr[0]=t[li]; tend_wr[0]=t[i];
                  lastlow_wr[0]=lastlow; lastlow__wr[0]=lastlow_; lasthigh_wr[0]=lasthigh; lasthigh__wr[0]=lasthigh_;
                  continue;
                 }
              }

            if(cl[i]>0)
              {
               if(lasthigh==lasthigh_)
                 {
                  if(cl[i]<lastlow_) {lastlow_=cl[i]; if(lastlow>lastlow_) li=i;}
                 }
               else if(lasthigh>lasthigh_)
                 {
                  if(cl[i]<lastlow_) {lastlow_=cl[i]; li=i;}
                 }
               lasthigh=lasthigh_; lasthigh_=0;
              }
           }
         else
           {
            if(cl[i]>0)
              {
               if(cl[i]<lastlow_) {lastlow_=cl[i]; li=i;}
               lasthigh=lasthigh_; lasthigh_=0;
               if(lastlow>lastlow_)                          // разворот
                 {
                  hl=dn; gH[hi]=ch[hi]; gT[hi]=t[hi];
                  // сохраняем переменные
                  hl_wr[1]=hl_wr[0]; thi_wr[1]=thi_wr[0]; tli_wr[1]=tli_wr[0]; tend_wr[1]=tend_wr[0]; 
                  lastlow_wr[1]=lastlow_wr[0]; lastlow__wr[1]=lastlow__wr[0]; lasthigh_wr[1]=lasthigh_wr[0]; lasthigh__wr[1]=lasthigh__wr[0];
                  hl_wr[0]=hl; thi_wr[0]=t[hi]; tli_wr[0]=t[li]; tend_wr[0]=t[i];
                  lastlow_wr[0]=lastlow; lastlow__wr[0]=lastlow_; lasthigh_wr[0]=lasthigh; lasthigh__wr[0]=lasthigh_;
                  continue;
                 }
              }

            if(ch[i]>0)
              {
               if(lastlow==lastlow_)
                 {
                  if(ch[i]>lasthigh_) {lasthigh_=ch[i]; if(lasthigh<lasthigh_) hi=i;}
                 }
               else if(lastlow<lastlow_)
                 {
                  if(ch[i]>lasthigh_) {lasthigh_=ch[i]; hi=i;}
                 }
               lastlow=lastlow_; lastlow_=1000000;
              }
           }
        }
     }

   if(hl==dn) {gL[li]=cl[li]; gT[li]=t[li];}
   else if(hl==up) {gH[hi]=ch[hi]; gT[hi]=t[hi];}

   k=ArraySize(gT);

   if(history)
     {
      ArrayResize(cl_,k); ArrayResize(ch_,k); ArrayResize(t_,k);
     }
   // Сжатие массивов
   //---
   j=0;
   for(i=0;i<k;i++)
     {
      if(gL[i]>0 || gH[i]>0)
        {
         if(history)  // только при первом проходе заполняются массивы cl_-ch_-t_
           {
            cl_[j]=gL[i]; ch_[j]=gH[i]; t_[j]=gT[i];
           }

         gL[j]=gL[i]; gH[j]=gH[i]; gT[j]=gT[i];
         j++;
        }
     }
   if(j<2) j=1;
   ArrayResize(gL,j); ArrayResize(gH,j); ArrayResize(gT,j);
   if(j<2) {ArrayInitialize(gL, 0); ArrayInitialize(gH, 0); ArrayInitialize(gT, 0);}
   if(history)
     {
      ArrayResize(cl_,j); ArrayResize(ch_,j); ArrayResize(t_,j);
     }

   if(history && t[0]>0 && Statistica>0) Statistika(cl, ch, t, cl_, ch_, t_);   // вывод статистики

   if(ArraySize(gT)>1)
     {
      if(history)
        {
         g_addnewextremum=true;
        }
      else
        {
         if(gT[0]>0 && gT[0]<t_[0] && ArraySize(t_)>4)
           {
            gcurrentBars=0; gRecalculation++; return(-1);
           }
         // определение необходимости проверки следующего уровня на наличие нового экстремума
         if(gT[0]!=t_[0] || gL[0]!=cl_[0] || gH[0]!=ch_[0]) g_addnewextremum=true;
        }
     }

   if(hl_wr[1]!=0)
     {
      gsave_hl[glevel]=hl_wr[1]; gt_hi[glevel]=thi_wr[1]; gt_li[glevel]=tli_wr[1]; gt_end[glevel]=tend_wr[1];
      gsave_lastlow[glevel]=lastlow_wr[1]; gsave_lasthigh[glevel]=lasthigh_wr[1];
      gsave_lastlow_[glevel]=lastlow__wr[1]; gsave_lasthigh_[glevel]=lasthigh__wr[1];
     }

   return (0);
  }
//+------------------------------------------------------------------+
//| Создание второго и следующих уровней экстремумов.                |
//| Трендовый алгоритм. (Dow) Конец.                                 |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Зигзаговый фильтр. Weeding. Начало.                              |
//+------------------------------------------------------------------+
int ZigZag(double& LB[], double& HB[], datetime& TB[])
  {
   int i, j, shift, lastlowpos=0, lasthighpos=0, limit, arr_size=ArraySize(TB);
   double lastlow=-1, lasthigh=-1, curlow=0, curhigh=0;
   datetime t_limit;
   int jl=0,jh=0;

   if(ArraySize(TB)<2) return(-1);

   if(history)
     {
      limit=arr_size-1;
     }
   else
     {
      if(gL2LTime[glevel]<=gL2HTime[glevel]) t_limit=gL2LTime[glevel]; else t_limit=gL2HTime[glevel];
      for(i=0;i<arr_size-1;i++) if(TB[i]==t_limit) break;
      limit=i;
     }

   limit=arr_size-1;

   for(shift=limit; shift>=0; shift--)
     {
      curlow=LB[shift];
      curhigh=HB[shift];

      if(curlow==0 && curhigh==0) continue;

      if(curhigh!=0)
        {
         if(lasthigh>0) 
           {
            if(lasthigh<curhigh) HB[lasthighpos]=0;
            else HB[shift]=0;
           }

         if(lasthigh<curhigh || lasthigh<0)
           {
            lasthigh=curhigh;
            lasthighpos=shift;
           }
         lastlow=-1;
        }

      if(curlow!=0)
        {
         if(lastlow>0)
           {
            if(lastlow>curlow) LB[lastlowpos]=0;
            else LB[shift]=0;
           }

         if(curlow<lastlow || lastlow<0)
           {
            lastlow=curlow;
            lastlowpos=shift;
           } 
         lasthigh=-1;
        }
     } 

   // Сжатие массивов
   j=0;
   for(i=0;i<arr_size;i++)
     {
      if(LB[i]>0 || HB[i]>0)
        {
         LB[j]=LB[i]; HB[j]=HB[i]; TB[j]=TB[i]; j++;
        }
     }
   ArrayResize(LB,j); ArrayResize(HB,j); ArrayResize(TB,j);

   if(filterZigZag<2)
     {
      if(!history) time_zigzag(LB, HB, TB);
     }

   return (0);
  }
//+------------------------------------------------------------------+
//| Зигзаговый фильтр. Weeding. Конец.                               |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Подбор массивов.                                                 |
//| Определение необходимости поиска новых экстремумов следующих     |
//| уровней. Начало.                                                 |
//+------------------------------------------------------------------+
void time_zigzag(double& LB[], double& HB[], datetime& TB[])
  {
   switch(glevel)
     {
      case 0: time_zigzag1(LB,  HB,  TB,  cL1,   cH1,  tL1,  cLz1,  cHz1,  tLz1);  break; // создание 1-го  уровня
      case 1: time_zigzag1(LB,  HB,  TB,  cL2,   cH2,  tL2,  cLz2,  cHz2,  tLz2);  break; // создание 2-го  уровня
      case 2: time_zigzag1(LB,  HB,  TB,  cL3,   cH3,  tL3,  cLz3,  cHz3,  tLz3);  break; // создание 3-го  уровня
      case 3: time_zigzag1(LB,  HB,  TB,  cL4,   cH4,  tL4,  cLz4,  cHz4,  tLz4);  break; // создание 4-го  уровня
      case 4: time_zigzag1(LB,  HB,  TB,  cL5,   cH5,  tL5,  cLz5,  cHz5,  tLz5);  break; // создание 5-го  уровня
      case 5: time_zigzag1(LB,  HB,  TB,  cL6,   cH6,  tL6,  cLz6,  cHz6,  tLz6);  break; // создание 6-го  уровня
      case 6: time_zigzag1(LB,  HB,  TB,  cL7,   cH7,  tL7,  cLz7,  cHz7,  tLz7);  break; // создание 7-го  уровня
      case 7: time_zigzag1(LB,  HB,  TB,  cL8,   cH8,  tL8,  cLz8,  cHz8,  tLz8);  break; // создание 8-го  уровня
      case 8: time_zigzag1(LB,  HB,  TB,  cL9,   cH9,  tL9,  cLz9,  cHz9,  tLz9);  break; // создание 9-го  уровня
      case 9: time_zigzag1(LB,  HB,  TB,  cLz10, cH10, tL10, cLz10, cHz10, tLz10); break; // создание 10-го уровня
      case 10:time_zigzag1(LB,  HB,  TB,  cLz11, cH11, tL11, cLz11, cHz11, tLz11);        // создание 11-го уровня
     }
   return;
  }
//+------------------------------------------------------------------+
//| Подбор массивов.                                                 |
//| Определение необходимости поиска новых экстремумов следующих     |
//| уровней. Конец.                                                  |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Определение необходимости поиска новых экстремумов следующих     |
//| уровней. Начало.                                                 |
//+------------------------------------------------------------------+
void time_zigzag1(double& LB[], double& HB[], datetime& TB[],double& cl_[], double& ch_[], datetime& t_[], double& clz[], double& chz[], datetime& tz[])
  {
   if(filterZigZag==0)
     {
      if(ArraySize(TB)>1 && ArraySize(t_)>1)
        {
         if(LB[0]!=cl_[0] || HB[0]!=ch_[0] || TB[0]!=t_[0] || LB[1]!=cl_[1] || HB[1]!=ch_[1] || TB[1]!=t_[1]) g_addnewextremum=true;
         else g_addnewextremum=false;
        }
      else
        {
         if(LB[0]!=cl_[0] || HB[0]!=ch_[0] || TB[0]!=t_[0]) g_addnewextremum=true;
         else g_addnewextremum=false;
        }
     }

   return;
  }
//+------------------------------------------------------------------+
//| Определение необходимости поиска новых экстремумов следующих     |
//| уровней. Конец.                                                  |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Создание первичной выборки экстремумов.                          |
//| Свинги Ганна. Начало.                                            |
//+------------------------------------------------------------------+
void swing()
  {
   int i, j, k, save1_hi, save1_li, end;
   string nameObj;
   datetime t;
   datetime tLast;
   int hi, li, hl=0;
   double lastlow=0, lasthigh=0; 

/*
tLast - время бара таймфрейма, с которого берутся данные для построения зигзага, на котором (баре) найден последний(ие) экстремум(ы)
*/
   if(history)  // полный пересчет
     {
      gbar=iBars(NULL, gtf);
      end=gbar+1;
      gbar--;
      lastlow=iLow(NULL, gtf, gbar); lasthigh=iHigh(NULL, gtf, gbar); tLast=iTime(NULL, gtf, gbar);
      hi=gbar; li=gbar;
      ArrayResize(gL, end); ArrayResize(gH, end); ArrayResize(gT, end);
      ArrayInitialize(gL,0); ArrayInitialize(gH,0); ArrayInitialize(gT,0);
     }
   else  // расчет последних баров, не расчитанных на предыдущем цикле (обработка нулевого бара)
     {
      gtimedinamic=tL1[2];
      end=iBarShift(NULL, gtf, tL1[2], false)+1;
      ArrayResize(gL, end); ArrayResize(gH, end); ArrayResize(gT, end);
      ArrayInitialize(gL,0); ArrayInitialize(gH,0); ArrayInitialize(gT,0);

      gbar=iBarShift(NULL, gtf, gtime_gbar[0], false);
      lastlow=gsave_lastlow[0]; lasthigh=gsave_lasthigh[0]; tLast=gsave_tLast[0];
      hi=iBarShift(NULL, gtf, gt_hi[0], false); li=iBarShift(NULL, gtf, gt_li[0], true);
      hl=gsave_hl[0];

      j=2;
      for(i=end-1;i>=0;i--)
        {
         if(tL1[j]==iTime(NULL, gtf, i)) {gT[i]=tL1[j]; gL[i]=cL1[j]; gH[i]=cH1[j]; j--;}
         if(j<0) break;
        }
     }

//---
   for(i=gbar;i>=0;i--)
     {
      if (i==1)
        {
         // сохраняем переменные для рассчета в "прямом эфире"
         gsave_lastlow[0]=lastlow; gsave_lasthigh[0]=lasthigh; gsave_tLast[0]=tLast;
         gt_hi[0]=iTime(NULL, gtf, hi); gt_li[0]=iTime(NULL, gtf, li);
         gsave_hl[0]=hl;
         gtime_gbar[0]=iTime(NULL, gtf, i);
        }


      if(lastlow>iLow(NULL, gtf, i) && lasthigh>=iHigh(NULL, gtf, i))              // тренд Down
        {
         if(hl==0) {gH[hi]=lasthigh; gT[hi]=iTime(NULL, gtf, hi);}
         
         if(hl==dn) gL[li]=0; 
         lastlow=iLow(NULL, gtf, i); lasthigh=iHigh(NULL, gtf, i); tLast=iTime(NULL, gtf, i);
         hl=dn; li=searchbarcur(Period(), dn, lastlow, lasthigh, tLast); 
         gL[li]=lastlow; gT[li]=iTime(NULL, gtf, li);
        }
      else if(lastlow<=iLow(NULL, gtf, i) && lasthigh<iHigh(NULL, gtf, i))         // тренд Up
        {
         if(hl==0) {gL[li]=lastlow; gT[li]=iTime(NULL, gtf, li);}
         
         if(hl==up) gH[hi]=0; 
         lastlow=iLow(NULL, gtf, i); lasthigh=iHigh(NULL, gtf, i); tLast=iTime(NULL, gtf, i);
         hl=up; hi=searchbarcur(Period(), up, lastlow, lasthigh, tLast); 
         gH[hi]=lasthigh; gT[hi]=iTime(NULL, gtf, hi);
        }
      else if(lastlow<=iLow(NULL, gtf, i) && lasthigh>=iHigh(NULL, gtf, i) && i>0) // обработка внутреннего бара. На нулевом баре внутренний бар не расчитывается.
        {
         if(_PrimarySelectionOfExtremums==3)                                       // дополнение к свингам Ганна от matrica
           {
            if(hl==0) continue;

            //---
            // определяем, что было раньше на предыдущем баре - минимум или максимум
            if(Period()<gtf) k=_tf(Period(), true); else k=_tf(Period()-1, true);
            for(j=k;j>=0;j--)
              {
               hi=searchbarcur(_tf(j, false), up, lastlow, lasthigh, tLast); 
               li=searchbarcur(_tf(j, false), dn, lastlow, lasthigh, tLast);
               if(hi!=li)
                 {
                  // корректируем прорисовку на предыдущем баре
                  if(hl==dn && hi<li) {hl=up; hi=searchbarcur(Period(), up, lastlow, lasthigh, tLast); gH[hi]=lasthigh; gT[hi]=iTime(NULL, gtf, hi);}
                  if(hl==up && hi>li) {hl=dn; li=searchbarcur(Period(), dn, lastlow, lasthigh, tLast); gL[li]=lastlow; gT[li]=iTime(NULL, gtf, li);}
                  break;
                 }
              }
            //---

            tLast=iTime(NULL, gtf, i); lastlow=iLow(NULL, gtf, i); lasthigh=iHigh(NULL, gtf, i);
            if(hl==dn) {hl=up; hi=searchbarcur(Period(), up, lastlow, lasthigh, tLast); gH[hi]=lasthigh; gT[hi]=iTime(NULL, gtf, hi);} // li=0;
            else if(hl==up) {hl=dn; li=searchbarcur(Period(), dn, lastlow, lasthigh, tLast); gL[li]=lastlow; gT[li]=iTime(NULL, gtf, li);}
           }
        }
      else if(lastlow>iLow(NULL, gtf, i) && lasthigh<iHigh(NULL, gtf, i))          // обработка внешнего бара (текущего)
        {
         if(hl==0)
           {
            lastlow=iLow(NULL, gtf, i); lasthigh=iHigh(NULL, gtf, i); tLast=iTime(NULL, gtf, i);
            hi=i; li=i;
            continue;
           }

         if(i==0)
           {
            nameObj="_"+ExtComplekt+"_TheExternalBar_on_"+gtf;
            t=iTime(NULL, gtf, 0);
            if(ObjectFind(nameObj)==0) ObjectDelete (nameObj);
            ObjectCreate(nameObj,OBJ_ARROW,0,t,iHigh(NULL, gtf, iBarShift(NULL, 0, t, false))+Point*3);
            ObjectSet(nameObj, OBJPROP_ARROWCODE, SYMBOL_STOPSIGN) ;
            ObjectSet(nameObj, OBJPROP_COLOR, Yellow) ;
            gTheExternalBar=true;
           }

         save1_hi=hi; save1_li=li;
         lastlow=iLow(NULL, gtf, i); lasthigh=iHigh(NULL, gtf, i); tLast=iTime(NULL, gtf, i);
         //---
         // Определяем направление луча на внешнем баре. Начало.
         // определяем, что было раньше - минимум или максимум внешнего бара
         if(Period()<gtf) k=_tf(Period(), true); else k=_tf(Period()-1, true);
         for(j=k;j>=0;j--)
           {
            hi=searchbarcur(_tf(j, false), up, lastlow, lasthigh, tLast); 
            li=searchbarcur(_tf(j, false), dn, lastlow, lasthigh, tLast);
            if(hi!=li) break;
           }

         if(hi!=li)
           {
            if(hl==dn && li>hi) gL[save1_li]=0;
            if(hl==up && li<hi) gH[save1_hi]=0;
            if(li>hi) hl=up; else hl=dn;
           }
         else
           {
            if(externalBar==0)
              {
               if(hl==dn)
                 {
                  if((lasthigh-gL[save1_li])<(gL[save1_li]-lastlow)) {hl=dn;} else {gL[save1_li]=0; hl=up;}
                 }
               else
                 {
                  if((lasthigh-gH[save1_hi])<(gH[save1_hi]-lastlow)) {gH[save1_hi]=0; hl=dn;} else {hl=up;}
                 }
              }
            else if(externalBar==1)
              {
               if(hl==dn) {gL[save1_li]=0; hl=up;}
               else {gH[save1_hi]=0; hl=dn;}
              }
            else if(externalBar==2)
              {
               if(iOpen(NULL, gtf, i)-iLow(NULL, gtf, i)==iHigh(NULL, gtf, i)-iOpen(NULL, gtf, i))
                 {
                  if(hl==dn) {gL[save1_li]=0; hl=up;}
                  else {gH[save1_hi]=0; hl=dn;}
                 }
               else
                 {
                  if(hl==dn)
                    {
                     if(iHigh(NULL, gtf, i)-iOpen(NULL, gtf, i)<iOpen(NULL, gtf, i)-iLow(NULL, gtf, i)) {hl=dn;} else {gL[save1_li]=0; hl=up;}
                    }
                  else
                    {
                     if(iHigh(NULL, gtf, i)-iOpen(NULL, gtf, i)<iOpen(NULL, gtf, i)-iLow(NULL, gtf, i)) {gH[save1_hi]=0; hl=dn;} else {hl=up;}
                    }
                 }
              }
           }
         // Определяем направление луча на внешнем баре. Конец.
         //---

         hi=searchbarcur(Period(), up, lastlow, lasthigh, tLast); gH[hi]=lasthigh; gT[hi]=iTime(NULL, gtf, hi);
         li=searchbarcur(Period(), dn, lastlow, lasthigh, tLast); gL[li]=lastlow; gT[li]=iTime(NULL, gtf, li);
        }
      else
        {
         lastlow=iLow(NULL, gtf, i); lasthigh=iHigh(NULL, gtf, i); tLast=iTime(NULL, gtf, i);
        }

     }
//---

   press_arr(cL1, cH1, tL1, cLz1, cHz1, tLz1);

   // сохраняем переменные
   gtime_gbar[0]=iTime(NULL, gtf, 1);
   if(history)  // только при первом проходе заполняются массивы cl-ch-t / clz-chz-tz
     {
      g_addnewextremum=true;
     }
   else
     {
      // определение необходимости проверки следующего уровня на наличие нового экстремума
      if(gT[0]!=tL1[0] || gL[0]!=cL1[0] || gH[0]!=cH1[0]) g_addnewextremum=true;
     }
  }
//+------------------------------------------------------------------+
//| Создание первичной выборки экстремумов.                          |
//| Свинги Ганна. Конец.                                             |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Создание второго и следующих уровней экстремумов.                |
//| Свинги Ганна. Начало.                                            |
//+------------------------------------------------------------------+
/*
cl, ch, t - массивы, из которых формируется следующий уровень - cl_, ch_, t_
*/
int swing_nextlevel(double& cl[], double& ch[], datetime& t[], double& cl_[], double& ch_[], datetime& t_[])
  {
   int i, j, k, end;
   int hi, li, hl=0;
   double lastlow=0, lasthigh=0, lastlow_=0, lasthigh_=0; 

   if(ArraySize(gT)==0 || ArraySize(t)<2) {g_addnewextremum=false; return(-1);}

   if(history)  // полный пересчет
     {
      end=ArraySize(t);
      gbar=end-1;
     }
   else  // режим реального времени
     {
      if(ArraySize(t_)<4)
        {
         end=ArraySize(t);
         gbar=end-1;
         gtimedinamic=t[ArraySize(t)-1];
        }
      else
        {
         for(i=2; i<ArraySize(t_)-1; i++)
           {
            if(cl_[i]>0 && ch_[i]==0) {hl=dn; break;}
            if(cl_[i]==0 && ch_[i]>0) {hl=up; break;}
           }
         gtimedinamic=t_[i];

         for(i=0; i<ArraySize(t)-1; i++)
           {
            if(t[i]==gtimedinamic) break;
           }

         if(hl==dn)
           {
            lastlow=cl[i]; li=i;

            lasthigh=0;
            for(j=i;j<ArraySize(t);j++)
              {
               if(ch[j]>0)
                 {
                  if(lasthigh==0) lasthigh=ch[j];
                  else if(lasthigh<ch[j]) lasthigh=ch[j];
                 }
               if(cl[j]>0 && j!=i) break;
              }
            end=j+1;
            gbar=j;

            lasthigh_=lasthigh;
            lasthigh=0;
            for(j=i;j>=0;j--)
              {
               if(ch[j]>0)
                 {
                  if(lasthigh==0) lasthigh=ch[j];
                  else if(lasthigh<ch[j]) lasthigh=ch[j];
                 }
               if(cl[j]>0 && j!=i) break;
              }
            if(lasthigh_<lasthigh) lasthigh=lasthigh_;
          }

         if(hl==up)
           {
            lasthigh=ch[i]; hi=i;

            lastlow=0;
            for(j=i;j<ArraySize(t);j++)
              {
               if(cl[j]>0 && (lastlow==0 || lastlow>cl[j]))  lastlow=cl[j];
               if(ch[j]>0 && j!=i) break;
              }
            end=j+1;
            gbar=j;

            lastlow_=lastlow;
            lastlow=0;
            for(j=i;j>=0;j--)
              {
               if(cl[j]>0 && (lastlow==0 || lastlow>cl[j]))  lastlow=cl[j];
               if(ch[j]>0 && j!=i) break;
              }
            if(lastlow_>lastlow || lastlow==0) lastlow=lastlow_;
           }
        }
     }
   ArrayResize(gL, end); ArrayResize(gH, end); ArrayResize(gT, end);
   ArrayInitialize(gL,0); ArrayInitialize(gH,0); ArrayInitialize(gT,0);

//---
   for(i=gbar;i>=0;i--)
     {
      if(cl[i]>0 || ch[i]>0)
        {
         if(hl==0) // определяем направление тренда
           {
            if(cl[i]>0 && ch[i]==0) {hl=dn; lastlow=cl[i]; li=i;}
            if(cl[i]==0 && ch[i]>0) {hl=up; lasthigh=ch[i]; hi=i;}
           }
         else
           {
            if(hl==dn)
              {
               if(lastlow>cl[i] && cl[i]>0)
                 {
                  if(ch[i]>0 && lasthigh<ch[i]) {}
                  else
                    {
                     lastlow=cl[i]; li=i;
                     if(i+1<ArraySize(t))
                       {
                        lasthigh=0;
                        for(j=i;j<ArraySize(t);j++)
                          {
                           if(cl[j]>0 && j!=i) break;
                           if(ch[j]>0)
                            {
                             if(i==j)
                               {
                                if(cl[i]>0 && ch[i]>0 && cl[i+1]==0) continue;
                               }
                             if(lasthigh==0) lasthigh=ch[j];
                             else if(lasthigh<ch[j]) lasthigh=ch[j];
                            }
                          }

                        lasthigh_=lasthigh;
                        lasthigh=0;
                        for(j=i;j>=0;j--)
                          {
                           if(cl[j]>0 && j!=i) break;
                           if(ch[j]>0)
                            {
                             if(lasthigh==0) lasthigh=ch[j];
                             else if(lasthigh<ch[j]) lasthigh=ch[j];
                            }
                          }
                        if(lasthigh_<lasthigh) lasthigh=lasthigh_;
                       }
                    }
                 }

               if(ch[i]>0)
                 {
                  if(lasthigh==0) lasthigh=ch[i];
                  else if(lasthigh<ch[i])  // разворот
                    {
                     hl=up; lasthigh=ch[i]; hi=i;
                     gL[li]=cl[li]; gT[li]=t[li];
                     if(i+1<ArraySize(t))
                       {
                        lastlow=0;
                        for(j=i;j<ArraySize(t);j++)
                          {
                           if(ch[j]>0 && j!=i) break;
                           if(i==j)
                             {
                              if(cl[i]>0 && ch[i]>0 && ch[i+1]==0) continue;
                             }
                           if(cl[j]>0 && (lastlow==0 || lastlow>cl[j]))  lastlow=cl[j];
                          }

                        if(cl[i]>0 && lastlow>cl[i])
                          {
                           hl=dn; lastlow=cl[i]; li=i;
                           gH[hi]=ch[hi]; gT[hi]=t[hi];
                          }
                        else
                          {
                           lastlow_=lastlow;
                           lastlow=0;
                           for(j=i;j>=0;j--)
                             {
                              if(ch[j]>0 && j!=i) break;
                              if(cl[j]>0 && (lastlow==0 || lastlow>cl[j]))  lastlow=cl[j];
                             }
                           if(cl[i]>0 && lastlow_>lastlow)
                             {
                              hl=dn; lastlow=cl[i]; li=i;
                              gH[hi]=ch[hi]; gT[hi]=t[hi];
                             }
                           else if(lastlow_>lastlow || lastlow==0) lastlow=lastlow_;
                          }
                       }
                    }
                 }
              }
            else   // тренд up
              {
               if(lasthigh<ch[i] && ch[i]>0)
                 {
                  if(cl[i]>0 && lastlow>cl[i]) {}
                  else
                    {
                     lasthigh=ch[i]; hi=i;
                     if(i+1<ArraySize(t))
                       {
                        lastlow=0;
                        for(j=i;j<ArraySize(t);j++)
                          {
                           if(ch[j]>0 && j!=i) break;
                           if(i==j)
                             {
                              if(cl[i]>0 && ch[i]>0 && ch[i+1]==0) continue;
                             }
                           if(cl[j]>0 && (lastlow==0 || lastlow>cl[j]))  lastlow=cl[j];
                          }

                        lastlow_=lastlow;
                        lastlow=0;
                        for(j=i;j>=0;j--)
                          {
                           if(ch[j]>0 && j!=i) break;
                           if(cl[j]>0 && (lastlow==0 || lastlow>cl[j]))  lastlow=cl[j];
                          }
                        if(lastlow_>lastlow || lastlow==0) lastlow=lastlow_;
                       }
                    }
                 }

               if(cl[i]>0)
                 {
                  if(lastlow==0) lastlow=cl[i];
                  else if(lastlow>cl[i])  // разворот
                    {
                     hl=dn; lastlow=cl[i]; li=i;
                     gH[hi]=ch[hi]; gT[hi]=t[hi];
                     if(i+1<ArraySize(t))
                       {
                        lasthigh=0;
                        for(j=i;j<ArraySize(t);j++)
                          {
                           if(i==j)
                             {
                              if(cl[i]>0 && ch[i]>0 && cl[i+1]==0) continue;
                             }

                           if(ch[j]>0)
                            {
                             if(lasthigh==0) lasthigh=ch[j];
                             else if(lasthigh<ch[j]) lasthigh=ch[j];
                            }
                           if(cl[j]>0 && j!=i) break;
                          }

                        if(ch[i]>0 && lasthigh<ch[i])
                          {
                           hl=up; lasthigh=ch[i]; hi=i;
                           gL[li]=cl[li]; gT[li]=t[li];
                          }
                        else
                          {
                           lasthigh_=lasthigh;
                           lasthigh=0;
                           for(j=i;j>=0;j--)
                             {
                              if(cl[j]>0 && j!=i) break;
                              if(ch[j]>0)
                               {
                                if(lasthigh==0) lasthigh=ch[j];
                                else if(lasthigh<ch[j]) lasthigh=ch[j];
                               }
                             }
                           if(lasthigh_<lasthigh) lasthigh=lasthigh_;
                          }
                       }
                    }
                 }
              }
           }
        }
     }

   if(ArraySize(gT)>0)
     {
      if(hl==dn) {gL[li]=lastlow; gT[li]=t[li];}
      else {gH[hi]=lasthigh; gT[hi]=t[hi];}
     }

//---

   k=ArraySize(gT);

   if(history)
     {
      ArrayResize(cl_,k); ArrayResize(ch_,k); ArrayResize(t_,k);
     }
   // Сжатие массивов
   //---
   j=0;
   for(i=0;i<k;i++)
     {
      if(gL[i]>0 || gH[i]>0)
        {
         if(history)  // только при первом проходе заполняются массивы cl_-ch_-t_
           {
            cl_[j]=gL[i]; ch_[j]=gH[i]; t_[j]=gT[i];
           }

         gL[j]=gL[i]; gH[j]=gH[i]; gT[j]=gT[i];
         j++;
        }
     }
   ArrayResize(gL,j); ArrayResize(gH,j); ArrayResize(gT,j);
   if(history)
     {
      ArrayResize(cl_,j); ArrayResize(ch_,j); ArrayResize(t_,j);
     }
   //---

   if(history)
     {
      if(ArraySize(gT)<3)
        {
         ArrayResize(cl_,1); ArrayResize(ch_,1); ArrayResize(t_,1);
         ArrayInitialize(cl_,0); ArrayInitialize(ch_,0); ArrayInitialize(t_,0);
         ArrayResize(gL, 1); ArrayResize(gH, 1); ArrayResize(gT, 1);
         ArrayInitialize(gL,0); ArrayInitialize(gH,0); ArrayInitialize(gT,0);
        }
     }
   else
     {
      if(ArraySize(gT)<3 && ArraySize(t_)<2)
        {
         ArrayResize(cl_,1); ArrayResize(ch_,1); ArrayResize(t_,1);
         ArrayInitialize(cl_,0); ArrayInitialize(ch_,0); ArrayInitialize(t_,0);
         ArrayResize(gL, 1); ArrayResize(gH, 1); ArrayResize(gT, 1);
         ArrayInitialize(gL,0); ArrayInitialize(gH,0); ArrayInitialize(gT,0);
        }
     }

   if(history && t[0]>0 && Statistica>0) Statistika(cl, ch, t, cl_, ch_, t_);   // вывод статистики

   if(ArraySize(gT)>2)
     {
      if(history)
        {
         g_addnewextremum=true;
        }
      else
        {
         // определение необходимости проверки следующего уровня на наличие нового экстремума
         if(gT[0]!=t_[0] || gL[0]!=cl_[0] || gH[0]!=ch_[0]) g_addnewextremum=true;
        }
     }

   return(0);
  }
//+------------------------------------------------------------------+
//| Создание второго и следующих уровней экстремумов.                |
//| Свинги Ганна. Конец.                                             |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Поиск бара на заданном таймфрейме. Начало.                       |
//+------------------------------------------------------------------+
int searchbarcur(int tf, int UpDn, double lastlow_, double lasthigh_, double tLast_)
  {
   int i, j, tend;
   double wr;

   j=iBarShift(NULL, tf, tLast_, false); tend=tLast_+gtf*60;
   i=-1;
   while (iTime(NULL, tf, j)<tLast_ && j>=0) j--;
   if(iTime(NULL, tf, j)>tLast_) j++;

   if(iTime(NULL, tf, j)<tend && j<iBars(NULL, tf) && j>=0)
     {
      if(UpDn==dn)
        {
         wr=1000000;
         while (iTime(NULL, tf, j)<tend && j>=0)
           {
            if(wr>iLow(NULL, tf, j)) {i=j; wr=iLow(NULL, tf, j); if(NormalizeDouble(wr-lastlow_, Digits)==0 || wr<lastlow_) return (i);}
            j--;
           }
        }
      else if(UpDn==up)
        {
         wr=0;
         while (iTime(NULL, tf, j)<tend && j>=0)
           {
            if(wr<iHigh(NULL, tf, j)) {i=j; wr=iHigh(NULL, tf, j); if(NormalizeDouble(wr-lasthigh_, Digits)==0 || wr>lasthigh_) return (i);}
            j--;
           }
        }
     }

   return (i);
  }
//+------------------------------------------------------------------+
//| Поиск бара на текущем таймфрейме. Конец.                         |
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//| Преобразование номера таймфрейма. Начало.                        |
//+------------------------------------------------------------------+
/*
y=true - преобразовывает TF в порядковый номер 
1     - 0
5     - 1
15    - 2
30    - 3
60    - 4
240   - 5
1440  - 6
10080 - 7
43200 - 8

y=false - преобразование номера в значение в минутах (обратное преобразование)
*/
int _tf (int tf, bool y)
  {
   if(y)
     {
      if(tf<5)          return (0);
      else if(tf<15)    return (1);
      else if(tf<30)    return (2);
      else if(tf<60)    return (3);
      else if(tf<240)   return (4);
      else if(tf<1440)  return (5);
      else if(tf<10080) return (6);
      else if(tf<43200) return (7);
      return (8);
     }
   else
     {
      if(tf==0)      return (PERIOD_M1);
      else if(tf==1) return (PERIOD_M5);
      else if(tf==2) return (PERIOD_M15);
      else if(tf==3) return (PERIOD_M30);
      else if(tf==4) return (PERIOD_H1);
      else if(tf==5) return (PERIOD_H4);
      else if(tf==6) return (PERIOD_D1);
      else if(tf==7) return (PERIOD_W1);
      else if(tf>=8) return (PERIOD_MN1);
      else if(tf<0)  return (-1);
     }
   return(0);
  }
//+------------------------------------------------------------------+
//| Преобразование номера таймфрейма. Конец.                         |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Перенос значений параметров из строки в числовой массив. Начало. |
//+------------------------------------------------------------------+
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 _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 delete_objects()
  {
   string nameObj="_"+ExtComplekt+"_TheExternalBar_on_"+gtf;
   if(ObjectFind(nameObj)==0) ObjectDelete (nameObj);
  }
//+------------------------------------------------------------------+
//| Удаление объектов. Конец.                                        |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Вывод статистики. Начало.                                        |
//+------------------------------------------------------------------+
// Статистика выводится во вкладке Эксперты метатрейдера после расчета истории.
// Statistica=1 - подсчет количества баров с экстремумами на каждом уровне
// Statistica=2 - подсчет количества лучей младшего уровня в одном луче старшего уровня
int Statistika(double& cl[], double& ch[], datetime& t[], double& cl_[], double& ch_[], datetime& t_[])
  {
   int i, j, k, m, s, p, q, wr;
   string temp=DoubleToStr(ArraySize(t),0), temp1="", temp2="";

   if(Statistica==1)
     {
      temp2=StringSubstr(temp,StringLen(temp)-2,2);
      k=StrToInteger(temp2);
      if(k>9 && k<20) temp="ов";
      else
        {
         temp2=StringSubstr(temp,StringLen(temp)-1,1);
         k=StrToInteger(temp2);
         if(k==1) temp="";
         else if(k>1 && k<5) temp="а";
         else temp="ов";
         }
      temp1="На уровне "+(glevel-1)+" найдено - "+ArraySize(t)+" - бар"+temp+" с экстремумами.";
     }
   else if(ArraySize(t_)>1 && !((PrimarySelectionOfExtremums==0 || _PrimarySelectionOfExtremums==1 || _NextSelectionOfExtremums==1) && filterZigZag==2))
     {
      if(Statistica==2)
        {
         m=0; // счетчик количества максимумов младшего уровня
         s=0; // количество волн младшего уровня
         p=0; // количество волн старшего уровня
         // массив для хранения количества лучей 1-3-5-7-9-11-13-15-17-19-21-23-25-27-29-31-33-35-37-39-41-43-45
         int n[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

         i=ArraySize(t_)-1;
         for(j=ArraySize(t)-1;j>=0;j--) {if(cl[j]>0) s++; if(ch[j]>0) s++; if(t[j]==t_[i]) {if(cl_[i]>0) p++; if(ch_[i]>0) p++; break;}} // определяем экстремум младшего уровня, совпадающий 
                                                                                                   // с первым слева экстремумом старшего уровня.
         k=j-1; i--; if(cl_[i]>0) p++; if(ch_[i]>0) p++;
         for(j=k;j>=0 && i>=0;j--)
           {
            if(cl[j]>0) s++; if(ch[j]>0) s++;
            if(t[j]<t_[i]) {if(ch[j]>0) m++;}
            else 
              {
               switch(m)
                 {
                  case 0:  n[0]++;  break; // совпадает луч младшего уровня и луч старшего уровня
                  case 1:  n[1]++;  break; // на один луч старшего уровня приходится 3 луча младшего уровня
                  case 2:  n[2]++;  break; // на один луч старшего уровня приходится 5 лучей младшего уровня
                  case 3:  n[3]++;  break; // на один луч старшего уровня приходится 7 лучей младшего уровня
                  case 4:  n[4]++;  break; // на один луч старшего уровня приходится 9 лучей младшего уровня
                  case 5:  n[5]++;  break; // на один луч старшего уровня приходится 11 лучей младшего уровня
                  case 6:  n[6]++;  break; // на один луч старшего уровня приходится 13 лучей младшего уровня
                  case 7:  n[7]++;  break; // на один луч старшего уровня приходится 15 лучей младшего уровня
                  case 8:  n[8]++;  break; // на один луч старшего уровня приходится 17 лучей младшего уровня
                  case 9:  n[9]++;  break; // на один луч старшего уровня приходится 19 лучей младшего уровня
                  case 10: n[10]++; break; // на один луч старшего уровня приходится 21 луч младшего уровня
                  case 11: n[11]++; break; // на один луч старшего уровня приходится 23 луча младшего уровня
                  case 12: n[12]++; break; // на один луч старшего уровня приходится 25 лучей младшего уровня
                  case 13: n[13]++; break; // на один луч старшего уровня приходится 27 лучей младшего уровня
                  case 14: n[14]++; break; // на один луч старшего уровня приходится 29 лучей младшего уровня
                  case 15: n[15]++; break; // на один луч старшего уровня приходится 31 луч младшего уровня
                  case 16: n[16]++; break; // на один луч старшего уровня приходится 33 луча младшего уровня
                  case 17: n[17]++; break; // на один луч старшего уровня приходится 35 лучей младшего уровня
                  case 18: n[18]++; break; // на один луч старшего уровня приходится 37 лучей младшего уровня
                  case 19: n[19]++; break; // на один луч старшего уровня приходится 39 лучей младшего уровня
                  case 20: n[20]++; break; // на один луч старшего уровня приходится 41 луч младшего уровня
                  case 21: n[21]++; break; // на один луч старшего уровня приходится 43 луча младшего уровня
                  case 22: n[22]++; // на один луч старшего уровня приходится 45 лучей младшего уровня
                 }
               m=0; i--;
               if(cl_[i]>0) p++; if(ch_[i]>0) p++;
              }
           }
         temp1="На уровне "+glevel+"  ";
         for(i=0;i<23;i++) if(n[i]>0) temp1=temp1+(1+i*2)+"="+n[i]+"  ";
         temp1=temp1+" ||  total wave = "+(s/2+s-(s/2)*2)+"/"+(p/2+p-(p/2)*2);
        }
      else if(Statistica==3)
        {
         int hl_=0;
         m=0;  // сумма количества пунктов
         wr=0; // количество пунктов от одной сделки
         s=100000;  // минимальная прибыль в пунктах
         p=0;  // максимальная прибыль в пунктах
         q=0;  // количество трейдов
         
         k=ArraySize(t)-1;
         for(i=ArraySize(t_)-1;i>0;i--)
           {
            for(j=k;j>=0;j--) {if(t[j]==t_[i]) break;} // определяем экстремум младшего уровня, совпадающий
            k=j;

            if(cl_[i]>0 && ch_[i]>0)
              {
               if(hl_==0) {if(cl_[i-1]>0) hl_=up; else hl_=dn;}
              }
            else {if(cl_[i]>0) hl_=up; else hl_=dn;}

            if(hl_==up) for(j=k;j>=0;j--) {if(ch[j]>0) {k=j; break;}}
            if(hl_==dn) for(j=k;j>=0;j--) {if(cl[j]>0) {k=j; break;}}
            if(k>=0) if(t[k]==t_[i] || t[k]==t_[i-1]) continue;

            if(hl_==up) {if(ch_[i-1]==ch[k]) continue; wr=(ch_[i-1]-ch[k])/Point;} // if(ch_[i-1]==0 || ch[k]==0) Print("На уровне "+glevel+"  hl_ = "+hl_+"  ch_[i] = "+ch_[i]+"  cl_[i] = "+cl_[i]+"  ch_[i-1] = "+ch_[i-1]+"  i = "+i);}
            else {if(cl[k]==cl_[i-1]) continue; wr=(cl[k]-cl_[i-1])/Point;}
            if(wr<=0) continue;
            if(wr<s) s=wr;
            if(wr>p) p=wr;
            m=m+wr;
            q++;
           }
         if(q>0) temp1="На уровне "+glevel+"  совершено сделок="+q+"  общая прибыль="+m+"  min прибыль="+s+"  max прибыль="+p+"  средняя прибыль="+m/q;
        }
     }

   if(StringLen(temp1)>0) Print(temp1);
   return(0);
  }
//+------------------------------------------------------------------+
//| Вывод статистики. Конец.                                         |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Преобразование строки в цвет. Начало.                            |
//| Функцию написал 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          |
//+------------------------------------------------------------------+

