/*
   Generated by EX4-TO-MQ4 decompiler V4.0.224.1 []
   Website: http://purebeam.biz
   E-mail : purebeam@gmail.com
*/
#property copyright "Copyright © 2008,FXDB, LLC"
#property link      "http://www.ForexDealButler.com"

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Black
#property indicator_color2 Black

//#include <FDB_File.mqh>

extern int Lines_Reversal = 3;
extern bool Ignore_Inside_Bars = FALSE;
extern bool Display_Risk = TRUE;
extern double Risk_Percent = 2.0;
extern int Max_Pairs_Active = 0;
extern double Max_Lots = 0.0;
extern double Fixed_Lots = 0.0;
extern int Slippage = 5;
extern int Display_Corner = 1;
extern bool AutoSet_Corner = TRUE;
extern color Long_Stop_Color = Blue;
extern color Short_Stop_Color = Red;
double g_ibuf_136[];
double g_ibuf_140[];
double gd_144;
double gd_152;
double g_pips_160 = 0.0;
bool gi_168;
bool gi_172 = TRUE;
int gi_176;
bool g_global_var_180;
int gi_184 = 0;
int g_str2dbl_188 = EMPTY_VALUE;
int g_str2dbl_192 = EMPTY_VALUE;
int gi_196;
int gi_200;
datetime g_time_204;
int g_datetime_208 = 0;
int gi_212 = 0;
int gi_216;

int init() {
   SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 1, Short_Stop_Color);
   SetIndexStyle(1, DRAW_LINE, STYLE_SOLID, 1, Long_Stop_Color);
   SetIndexBuffer(0, g_ibuf_136);
   SetIndexBuffer(1, g_ibuf_140);
   SetIndexEmptyValue(0, 0);
   SetIndexEmptyValue(1, 0);
   IndicatorShortName("3BarReversal_v3");
   SetIndexLabel(0, "3BarReversal_v3");
   SetIndexDrawBegin(0, Lines_Reversal);
   SetIndexDrawBegin(1, Lines_Reversal);
   Print("                          MONTH (October) = " + Month());
   if (Risk_Percent < 0.1) Risk_Percent = 0.1;
   if (Display_Corner < 0 || Display_Corner > 3) Display_Corner = 1;
   g_global_var_180 = TRUE;
   if (GlobalVariableCheck("GV_Pairs_in_Play")) g_global_var_180 = GlobalVariableGet("GV_Pairs_in_Play");
   /*if (FDB_Open("FDB.rkey")) {
      if (FDB_GetStatus(1) == 1) g_str2dbl_188 = StrToDouble(FDB_GetValue(1));
      if (FDB_GetStatus(2) == 1) g_str2dbl_192 = StrToDouble(FDB_GetValue(2));
      Print("Run_Key loaded from file.");
   } else Print("Run_Key file not Found."); */
   gi_168 = TRUE;
   if (GlobalVariableCheck(Symbol() + "_" + Period() + "_LotRisk")) GlobalVariableDel(Symbol() + "_" + Period() + "_LotRisk");
   if (GlobalVariableCheck(Symbol() + "_" + Period() + "_TradeLots")) GlobalVariableDel(Symbol() + "_" + Period() + "_TradeLots");
   if (GlobalVariableCheck(Symbol() + "_" + Period() + "_FixedLots")) GlobalVariableDel(Symbol() + "_" + Period() + "_FixedLots");
   if (GlobalVariableCheck(Symbol() + "_" + Period() + "_Slippage")) GlobalVariableDel(Symbol() + "_" + Period() + "_Slippage");
   gi_212 = fnMakeMagicNumber();
   return (0);
}

