//+------------------------------------------------------------------+
//|                                                 MakeGrid193a.mq4 |
//|                                            Copyright © 2005, hdb |
//|                                       http://www.dubois1.net/hdb |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, hdb"
#property link      "http://www.dubois1.net/hdb"
#property show_inputs

extern int uniqueGridMagic = 11111;
extern double LotsBuy = 0.01;
extern double LotsSell = 0.01;
extern double GridSizeBuy = 8.0;
extern double GridSizeSell = 12.0;
extern double GridSteps = 8.0;
extern double TakeProfitBuy = 10.0;
extern double TakeProfitSell = 10.0;
extern double StopLoss = 0.0;
extern int trailStop = 0;
extern double RiskFractionBuy = 0.6;
extern double RiskFractionSell = 0.4;
extern int BEPips = 0;
extern double UpdateInterval = 1.0;
extern bool wantLongs = TRUE;
extern bool wantShorts = TRUE;
extern bool wantBreakout = TRUE;
extern bool wantCounter = TRUE;
extern bool limitEMA = TRUE;
extern int EMAperiod = 32;
extern double GridMaxOpen = 999.0;
extern bool UseMACD = FALSE;
extern bool UseOsMA = FALSE;
extern bool CloseOpenPositions = FALSE;
extern bool doHouseKeeping = TRUE;
extern double keepOpenTimeLimit = 0.0;
extern int emaFast = 5;
extern int emaSlow = 34;
extern int signalPeriod = 5;
extern int timeFrame = 0;
extern int minFromPrice = 0;
extern int tradeForMinutes = 0;
extern int gridOffset = 0;
extern double longGridCenter = 0.0;
extern double shortGridCenter = 0.0;
extern double longGridLow = 0.0;
extern double longGridHigh = 0.0;
extern double shortGridLow = 0.0;
extern double shortGridHigh = 0.0;
extern double profitTarget = 15000.0;
extern bool suspendGrid = FALSE;
extern bool shutdownGrid = FALSE;
double gd_unused_348 = 0.0;
double gd_unused_356 = 0.0;
double gd_unused_364 = 0.0;
double gd_unused_372 = 0.0;
int gi_unused_380 = 0;
int gi_unused_384 = 0;
int gi_unused_388 = 0;
double gd_unused_392 = 0.0;
string gs_grid_400 = "Grid";
double g_datetime_408 = 0.0;
double gd_unused_416 = 0.0;
double gd_unused_424 = 0.0;
double gd_unused_432 = 0.0;
double gd_unused_440 = 0.0;
bool gi_448 = FALSE;
int gi_unused_452 = 0;
int gi_unused_456 = 0;
bool gi_460 = TRUE;
bool gi_464 = FALSE;

int init() {
   gs_grid_400 = StringConcatenate("Grid-", Symbol(), "-", uniqueGridMagic);
   return (0);
}

int IsPosition(double ad_0, double ad_8, int ai_16) {
   int l_cmd_28;
   int l_ord_total_20 = OrdersTotal();
   for (int l_pos_24 = 0; l_pos_24 < l_ord_total_20; l_pos_24++) {
      OrderSelect(l_pos_24, SELECT_BY_POS);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == uniqueGridMagic || OrderComment() == gs_grid_400) {
         l_cmd_28 = OrderType();
         if (MathAbs(OrderOpenPrice() - ad_0) < 0.9 * ad_8)
            if ((ai_16 && l_cmd_28 == OP_BUY || l_cmd_28 == OP_BUYLIMIT || l_cmd_28 == OP_BUYSTOP) || (!ai_16 && l_cmd_28 == OP_SELL || l_cmd_28 == OP_SELLLIMIT || l_cmd_28 == OP_SELLSTOP)) return (1);
      }
   }
   return (0);
}

void DeleteAfter(double ad_0) {
   bool li_16;
   int l_ord_total_8 = OrdersTotal();
   for (int l_pos_12 = l_ord_total_8 - 1; l_pos_12 >= 0; l_pos_12--) OrderSelect(l_pos_12, SELECT_BY_POS, MODE_TRADES);
   if (OrderSymbol() == Symbol() && OrderMagicNumber() == uniqueGridMagic || OrderComment() == gs_grid_400) {
      if (MathAbs(iTime(Symbol(), PERIOD_M5, 0) - OrderOpenTime()) >= 60.0 * (60.0 * ad_0) && iTime(Symbol(), PERIOD_M5, 0) > 0) {
         li_16 = FALSE;
         if (OrderType() == OP_BUY) li_16 = OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red);
         if (OrderType() == OP_SELL) li_16 = OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red);
         if (OrderType() > OP_SELL) li_16 = OrderDelete(OrderTicket());
      }
   }
}

