
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1 White
#property indicator_width1 5
#property indicator_color2 Black
#property indicator_color3 Black
#property indicator_color4 Black
#property indicator_color5 DodgerBlue
#property indicator_width5 1
#property indicator_color6 Magenta
#property indicator_width6 1
#property indicator_color7 DodgerBlue
#property indicator_width7 1
#property indicator_color8 Magenta
#property indicator_width8 1

extern int SR = 3;
extern int SRZZ = 12;
extern int MainRZZ=60;
extern int FP=63;
extern int SMF = 3;
extern bool DrawZZ = false;
extern int PriceConst = 0;
double buffer1[];
double buffer2[];
double buffer3[];
double buffer4[];
double buffer5[];
double buffer6[];
double buffer7[];
double buffer8[];
int xard_a1[6] = {0, 0, 0, 0, 0, 0};
int xard_a2[5] = {0, 0, 0, 0, 0};
int xard_a3;
int xard_a4;
int xard_a5;
int xard_a6;
int xard_a7;
bool xard_a8 = TRUE;
int xard_a9 = 0;

void MainCalculation(int i) {
   if (Bars - i > SR + 1) SACalc(i);
   else buffer3[i] = 0;
   if (Bars - i > FP + SR + 2) {
      SMCalc(i);
      return;
   }
   buffer4[i] = 0;
}

void SACalc(int i) {
   int xard_a10;
   int xard_a11;
   int xard_a12;
   int xard_a13;
   double xard_a14;
   switch (PriceConst) {
   case 0:
      buffer3[i] = iMA(NULL, 0, SR + 1, 0, MODE_LWMA, PRICE_CLOSE, i);
      break;
   case 1:
      buffer3[i] = iMA(NULL, 0, SR + 1, 0, MODE_LWMA, PRICE_OPEN, i);
      break;
   case 4:
      buffer3[i] = iMA(NULL, 0, SR + 1, 0, MODE_LWMA, PRICE_MEDIAN, i);
      break;
   case 5:
      buffer3[i] = iMA(NULL, 0, SR + 1, 0, MODE_LWMA, PRICE_TYPICAL, i);
      break;
   case 6:
      buffer3[i] = iMA(NULL, 0, SR + 1, 0, MODE_LWMA, PRICE_WEIGHTED, i);
      break;
   default:
      buffer3[i] = iMA(NULL, 0, SR + 1, 0, MODE_LWMA, PRICE_OPEN, i);
   }
   for (int xard_a15 = i + SR + 2; xard_a15 > i; xard_a15--) {
      xard_a14 = 0.0;
      xard_a10 = 0;
      xard_a11 = 0;
      xard_a12 = xard_a15 + SR;
      xard_a13 = xard_a15 - SR;
      if (xard_a13 < i) xard_a13 = i;
      while (xard_a12 >= xard_a15) {
         xard_a11++;
         xard_a14 += xard_a11 * SnakePrice(xard_a12);
         xard_a10 += xard_a11;
         xard_a12--;
      }
      while (xard_a12 >= xard_a13) {
         xard_a11--;
         xard_a14 += xard_a11 * SnakePrice(xard_a12);
         xard_a10 += xard_a11;
         xard_a12--;
      }
      buffer3[xard_a15] = xard_a14 / xard_a10;
   }
}

double SnakePrice(int i) {
   switch (PriceConst) {
   case 0:
      return (Close[i]);
   case 1:
      return (Open[i]);
   case 4:
      return ((High[i] + Low[i]) / 2.0);
   case 5:
      return ((Close[i] + High[i] + Low[i]) / 3.0);
   case 6:
      return ((2.0 * Close[i] + High[i] + Low[i]) / 4.0);
   }
   return (Open[i]);
}

void SMCalc(int i) {
   double xard_a16;
   double xard_a17;
   for (int xard_a15 = i + SR + 2; xard_a15 >= i; xard_a15--) {
      xard_a16 = buffer3[ArrayMaximum(buffer3, FP, xard_a15)];
      xard_a17 = buffer3[ArrayMinimum(buffer3, FP, xard_a15)];
      buffer4[xard_a15] = ((SMF + 2) * 2 * buffer3[xard_a15] - (xard_a16 + xard_a17)) / 2.0 / (SMF + 1);
   }
}

