//+------------------------------------------------------------------+
//|                                                Crystal Trend.mq4 |
//|                            Copyright © 2011, MQL-Programming.com |
//|                                   http://www.mql-programming.com |
//+------------------------------------------------------------------+

#property copyright "Copyright 2011, MQL-Programming.com"
#property link      "http://www.mql-programming.com"


#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 White

extern int Strictness = 5;
double gd_80;
double gd_88;
double g_ibuf_96[];
int gi_100;
int gi_104;
double gd_108;
double gd_116;
double gd_124;
double gd_132;
double gd_140;
datetime g_time_148;
bool gi_152 = TRUE;

int init() {
   iCustom(Symbol(), Period(), "client alert", 0, 1);
   IndicatorDigits(Digits);
   SetIndexStyle(0, DRAW_ARROW);
   SetIndexArrow(0, 250);
   SetIndexBuffer(0, g_ibuf_96);
   SetIndexLabel(0, "Trend Stop Loss");
   switch (Strictness) {
   case 1:
      gd_80 = 0.02;
      gd_88 = 0.2;
      break;
   case 2:
      gd_80 = 0.03;
      gd_88 = 0.3;
      break;
   case 3:
      gd_80 = 0.04;
      gd_88 = 0.4;
      break;
   case 4:
      gd_80 = 0.05;
      gd_88 = 0.5;
      break;
   case 5:
      gd_80 = 0.06;
      gd_88 = 0.6;
      break;
   default:
      Alert("Unable to set Strictness value ", Strictness, ".  Available values {1 2 3 4 5} 5 being Loosest.");
      gd_80 = 0.03;
      gd_88 = 0.3;
   }
   return (0);
}

void SaveLastReverse(int ai_0, int ai_4, double ad_8, double ad_16, double ad_24, double ad_32, double ad_40) {
   gi_100 = ai_0;
   gi_104 = ai_4;
   gd_108 = ad_8;
   gd_124 = ad_16;
   gd_116 = ad_24;
   gd_132 = ad_32;
   gd_140 = ad_40;
}

int start() {
   bool li_0;
   double ld_4;
   double l_high_12;
   double l_low_20;
   double ld_28;
   double ld_36;
   double l_low_44;
   double l_high_52;
   double ld_60;
   int li_76;
   int l_ind_counted_72 = IndicatorCounted();
   if (Bars < 3) return (0);
   int li_68 = Bars - 2;
   if (l_ind_counted_72 == 0 || gi_152) {
      li_76 = Bars - 1;
      gi_152 = FALSE;
      li_0 = TRUE;
      ld_4 = gd_80;
      l_high_12 = -10000000.0;
      l_low_20 = 10000000.0;
      while (li_68 > 0) {
         gi_100 = li_68;
         l_low_44 = Low[li_68];
         if (l_low_20 > l_low_44) l_low_20 = l_low_44;
         l_high_52 = High[li_68];
         if (l_high_12 < l_high_52) l_high_12 = l_high_52;
         if (l_high_52 > High[li_68 + 1] && l_low_44 > Low[li_68 + 1]) break;
         if (l_high_52 < High[li_68 + 1] && l_low_44 < Low[li_68 + 1]) {
            li_0 = FALSE;
            break;
         }
         li_68--;
      }
      for (int li_80 = li_68; li_80 < Bars; li_80++) g_ibuf_96[li_80] = 0.0;
      if (li_0) {
         g_ibuf_96[li_68] = Low[li_68 + 1];
         ld_28 = High[li_68];
      } else {
         g_ibuf_96[li_68] = High[li_68 + 1];
         ld_28 = Low[li_68];
      }
      li_68--;
   } else {
      li_68 = gi_100;
      ld_4 = gd_108;
      li_0 = gi_104;
      l_high_12 = gd_116;
      l_low_20 = gd_124;
      ld_28 = gd_132;
      ld_36 = gd_140;
      if (Time[0] != g_time_148) {
         g_time_148 = Time[0];
         li_68++;
      }
   }
   while (li_68 >= 0) {
      l_low_44 = Low[li_68];
      l_high_52 = High[li_68];
      if (li_0 && l_low_44 < g_ibuf_96[li_68 + 1]) {
         SaveLastReverse(li_68, 1, ld_4, l_low_44, l_high_12, ld_28, ld_36);
         ld_4 = gd_80;
         li_0 = FALSE;
         ld_28 = l_low_44;
         l_low_20 = l_low_44;
         g_ibuf_96[li_68] = l_high_12;
         li_68--;
         continue;
      }
      if (!li_0 && l_high_52 > g_ibuf_96[li_68 + 1]) {
         SaveLastReverse(li_68, 0, ld_4, l_low_20, l_high_52, ld_28, ld_36);
         ld_4 = gd_80;
         li_0 = TRUE;
         ld_28 = l_high_52;
         l_high_12 = l_high_52;
         g_ibuf_96[li_68] = l_low_20;
         li_68--;
         continue;
      }
      ld_60 = g_ibuf_96[li_68 + 1];
      ld_36 = ld_60 + ld_4 * (ld_28 - ld_60);
      if (li_0) {
         if (ld_28 < l_high_52 && ld_4 + gd_80 <= gd_88) ld_4 += gd_80;
         if (l_high_52 < High[li_68 + 1] && li_68 == Bars - 2) ld_36 = g_ibuf_96[li_68 + 1];
         ld_60 = Low[li_68 + 1];
         if (ld_36 > ld_60) ld_36 = ld_60;
         ld_60 = Low[li_68 + 2];
         if (ld_36 > ld_60) ld_36 = ld_60;
         if (ld_36 > l_low_44) {
            SaveLastReverse(li_68, 1, ld_4, l_low_44, l_high_12, ld_28, ld_36);
            ld_4 = gd_80;
            li_0 = FALSE;
            ld_28 = l_low_44;
            l_low_20 = l_low_44;
            g_ibuf_96[li_68] = l_high_12;
            li_68--;
            continue;
         }
         if (ld_28 < l_high_52) {
            l_high_12 = l_high_52;
            ld_28 = l_high_52;
         }
      } else {
         if (ld_28 > l_low_44 && ld_4 + gd_80 <= gd_88) ld_4 += gd_80;
         if (l_low_44 < Low[li_68 + 1] && li_68 == Bars - 2) ld_36 = g_ibuf_96[li_68 + 1];
         ld_60 = High[li_68 + 1];
         if (ld_36 < ld_60) ld_36 = ld_60;
         ld_60 = High[li_68 + 2];
         if (ld_36 < ld_60) ld_36 = ld_60;
         if (ld_36 < l_high_52) {
            SaveLastReverse(li_68, 0, ld_4, l_low_20, l_high_52, ld_28, ld_36);
            ld_4 = gd_80;
            li_0 = TRUE;
            ld_28 = l_high_52;
            l_high_12 = l_high_52;
            g_ibuf_96[li_68] = l_low_20;
            li_68--;
            continue;
         }
         if (ld_28 > l_low_44) {
            l_low_20 = l_low_44;
            ld_28 = l_low_44;
         }
      }
      g_ibuf_96[li_68] = ld_36;
      li_68--;
   }
   return (0);
}