/*
   Generated by EX4-TO-MQ4 decompiler V4.0.438.3 [-]
   Website: https://purebeam.biz
   E-mail : purebeam@gmail.com
*/

#property indicator_separate_window
#property indicator_minimum -1.3
#property indicator_maximum 1.3
#property indicator_buffers 2
#property indicator_color1 Lime
#property indicator_color2 Yellow
#property indicator_level1 0.9
#property indicator_level2 -0.9
#property indicator_level3 0.75
#property indicator_level4 -0.75

extern int SnakeRange = 12;
extern int FilterPeriod = 12;
extern double MartFiltr = 2.0;
extern int PriceConst = 6;
double g_ibuf_96[];
double g_ibuf_100[];
double gda_104[];
double g_ibuf_108[];
int gi_112 = 14;
double gda_116[];
double gd_120;
int gia_128[];
int gia_132[];

void f0_0(int ai_0) {
   int li_4;
   int count_8;
   int li_12;
   int li_16;
   double ld_24;
   switch (PriceConst) {
   case 0:
      gda_104[ai_0] = iMA(NULL, 0, SnakeRange + 1, 0, MODE_LWMA, PRICE_CLOSE, ai_0);
      break;
   case 1:
      gda_104[ai_0] = iMA(NULL, 0, SnakeRange + 1, 0, MODE_LWMA, PRICE_OPEN, ai_0);
      break;
   case 2:
      gda_104[ai_0] = iMA(NULL, 0, SnakeRange + 1, 0, MODE_LWMA, PRICE_HIGH, ai_0);
      break;
   case 3:
      gda_104[ai_0] = iMA(NULL, 0, SnakeRange + 1, 0, MODE_LWMA, PRICE_LOW, ai_0);
      break;
   case 4:
      gda_104[ai_0] = iMA(NULL, 0, SnakeRange + 1, 0, MODE_LWMA, PRICE_MEDIAN, ai_0);
      break;
   case 5:
      gda_104[ai_0] = iMA(NULL, 0, SnakeRange + 1, 0, MODE_LWMA, PRICE_TYPICAL, ai_0);
      break;
   case 6:
      gda_104[ai_0] = iMA(NULL, 0, SnakeRange + 1, 0, MODE_LWMA, PRICE_WEIGHTED, ai_0);
      break;
   default:
      gda_104[ai_0] = iMA(NULL, 0, SnakeRange + 1, 0, MODE_LWMA, PRICE_WEIGHTED, ai_0);
   }
   for (int li_20 = ai_0 + SnakeRange + 2; li_20 > ai_0; li_20--) {
      ld_24 = 0.0;
      li_4 = 0;
      count_8 = 0;
      li_12 = li_20 + SnakeRange;
      li_16 = li_20 - SnakeRange;
      if (li_16 < ai_0) li_16 = ai_0;
      while (li_12 >= li_20) {
         count_8++;
         ld_24 += count_8 * f0_2(li_12);
         li_4 += count_8;
         li_12--;
      }
      while (li_12 >= li_16) {
         count_8--;
         ld_24 += count_8 * f0_2(li_12);
         li_4 += count_8;
         li_12--;
      }
      gda_104[li_20] = ld_24 / li_4;
   }
}

double f0_2(int ai_0) {
   switch (PriceConst) {
   case 0:
      return (Close[ai_0]);
   case 1:
      return (Open[ai_0]);
   case 2:
      return (High[ai_0]);
   case 3:
      return (Low[ai_0]);
   case 4:
      return ((High[ai_0] + Low[ai_0]) / 2.0);
   case 5:
      return ((Close[ai_0] + High[ai_0] + Low[ai_0]) / 3.0);
   case 6:
      return ((2.0 * Close[ai_0] + High[ai_0] + Low[ai_0]) / 4.0);
   }
   return (Close[ai_0]);
}

void f0_4(int ai_0) {
   double ld_4 = gda_104[ArrayMaximum(gda_104, FilterPeriod, ai_0)];
   double ld_12 = gda_104[ArrayMinimum(gda_104, FilterPeriod, ai_0)];
   g_ibuf_108[ai_0] = (2.0 * (MartFiltr + 2.0) * gda_104[ai_0] - (ld_4 + ld_12)) / 2.0 / (MartFiltr + 1.0);
}

double f0_1(double ada_0[], int ai_4) {
   double ld_16;
   for (int index_24 = 0; index_24 < ai_4; index_24++) ld_16 += MathPow(ada_0[index_24] - index_24 - 1.0, 2);
   double ld_ret_8 = 1 - 6.0 * ld_16 / (MathPow(ai_4, 3) - ai_4);
   return (ld_ret_8);
}

