/*
   Generated by EX4-TO-MQ4 decompiler V4.0.224.1 []
   Website: http://purebeam.biz
   E-mail : purebeam@gmail.com
*/
#property copyright "Copyright 2010, Shams Soft"
#property link      "http://www.6thorigin.com"

#include <stdlib.mqh>

extern string GANN_OPTIONS = "GANN SETTINGS";
extern int iMagicNumber = 86576463;
extern int gannHiLo = 7;
extern bool mtfGannOption = FALSE;
extern int mtfGannHiLo = 5;
extern int mtfGannTime = 60;
extern bool OpenInitialTrade = FALSE;
extern string STOCHASTIC_OPTIONS = "STOCHASTIC SETTINGS";
extern int stochTF = 15;
extern int stochKPeriod = 8;
extern int stochDPeriod = 3;
extern int stochSlowing = 3;
extern int stochMAMathod = 0;
extern int stochMAPrice = 0;
extern string PROFIT_LOSS_OPTIONS = "PROFIT LOSS SETTINGS";
extern int takeProfit = 100;
extern int StopLoss = 100;
extern bool swingSlOption = FALSE;
extern int swingBufferPoints = 20;
extern bool useTrailing = TRUE;
extern double iTrailingStop = 30.0;
extern bool usePartialProfit = TRUE;
extern int partialProfit = 30;
extern bool doubleRiskOnTradeLoss = FALSE;
extern bool martingleStyle = FALSE;
extern string TRADE_TIME_OPTIONS = "TRADE TIME SETTINGS";
extern int tradeStartHour = 0;
extern int tradeStopHour = 24;
extern string LOT_MNGMNT_OPTIONS = "LOT MNGMNT SETTINGS";
extern double Lotsize = 0.1;
extern bool UseMoneyMgmt = TRUE;
extern double RiskPercent = 3.0;
extern double normalSpread = 4.0;
double g_point_244;
double g_lots_252;
double g_price_268;
double gd_276;
double gda_284[];
double gd_288;
double gd_296;
double gd_304;
bool gi_312 = FALSE;

int init() {
   if (Point == 0.00001) g_point_244 = 0.0001;
   else {
      if (Point == 0.001) g_point_244 = 0.01;
      else g_point_244 = Point;
   }
   gd_288 = MarketInfo(Symbol(), MODE_SPREAD);
   gd_296 = MarketInfo(Symbol(), MODE_TICKVALUE);
   gd_304 = 20;
   if (Point == 0.00001 || Point == 0.001) {
      gd_288 /= 10.0;
      gd_296 = 10.0 * gd_296;
      gd_304 = 200;
   }
   if (Lotsize <= 0.0) Lotsize = 0.1;
   if (StopLoss <= 0) StopLoss = 100;
   if (takeProfit <= 0) takeProfit = 100;
   ArrayResize(gda_284, 20);
   if (OpenInitialTrade) OpenInitial();
   return (0);
}

int ordersTotals() {
   int l_count_0 = 0;
   for (int l_pos_4 = 0; l_pos_4 < OrdersTotal(); l_pos_4++) {
      if (OrderSelect(l_pos_4, SELECT_BY_POS, MODE_TRADES) != FALSE)
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == iMagicNumber) l_count_0++;
   }
   return (l_count_0);
}

void OpenInitial() {
   double l_icustom_0 = iCustom(NULL, 0, "###Gann_HiLo_Activator_v2###", gannHiLo, 0, 1);
   if (ordersTotals() == 0) {
      gd_276 = StopLoss;
      if (Close[1] > l_icustom_0) {
         g_price_268 = Ask - StopLoss * g_point_244;
         openBuy();
      }
      if (Close[1] < l_icustom_0) {
         g_price_268 = Bid + StopLoss * g_point_244;
         openSell();
      }
   }
}