int deinit() {
   ObjectDelete("FDB_3bar1");
   ObjectDelete("FDB_3bar2");
   ObjectDelete("FDB_3bar3");
   if (GlobalVariableCheck(Symbol() + "_" + Period() + "_LotRisk")) GlobalVariableDel(Symbol() + "_" + Period() + "_LotRisk");
   if (GlobalVariableCheck(Symbol() + "_" + Period() + "_TradeLots")) GlobalVariableDel(Symbol() + "_" + Period() + "_TradeLots");
   if (GlobalVariableCheck(Symbol() + "_" + Period() + "_FixedLots")) GlobalVariableDel(Symbol() + "_" + Period() + "_FixedLots");
   if (GlobalVariableCheck(Symbol() + "_" + Period() + "_Slippage")) GlobalVariableDel(Symbol() + "_" + Period() + "_Slippage");
   return (0);
}

int start() {
   int l_count_0;
   int l_count_4;
   double ld_12;
   if (!IsConnected()) {
      if (gi_184 > 1) Print("No login Connection.");
      gi_184++;
   }
//  if (CheckKey() == 0 && AccountNumber() != 0) {
      for (int l_index_8 = 0; l_index_8 < 6; l_index_8++) {
//         if (CheckKey() == 1) break;
//         if (l_index_8 == 5 && CheckKey() == 0) {
//            Print("Registration Key Failed for Account#: " + AccountNumber());
//            deinit();
//            return (0);
//         }
      }
//   }  
   if (TimeCurrent() > g_datetime_208 + 15 + gi_212) {
      g_global_var_180 = GlobalVariableGet("GV_Pairs_in_Play");
      if (Max_Pairs_Active > 0) gi_196 = Max_Pairs_Active;
      else gi_196 = CheckPairs();
      if (g_global_var_180 != gi_196) GlobalVariableSet("GV_Pairs_in_Play", gi_196);
      g_datetime_208 = TimeCurrent();
   }
   if (Max_Lots > 0.0) GlobalVariableSet(Symbol() + "_" + Period() + "_TradeLots", Max_Lots);
   if (GlobalVariableCheck(Symbol() + "_" + Period() + "_TradeLots") && Max_Lots == 0.0) GlobalVariableDel(Symbol() + "_" + Period() + "_TradeLots");
   if (Slippage > 0) GlobalVariableSet(Symbol() + "_" + Period() + "_Slippage", Slippage);
   if (Fixed_Lots > 0.0) GlobalVariableSet(Symbol() + "_" + Period() + "_FixedLots", Fixed_Lots);
   if (GlobalVariableCheck(Symbol() + "_" + Period() + "_FixedLots") && Fixed_Lots == 0.0) GlobalVariableDel(Symbol() + "_" + Period() + "_FixedLots");
   int li_20 = IndicatorCounted();
   if (li_20 < 0) return (-1);
   if (li_20 > 0) li_20--;
   int li_24 = Bars - 1 - Lines_Reversal;
   int li_28 = Bars - 1 - li_20;
   if (li_28 > li_24) {
      for (l_index_8 = li_28; l_index_8 > li_24; l_index_8--) {
         g_ibuf_136[l_index_8] = 0.0;
         g_ibuf_140[l_index_8] = 0.0;
      }
      li_28 = li_24;
   }
   datetime l_time_32 = Time[li_28 + 1];
   if (li_28 < li_24) {
      if (l_time_32 == g_time_204) gi_172 = gi_176;
      else
         if (l_time_32 > g_time_204) return (-1);
   }
   if (newbar(Time[0])) g_pips_160 = NormalizeDouble(MarketInfo(Symbol(), MODE_SPREAD), Digits);
   for (l_index_8 = li_28; l_index_8 >= 0; l_index_8--) {
      if (l_index_8 == 1) {
         if ((li_28 == 1 && g_time_204 != Time[2]) || li_28 > 1) {
            g_time_204 = Time[2];
            gi_176 = gi_172;
         }
      }
      l_count_0 = 0;
      l_count_4 = 0;
      if (Ignore_Inside_Bars) {
         for (int li_36 = 1; li_36 < Lines_Reversal * 2; li_36++) {
            if (High[l_index_8 + li_36] > High[l_index_8 + li_36 + 1] || Low[l_index_8 + li_36] < Low[l_index_8 + li_36 + 1]) l_count_4++;
            else
               if (High[l_index_8 + li_36] < High[l_index_8 + li_36 + 1] || Low[l_index_8 + li_36] > Low[l_index_8 + li_36 + 1]) l_count_0++;
            if (l_count_4 == Lines_Reversal) break;
         }
      }
      gi_200 = gi_172;
      gd_144 = High[iHighest(NULL, 0, MODE_HIGH, Lines_Reversal + l_count_0, l_index_8 + 1)];
      gd_152 = Low[iLowest(NULL, 0, MODE_LOW, Lines_Reversal + l_count_0, l_index_8 + 1)];
      if (gi_200 && Low[l_index_8] <= gd_152) gi_172 = FALSE;
      if (!gi_200 && High[l_index_8] >= gd_144) gi_172 = TRUE;
      ld_12 = NormalizeDouble(MarketInfo(Symbol(), MODE_SPREAD), Digits);
      if (ld_12 > g_pips_160) {
         g_pips_160 = ld_12;
         newbar(Time[0]);
      }
      if (!gi_172) {
         g_ibuf_136[l_index_8] = gd_144 + g_pips_160 * Point;
         g_ibuf_140[l_index_8] = 0.0;
      }
      if (gi_172) {
         g_ibuf_140[l_index_8] = gd_152;
         g_ibuf_136[l_index_8] = 0.0;
      }
   }
   if (Display_Risk) watermark();
   return (0);
}

