//+------------------------------------------------------------------+
//|                                    ZigZag_HH-HL-LH-LL_Cb (1).mq5 |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_color1 Orange

#property indicator_label1 "ZigZag"
#property indicator_label2 "HH"
#property indicator_label3 "LL"

#define c_H_LL clrBlue
#define c_L_LL clrRed
#define c_H_HH clrBlue
#define c_L_HH clrRed

#define HH_name "Line_Trend_HH_"
#define LL_name "Line_Trend_LL_"

extern int      ExtDepth           = 1 ;
extern int      ExtDeviation       = 1 ;
extern int      ExtBackstep        = 1 ;
extern color    TopColorHH         = Black;
extern color    TopColorLH         = Black;
extern color    BotColorHL         = Black ;
extern color    BotColorLL         = Black;
extern int      Labeldistance      = 2;

extern int      TxtSize1            = 10;
extern int      TxtSize2            = 10;
extern string   Fonts              = "Arial Black";
extern int      Line_HH_LL_Width    = 3;

extern int      CountBars          = 500 ;

//double       Poin, puShift, pdShift, Mut, Mdt;
double       Poin, Mut;
int level=3;
bool downloadhistory = false;

//int PipFactor = 1;

double ZigzagBuffer[];
double HH[],LL[];
double HighMapBuffer[];
double LowMapBuffer[];
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int init()
  {
   
  // if (Digits == 3 || Digits == 5)
  // {
  //    PipFactor = 10;
  // }

   //SetIndexStyle(0,DRAW_SECTION,STYLE_SOLID,2);
   
   
   SetIndexBuffer(0,ZigzagBuffer);
   SetIndexBuffer(1,HH);
   SetIndexBuffer(2,LL);
   SetIndexBuffer(3,HighMapBuffer);
   SetIndexBuffer(4,LowMapBuffer);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   //SetIndexEmptyValue(0,0.0);
   
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_SECTION);
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID);
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,2);

   //IndicatorShortName("ZigZag("+ExtDepth+","+ExtDeviation+","+ExtBackstep+")");
    del_objF();    
//===============================================================      
  /*     switch(Period())
      {
        case     1:  puShift = 1.0 ;   pdShift = -1.0 ;   break;    
        case     5:  puShift = 1.0 ;   pdShift = -1.0 ;   break; 
        case    15:  puShift = 6.0 ;   pdShift = -1.0 ;   break; 
        case    30:  puShift = 9.0 ;   pdShift = -1.0 ;   break; 
        case    PERIOD_H1:  puShift = 12  ;   pdShift = -4.0 ;   break; 
        case   PERIOD_H4:  puShift = 35  ;   pdShift = -7.0 ;   break; 
        case  PERIOD_D1:  puShift = 100  ;  pdShift = -20  ;   break; 
        case PERIOD_W1:  puShift = 200 ;   pdShift = -50  ;   break; 
        case PERIOD_MN1:  puShift = 300 ;   pdShift = -100 ;   break;               
      }    
  */    
//==============================================================   
         if (Point() == 0.00001)  Poin = 0.0001;   // 6 digits
    else if (Point() == 0.001)    Poin = 0.01;     // 3 digits (for Yen based pairs)
                           else Poin = Point();    // Normal 