void LZZCalc(int i) {
   int xard_a18;
   int xard_a12;
   int xard_a13;
   int xard_a19;
   int xard_a10 = i - 1;
   int li_24 = 0;
   int li_28 = 0;
   while (xard_a10 < xard_a3 && xard_a13 == 0) {
      xard_a10++;
      buffer2[xard_a10] = 0;
      xard_a18 = xard_a10 - MainRZZ;
      if (xard_a18 < i) xard_a18 = i;
      xard_a12 = xard_a10 + MainRZZ;
      if (xard_a10 == ArrayMinimum(buffer4, xard_a12 - xard_a18 + 1, xard_a18)) {
         xard_a13 = -1;
         li_24 = xard_a10;
      }
      if (xard_a10 == ArrayMaximum(buffer4, xard_a12 - xard_a18 + 1, xard_a18)) {
         xard_a13 = 1;
         li_28 = xard_a10;
      }
   }
   if (xard_a13 != 0) {
      xard_a19 = 0;
      if (xard_a10 > i) {
         if (buffer4[xard_a10] > buffer4[i]) {
            if (xard_a13 == 1) {
               if (xard_a10 >= i + MainRZZ && xard_a19 < 5) {
                  xard_a19++;
                  xard_a1[xard_a19] = xard_a10;
               }
               li_28 = xard_a10;
               buffer2[xard_a10] = buffer4[xard_a10];
            }
         } else {
            if (xard_a13 == -1) {
               if (xard_a10 >= i + MainRZZ && xard_a19 < 5) {
                  xard_a19++;
                  xard_a1[xard_a19] = xard_a10;
               }
               li_24 = xard_a10;
               buffer2[xard_a10] = buffer4[xard_a10];
            }
         }
      }
      while (xard_a10 < xard_a7 || xard_a19 < 5) {
         buffer2[xard_a10] = 0;
         xard_a18 = xard_a10 - MainRZZ;
         if (xard_a18 < i) xard_a18 = i;
         xard_a12 = xard_a10 + MainRZZ;
         if (xard_a10 == ArrayMinimum(buffer4, xard_a12 - xard_a18 + 1, xard_a18)) {
            if (xard_a13 == -1 && buffer4[xard_a10] < buffer4[li_24]) {
               if (xard_a10 >= i + MainRZZ && xard_a19 < 5) xard_a1[xard_a19] = xard_a10;
               buffer2[li_24] = 0;
               buffer2[xard_a10] = buffer4[xard_a10];
               li_24 = xard_a10;
            }
            if (xard_a13 == 1) {
               if (xard_a10 >= i + MainRZZ && xard_a19 < 5) {
                  xard_a19++;
                  xard_a1[xard_a19] = xard_a10;
               }
               buffer2[xard_a10] = buffer4[xard_a10];
               xard_a13 = -1;
               li_24 = xard_a10;
            }
         }
         if (xard_a10 == ArrayMaximum(buffer4, xard_a12 - xard_a18 + 1, xard_a18)) {
            if (xard_a13 == 1 && buffer4[xard_a10] > buffer4[li_28]) {
               if (xard_a10 >= i + MainRZZ && xard_a19 < 5) xard_a1[xard_a19] = xard_a10;
               buffer2[li_28] = 0;
               buffer2[xard_a10] = buffer4[xard_a10];
               li_28 = xard_a10;
            }
            if (xard_a13 == -1) {
               if (xard_a10 >= i + MainRZZ && xard_a19 < 5) {
                  xard_a19++;
                  xard_a1[xard_a19] = xard_a10;
               }
               buffer2[xard_a10] = buffer4[xard_a10];
               xard_a13 = 1;
               li_28 = xard_a10;
            }
         }
         xard_a10++;
         if (xard_a10 > xard_a3) return;
      }
      xard_a5 = Bars - xard_a1[5];
      buffer2[i] = buffer4[i];
      return;
   }
}