/* int CheckKey() {
   double ld_0;
   double ld_8;
   double ld_16;
   int l_month_24 = TimeMonth(TimeCurrent());
   if (IsDemo() == TRUE) {
      ld_0 = NormalizeDouble(MathAbs(AccountNumber() << 2 - 3912671 * l_month_24), 0);
      ld_16 = NormalizeDouble(MathAbs(g_str2dbl_192), 0);
   } else {
      ld_0 = NormalizeDouble(MathAbs(AccountNumber() << 2 + 10110110 - 5382974 * l_month_24), 0);
      ld_16 = NormalizeDouble(MathAbs(g_str2dbl_188), 0);
   }
   if (TimeMonth(TimeCurrent() - 259200) == l_month_24 - 1 && ld_16 > 0.0) {
      if (IsDemo() == TRUE) ld_8 = NormalizeDouble(MathAbs(AccountNumber() << 2 - 3912671 * (l_month_24 - 1)), 0);
      else ld_8 = NormalizeDouble(MathAbs(AccountNumber() << 2 + 10110110 - 5382974 * (l_month_24 - 1)), 0);
   }
   if (gi_168 == TRUE && ld_16 == ld_8) {
      Print("Registration Key expires on the 3rd at Midnite.  Login and generate a new key.");
      gi_168 = FALSE;
   }
   if (ld_16 == ld_0 || ld_16 == ld_8 && ld_16 > 0.0) return (1);
   return (0);
} */