//====================================================================    
     if (StringSubstr(Symbol(),0,6) == "GBPUSD")  {switch(Period()) {case 1:Mut=1.5;break;    case 5:Mut=4;break;     case 15:Mut=6;break;     case 30:Mut=10;break;    case PERIOD_H1:Mut=13;break;    case PERIOD_H4:Mut=35;break;    case PERIOD_D1:Mut=100;break;    case PERIOD_W1:Mut=150;break;    case PERIOD_MN1:Mut=300;break; } }                                                 
     if (StringSubstr(Symbol(),0,6) == "GBPJPY")  {switch(Period()) {case 1:Mut=2.5;break;    case 5:Mut=6;break;     case 15:Mut=8;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=10;break;    case PERIOD_H4:Mut=35;break;    case PERIOD_D1:Mut=150;break;    case PERIOD_W1:Mut=200;break;    case PERIOD_MN1:Mut=300;break; } }  
     if (StringSubstr(Symbol(),0,6) == "USDJPY")  {switch(Period()) {case 1:Mut=1.5;break;    case 5:Mut=3;break;     case 15:Mut=6;break;     case 30:Mut=12;break;    case PERIOD_H1:Mut=25;break;    case PERIOD_H4:Mut=30;break;    case PERIOD_D1:Mut=80;break;     case PERIOD_W1:Mut=150;break;    case PERIOD_MN1:Mut=200;break; } }  
     if (StringSubstr(Symbol(),0,6) == "EURUSD")  {switch(Period()) {case 1:Mut=0.7;break;    case 5:Mut=2;break;     case 15:Mut=5;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=20;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=250;break; } }  
     
     if (StringSubstr(Symbol(),0,6) == "XAUUSD")  {switch(Period()) {case 1:Mut=12.0;break;   case 5:Mut=40;break;    case 15:Mut=80;break;    case 30:Mut=200;break;   case PERIOD_H1:Mut=300;break;   case PERIOD_H4:Mut=400;break;   case PERIOD_D1:Mut=700;break;    case PERIOD_W1:Mut=2000;break;   case PERIOD_MN1:Mut=3000;break; } }
     if (StringSubstr(Symbol(),0,5) == "GER30" )  {switch(Period()) {case 1:Mut=90;break;     case 5:Mut=350;break;   case 15:Mut=500;break;   case 30:Mut=2000;break;  case PERIOD_H1:Mut=2400;break;  case PERIOD_H4:Mut=2000;break;  case PERIOD_D1:Mut=7000;break;   case PERIOD_W1:Mut=20000;break;  case PERIOD_MN1:Mut=25000;break; } }
     if (StringSubstr(Symbol(),0,6) == "JPN225")  {switch(Period()) {case 1:Mut=200;break;    case 5:Mut=500;break;   case 15:Mut=1200;break;  case 30:Mut=2800;break;  case PERIOD_H1:Mut=5000;break;  case PERIOD_H4:Mut=6000;break;  case PERIOD_D1:Mut=15000;break;  case PERIOD_W1:Mut=30000;break;  case PERIOD_MN1:Mut=50000;break; } }
     if (StringSubstr(Symbol(),0,4) == "US30"  )  {switch(Period()) {case 1:Mut=100;break;    case 5:Mut=200;break;   case 15:Mut=400;break;   case 30:Mut=1000;break;  case PERIOD_H1:Mut=3500;break;  case PERIOD_H4:Mut=4000;break;  case PERIOD_D1:Mut=9000;break;   case PERIOD_W1:Mut=20000;break;  case PERIOD_MN1:Mut=40000;break; } }
        
     if (StringSubstr(Symbol(),0,6) == "AUDUSD")  {switch(Period()) {case 1:Mut=0.3;break;    case 5:Mut=3;break;     case 15:Mut=7;break;     case 30:Mut=10;break;    case PERIOD_H1:Mut=13;break;    case PERIOD_H4:Mut=13;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=200;break; } }    
     if (StringSubstr(Symbol(),0,6) == "AUDNZD")  {switch(Period()) {case 1:Mut=0.5;break;    case 5:Mut=3;break;     case 15:Mut=5;break;     case 30:Mut=7;break;     case PERIOD_H1:Mut=10;break;    case PERIOD_H4:Mut=13;break;    case PERIOD_D1:Mut=25;break;     case PERIOD_W1:Mut=100;break;    case PERIOD_MN1:Mut=120;break; } }    
     if (StringSubstr(Symbol(),0,6) == "AUDCAD")  {switch(Period()) {case 1:Mut=0.3;break;    case 5:Mut=3;break;     case 15:Mut=7;break;     case 30:Mut=10;break;    case PERIOD_H1:Mut=13;break;    case PERIOD_H4:Mut=13;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=200;break; } }    
     if (StringSubstr(Symbol(),0,6) == "AUDCHF")  {switch(Period()) {case 1:Mut=0.3;break;    case 5:Mut=3;break;     case 15:Mut=7;break;     case 30:Mut=10;break;    case PERIOD_H1:Mut=13;break;    case PERIOD_H4:Mut=13;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=200;break; } }    
     if (StringSubstr(Symbol(),0,6) == "AUDJPY")  {switch(Period()) {case 1:Mut=0.3;break;    case 5:Mut=3;break;     case 15:Mut=7;break;     case 30:Mut=10;break;    case PERIOD_H1:Mut=13;break;    case PERIOD_H4:Mut=13;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=200;break; } }    
        
     if (StringSubstr(Symbol(),0,6) == "CHFJPY")  {switch(Period()) {case 1:Mut=1.5;break;   case 5:Mut=2;break;      case 15:Mut=4;break;     case 30:Mut=6;break;     case PERIOD_H1:Mut=10;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=PERIOD_H1;break;    case PERIOD_W1:Mut=200;break;     case PERIOD_MN1:Mut=250;break; } }    
     if (StringSubstr(Symbol(),0,6) == "CADJPY")  {switch(Period()) {case 1:Mut=1.5;break;   case 5:Mut=2;break;      case 15:Mut=4;break;     case 30:Mut=6;break;     case PERIOD_H1:Mut=10;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=PERIOD_H1;break;    case PERIOD_W1:Mut=200;break;     case PERIOD_MN1:Mut=250;break; } }    
     if (StringSubstr(Symbol(),0,6) == "CADCHF")  {switch(Period()) {case 1:Mut=1.5;break;   case 5:Mut=2;break;      case 15:Mut=4;break;     case 30:Mut=6;break;     case PERIOD_H1:Mut=10;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=PERIOD_H1;break;    case PERIOD_W1:Mut=200;break;     case PERIOD_MN1:Mut=250;break; } }    
          
     if (StringSubstr(Symbol(),0,6) == "EURGBP")  {switch(Period()) {case 1:Mut=0.7;break;    case 5:Mut=2;break;     case 15:Mut=5;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=20;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=250;break; } }  
     if (StringSubstr(Symbol(),0,6) == "EURAUD")  {switch(Period()) {case 1:Mut=0.7;break;    case 5:Mut=2;break;     case 15:Mut=5;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=20;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=250;break; } }  
     if (StringSubstr(Symbol(),0,6) == "EURNZD")  {switch(Period()) {case 1:Mut=0.7;break;    case 5:Mut=2;break;     case 15:Mut=5;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=20;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=250;break; } }  
     if (StringSubstr(Symbol(),0,6) == "EURCAD")  {switch(Period()) {case 1:Mut=0.7;break;    case 5:Mut=2;break;     case 15:Mut=5;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=20;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=250;break; } }  
     if (StringSubstr(Symbol(),0,6) == "EURCHF")  {switch(Period()) {case 1:Mut=0.7;break;    case 5:Mut=2;break;     case 15:Mut=5;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=20;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=250;break; } }  
     if (StringSubstr(Symbol(),0,6) == "EURJPY")  {switch(Period()) {case 1:Mut=0.7;break;    case 5:Mut=2;break;     case 15:Mut=5;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=20;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=250;break; } }  
         
     if (StringSubstr(Symbol(),0,6) == "GBPAUD")  {switch(Period()) {case 1:Mut=1.5;break;    case 5:Mut=4;break;     case 15:Mut=6;break;     case 30:Mut=10;break;    case PERIOD_H1:Mut=13;break;    case PERIOD_H4:Mut=35;break;    case PERIOD_D1:Mut=100;break;    case PERIOD_W1:Mut=150;break;    case PERIOD_MN1:Mut=300;break; } }   
     if (StringSubstr(Symbol(),0,6) == "GBPCHF")  {switch(Period()) {case 1:Mut=1.5;break;    case 5:Mut=4;break;     case 15:Mut=6;break;     case 30:Mut=10;break;    case PERIOD_H1:Mut=13;break;    case PERIOD_H4:Mut=35;break;    case PERIOD_D1:Mut=100;break;    case PERIOD_W1:Mut=150;break;    case PERIOD_MN1:Mut=300;break; } }   
     if (StringSubstr(Symbol(),0,6) == "GBPCAD")  {switch(Period()) {case 1:Mut=1.5;break;    case 5:Mut=4;break;     case 15:Mut=6;break;     case 30:Mut=10;break;    case PERIOD_H1:Mut=13;break;    case PERIOD_H4:Mut=35;break;    case PERIOD_D1:Mut=100;break;    case PERIOD_W1:Mut=150;break;    case PERIOD_MN1:Mut=300;break; } }   
     if (StringSubstr(Symbol(),0,6) == "GBPNZD")  {switch(Period()) {case 1:Mut=1.5;break;    case 5:Mut=4;break;     case 15:Mut=6;break;     case 30:Mut=10;break;    case PERIOD_H1:Mut=13;break;    case PERIOD_H4:Mut=35;break;    case PERIOD_D1:Mut=100;break;    case PERIOD_W1:Mut=150;break;    case PERIOD_MN1:Mut=300;break; } }   
     
     if (StringSubstr(Symbol(),0,6) == "NZDJPY")  {switch(Period()) {case 1:Mut=0.7;break;    case 5:Mut=2;break;     case 15:Mut=5;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=20;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=250;break; } }  
     if (StringSubstr(Symbol(),0,6) == "NZDUSD")  {switch(Period()) {case 1:Mut=0.7;break;    case 5:Mut=2;break;     case 15:Mut=5;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=20;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=250;break; } }  
     if (StringSubstr(Symbol(),0,6) == "NZDCHF")  {switch(Period()) {case 1:Mut=0.7;break;    case 5:Mut=2;break;     case 15:Mut=5;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=20;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=250;break; } }  
     if (StringSubstr(Symbol(),0,6) == "NZDCAD")  {switch(Period()) {case 1:Mut=0.7;break;    case 5:Mut=2;break;     case 15:Mut=5;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=20;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=250;break; } }  
        
     if (StringSubstr(Symbol(),0,6) == "USDCAD")  {switch(Period()) {case 1:Mut=0.7;break;    case 5:Mut=2;break;     case 15:Mut=5;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=20;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=250;break; } }  
     if (StringSubstr(Symbol(),0,6) == "USDCHF")  {switch(Period()) {case 1:Mut=0.7;break;    case 5:Mut=2;break;     case 15:Mut=5;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=20;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=250;break; } }  
       
     if (StringSubstr(Symbol(),0,6) == "USDZAR")  {switch(Period()) {case 1:Mut=0.7;break;    case 5:Mut=2;break;     case 15:Mut=5;break;     case 30:Mut=11;break;    case PERIOD_H1:Mut=20;break;    case PERIOD_H4:Mut=20;break;    case PERIOD_D1:Mut=30;break;     case PERIOD_W1:Mut=120;break;    case PERIOD_MN1:Mut=250;break; } }  
         
     if (StringSubstr(Symbol(),0,6) == "AUS200")  {switch(Period()) {case 1:Mut=90;break;     case 5:Mut=350;break;   case 15:Mut=500;break;   case 30:Mut=2000;break;  case PERIOD_H1:Mut=2400;break;  case PERIOD_H4:Mut=2000;break;  case PERIOD_D1:Mut=7000;break;   case PERIOD_W1:Mut=20000;break;  case PERIOD_MN1:Mut=25000;break; } }
     if (StringSubstr(Symbol(),0,5) == "FRA40" )  {switch(Period()) {case 1:Mut=90;break;     case 5:Mut=350;break;   case 15:Mut=500;break;   case 30:Mut=2000;break;  case PERIOD_H1:Mut=2400;break;  case PERIOD_H4:Mut=2000;break;  case PERIOD_D1:Mut=7000;break;   case PERIOD_W1:Mut=20000;break;  case PERIOD_MN1:Mut=25000;break; } }
     if (StringSubstr(Symbol(),0,6) == "SPX500")  {switch(Period()) {case 1:Mut=15;break;     case 5:Mut=30;break;    case 15:Mut=PERIOD_H1;break;    case 30:Mut=120;break;   case PERIOD_H1:Mut=350;break;   case PERIOD_H4:Mut=400;break;   case PERIOD_D1:Mut=1200;break;   case PERIOD_W1:Mut=3000;break;   case PERIOD_MN1:Mut=4000;break; } }
     if (StringSubstr(Symbol(),0,5) == "UK100" )  {switch(Period()) {case 1:Mut=PERIOD_H1;break;     case 5:Mut=200;break;   case 15:Mut=300;break;   case 30:Mut=1000;break;  case PERIOD_H1:Mut=1200;break;  case PERIOD_H4:Mut=1500;break;  case PERIOD_D1:Mut=5000;break;   case PERIOD_W1:Mut=8000;break;   case PERIOD_MN1:Mut=10000;break; } }
     if (StringSubstr(Symbol(),0,6) == "XAGUSD")  {switch(Period()) {case 1:Mut=90;break;     case 5:Mut=350;break;   case 15:Mut=500;break;   case 30:Mut=2000;break;  case PERIOD_H1:Mut=2400;break;  case PERIOD_H4:Mut=2000;break;  case PERIOD_D1:Mut=7000;break;   case PERIOD_W1:Mut=20000;break;  case PERIOD_MN1:Mut=25000;break; } }
     if (StringSubstr(Symbol(),0,5) == "USOil" )  {switch(Period()) {case 1:Mut=90;break;     case 5:Mut=350;break;   case 15:Mut=500;break;   case 30:Mut=2000;break;  case PERIOD_H1:Mut=2400;break;  case PERIOD_H4:Mut=2000;break;  case PERIOD_D1:Mut=7000;break;   case PERIOD_W1:Mut=20000;break;  case PERIOD_MN1:Mut=25000;break; } }
     if (StringSubstr(Symbol(),0,4) == "NGAS"  )  {switch(Period()) {case 1:Mut=90;break;     case 5:Mut=350;break;   case 15:Mut=500;break;   case 30:Mut=2000;break;  case PERIOD_H1:Mut=2400;break;  case PERIOD_H4:Mut=2000;break;  case PERIOD_D1:Mut=7000;break;   case PERIOD_W1:Mut=20000;break;  case PERIOD_MN1:Mut=25000;break; } }
     if (StringSubstr(Symbol(),0,6) == "Copper")  {switch(Period()) {case 1:Mut=10;break;     case 5:Mut=15;break;    case 15:Mut=20;break;    case 30:Mut=80;break;    case PERIOD_H1:Mut=150;break;   case PERIOD_H4:Mut=200;break;   case PERIOD_D1:Mut=250;break;    case PERIOD_W1:Mut=500;break;    case PERIOD_MN1:Mut=800;break; } }
     if (StringSubstr(Symbol(),0,4) == "Bund"  )  {switch(Period()) {case 1:Mut=0.8;break;    case 5:Mut=3;break;     case 15:Mut=5;break;     case 30:Mut=10;break;    case PERIOD_H1:Mut=15;break;    case PERIOD_H4:Mut=30;break;    case PERIOD_D1:Mut=40;break;     case PERIOD_W1:Mut=80;break;     case PERIOD_MN1:Mut=120;break; } }
     
     if (StringSubstr(Symbol(),0,8) == "USDOLLAR"){switch(Period()) {case 1:Mut=0.5;break;    case 5:Mut=2;break;     case 15:Mut=4;break;     case 30:Mut=8;break;     case PERIOD_H1:Mut=12;break;    case PERIOD_H4:Mut=15;break;    case PERIOD_D1:Mut=20;break;     case PERIOD_W1:Mut=70;break;     case PERIOD_MN1:Mut=100;break; } }
     

