
#property copyright "Copyright © 2009, FXKnight"
#property link      ""

extern double TakeProfit = 40.0;
extern double Lots = 0.02;
extern double StopLoss = 0.0;
extern double TrailingStop = 20.0;
extern double LotsMultiplier = 1.50;
extern int MaxTrades = 10;
extern int Pips = 40;
extern int SecureProfit = 10;
extern int AccountProtection = 1;
extern int AllSymbolsProtect = 0;
extern int OrderstoProtect = 10;
extern int ReverseCondition = 0;
extern int mm = 1;
extern int risk = 12;
extern int AccountIsNormal = 0;
extern int MagicNumber = 222777;
extern int Manual = 0;
extern int OpenOrdersBasedOn = 2;
extern int TimeZone = 16;
int g_count_164 = 0;
int gi_unused_168 = 0;
int g_slippage_172 = 5;
double g_price_176 = 0.0;
double g_price_184 = 0.0;
double g_ask_192 = 0.0;
double g_bid_200 = 0.0;
double gd_208 = 0.0;
double g_lots_216 = 0.0;
int g_cmd_224 = OP_BUY;
int g_price_228 = 0;
bool gi_232 = TRUE;
double g_ord_open_price_236 = 0.0;
int gi_244 = 0;
double gd_248 = 0.0;
int g_ticket_256 = 0;
int gi_260 = 0;
double g_price_264 = 0.0;
double g_ord_lots_272 = 0.0;
double gd_unused_280 = 0.0;
double gd_288 = 0.0;
bool gi_unused_296 = FALSE;
string gs_300 = "";
double gd_308 = 0.0;
double gd_unused_316 = 0.0;
double gd_unused_324 = 0.0;

int init() {
   return (0);
}

int deinit() {
   return (0);
}