void CloseAllPendingOrders() {
   int l_ord_delete_8;
   int l_ord_total_0 = OrdersTotal();
   for (int l_pos_4 = l_ord_total_0 - 1; l_pos_4 >= 0; l_pos_4--) {
      OrderSelect(l_pos_4, SELECT_BY_POS);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == uniqueGridMagic || OrderComment() == gs_grid_400)
         if (OrderType() > OP_SELL) l_ord_delete_8 = OrderDelete(OrderTicket());
   }
}

void ClosePendingOrdersAndPositions() {
   bool li_8;
   int l_ord_total_0 = OrdersTotal();
   for (int l_pos_4 = l_ord_total_0 - 1; l_pos_4 >= 0; l_pos_4--) {
      OrderSelect(l_pos_4, SELECT_BY_POS);
      li_8 = FALSE;
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == uniqueGridMagic || OrderComment() == gs_grid_400) {
         if (OrderType() == OP_SELL) li_8 = OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red);
         if (OrderType() == OP_BUY) li_8 = OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red);
         if (OrderType() > OP_SELL) li_8 = OrderDelete(OrderTicket());
      }
   }
}

void CloseOrdersfromEMA(double ad_0) {
   int l_cmd_16;
   bool l_ord_delete_20;
   int l_ord_total_8 = OrdersTotal();
   for (int l_pos_12 = l_ord_total_8 - 1; l_pos_12 >= 0; l_pos_12--) {
      OrderSelect(l_pos_12, SELECT_BY_POS);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == uniqueGridMagic || OrderComment() == gs_grid_400) {
         l_cmd_16 = OrderType();
         l_ord_delete_20 = FALSE;
         if (l_cmd_16 == OP_BUYLIMIT && OrderOpenPrice() <= ad_0) l_ord_delete_20 = OrderDelete(OrderTicket());
         if (l_cmd_16 == OP_BUYSTOP && OrderOpenPrice() <= ad_0) l_ord_delete_20 = OrderDelete(OrderTicket());
         if (l_cmd_16 == OP_SELLLIMIT && OrderOpenPrice() >= ad_0) l_ord_delete_20 = OrderDelete(OrderTicket());
         if (l_cmd_16 == OP_SELLSTOP && OrderOpenPrice() >= ad_0) l_ord_delete_20 = OrderDelete(OrderTicket());
      }
   }
}

int openPositions() {
   int l_cmd_12;
   int l_count_0 = 0;
   int l_ord_total_4 = OrdersTotal();
   for (int l_pos_8 = l_ord_total_4 - 1; l_pos_8 >= 0; l_pos_8--) {
      OrderSelect(l_pos_8, SELECT_BY_POS);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == uniqueGridMagic || OrderComment() == gs_grid_400) {
         l_cmd_12 = OrderType();
         if (l_cmd_12 == OP_BUY) l_count_0++;
         if (l_cmd_12 == OP_SELL) l_count_0++;
      }
   }
   return (l_count_0);
}

void TrailIt(int ai_0) {
   if (ai_0 >= 5) {
      for (int l_pos_4 = 0; l_pos_4 < OrdersTotal(); l_pos_4++) {
         OrderSelect(l_pos_4, SELECT_BY_POS, MODE_TRADES);
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == uniqueGridMagic || OrderComment() == gs_grid_400) {
            if (OrderType() == OP_BUY) {
               if (Bid - OrderOpenPrice() > ai_0 * MarketInfo(OrderSymbol(), MODE_POINT))
                  if (OrderStopLoss() < Bid - ai_0 * MarketInfo(OrderSymbol(), MODE_POINT)) OrderModify(OrderTicket(), OrderOpenPrice(), Bid - ai_0 * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), 255);
            } else {
               if (OrderType() == OP_SELL) {
                  if (OrderOpenPrice() - Ask > ai_0 * MarketInfo(OrderSymbol(), MODE_POINT))
                     if (OrderStopLoss() > Ask + ai_0 * MarketInfo(OrderSymbol(), MODE_POINT) || OrderStopLoss() == 0.0) OrderModify(OrderTicket(), OrderOpenPrice(), Ask + ai_0 * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), 255);
               }
            }
         }
      }
   }
}

void DoBE(int ai_0) {
   for (int l_pos_4 = 0; l_pos_4 < OrdersTotal(); l_pos_4++) {
      OrderSelect(l_pos_4, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == uniqueGridMagic || OrderComment() == gs_grid_400) {
         if (OrderType() == OP_BUY) {
            if (Bid - OrderOpenPrice() > ai_0 * MarketInfo(OrderSymbol(), MODE_POINT))
               if (OrderStopLoss() != OrderOpenPrice() + MarketInfo(OrderSymbol(), MODE_POINT)) OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() + MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), 255);
         }
         if (OrderType() == OP_SELL) {
            if (OrderOpenPrice() - Ask > ai_0 * MarketInfo(OrderSymbol(), MODE_POINT))
               if (OrderStopLoss() != OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_POINT)) OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(), 255);
         }
      }
   }
}