//===================================================================================================================             
    
   return(0);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+  
  int deinit()
  {       del_objF();  ObjectsDeleteAll(0,"Line_Trend_");  
    return(0);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[]) 
  {
    del_objF();
   int i, counted_bars = prev_calculated;
   int limit,counterZ,whatlookfor;
   int shift,back,lasthighpos,lastlowpos;
   double val,res;
   double curlow,curhigh,lasthigh,lastlow;
   
     PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,Bars(_Symbol,_Period)-CountBars); //SetIndexDrawBegin(0,Bars-CountBars);
     PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,Bars(_Symbol,_Period)-CountBars); //SetIndexDrawBegin(1,Bars-CountBars);
     PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,Bars(_Symbol,_Period)-CountBars); //SetIndexDrawBegin(2,Bars-CountBars);

   if (counted_bars==0 && downloadhistory) 
     {    ArrayInitialize(ZigzagBuffer,0.0);
          ArrayInitialize(HighMapBuffer,0.0);
          ArrayInitialize(LowMapBuffer,0.0);
     }
//==============================================================================================     
   if (counted_bars==0) 
     {  limit=Bars(_Symbol,_Period)-ExtDepth;
        downloadhistory=true;
     }
   if (counted_bars>0) 
     {   while (counterZ<level && i<100)
        {     res=ZigzagBuffer[i];
           if (res!=0) counterZ++;
               i++;
        }
      i--;
      limit=i;
      
         if (LowMapBuffer[i]!=0) 
            {    curlow=LowMapBuffer[i];
                 whatlookfor=1;
            }
      else  {    curhigh=HighMapBuffer[i];
                 whatlookfor=-1;
            }
//==============================================================================================            
      for (i=limit-1;i>=0;i--)  
        {
         ZigzagBuffer[i]=0.0;  
         LowMapBuffer[i]=0.0;
         HighMapBuffer[i]=0.0;
         HH[i] = EMPTY_VALUE;
         LL[i] = EMPTY_VALUE;
         ObjectDelete(0,HH_name+string(int(iTime(NULL,PERIOD_CURRENT,i))));
         ObjectDelete(0,LL_name+string(int(iTime(NULL,PERIOD_CURRENT,i))));
        }
     }