int start() {
   int l_pos_24 = 0;
   if (AccountIsNormal == 1) 
      {
         if (mm != 0) gd_208 = MathCeil(AccountBalance() * risk / 10000.0);
         else gd_208 = Lots;
      } 
   else 
      {
         if (mm != 0) gd_208 = MathCeil(AccountBalance() * risk / 10000.0) / 10.0;
         else gd_208 = Lots;
      }
   
   if (gd_208 > 100.0) gd_208 = 100;
   
   g_count_164 = 0;
   for (l_pos_24 = 0; l_pos_24 < OrdersTotal(); l_pos_24++) {
      OrderSelect(l_pos_24, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) g_count_164++;
   }
   if (Symbol() == "EURUSD") gd_288 = 10.0;
   if (Symbol() == "GBPUSD") gd_288 = 10.0;
   if (Symbol() == "USDJPY") gd_288 = 9.715;
   if (Symbol() == "USDCHF") gd_288 = 8.7;
   if (gd_288 == 0.0) gd_288 = 5;
   if (gi_244 > g_count_164) {
      for (l_pos_24 = OrdersTotal() - 1; l_pos_24 >= 0; l_pos_24--) {
         OrderSelect(l_pos_24, SELECT_BY_POS, MODE_TRADES);
         g_cmd_224 = OrderType();
         if ((OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) || AllSymbolsProtect == 1) {
            if (g_cmd_224 == OP_BUY) OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), g_slippage_172, Blue);
            if (g_cmd_224 == OP_SELL) OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), g_slippage_172, Red);
            return (0);
         }
      }
   }
   gi_244 = g_count_164;
   if (g_count_164 >= MaxTrades) gi_232 = FALSE;
   else gi_232 = TRUE;
   if (g_ord_open_price_236 == 0.0) {
      for (l_pos_24 = 0; l_pos_24 < OrdersTotal(); l_pos_24++) {
         OrderSelect(l_pos_24, SELECT_BY_POS, MODE_TRADES);
         g_cmd_224 = OrderType();
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
            g_ord_open_price_236 = OrderOpenPrice();
            if (g_cmd_224 == OP_BUY) g_price_228 = 2;
            if (g_cmd_224 == OP_SELL) g_price_228 = 1;
         }
      }
   }
   if (g_count_164 < 1 && Manual == 0) {
      switch (OpenOrdersBasedOn) {
      case 0:
         g_price_228 = OpenOrdersBasedOnMACD();
         break;
      case 1:
         g_price_228 = OpenOrdersBasedOnPivot();
         break;
      case 2:
         g_price_228 = OpenOrdersBasedOnSupRes();
         break;
      default:
         g_price_228 = OpenOrdersBasedOnMACD();
         break;
      }
      if (ReverseCondition == 1) {
         if (g_price_228 == 1) g_price_228 = 2;
         else
            if (g_price_228 == 2) g_price_228 = 1;
      }
   }
   for (l_pos_24 = OrdersTotal(); l_pos_24 >= 0; l_pos_24--) {
      OrderSelect(l_pos_24, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
         //Print("Ticket ", OrderTicket(), " modified.");
         if (OrderType() == OP_SELL) {
            if (TrailingStop > 0.0) {
               if (OrderOpenPrice() - Ask >= TrailingStop * Point + Pips * Point) {
                  if (OrderStopLoss() > Ask + Point * TrailingStop || OrderStopLoss() == 0.0) {
                     OrderModify(OrderTicket(), OrderOpenPrice(), Ask + Point * TrailingStop, OrderClosePrice() - TakeProfit * Point - TrailingStop * Point, 0, Purple);
                     return (0);
                  }
               }
            }
         }
         if (OrderType() == OP_BUY) {
            if (TrailingStop > 0.0) {
               if (Bid - OrderOpenPrice() >= TrailingStop * Point + Pips * Point) {
                  if (OrderStopLoss() < Bid - Point * TrailingStop) {
                     OrderModify(OrderTicket(), OrderOpenPrice(), Bid - Point * TrailingStop, OrderClosePrice() + TakeProfit * Point + TrailingStop * Point, 0, Yellow);
                     return (0);
                  }
               }
            }
         }
      }
   }
   if (g_count_164 >= MaxTrades - OrderstoProtect && AccountProtection == 1) {
      gd_248 = 0;
      g_ticket_256 = 0;
      gi_260 = FALSE;
      g_price_264 = 0;
      g_ord_lots_272 = 0;
      for (l_pos_24 = 0; l_pos_24 < OrdersTotal(); l_pos_24++) {
         OrderSelect(l_pos_24, SELECT_BY_POS, MODE_TRADES);
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
            g_ticket_256 = OrderTicket();
            if (OrderType() == OP_BUY) gi_260 = FALSE;
            if (OrderType() == OP_SELL) gi_260 = TRUE;
            g_price_264 = OrderClosePrice();
            g_ord_lots_272 = OrderLots();
            if (gi_260 == FALSE) {
               if (OrderClosePrice() < OrderOpenPrice()) gd_248 -= (OrderOpenPrice() - OrderClosePrice()) * OrderLots() / Point;
               if (OrderClosePrice() > OrderOpenPrice()) gd_248 += (OrderClosePrice() - OrderOpenPrice()) * OrderLots() / Point;
            }
            if (gi_260 == TRUE) {
               if (OrderClosePrice() > OrderOpenPrice()) gd_248 -= (OrderClosePrice() - OrderOpenPrice()) * OrderLots() / Point;
               if (OrderClosePrice() < OrderOpenPrice()) gd_248 += (OrderOpenPrice() - OrderClosePrice()) * OrderLots() / Point;
            }
         }
      }
      gd_248 *= gd_288;
      if (AllSymbolsProtect == 1) gd_308 = AccountBalance();
      else gd_308 = SecureProfit;
      if (gd_248 >= gd_308) {
         OrderClose(g_ticket_256, g_ord_lots_272, g_price_264, g_slippage_172, Yellow);
         gi_232 = FALSE;
         return (0);
      }
   }
   if (!IsTesting()) {
      if (g_price_228 == 3) gs_300 = "No conditions to open trades";
      else gs_300 = "                         ";
      Comment("LastPrice=", g_ord_open_price_236, " Previous open orders=", gi_244, 
         "\nContinue opening=", gi_232, " OrderType=", g_price_228, 
         "\nLots=", gd_208, 
      "\n", gs_300);
   }
   if (g_price_228 == 1 && gi_232) {
      if (Bid - g_ord_open_price_236 >= Pips * Point || g_count_164 < 1) {
         g_bid_200 = Bid;
         g_ord_open_price_236 = 0;
         if (TakeProfit == 0.0) g_price_184 = 0;
         else g_price_184 = g_bid_200 - TakeProfit * Point;
         if (StopLoss == 0.0) g_price_176 = 0;
         else g_price_176 = g_bid_200 + StopLoss * Point;
         if (g_count_164 != 0) {
            g_lots_216 = gd_208;
            for (l_pos_24 = 1; l_pos_24 <= g_count_164; l_pos_24++) {
               if (MaxTrades > 12) g_lots_216 = NormalizeDouble(1.5 * g_lots_216, 2);
               else g_lots_216 = NormalizeDouble(LotsMultiplier * g_lots_216, 2);
            }
         } else g_lots_216 = gd_208;
         if (g_lots_216 > 100.0) g_lots_216 = 100;
         OrderSend(Symbol(), OP_SELL, g_lots_216, ND(g_bid_200), g_slippage_172, ND(g_price_176), ND(g_price_184), "BFXS-SELL" + MagicNumber, MagicNumber, 0, Red);
         return (0);
      }
   }
   if (g_price_228 == 2 && gi_232) {
      if (g_ord_open_price_236 - Ask >= Pips * Point || g_count_164 < 1) {
         g_ask_192 = Ask;
         g_ord_open_price_236 = 0;
         if (TakeProfit == 0.0) g_price_184 = 0;
         else g_price_184 = g_ask_192 + TakeProfit * Point;
         if (StopLoss == 0.0) g_price_176 = 0;
         else g_price_176 = g_ask_192 - StopLoss * Point;
         if (g_count_164 != 0) {
            g_lots_216 = gd_208;
            for (l_pos_24 = 1; l_pos_24 <= g_count_164; l_pos_24++) {
               if (MaxTrades > 12) g_lots_216 = NormalizeDouble(1.5 * g_lots_216, 2);
               else g_lots_216 = NormalizeDouble(LotsMultiplier * g_lots_216, 2);
            }
         } else g_lots_216 = gd_208;
         if (g_lots_216 > 100.0) g_lots_216 = 100;
         OrderSend(Symbol(), OP_BUY, g_lots_216, ND(g_ask_192), g_slippage_172, ND(g_price_176), ND(g_price_184), "BFXS-BUY" + MagicNumber, MagicNumber, 0, Blue);
         return (0);
      }
   }
   return (0);
}

