extern double Lots = 0.01;
extern int KillZone = 25;
extern int TakeProfit = 70;
extern bool Kill_Switch = TRUE;
extern bool First_Long = TRUE;
extern bool First_Short = FALSE;
extern bool buy_sell_buy = TRUE;
extern bool sell_sell = FALSE;
extern bool buy_buy = FALSE;
extern int Move_SL_Point = 60;
extern int Move_SL_To = 45;
extern double Max_Lots = 14.4;
extern int Slippage = 3;
extern int Magic_Number = 100;
int gi_140 = 1;
int gi_144 = 0;
string gs_007_148 = "007";
int gi_156 = -1;
double gd_160 = 1.0;

void SetDigits() {
   if (Digits == 5 || Digits == 3) gd_160 = 10;
}

int init() {
   SetDigits();
   return (0);
}

int deinit() {
   return (0);
}

int start() {
   int li_4;
   double ld_8;
   int li_64;
   int li_0 = 0;
   double ld_24 = 0;
   double ld_32 = 0;
   bool li_40 = FALSE;
   bool li_44 = FALSE;
   if (First_Long && Kill_Switch) {
      li_40 = TRUE;
      li_44 = FALSE;
   }
   if (First_Short && Kill_Switch) {
      li_44 = TRUE;
      li_40 = FALSE;
   }
   if (gi_156 == FALSE && Kill_Switch) {
      if (!buy_buy) {
         li_44 = TRUE;
         li_40 = FALSE;
      } else {
         li_40 = TRUE;
         li_44 = FALSE;
      }
   }
   if (gi_156 == TRUE && Kill_Switch) {
      if (!sell_sell) {
         li_40 = TRUE;
         li_44 = FALSE;
      } else {
         li_44 = TRUE;
         li_40 = FALSE;
      }
   }
   double ld_48 = Ask - Bid;
   if (TotalOrders(Magic_Number) == 0 && Time[0] > gi_144) {
      if (li_40) {
         RefreshRates();
         if (TakeProfit > 0) ld_32 = NormalizeDouble(Ask + TakeProfit * Point * gd_160, Digits);
         else ld_32 = 0;
         ld_24 = NormalizeDouble(Ask - KillZone * Point * gd_160 - TakeProfit * Point * gd_160 - ld_48, Digits);
         li_4 = OrderSend(Symbol(), OP_BUY, Lots, NormalizeDouble(Ask, Digits), Slippage, 0, 0, gs_007_148, Magic_Number, 0, Blue);
         if (li_4 == -1) {
            li_0 = GetLastError();
            if (li_0 != 1/* NO_RESULT */ && li_0 != 0/* NO_ERROR */) Print("Buy Error :" + error(li_0) + " at " + Symbol() + " " + Period());
         } else {
            OrderModify(li_4, OrderOpenPrice(), ld_24, ld_32, 0, CLR_NONE);
            gi_156 = FALSE;
            if (TakeProfit > 0) ld_32 = NormalizeDouble(Ask - KillZone * Point * gd_160 - TakeProfit * Point * gd_160, Digits);
            else ld_32 = 0;
            ld_24 = NormalizeDouble(Ask + TakeProfit * Point * gd_160 + ld_48, Digits);
            if (OrderSend(Symbol(), OP_SELLSTOP, NormalizeDouble(nextFibo(1) * Lots, Digits), NormalizeDouble(ld_8 - KillZone * Point * gd_160, Digits), Slippage, ld_24, ld_32,
               gs_007_148, Magic_Number, 0, Red) == -1) {
               li_0 = GetLastError();
               if (li_0 != 1/* NO_RESULT */ && li_0 != 0/* NO_ERROR */) Print("SellStop Error :" + error(li_0) + " at " + Symbol() + " " + Period());
            } else {
               gi_144 = Time[0];
               return (0);
            }
         }
      }
      if (li_44) {
         RefreshRates();
         if (TakeProfit > 0) ld_32 = NormalizeDouble(Bid - TakeProfit * Point * gd_160, Digits);
         else ld_32 = 0;
         ld_24 = NormalizeDouble(Bid + KillZone * Point * gd_160 + TakeProfit * Point * gd_160 + ld_48, Digits);
         li_4 = OrderSend(Symbol(), OP_SELL, Lots, NormalizeDouble(Bid, Digits), Slippage, 0, 0, gs_007_148, Magic_Number, 0, Red);
         if (li_4 == -1) {
            li_0 = GetLastError();
            if (li_0 != 1/* NO_RESULT */ && li_0 != 0/* NO_ERROR */) Print("Sell Error :" + error(li_0) + " at " + Symbol() + " " + Period());
         } else {
            OrderModify(li_4, OrderOpenPrice(), ld_24, ld_32, 0, CLR_NONE);
            gi_156 = TRUE;
            if (TakeProfit > 0) ld_32 = NormalizeDouble(Bid + KillZone * Point * gd_160 + TakeProfit * Point * gd_160, Digits);
            else ld_32 = 0;
            ld_24 = NormalizeDouble(Bid - TakeProfit * Point * gd_160 - ld_48, Digits);
            if (OrderSend(Symbol(), OP_BUYSTOP, NormalizeDouble(nextFibo(1) * Lots, Digits), NormalizeDouble(Bid + KillZone * Point * gd_160, Digits), Slippage, ld_24, ld_32,
               gs_007_148, Magic_Number, 0, Blue) == -1) {
               li_0 = GetLastError();
               if (li_0 != 1/* NO_RESULT */ && li_0 != 0/* NO_ERROR */) Print("BuyStop Error :" + error(li_0) + " at " + Symbol() + " " + Period());
            } else {
               gi_144 = Time[0];
               return (0);
            }
         }
      }
   }
   if (TotalOrders(Magic_Number) == 1) {
      for (int li_56 = 0; li_56 < OrdersTotal(); li_56++) {
         OrderSelect(li_56, SELECT_BY_POS);
         if (OrderMagicNumber() == Magic_Number) break;
      }
      if (OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP) {
         OrderDelete(OrderTicket());
         return (0);
      }
      if (OrderType() == OP_BUY) {
         if (TakeProfit > 0) ld_32 = NormalizeDouble(OrderOpenPrice() - KillZone * Point * gd_160 - TakeProfit * Point * gd_160, Digits);
         else ld_32 = 0;
         ld_24 = NormalizeDouble(OrderOpenPrice() + TakeProfit * Point * gd_160 + ld_48, Digits);
         if (OrderSend(Symbol(), OP_SELLSTOP, NormalizeDouble(nextFibo(NormalizeDouble(OrderLots() / Lots, 0)) * Lots, Digits), NormalizeDouble(OrderOpenPrice() - KillZone * Point * gd_160,
            Digits), Slippage, ld_24, ld_32, gs_007_148, Magic_Number, 0, Red) == -1) {
            li_0 = GetLastError();
            if (li_0 != 1/* NO_RESULT */ && li_0 != 0/* NO_ERROR */) Print("SellStop Error :" + error(li_0) + " at " + Symbol() + " " + Period());
         } else {
            gi_144 = Time[0];
            return (0);
         }
      }
      if (OrderType() == OP_SELL) {
         if (TakeProfit > 0) ld_32 = NormalizeDouble(OrderOpenPrice() + KillZone * Point * gd_160 + TakeProfit * Point * gd_160, Digits);
         else ld_32 = 0;
         ld_24 = NormalizeDouble(OrderOpenPrice() - TakeProfit * Point * gd_160 - ld_48, Digits);
         if (OrderSend(Symbol(), OP_BUYSTOP, NormalizeDouble(nextFibo(NormalizeDouble(OrderLots() / Lots, 0)) * Lots, Digits), NormalizeDouble(OrderOpenPrice() + KillZone * Point * gd_160,
            Digits), Slippage, ld_24, ld_32, gs_007_148, Magic_Number, 0, Blue) == -1) {
            li_0 = GetLastError();
            if (li_0 != 1/* NO_RESULT */ && li_0 != 0/* NO_ERROR */) Print("BuyStop Error :" + error(li_0) + " at " + Symbol() + " " + Period());
         } else {
            gi_144 = Time[0];
            return (0);
         }
      }
   }
   if (TotalOrders(Magic_Number) == 2 && TotalOrdersM(Magic_Number, OP_BUYSTOP) + TotalOrdersM(Magic_Number, OP_SELLSTOP) == 1) {
      for (int li_60 = 0; li_60 < OrdersTotal(); li_60++) {
         OrderSelect(li_60, SELECT_BY_POS);
         if (OrderMagicNumber() == Magic_Number && OrderType() == OP_BUY || OrderType() == OP_SELL) break;
      }
      if (OrderType() == OP_BUY && Bid - OrderOpenPrice() >= Move_SL_Point * Point * gd_160 && OrderStopLoss() != OrderOpenPrice() + Move_SL_To * Point * gd_160) OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(OrderOpenPrice() + Move_SL_To * Point * gd_160, Digits), OrderTakeProfit(), 0, Brown);
      if (OrderType() == OP_SELL && OrderOpenPrice() - Ask >= Move_SL_Point * Point * gd_160 && OrderStopLoss() != OrderOpenPrice() - Move_SL_To * Point * gd_160) OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(OrderOpenPrice() - Move_SL_To * Point * gd_160, Digits), OrderTakeProfit(), 0, Brown);
   }
   if (TotalOrders(Magic_Number) > 1 && TotalOrdersM(Magic_Number, OP_BUYSTOP) + TotalOrdersM(Magic_Number, OP_SELLSTOP) == 0) {
      li_64 = lastTrade(Magic_Number);
      if (li_64 != 0) {
         OrderSelect(li_64, SELECT_BY_TICKET);
         if (OrderLots() >= Max_Lots) return (0);
         if (OrderType() == OP_BUY) {
            if (TakeProfit > 0) ld_32 = NormalizeDouble(OrderOpenPrice() - KillZone * Point * gd_160 - TakeProfit * Point * gd_160, Digits);
            else ld_32 = 0;
            ld_24 = NormalizeDouble(OrderOpenPrice() + TakeProfit * Point * gd_160 + ld_48, Digits);
            if (OrderSend(Symbol(), OP_SELLSTOP, NormalizeDouble(nextFibo(NormalizeDouble(OrderLots() / Lots, 0)) * Lots, Digits), NormalizeDouble(OrderOpenPrice() - KillZone * Point * gd_160,
               Digits), Slippage, ld_24, ld_32, gs_007_148, Magic_Number, 0, Red) == -1) {
               li_0 = GetLastError();
               if (li_0 != 1/* NO_RESULT */ && li_0 != 0/* NO_ERROR */) {
                  Print("SellStop Error :" + error(li_0) + " at " + Symbol() + " " + Period() + "SL=" + ld_24 + " TP=" + ld_32 + " OP=" + NormalizeDouble(OrderOpenPrice() - KillZone * Point * gd_160,
                     Digits) + " Lots=" + NormalizeDouble(nextFibo(NormalizeDouble(OrderLots() / Lots, 0)) * Lots, Digits) + " Bid=" + Bid);
               }
            } else {
               gi_144 = Time[0];
               return (0);
            }
         }
         if (OrderType() == OP_SELL) {
            if (TakeProfit > 0) ld_32 = NormalizeDouble(OrderOpenPrice() + KillZone * Point * gd_160 + TakeProfit * Point * gd_160, Digits);
            else ld_32 = 0;
            ld_24 = NormalizeDouble(OrderOpenPrice() - TakeProfit * Point * gd_160 - ld_48, Digits);
            if (OrderSend(Symbol(), OP_BUYSTOP, NormalizeDouble(nextFibo(NormalizeDouble(OrderLots() / Lots, 0)) * Lots, Digits), NormalizeDouble(OrderOpenPrice() + KillZone * Point * gd_160,
               Digits), Slippage, ld_24, ld_32, gs_007_148, Magic_Number, 0, Blue) == -1) {
               li_0 = GetLastError();
               if (li_0 != 1/* NO_RESULT */ && li_0 != 0/* NO_ERROR */) {
                  Print("BuyStop Error :" + error(li_0) + " at " + Symbol() + " " + Period() + "SL=" + ld_24 + " TP=" + ld_32 + " OP=" + NormalizeDouble(OrderOpenPrice() - KillZone * Point * gd_160,
                     Digits) + " Lots=" + NormalizeDouble(nextFibo(NormalizeDouble(OrderLots() / Lots, 0)) * Lots, Digits) + " Ask=" + Ask);
               }
            } else {
               gi_144 = Time[0];
               return (0);
            }
         }
      }
   }
   return (0);
}