//==============================================================================================      
   for(shift=limit; shift>=0; shift--)
   {    //--- Low
      val=iLow(NULL,PERIOD_CURRENT,iLowest(NULL,0,MODE_LOW,ExtDepth,shift));
      if    (    val==lastlow  ) val=0.0;
      else  {    lastlow=val;
       
      if    (   (iLow(NULL,PERIOD_CURRENT,shift)-val)>(ExtDeviation*Point())  )   val=0.0;         
      else  {   for(back = 1; back<=ExtBackstep; back++)
            {   res = LowMapBuffer[shift+back];
                if((res!=0)&&(res>val)) LowMapBuffer[shift+back]=0.0; 
           }}} 
//========================================        
      if (iLow(NULL,PERIOD_CURRENT,shift)==val) LowMapBuffer[shift]=val; else LowMapBuffer[shift]=0.0;
      //--- high
      val=iHigh(NULL,PERIOD_CURRENT,iHighest(NULL,0,MODE_HIGH,ExtDepth,shift));
      if     (   val==lasthigh  ) val=0.0;
      else   {   lasthigh=val;
                if((val-iHigh(NULL,PERIOD_CURRENT,shift))>(ExtDeviation*Point())) val=0.0;
      else   {    for(back=1; back<=ExtBackstep; back++)
             {    res=HighMapBuffer[shift+back];
                  if((res!=0)&&(res<val)) HighMapBuffer[shift+back]=0.0; 
            }}}
      if (iHigh(NULL,PERIOD_CURRENT,shift)==val) HighMapBuffer[shift]=val; else HighMapBuffer[shift]=0.0;
  }