void watermark() {
   double ld_0;
   color l_color_8;
   double ld_12;
   string l_text_20;
   string l_dbl2str_28;
   string l_dbl2str_36;
   double ld_44;
   string l_text_52;
   if (g_ibuf_140[0] > 0.0) {
      ld_0 = (Close[0] - g_ibuf_140[0]) / Point;
      l_color_8 = Long_Stop_Color;
   } else {
      if (g_ibuf_136[0] > 0.0) {
         ld_0 = (g_ibuf_136[0] - Close[0]) / Point;
         l_color_8 = Short_Stop_Color;
      }
   }
   double ld_60 = (WindowPriceMax() - WindowPriceMin()) / 3.0 + WindowPriceMin();
   double ld_68 = WindowPriceMax() - (WindowPriceMax() - WindowPriceMin()) / 3.0;
   int l_corner_76 = Display_Corner;
   if (AutoSet_Corner == TRUE) {
      if (l_corner_76 == 3 && Close[1] < ld_60) l_corner_76 = 1;
      if (l_corner_76 == 1 && Close[1] > ld_68) l_corner_76 = 3;
   }
   int li_80 = CheckPairs();
   if (li_80 < 1) li_80 = 1;
   if (Max_Pairs_Active > 0) li_80 = Max_Pairs_Active;
   double ld_84 = NormalizeDouble(AccountFreeMargin() * Risk_Percent / 100.0, 2) / li_80;
   if (MarketInfo(Symbol(), MODE_TICKVALUE) > 0.01) ld_12 = NormalizeDouble(MarketInfo(Symbol(), MODE_TICKVALUE) * ld_0, 8);
   else ld_12 = MarketInfo(Symbol(), MODE_TICKVALUE) * MarketInfo(Symbol(), MODE_LOTSTEP) * ld_0;
   if (Max_Pairs_Active > 0) l_text_20 = "Risk at " + DoubleToStr(NormalizeDouble(Risk_Percent, 1), 1) + " % = $" + DoubleToStr(NormalizeDouble(ld_84, 2), 2) + " with " + gi_196 + " Pairs Fixed ";
   else l_text_20 = "Risk at " + DoubleToStr(NormalizeDouble(Risk_Percent, 1), 1) + " % = $" + DoubleToStr(NormalizeDouble(ld_84, 2), 2) + " with " + gi_196 + " Pairs Active ";
   if (Digits == 3 || Digits == 5) {
      l_dbl2str_28 = DoubleToStr(NormalizeDouble(ld_0 / 10.0, 1), 1);
      l_dbl2str_36 = DoubleToStr(NormalizeDouble(ld_12 / 10.0, 2), 2);
   } else {
      l_dbl2str_28 = DoubleToStr(NormalizeDouble(ld_0, 0), 0);
      l_dbl2str_36 = DoubleToStr(NormalizeDouble(ld_12, 2), 2);
   }
   string l_text_92 = "Stop loss is " + l_dbl2str_28 + " pips = $" + l_dbl2str_36 + " per lot ";
   if (ld_12 <= 0.0) ld_12 = 1;
   if (MarketInfo(Symbol(), MODE_TICKVALUE) > 0.01) ld_44 = ld_84 / ld_12;
   else ld_44 = ld_84 / ld_12 * MarketInfo(Symbol(), MODE_LOTSTEP);
   if (Fixed_Lots > 0.0) l_text_52 = "Position size Fixed to " + DoubleToStr(NormalizeVolume(Fixed_Lots), 1) + " lot ";
   else {
      if (Fixed_Lots == 0.0 && Max_Lots > 0.0 && NormalizeVolume(ld_44) > NormalizeVolume(Max_Lots)) l_text_52 = "Position size Limited to " + DoubleToStr(NormalizeVolume(Max_Lots), 1) + " lot ";
      else l_text_52 = "Position size should be " + DoubleToStr(NormalizeVolume(ld_44), 1) + " lot ";
   }
   GlobalVariableSet(Symbol() + "_" + Period() + "_LotRisk", NormalizeVolume(ld_44));
   ObjectCreate("FDB_3bar1", OBJ_LABEL, 0, 0, 0);
   ObjectSetText("FDB_3bar1", l_text_20, 10, "Arial Bold", l_color_8);
   ObjectSet("FDB_3bar1", OBJPROP_CORNER, l_corner_76);
   ObjectSet("FDB_3bar1", OBJPROP_XDISTANCE, 5);
   ObjectSet("FDB_3bar1", OBJPROP_YDISTANCE, 15);
   ObjectCreate("FDB_3bar2", OBJ_LABEL, 0, 0, 0);
   ObjectSetText("FDB_3bar2", l_text_92, 10, "Arial Bold", l_color_8);
   ObjectSet("FDB_3bar2", OBJPROP_CORNER, l_corner_76);
   ObjectSet("FDB_3bar2", OBJPROP_XDISTANCE, 5);
   ObjectSet("FDB_3bar2", OBJPROP_YDISTANCE, 35);
   ObjectCreate("FDB_3bar3", OBJ_LABEL, 0, 0, 0);
   ObjectSetText("FDB_3bar3", l_text_52, 10, "Arial Bold", l_color_8);
   ObjectSet("FDB_3bar3", OBJPROP_CORNER, l_corner_76);
   ObjectSet("FDB_3bar3", OBJPROP_XDISTANCE, 5);
   ObjectSet("FDB_3bar3", OBJPROP_YDISTANCE, 55);
}