int lastTrade(int ai_0) {
   int li_4 = 0;
   int li_8 = 0;
   for (int li_12 = 0; li_12 < OrdersTotal(); li_12++) {
      OrderSelect(li_12, SELECT_BY_POS);
      if (OrderMagicNumber() == ai_0 && OrderOpenTime() > li_8) {
         li_8 = OrderOpenTime();
         li_4 = OrderTicket();
      }
   }
   return (li_4);
}

int TotalOrders(int ai_0) {
   int li_4 = 0;
   for (int li_8 = 0; li_8 < OrdersTotal(); li_8++) {
      OrderSelect(li_8, SELECT_BY_POS);
      if (OrderMagicNumber() == ai_0) li_4++;
   }
   return (li_4);
}

int TotalOrdersM(int ai_0, int ai_4) {
   int li_8 = 0;
   for (int li_12 = 0; li_12 < OrdersTotal(); li_12++) {
      OrderSelect(li_12, SELECT_BY_POS);
      if (OrderMagicNumber() == ai_0 && OrderType() == ai_4) li_8++;
   }
   return (li_8);
}

int nextFibo(int ai_0) {
   int li_12;
   if (ai_0 == 0) return (1);
   int li_4 = 0;
   for (int li_8 = 1; li_8 <= ai_0; li_4 = li_12) {
      li_12 = li_8;
      li_8 += li_4;
   }
   return (li_8);
}