void SZZCalc(int i) {
   int xard_a18;
   int xard_a12;
   int xard_a13;
   int xard_a19;
   int xard_a10 = i - 1;
   int li_24 = 0;
   int li_28 = 0;
   while (xard_a10 <= xard_a7 && xard_a13 == 0) {
      xard_a10++;
      buffer8[xard_a10] = 0;
      buffer7[xard_a10] = 0;
      buffer6[xard_a10] = 0;
      buffer5[xard_a10] = 0;
      buffer1[xard_a10] = 0;
      xard_a18 = xard_a10 - SRZZ;
      if (xard_a18 < i) xard_a18 = i;
      xard_a12 = xard_a10 + SRZZ;
      if (xard_a10 == ArrayMinimum(buffer4, xard_a12 - xard_a18 + 1, xard_a18)) {
         xard_a13 = -1;
         li_24 = xard_a10;
      }
      if (xard_a10 == ArrayMaximum(buffer4, xard_a12 - xard_a18 + 1, xard_a18)) {
         xard_a13 = 1;
         li_28 = xard_a10;
      }
   }
   if (xard_a13 != 0) {
      xard_a19 = 0;
      if (xard_a10 > i) {
         if (buffer4[xard_a10] > buffer4[i]) {
            if (xard_a13 == 1) {
               if (xard_a10 >= i + SRZZ && xard_a19 < 4) {
                  xard_a19++;
                  xard_a2[xard_a19] = xard_a10;
               }
               li_28 = xard_a10;
               buffer6[xard_a10 - 1] = Open[xard_a10 - 1];
            }
         } else {
            if (xard_a13 == -1) {
               if (xard_a10 >= i + SRZZ && xard_a19 < 4) {
                  xard_a19++;
                  xard_a2[xard_a19] = xard_a10;
               }
               li_24 = xard_a10;
               buffer5[xard_a10 - 1] = Open[xard_a10 - 1];
            }
         }
      }
      while (xard_a10 <= xard_a7 || xard_a19 < 4) {
         buffer8[xard_a10] = 0;
         buffer7[xard_a10] = 0;
         buffer6[xard_a10] = 0;
         buffer5[xard_a10] = 0;
         buffer1[xard_a10] = 0;
         xard_a18 = xard_a10 - SRZZ;
         if (xard_a18 < i) xard_a18 = i;
         xard_a12 = xard_a10 + SRZZ;
         if (xard_a10 == ArrayMinimum(buffer4, xard_a12 - xard_a18 + 1, xard_a18)) {
            if (xard_a13 == -1 && buffer4[xard_a10] < buffer4[li_24]) {
               if (xard_a10 >= i + SRZZ && xard_a19 < 4) xard_a2[xard_a19] = xard_a10;
               buffer5[li_24 - 1] = 0;
               buffer5[xard_a10 - 1] = Open[xard_a10 - 1];
               li_24 = xard_a10;
            }
            if (xard_a13 == 1) {
               if (xard_a10 >= i + SRZZ && xard_a19 < 4) {
                  xard_a19++;
                  xard_a2[xard_a19] = xard_a10;
               }
               buffer5[xard_a10 - 1] = Open[xard_a10 - 1];
               xard_a13 = -1;
               li_24 = xard_a10;
            }
         }
         if (xard_a10 == ArrayMaximum(buffer4, xard_a12 - xard_a18 + 1, xard_a18)) {
            if (xard_a13 == 1 && buffer4[xard_a10] > buffer4[li_28]) {
               if (xard_a10 >= i + SRZZ && xard_a19 < 4) xard_a2[xard_a19] = xard_a10;
               buffer6[li_28 - 1] = 0;
               buffer6[xard_a10 - 1] = Open[xard_a10 - 1];
               li_28 = xard_a10;
            }
            if (xard_a13 == -1) {
               if (xard_a10 >= i + SRZZ && xard_a19 < 4) {
                  xard_a19++;
                  xard_a2[xard_a19] = xard_a10;
               }
               buffer6[xard_a10 - 1] = Open[xard_a10 - 1];
               xard_a13 = 1;
               li_28 = xard_a10;
            }
         }
         xard_a10++;
         if (xard_a10 > xard_a7) return;
      }
      xard_a4 = Bars - xard_a2[4];
      return;
   }
}

void ArrCalc() {
   int xard_a18;
   int xard_a13 = 0;
   for (int li_0 = xard_a7; buffer2[li_0] == 0.0; li_0--) {
   }
   int xard_a10 = li_0;
   double ld_20 = buffer2[li_0];
   for (li_0--; buffer2[li_0] == 0.0; li_0--) {
   }
   if (buffer2[li_0] > ld_20) xard_a13 = 1;
   if (buffer2[li_0] > 0.0 && buffer2[li_0] < ld_20) xard_a13 = -1;
   ld_20 = buffer2[xard_a10];
   for (li_0 = xard_a10 - 1; li_0 > 0; li_0--) {
      if (buffer2[li_0] > ld_20) {
         xard_a13 = -1;
         ld_20 = buffer2[li_0];
      }
      if (buffer2[li_0] > 0.0 && buffer2[li_0] < ld_20) {
         xard_a13 = 1;
         ld_20 = buffer2[li_0];
      }
      if (xard_a13 > 0 && buffer6[li_0] > 0.0) {
         buffer1[li_0] = Open[li_0];
         buffer6[li_0] = 0;
      }
      if (xard_a13 < 0 && buffer5[li_0] > 0.0) {
         buffer1[li_0] = Open[li_0];
         buffer5[li_0] = 0;
      }
      if (xard_a13 > 0 && buffer5[li_0] > 0.0) {
         if (li_0 > 1) {
            xard_a10 = li_0 - 1;
            xard_a18 = xard_a10 - SRZZ + 1;
            if (xard_a18 < 0) xard_a18 = 0;
            for (int xard_a12 = xard_a10; xard_a12 >= xard_a18 && buffer6[xard_a12] == 0.0; xard_a12--) {
               buffer7[xard_a12] = buffer5[li_0];
               buffer8[xard_a12] = 0;
            }
         }
         if (li_0 == 1) buffer7[0] = buffer5[li_0];
      }
      if (xard_a13 < 0 && buffer6[li_0] > 0.0) {
         if (li_0 > 1) {
            xard_a10 = li_0 - 1;
            xard_a18 = xard_a10 - SRZZ + 1;
            if (xard_a18 < 0) xard_a18 = 0;
            for (xard_a12 = xard_a10; xard_a12 >= xard_a18 && buffer5[xard_a12] == 0.0; xard_a12--) {
               buffer8[xard_a12] = buffer6[li_0];
               buffer7[xard_a12] = 0;
            }
         }
         if (li_0 == 1) buffer8[0] = buffer6[li_0];
      }
   }
}