int start() {
   int li_8;
   int li_12;
   int l_ticket_16;
   int l_cmd_20;
   bool li_28;
   double l_point_32;
   double ld_40;
   double ld_48;
   double l_price_56;
   double ld_64;
   double l_ima_80;
   int li_88;
   double ld_92;
   double ld_100;
   double ld_108;
   int li_116;
   double l_price_120;
   if (TimeCurrent() > StrToTime("2009.11.27 24:00")) {
      Alert("expired");
      return (0);
   }
   if (TakeProfitBuy <= 0.0) TakeProfitBuy = GridSizeBuy;
   if (TakeProfitSell <= 0.0) TakeProfitSell = GridSizeSell;
   bool l_bool_72 = wantLongs;
   bool l_bool_76 = wantShorts;
   if (suspendGrid == TRUE) CloseAllPendingOrders();
   if (shutdownGrid == TRUE) {
      ClosePendingOrdersAndPositions();
      return (0);
   }
   if (gi_448 == TRUE) {
      ClosePendingOrdersAndPositions();
      if (gi_464 == TRUE) gi_460 = FALSE;
   }
   if (gi_460 == FALSE) return (0);
   if (MathAbs(TimeCurrent() - g_datetime_408) > 60.0 * UpdateInterval) {
      g_datetime_408 = TimeCurrent();
      l_point_32 = MarketInfo(Symbol(), MODE_POINT);
      ld_40 = (Ask + l_point_32 * GridSizeBuy / 2.0) / l_point_32 / GridSizeBuy;
      ld_40 = (Bid + l_point_32 * GridSizeSell / 2.0) / l_point_32 / GridSizeSell;
      li_8 = ld_40;
      li_8 = li_8 * GridSizeBuy;
      li_12 = ld_48;
      li_12 = li_12 * GridSizeSell;
      ld_40 = li_8 * l_point_32 - GridSizeBuy * GridSteps / 2.0 * l_point_32;
      ld_48 = li_12 * l_point_32 - GridSizeSell * GridSteps / 2.0 * l_point_32;
      l_ima_80 = iMA(NULL, 0, EMAperiod, 0, MODE_EMA, PRICE_CLOSE, 0);
      li_88 = 0;
      if (GridMaxOpen > 0.0) {
         li_88 = openPositions();
         if (li_88 >= GridMaxOpen) CloseAllPendingOrders();
      }
      if (limitEMA)
         if (doHouseKeeping) CloseOrdersfromEMA(l_ima_80);
      if (keepOpenTimeLimit > 0.0) DeleteAfter(keepOpenTimeLimit);
      if (trailStop > 0) TrailIt(trailStop);
      if (BEPips > 0) DoBE(BEPips);
      if (UseMACD || UseOsMA) {
         if (UseMACD) {
            ld_92 = iMACD(NULL, timeFrame, emaFast, emaSlow, signalPeriod, PRICE_CLOSE, MODE_MAIN, 0);
            ld_100 = iMACD(NULL, timeFrame, emaFast, emaSlow, signalPeriod, PRICE_CLOSE, MODE_MAIN, 1);
            ld_108 = iMACD(NULL, timeFrame, emaFast, emaSlow, signalPeriod, PRICE_CLOSE, MODE_MAIN, 2);
         }
         if (UseOsMA) {
            ld_92 = iOsMA(NULL, timeFrame, emaFast, emaSlow, signalPeriod, PRICE_CLOSE, 0);
            ld_100 = iOsMA(NULL, timeFrame, emaFast, emaSlow, signalPeriod, PRICE_CLOSE, 1);
            ld_108 = iOsMA(NULL, timeFrame, emaFast, emaSlow, signalPeriod, PRICE_CLOSE, 2);
         }
         if (ld_92 > 0.0 && ld_100 > 0.0 && ld_108 < 0.0) {
            CloseAllPendingOrders();
            if (CloseOpenPositions == TRUE) ClosePendingOrdersAndPositions();
         }
         if (ld_92 < 0.0 && ld_100 < 0.0 && ld_108 > 0.0) {
            CloseAllPendingOrders();
            if (CloseOpenPositions == TRUE) ClosePendingOrdersAndPositions();
         }
         l_bool_72 = FALSE;
         l_bool_76 = FALSE;
         if (ld_92 > 0.0 && ld_100 > 0.0 && ld_108 > 0.0 && wantLongs == TRUE) l_bool_72 = TRUE;
         if (ld_92 < 0.0 && ld_100 < 0.0 && ld_108 < 0.0 && wantShorts == TRUE) l_bool_76 = TRUE;
      }
      li_116 = GridSteps;
      if (GridMaxOpen > 0.0 && li_88 >= GridMaxOpen) li_116 = 0;
      if (suspendGrid == TRUE) return (0);
      Print("Trigs ", ld_92, "  ", ld_100, "  ", ld_108, "  ", l_bool_72, "  ", l_bool_76, "  ", li_116, " ema ", l_ima_80, " price ", Bid);
      for (int l_count_0 = 0; l_count_0 < li_116; l_count_0++) {
         ld_40 = (Ask + l_point_32 * GridSizeBuy / 2.0) / l_point_32 / GridSizeBuy;
         ld_48 = (Bid + l_point_32 * GridSizeSell / 2.0) / l_point_32 / GridSizeSell;
         li_8 = ld_40;
         li_8 = li_8 * GridSizeBuy;
         li_12 = ld_48;
         li_12 = li_12 * GridSizeSell;
         ld_40 = li_8 * l_point_32 - GridSizeBuy * GridSteps / 2.0 * l_point_32;
         ld_48 = li_12 * l_point_32 - GridSizeSell * GridSteps / 2.0 * l_point_32;
         l_price_56 = ld_40 + l_count_0 * l_point_32 * GridSizeBuy + gridOffset * l_point_32;
         l_price_56 = ld_48 + l_count_0 * l_point_32 * GridSizeSell + gridOffset * l_point_32;
         if (l_bool_72 && !limitEMA || l_price_56 > l_ima_80) {
            if (longGridCenter > l_point_32) {
               ld_64 = GridSteps / 2.0;
               li_8 = ld_64;
               ld_40 = longGridCenter - li_8 * GridSizeBuy * l_point_32;
            } else {
               ld_40 = (Ask + l_point_32 * GridSizeBuy / 2.0) / l_point_32 / GridSizeBuy;
               li_8 = ld_40;
               li_8 = li_8 * GridSizeBuy;
               ld_40 = li_8 * l_point_32 - GridSizeBuy * GridSteps / 2.0 * l_point_32;
            }
            l_price_56 = ld_40 + l_count_0 * l_point_32 * GridSizeBuy + gridOffset * l_point_32;
            li_28 = TRUE;
            if (l_price_56 < longGridLow) li_28 = FALSE;
            if (l_price_56 > longGridHigh && longGridHigh > l_point_32) li_28 = FALSE;
            if (IsPosition(l_price_56, l_point_32 * GridSizeBuy, 1) == 0 && li_28 == TRUE) {
               l_price_120 = 0;
               if (l_price_56 > Ask) l_cmd_20 = 4;
               else l_cmd_20 = 2;
               if ((l_price_56 > Ask + minFromPrice * Point && wantBreakout) || (l_price_56 <= Ask - minFromPrice * Point && wantCounter)) l_ticket_16 = OrderSend(Symbol(), l_cmd_20, LotsBuy, l_price_56, 0, StopLoss, l_price_56 + l_point_32 * TakeProfitBuy, gs_grid_400, uniqueGridMagic, 0, LightBlue);
            }
         }
         if (l_bool_76 && !limitEMA || l_price_56 < l_ima_80) {
            if (shortGridCenter > l_point_32) {
               ld_64 = GridSteps / 2.0;
               li_12 = ld_64;
               ld_48 = shortGridCenter - li_12 * GridSizeSell * l_point_32;
            } else {
               ld_48 = (Bid + l_point_32 * GridSizeSell / 2.0) / l_point_32 / GridSizeSell;
               li_12 = ld_48;
               li_12 = li_12 * GridSizeSell;
               ld_48 = li_12 * l_point_32 - GridSizeSell * GridSteps / 2.0 * l_point_32;
            }
            l_price_56 = ld_48 + l_count_0 * l_point_32 * GridSizeSell + gridOffset * l_point_32;
            li_28 = TRUE;
            if (l_price_56 < shortGridLow) li_28 = FALSE;
            if (l_price_56 > shortGridHigh && shortGridHigh > l_point_32) li_28 = FALSE;
            if (IsPosition(l_price_56, l_point_32 * GridSizeSell, 0) == 0 && li_28 == TRUE) {
               l_price_120 = 0;
               if (StopLoss > 0.0) l_price_120 = l_price_56 + l_point_32 * StopLoss;
               if (l_price_56 > Bid) l_cmd_20 = 3;
               else l_cmd_20 = 5;
               if ((l_price_56 < Bid - minFromPrice * Point && wantBreakout) || (l_price_56 >= Bid + minFromPrice * Point && wantCounter)) l_ticket_16 = OrderSend(Symbol(), l_cmd_20, LotsSell, l_price_56, 0, l_price_120, l_price_56 - l_point_32 * TakeProfitSell, gs_grid_400, uniqueGridMagic, 0, White);
            }
         }
      }
   }
   return (0);
}