string error(int ai_0) {
   switch (ai_0) {
   case 0:
      return ("No error returned.");
   case 1:
      return ("No error returned, but the result is unknown. ");
   case 2:
      return ("Common error. ");
   case 3:
      return ("Invalid trade parameters. ");
   case 4:
      return ("Trade server is busy. ");
   case 5:
      return ("Old version of the client terminal. ");
   case 6:
      return ("No connection with trade server. ");
   case 7:
      return ("Not enough rights. ");
   case 8:
      return ("Too frequent requests.");
   case 9:
      return ("Malfunctional trade operation. ");
   case 64:
      return ("Account disabled. ");
   case 65:
      return ("Invalid account. ");
   case 128:
      return ("Trade timeout. ");
   case 129:
      return ("Invalid price. ");
   case 130:
      return ("Invalid stops. ");
   case 131:
      return ("Invalid trade volume. ");
   case 132:
      return ("Market is closed. ");
   case 133:
      return ("Trade is disabled. ");
   case 134:
      return ("Not enough money. ");
   case 135:
      return ("Price changed. ");
   case 136:
      return ("Off quotes. ");
   case 137:
      return ("Broker is busy.");
   case 138:
      return ("Requote. ");
   case 139:
      return ("Order is locked. ");
   case 140:
      return ("Long positions only allowed. ");
   case 141:
      return ("Too many requests. ");
   case 145:
      return ("Modification denied because order too close to market. ");
   case 146:
      return ("Trade context is busy. ");
   case 147:
      return ("Expirations are denied by broker. ");
   case 148:
      return ("The amount of open and pending orders has reached the limit set by the broker. ");
   case 4000:
      return ("No error. ");
   case 4001:
      return ("Wrong function pointer. ");
   case 4002:
      return ("Array index is out of range. ");
   case 4003:
      return ("No memory for function call stack. ");
   case 4004:
      return ("Recursive stack overflow. ");
   case 4005:
      return ("Not enough stack for parameter. ");
   case 4006:
      return ("No memory for parameter string. ");
   case 4007:
      return ("No memory for temp string. ");
   case 4008:
      return ("Not initialized string. ");
   case 4009:
      return ("Not initialized string in array. ");
   case 4010:
      return ("No memory for array string. ");
   case 4011:
      return ("Too long string. ");
   case 4012:
      return ("Remainder from zero divide. ");
   case 4013:
      return ("Zero divide. ");
   case 4014:
      return ("Unknown command. ");
   case 4015:
      return ("Wrong jump (never generated error). ");
   case 4016:
      return ("Not initialized array. ");
   case 4017:
      return ("DLL calls are not allowed. ");
   case 4018:
      return ("Cannot load library. ");
   case 4019:
      return ("Cannot call function. ");
   case 4020:
      return ("Expert function calls are not allowed. ");
   case 4021:
      return ("Not enough memory for temp string returned from function. ");
   case 4022:
      return ("System is busy (never generated error). ");
   case 4050:
      return ("Invalid function parameters count. ");
   case 4051:
      return ("Invalid function parameter value. ");
   case 4052:
      return ("String function internal error. ");
   case 4053:
      return ("Some array error. ");
   case 4054:
      return ("Incorrect series array using. ");
   case 4055:
      return ("Custom indicator error. ");
   case 4056:
      return ("Arrays are incompatible. ");
   case 4057:
      return ("Global variables processing error. ");
   case 4058:
      return ("Global variable not found. ");
   case 4059:
      return ("Function is not allowed in testing mode. ");
   case 4060:
      return ("Function is not confirmed. ");
   case 4061:
      return ("Send mail error. ");
   case 4062:
      return ("String parameter expected. ");
   case 4063:
      return ("Integer parameter expected. ");
   case 4064:
      return ("Double parameter expected. ");
   case 4065:
      return ("Array as parameter expected. ");
   case 4066:
      return ("Requested history data in updating state. ");
   case 4067:
      return ("Some error in trading function. ");
   case 4099:
      return ("End of file. ");
   case 4100:
      return ("Some file error.");
   case 4101:
      return ("Wrong file name. ");
   case 4102:
      return ("Too many opened files. ");
   case 4103:
      return ("Cannot open file. ");
   case 4104:
      return ("Incompatible access to a file. ");
   case 4105:
      return ("No order selected. ");
   case 4106:
      return ("Unknown symbol. ");
   case 4107:
      return ("Invalid price. ");
   case 4108:
      return ("Invalid ticket. ");
   case 4109:
      return ("Trade is not allowed. ");
   case 4110:
      return ("Longs are not allowed. ");
   case 4111:
      return ("Shorts are not allowed. ");
   case 4200:
      return ("Object exists already. ");
   case 4201:
      return ("Unknown object property. ");
   case 4202:
      return ("Object does not exist. ");
   case 4203:
      return ("Unknown object type. ");
   case 4204:
      return ("No object name. ");
   case 4205:
      return ("Object coordinates error. ");
   case 4206:
      return ("No specified subwindow. ");
   case 4207:
      return ("Some error in object function. ");
   }
   return ("Unknown error:" + ai_0);
}