//==============================================================================================
   // final cutting 
   if (whatlookfor==0)
         {  lastlow=0;
            lasthigh=0;  
         }
   else  {   lastlow=curlow;
             lasthigh=curhigh;
         }
//==============================================================================================          
  // for (shift=limit;shift>=0;shift--)
   for (shift=CountBars ;shift>=0;shift--)
     {
      res=0.0;
      switch(whatlookfor)
        {    case 0: // look for peak or lawn 
            if (lastlow==0 && lasthigh==0)
              {    if (HighMapBuffer[shift]!=0)
                 {     lasthigh=iHigh(NULL,PERIOD_CURRENT,shift);
                       lasthighpos=shift;
                       whatlookfor=-1;
                       ZigzagBuffer[shift]=lasthigh;
                       DrawHighLabel(shift);
                       res=1;
                 }
               if (LowMapBuffer[shift]!=0)
                 {    lastlow=iLow(NULL,PERIOD_CURRENT,shift);
                      lastlowpos=shift;
                      whatlookfor=1;
                      ZigzagBuffer[shift]=lastlow;
                      DrawLowLabel(shift);
                      res=1;
                 }
              }
             break;
//==============================================================================================               
         case 1: // look for peak
            if (LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow && HighMapBuffer[shift]==0.0)
              {     ZigzagBuffer[lastlowpos]=0.0;
                    RemoveLabel(lastlowpos);
                    lastlowpos=shift;
                    lastlow=LowMapBuffer[shift];
                    ZigzagBuffer[shift]=lastlow;
                    DrawLowLabel(shift);
                    res=1;
              }
            if (HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
              {    lasthigh=HighMapBuffer[shift];
                   lasthighpos=shift;
                   ZigzagBuffer[shift]=lasthigh;
                   DrawHighLabel(shift);
                   whatlookfor=-1;
                   res=1;
              }   
            break;  
//==============================================================================================                         
         case -1: // look for lawn
            if (HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh && LowMapBuffer[shift]==0.0)
              {    ZigzagBuffer[lasthighpos]=0.0;
                   RemoveLabel(lasthighpos);
                   lasthighpos=shift;
                   lasthigh=HighMapBuffer[shift];
                   ZigzagBuffer[shift]=lasthigh;
                   DrawHighLabel(shift);
                   res=1;
              }
            if (LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
              {    lastlow=LowMapBuffer[shift];
                   lastlowpos=shift;
                   ZigzagBuffer[shift]=lastlow;
                   DrawLowLabel(shift);
                   whatlookfor=1;
                   res=1;
              }   
            break;               
         default: 
            break;
      }   
   }
//==============================================================================================
   return(0);
  }
//==============================================================================================
//==============================================================================================  
void DrawHighLabel(int shift)
{  
   string status = "";
   double currentHigh = HighMapBuffer[shift];
   double previousHigh;
   
   // find the previous high
  for (int i=shift+1; i<shift+1000; i++)
       {       if (HighMapBuffer[i] != 0 && ZigzagBuffer[i] != 0)
              {    previousHigh = HighMapBuffer[i];
                   break;
       }      }
//------------------------------------
  //  double position = HighMapBuffer[shift] + (Labeldistance * Point * PipFactor);  
     double position = HighMapBuffer[shift] +  (Mut*Poin );
//-----------------------    
   // if   (currentHigh > previousHigh)  {   status = "HH  ";  }
   // else                               {   status = "LH  ";  }
  // ObjectCreate( +"statusLabel"+Time[shift], OBJ_TEXT, 0, Time[shift], position);
  // ObjectSetText(+"statusLabel"+Time[shift], status, 10, "Arial", TopColorHH); 
     
   ObjectCreate(0,"statusLabel"+iTime(NULL,PERIOD_CURRENT,shift), OBJ_TEXT, 0, iTime(NULL,PERIOD_CURRENT,shift), position);
   if   (currentHigh >= previousHigh) {
      ObjectSetText("statusLabel"+iTime(NULL,PERIOD_CURRENT,shift), "HH  ", TxtSize1, Fonts, TopColorHH);
      HH[shift] = HighMapBuffer[shift];
      double prev_price_HH = EMPTY_VALUE;
      datetime prev_time_HH = 0;
      color clr;
      GetPrev(HH,shift,prev_price_HH,prev_time_HH);
      if(prev_price_HH!=EMPTY_VALUE) {
         clr = HH[shift]>=prev_price_HH? c_H_HH : c_L_HH;
         DrawLine(HH_name+string(int(iTime(NULL,PERIOD_CURRENT,shift))), prev_time_HH, prev_price_HH, iTime(NULL,PERIOD_CURRENT,shift), HH[shift], clr);
      }
   }
   if   (currentHigh <= previousHigh) (ObjectSetText("statusLabel"+Time[shift], "LH  ", TxtSize2, Fonts, TopColorLH));
//-------------------------  
}
//==============================================================================================
//==============================================================================================
void DrawLowLabel(int shift)
{ 
  string status = "";
   double currentLow = LowMapBuffer[shift];
   double previousLow;
   
   // find the previous Low
   for (int i=shift+1; i<shift+1000; i++)
       {   if (LowMapBuffer[i] != 0 && ZigzagBuffer[i] != 0)
              {  previousLow = LowMapBuffer[i];
                 break;
       }      }
//------------------------------------     
  // double position = LowMapBuffer[shift] - (Labeldistance/2 * Point * PipFactor);
  //   double position = LowMapBuffer[shift] +  ( Mdt*Poin );
      double position = LowMapBuffer[shift] ;
//------------------------------------       
 //   if   (currentLow > previousLow)     {   status = "HL  " ;   }
 //   else                                {   status = "LL  ";    } 
 //  ObjectCreate( +"statusLabel"+Time[shift], OBJ_TEXT, 0, Time[shift], position);
  // ObjectSetText(+"statusLabel"+Time[shift], status, 10, "Arial", LabelColor2);
   
    ObjectCreate(0, "statusLabel"+iTime(NULL,PERIOD_CURRENT,shift), OBJ_TEXT, 0, iTime(NULL,PERIOD_CURRENT,shift), position);
   if   (currentLow >= previousLow) ObjectSetText("statusLabel"+iTime(NULL,PERIOD_CURRENT,shift), "HL  ", TxtSize2, Fonts, BotColorHL);
   if   (currentLow <= previousLow) {
      ObjectSetText("statusLabel"+iTime(NULL,PERIOD_CURRENT,shift), "LL  ", TxtSize1, Fonts, BotColorLL);
      LL[shift] = LowMapBuffer[shift];
      double prev_price_LL = EMPTY_VALUE;
      datetime prev_time_LL = 0;
      color clr;
      GetPrev(LL,shift,prev_price_LL,prev_time_LL);
      if(prev_price_LL!=EMPTY_VALUE) {
         clr = LL[shift]<=prev_price_LL? c_L_LL : c_H_LL;
         DrawLine(LL_name+string(int(iTime(NULL,PERIOD_CURRENT,shift))), prev_time_LL, prev_price_LL, iTime(NULL,PERIOD_CURRENT,shift), LL[shift], clr);
      }
   }
    
//-------------------------------------  
}
//==============================================================================================
//==============================================================================================
void RemoveLabel(int shift)
{  ObjectDelete(0,"statusLabel"+iTime(NULL,PERIOD_CURRENT,shift));
}
//==============================================================================================
//==============================================================================================
void del_objF() 
 {
   int k=0;
  while (k<ObjectsTotal(0,0,-1))  
   {    string ObjName = ObjectName(0,k,0,-1);
     if (StringSubstr(ObjName,0,StringLen("statusLabel")) =="statusLabel")  
         ObjectDelete(0,ObjName);
    else
         k++;
  } 
  return;
}
//==============================================================================================
//==============================================================================================
void GetPrev(double &array[], int shift, double &prev_price, datetime &prev_time) {
//---
   for(int i=shift+1; i<Bars; i++) {
      if(array[i]!=EMPTY_VALUE) {
         prev_price = array[i];
         prev_time = iTime(NULL,PERIOD_CURRENT,i);
         break;
      }
   }
//---
}
//==============================================================================================
//============================================================================================== 
void DrawLine(string name, datetime time1, double price1, datetime time2, double price2, color clr) {
//---
   long chart_ID = 0;
   ObjectDelete(chart_ID,name);
   ObjectCreate(chart_ID,name,OBJ_TREND,0,time1,price1,time2,price2);
   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
   ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,STYLE_SOLID);
   ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,Line_HH_LL_Width);
   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,false);
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,false);
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,false);
   ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,false);
   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,true);
//---
}