void f0_3(int aia_0[]) {
   double ld_4;
   double ld_12;
   int index_24;
   int li_32;
   int li_36;
   int li_40;
   double lda_44[];
   ArrayResize(lda_44, gi_112);
   ArrayCopy(gia_132, aia_0);
   for (int index_20 = 0; index_20 < gi_112; index_20++) lda_44[index_20] = index_20 + 1;
   ArraySort(gia_132, WHOLE_ARRAY, 0, MODE_DESCEND);
   for (index_20 = 0; index_20 < gi_112 - 1; index_20++) {
      if (gia_132[index_20] == gia_132[index_20 + 1]) {
         li_32 = gia_132[index_20];
         index_24 = index_20 + 1;
         li_36 = 1;
         ld_12 = index_20 + 1;
         while (index_24 < gi_112) {
            if (gia_132[index_24] != li_32) break;
            li_36++;
            ld_12 += index_24 + 1;
            index_24++;
         }
         ld_4 = li_36;
         ld_12 /= ld_4;
         for (int li_28 = index_20; li_28 < index_24; li_28++) lda_44[li_28] = ld_12;
         index_20 = index_24;
      }
   }
   for (index_20 = 0; index_20 < gi_112; index_20++) {
      li_40 = aia_0[index_20];
      for (index_24 = 0; index_24 < gi_112; index_24++) {
         if (li_40 == gia_132[index_24]) {
            gda_116[index_20] = lda_44[index_24];
            break;
         }
      }
   }
}

int init() {
   IndicatorBuffers(4);
   SetIndexBuffer(0, g_ibuf_96);
   SetIndexStyle(0, DRAW_LINE);
   SetIndexBuffer(1, g_ibuf_100);
   SetIndexStyle(1, DRAW_LINE);
   SetIndexBuffer(2, gda_104);
   SetIndexStyle(2, DRAW_NONE);
   SetIndexBuffer(3, g_ibuf_108);
   SetIndexStyle(3, DRAW_NONE);
   ArrayResize(gda_116, gi_112);
   ArrayResize(gia_128, gi_112);
   ArrayResize(gia_132, gi_112);
   if (gi_112 > 30) IndicatorShortName("Decrease rangeN input!");
   else SetIndexLabel(0, "main");
   SetIndexLabel(1, "signal");
   IndicatorShortName("S");
   gd_120 = MathPow(10, Digits);
   return (0);
}

int deinit() {
   return (0);
}

int start() {
   int li_8;
   int li_12;
   int li_16;
   double ld_44;
   int ind_counted_20 = IndicatorCounted();
   if (gi_112 > 30) return (-1);
   if (ind_counted_20 == 0) {
      li_8 = Bars - (gi_112 + FilterPeriod + SnakeRange + 4);
      li_12 = Bars - (SnakeRange + 2);
      li_16 = Bars - (FilterPeriod + SnakeRange + 3);
   }
   if (ind_counted_20 > 0) {
      li_8 = Bars - ind_counted_20 + 1;
      li_12 = li_8;
      li_16 = li_8;
   }
   for (int li_0 = li_12; li_0 >= 0; li_0--) f0_0(li_0);
   for (li_0 = li_16; li_0 >= 0; li_0--) f0_4(li_0);
   for (li_0 = li_8; li_0 >= 0; li_0--) {
      for (int index_4 = 0; index_4 < gi_112; index_4++) gia_128[index_4] = (g_ibuf_108[li_0 + index_4]) * gd_120;
      f0_3(gia_128);
      g_ibuf_96[li_0] = f0_1(gda_116, gi_112);
      if (g_ibuf_96[li_0] > 1.0) g_ibuf_96[li_0] = 1.0;
      if (g_ibuf_96[li_0] < -1.0) g_ibuf_96[li_0] = -1.0;
   }
   int li_24 = Bars - ind_counted_20;
   double ld_28 = 0.9;
   double ld_36 = -0.9;
   while (li_24 >= 0) {
      ld_44 = g_ibuf_96[li_24];
      if (ld_44 >= ld_28) g_ibuf_100[li_24] = 1;
      if (ld_44 <= ld_36) g_ibuf_100[li_24] = -1;
      if (ld_44 < ld_28)
         if (ld_44 > ld_36) g_ibuf_100[li_24] = 0;
      li_24--;
   }
   return (0);
}