string CheckSide() {
   double l_icustom_0 = iCustom(NULL, 0, "###Gann_HiLo_Activator_v2###", gannHiLo, 0, 1);
   double l_icustom_8 = iCustom(NULL, 0, "###Gann_HiLo_Activator_v2###", gannHiLo, 0, 2);
   double l_istochastic_16 = iStochastic(NULL, stochTF, stochKPeriod, stochDPeriod, stochSlowing, stochMAMathod, stochMAPrice, MODE_MAIN, 1);
   double l_istochastic_24 = iStochastic(NULL, stochTF, stochKPeriod, stochDPeriod, stochSlowing, stochMAMathod, stochMAPrice, MODE_MAIN, 2);
   int li_32 = tradeStopHour - 1;
   if (tradeStartHour < li_32 && Hour() >= tradeStartHour && Hour() <= li_32) gi_312 = TRUE;
   else {
      if (tradeStartHour > li_32 && (Hour() >= tradeStartHour && Hour() <= 23) || (Hour() >= 0 && Hour() <= li_32)) gi_312 = TRUE;
      else gi_312 = FALSE;
   }
   if (gi_312 == TRUE) {
      if (Close[1] > l_icustom_0 && Close[2] < l_icustom_8) {
         if (l_istochastic_16 - l_istochastic_24 >= 0.0 && l_istochastic_16 < 80.0) {
            if (gd_288 <= normalSpread) {
               if (mtfGannOption) {
                  mtfGann();
                  if (Close[0] > gda_284[0]) return ("l");
                  return ("n");
               }
               return ("l");
            }
         }
      }
      if (!(Close[1] < l_icustom_0 && Close[2] > l_icustom_8)) return ("");
      if (!(l_istochastic_16 - l_istochastic_24 <= 0.0 && l_istochastic_16 > 20.0)) return ("");
      if (gd_288 > normalSpread) return ("");
      if (mtfGannOption) {
         mtfGann();
         if (Close[0] < gda_284[0]) return ("s");
         return ("n");
      }
      return ("s");
   }
   if ((Close[1] > l_icustom_0 && Close[2] < l_icustom_8) || (Close[1] < l_icustom_0 && Close[2] > l_icustom_8)) return ("c");
   return ("n");
}

void mtfGann() {
   int lia_0[];
   int l_index_8 = 0;
   for (int l_index_4 = 0; l_index_4 < 20; l_index_4++) {
      if (Time[l_index_4] < lia_0[l_index_8]) l_index_8++;
      gda_284[l_index_4] = iCustom(NULL, mtfGannTime, "###Gann_HiLo_Activator_v2###", mtfGannHiLo, 0, l_index_8);
   }
}

void openBuy() {
   g_lots_252 = moneyManagment();
   for (int l_count_0 = 0; l_count_0 < 10; l_count_0++) {
      RefreshRates();
      OrderSend(Symbol(), OP_BUY, g_lots_252, Ask, 3, g_price_268, Ask + takeProfit * g_point_244, "EA Buy", iMagicNumber, 0, Blue);
      if (GetLastError() == 0/* NO_ERROR */) break;
      Sleep(1000);
      Print("Buy Error: ", ErrorDescription(GetLastError()));
   }
}

void openSell() {
   g_lots_252 = moneyManagment();
   for (int l_count_0 = 0; l_count_0 < 10; l_count_0++) {
      RefreshRates();
      OrderSend(Symbol(), OP_SELL, g_lots_252, Bid, 3, g_price_268, Bid - takeProfit * g_point_244, "EA Sell", iMagicNumber, 0, Red);
      if (GetLastError() == 0/* NO_ERROR */) break;
      Sleep(1000);
      Print("Sell Error: ", ErrorDescription(GetLastError()));
   }
}

void checkClose() {
   for (int l_pos_0 = 0; l_pos_0 < OrdersTotal(); l_pos_0++) {
      if (OrderSelect(l_pos_0, SELECT_BY_POS, MODE_TRADES) != FALSE) {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == iMagicNumber) {
            if (OrderType() == OP_BUY) {
               if (usePartialProfit && OrderComment() == "EA Buy" && Bid - OrderOpenPrice() >= partialProfit * g_point_244) OrderClose(OrderTicket(), OrderLots() / 2.0, Bid, 2, Green);
               else {
                  if (CheckSide() == "c") OrderClose(OrderTicket(), OrderLots(), Bid, 2, Green);
                  else {
                     if (CheckSide() == "s") {
                        OrderClose(OrderTicket(), OrderLots(), Bid, 2, Green);
                        openSell();
                     }
                  }
               }
            }
            if (OrderType() == OP_SELL) {
               if (usePartialProfit && OrderComment() == "EA Sell" && OrderOpenPrice() - Ask >= partialProfit * g_point_244) OrderClose(OrderTicket(), OrderLots() / 2.0, Ask, 2, Red);
               else {
                  if (CheckSide() == "c") OrderClose(OrderTicket(), OrderLots(), Ask, 2, Red);
                  else {
                     if (CheckSide() == "l") {
                        OrderClose(OrderTicket(), OrderLots(), Ask, 2, Red);
                        openBuy();
                     }
                  }
               }
            }
         }
      }
   }
}