double NormalizeVolume(double ad_0) {
   double ld_ret_8;
   double l_lotstep_16 = MarketInfo(Symbol(), MODE_LOTSTEP);
   double l_minlot_24 = MarketInfo(Symbol(), MODE_MINLOT);
   double l_maxlot_32 = MarketInfo(Symbol(), MODE_MAXLOT);
   if (l_maxlot_32 > 0.0) ad_0 = MathMin(ad_0, l_maxlot_32);
   if (l_lotstep_16 > 0.0) ld_ret_8 = MathFloor(ad_0 / l_lotstep_16) * l_lotstep_16;
   else ld_ret_8 = 0;
   if (ld_ret_8 < l_minlot_24) {
      if (l_minlot_24 > 0.0) return (l_minlot_24);
      return (ad_0);
   }
   if (ld_ret_8 > 0.0) return (ld_ret_8);
   return (ad_0);
}

int CheckPairs() {
   string ls_0;
   int l_global_var_8;
   int l_count_12 = 0;
   for (int li_16 = GlobalVariablesTotal(); li_16 > 0; li_16--) {
      ls_0 = GlobalVariableName(li_16);
      if (StringFind(ls_0, "TradeDir", 0) > 0) {
         l_global_var_8 = GlobalVariableGet(ls_0);
         if (l_global_var_8 == 1 || l_global_var_8 == 2) l_count_12++;
      }
   }
   return (l_count_12);
}

int fnMakeMagicNumber() {
   if (Symbol() == "AUDCAD" || Symbol() == "AUDCADm") return (1);
   if (Symbol() == "AUDJPY" || Symbol() == "AUDJPYm") return (2);
   if (Symbol() == "AUDNZD" || Symbol() == "AUDNZDm") return (3);
   if (Symbol() == "AUDUSD" || Symbol() == "AUDUSDm") return (4);
   if (Symbol() == "CHFJPY" || Symbol() == "CHFJPYm") return (5);
   if (Symbol() == "EURAUD" || Symbol() == "EURAUDm") return (6);
   if (Symbol() == "EURCAD" || Symbol() == "EURCADm") return (7);
   if (Symbol() == "EURCHF" || Symbol() == "EURCHFm") return (8);
   if (Symbol() == "EURGBP" || Symbol() == "EURGBPm") return (9);
   if (Symbol() == "EURJPY" || Symbol() == "EURJPYm") return (10);
   if (Symbol() == "EURUSD" || Symbol() == "EURUSDm") return (11);
   if (Symbol() == "GBPCHF" || Symbol() == "GBPCHFm") return (12);
   if (Symbol() == "GBPJPY" || Symbol() == "GBPJPYm") return (13);
   if (Symbol() == "GBPUSD" || Symbol() == "GBPUSDm") return (14);
   if (Symbol() == "NZDJPY" || Symbol() == "NZDJPYm") return (15);
   if (Symbol() == "NZDUSD" || Symbol() == "NZDUSDm") return (16);
   if (Symbol() == "USDCAD" || Symbol() == "USDCADm") return (17);
   if (Symbol() == "USDCHF" || Symbol() == "USDCHFm") return (18);
   if (Symbol() == "USDJPY" || Symbol() == "USDJPYm") return (19);
   return (0);
}

bool newbar(int ai_0) {
   if (ai_0 != gi_216) {
      gi_216 = ai_0;
      return (TRUE);
   }
   return (FALSE);
}