int OpenOrdersBasedOnMACD() {
   int li_ret_0 = 3;
   if (iMACD(NULL, 0, 14, 26, 9, PRICE_CLOSE, MODE_MAIN, 0) > iMACD(NULL, 0, 14, 26, 9, PRICE_CLOSE, MODE_MAIN, 1)) li_ret_0 = 2;
   if (iMACD(NULL, 0, 14, 26, 9, PRICE_CLOSE, MODE_MAIN, 0) < iMACD(NULL, 0, 14, 26, 9, PRICE_CLOSE, MODE_MAIN, 1)) li_ret_0 = 1;
   return (li_ret_0);
}

int OpenOrdersBasedOnPivot() {
   int li_ret_0 = 3;
   double l_icustom_4 = 0;
   l_icustom_4 = iCustom(Symbol(), 0, "Pivot Lines TimeZone", TimeZone, 1, 0, 0, 0, 0);
   if (Close[0] > l_icustom_4) li_ret_0 = 2;
   if (Close[0] < l_icustom_4) li_ret_0 = 1;
   return (li_ret_0);
}

int OpenOrdersBasedOnSupRes() {
   int li_ret_0 = 3;
   double ld_4 = 0;
   double ld_12 = 0;
   ld_4 = iCustom(Symbol(), 0, "Support and Resistance", 0, 0);               // Resistance
   ld_12 = iCustom(Symbol(), 0, "Support and Resistance", 1, 0);              // Support
   if (Close[0] == ld_12) li_ret_0 = 1;
   if (Close[0] == ld_4) li_ret_0 = 2;
   return (li_ret_0);
}

double ND (double price)
{
   return (NormalizeDouble(price, Digits));
}