void TrailingStop() {
   if (iTrailingStop >= 1.0) {
      for (int l_pos_0 = 0; l_pos_0 < OrdersTotal(); l_pos_0++) {
         OrderSelect(l_pos_0, SELECT_BY_POS, MODE_TRADES);
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == iMagicNumber) {
            switch (OrderType()) {
            case OP_BUY:
               if (Bid - OrderOpenPrice() > g_point_244 * iTrailingStop)
                  if (OrderStopLoss() < Bid - g_point_244 * iTrailingStop) OrderModify(OrderTicket(), OrderOpenPrice(), Bid - g_point_244 * iTrailingStop, OrderTakeProfit(), 0, Green);
               break;
            case OP_SELL:
               if (OrderOpenPrice() - Ask > g_point_244 * iTrailingStop)
                  if (OrderStopLoss() > Ask + g_point_244 * iTrailingStop || OrderStopLoss() == 0.0) OrderModify(OrderTicket(), OrderOpenPrice(), Ask + g_point_244 * iTrailingStop, OrderTakeProfit(), 0, Red);
            }
         }
      }
   }
}

double moneyManagment() {
   double ld_0;
   int li_8;
   double ld_20;
   double ld_28;
   double ld_36;
   double ld_44;
   switch (MarketInfo(Symbol(), MODE_MINLOT)) {
   case 0.00001:
      li_8 = 5;
      break;
   case 0.0001:
      li_8 = 4;
      break;
   case 0.001:
      li_8 = 3;
      break;
   case 0.01:
      li_8 = 2;
      break;
   case 0.1:
      li_8 = 1;
      break;
   default:
      li_8 = 0;
   }
   if (UseMoneyMgmt) {
      if (doubleRiskOnTradeLoss) {
         if (LossTradeCount() > 0) ld_0 = 2.0 * RiskPercent;
         else ld_0 = RiskPercent;
      } else {
         if (martingleStyle) {
            if (LossTradeCount() > 0) ld_0 = RiskPercent * MathPow(2, LossTradeCount());
            else ld_0 = RiskPercent;
         } else ld_0 = RiskPercent;
      }
      ld_20 = AccountBalance();
      ld_28 = ld_20 * ld_0 / 100.0;
      if (gd_276 <= 0.0) gd_276 = StopLoss;
      ld_36 = gd_276 * gd_296;
      if (ld_36 <= 0.0) return (NormalizeDouble(Lotsize, li_8));
      ld_44 = ld_28 / ld_36;
      return (NormalizeDouble(ld_44, li_8));
   }
   return (NormalizeDouble(Lotsize, li_8));
}

int LossTradeCount() {
   int l_count_0 = 0;
   for (int l_pos_4 = OrdersHistoryTotal() - 1; l_pos_4 >= 0; l_pos_4--) {
      OrderSelect(l_pos_4, SELECT_BY_POS, MODE_HISTORY);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == iMagicNumber) {
         if (OrderProfit() >= 0.0) break;
         l_count_0++;
      }
   }
   return (l_count_0);
}

int start() {
   if (ordersTotals() > 0) {
      if (useTrailing) TrailingStop();
      checkClose();
      return (0);
   }
   double l_icustom_0 = iCustom(NULL, 0, "###Gann_HiLo_Activator_v2###", gannHiLo, 0, 1);
   if (CheckSide() == "l" && Volume[0] <= gd_304) {
      if (swingSlOption || StopLoss == 0) g_price_268 = l_icustom_0 - swingBufferPoints * g_point_244;
      else g_price_268 = Ask - StopLoss * g_point_244;
      gd_276 = (Bid - g_price_268) / g_point_244;
      openBuy();
      return (0);
   }
   if (CheckSide() == "s" && Volume[0] <= gd_304) {
      if (swingSlOption || StopLoss == 0) g_price_268 = l_icustom_0 + swingBufferPoints * g_point_244;
      else g_price_268 = Bid + StopLoss * g_point_244;
      gd_276 = (g_price_268 - Ask) / g_point_244;
      openSell();
      return (0);
   }
   return (0);
}