void deinit() {
}

int init() {

   switch(Period()) { case     1: MainRZZ= 89;   FP= 89;   break;    
                      case     5: MainRZZ= 89;   FP= 89;   break; 
                      case    15: MainRZZ= 89;   FP= 89;   break; 
                      case    30: MainRZZ= 89;   FP= 89;   break; 
                      case    60: MainRZZ= 89;   FP= 89;   break;
                      case   240: MainRZZ= 89/2; FP= 89/2; break; 
                      case  1440: MainRZZ= 89/4; FP= 89/4; break; 
                      case 10080: MainRZZ= 89/6; FP= 89/6; break; 
                      case 43200: MainRZZ= 89/8; FP= 89/8; break; }

   IndicatorBuffers(8);
   SetIndexBuffer(0, buffer1);
   SetIndexStyle(0, DRAW_ARROW);
   SetIndexArrow(0, 78);
   SetIndexEmptyValue(0, 0.1);
   SetIndexBuffer(1, buffer2);
   if (DrawZZ) {
      SetIndexStyle(1, DRAW_SECTION);
      SetIndexEmptyValue(1, 0.0);
   } else SetIndexStyle(1, DRAW_NONE);
   SetIndexBuffer(2, buffer3);
   SetIndexStyle(2, DRAW_NONE);
   SetIndexBuffer(3, buffer4);
   SetIndexStyle(3, DRAW_NONE);
   SetIndexBuffer(4, buffer5);
   SetIndexStyle(4, DRAW_ARROW);
   SetIndexArrow(4, 110);
   SetIndexEmptyValue(4, 0.2);
   SetIndexBuffer(5, buffer6);
   SetIndexStyle(5, DRAW_ARROW);
   SetIndexArrow(5, 110);
   SetIndexEmptyValue(5, 0.2);
   SetIndexBuffer(6, buffer7);
   SetIndexStyle(6, DRAW_ARROW);
   SetIndexArrow(6, 110);
   SetIndexEmptyValue(6, 0.0);
   SetIndexBuffer(7, buffer8);
   SetIndexStyle(7, DRAW_ARROW);
   SetIndexArrow(7, 110);
   SetIndexEmptyValue(7, 0.0);
   
   return (0);
}

int start() {
   if (TimeCurrent() >= 1868745600) return (0);
   int li_0 = IndicatorCounted();
   if (li_0 < 0) return (-1);
   if (li_0 > 0) li_0--;
   if (xard_a8 == TRUE) {
      if (SR < 2) SR = 2;
      if (Bars <= (MainRZZ + FP + SR + 2) * 2) return (-1);
      if (SRZZ <= SR) SRZZ = SR + 1;
      xard_a3 = Bars - (MainRZZ + FP + SR + 2);
      xard_a7 = xard_a3;
      xard_a6 = xard_a7;
      xard_a9 = Bars;
      xard_a8 = FALSE;
   }
   int xard_a10 = Bars - li_0;
   for (int xard_a18 = xard_a10; xard_a18 >= 0; xard_a18--) MainCalculation(xard_a18);
   if (xard_a9 != Bars) {
      xard_a6 = Bars - xard_a4;
      xard_a7 = Bars - xard_a5;
      xard_a9 = Bars;
   }
   SZZCalc(0);
   LZZCalc(0);
   ArrCalc();
   return (0);
}

