//
// торгуем на новостях 
//
// by VAY loopsidery@yahoo.com
//

string EAname = "NewsLock_1.2";
int MagicNumber  = 23547887;

int slippage = 3;

extern double LotSize = 0.1;

extern string TimeSetOrders  = "15:15"; // Время установки ордеров
extern string TimeDelOrders  = "16:15"; // Время удаления ордеров

extern double Dist = 30; // дистанция отложек 

extern double MaxTotalLoss = 60; // максимальная общая просадка

extern bool SetMarketOrders = TRUE;

double point4;

//
//--
//
int init() {
   if (Digits < 4) {
      point4 = 0.01;
   } else {
      point4 = 0.0001;
   }
   return(0);
}
 
//
//--
//
int start()  {
//
// Закрываем позиции по истечении времени
//
   if (TimeToStr(TimeCurrent(), TIME_MINUTES) == TimeDelOrders && CountAllOpenTrades() > 0) {
      Print("Закрываем позиции по истечению времени");
      CloseAllOrders();
   }
//
// Фиксируем убытки
//
   if (TotalProfit() < -MaxTotalLoss) {
      Print("Фиксируем убытки");
      CloseAllOrders();
   }
//
// Открываем позиции
//
   int ticket;
   int nAttempts = 10;
   int i;
   HideTestIndicators(TRUE);

   double DELTA = MathMax(Dist*point4,MarketInfo(Symbol(),MODE_STOPLEVEL)*Point);

   if (TimeToStr(TimeCurrent(), TIME_MINUTES) == TimeSetOrders && CountAllOpenTrades() < 1) {
      if (SetMarketOrders) {
         if (iStochastic(NULL, PERIOD_M1,5,3,3,MODE_SMA,0,MODE_SIGNAL,0) > iStochastic(NULL, PERIOD_M1,5,3,3,MODE_SMA,0,MODE_MAIN,0)) {
            for (i = 1; i <= nAttempts; i++) {
               ticket = OrderSend(Symbol(), OP_BUY, LotSize, ND(Ask), slippage, 0 ,0, EAname, MagicNumber, 0, Blue);
               if (ticket > 0) break;
               HandleError();
            }   
            RefreshRates();
            for (i = 1; i <= nAttempts; i++) {
    	         ticket = OrderSend(Symbol(), OP_SELL, LotSize, ND(Bid), slippage, 0, 0, EAname, MagicNumber, 0, Red);
               if (ticket > 0) break;
               HandleError();
            }   
 	      } else {
            for (i = 1; i <= nAttempts; i++) {
    	         ticket = OrderSend(Symbol(), OP_SELL, LotSize, ND(Bid), slippage, 0, 0, EAname, MagicNumber, 0, Red);
               if (ticket > 0) break;
               HandleError();
            }   
            RefreshRates();
            for (i = 1; i <= nAttempts; i++) {
               ticket = OrderSend(Symbol(), OP_BUY, LotSize, ND(Ask), slippage, 0 ,0, EAname, MagicNumber, 0, Blue);
               if (ticket > 0) break;
               HandleError();
            }   
         }
      }
      for (i = 1; i <= nAttempts; i++) {
         ticket = OrderSend(Symbol(), OP_SELLLIMIT, LotSize, ND(Ask+DELTA), slippage, 0 ,0, EAname, MagicNumber, 0, Blue);
         if (ticket > 0) break;
         HandleError();
      }   
      for (i = 1; i <= nAttempts; i++) {
         ticket = OrderSend(Symbol(), OP_BUYLIMIT, LotSize, ND(Bid-DELTA), slippage, 0, 0, EAname, MagicNumber, 0, Red);
         if (ticket > 0) break;
         HandleError();
      }   
   }
}

//
//---------------
// считаем ВСЕ открытые позиции
int CountAllOpenTrades() {
   int count = 0;
   int num = OrdersTotal();
   for (int cnt = num - 1; cnt >= 0; cnt--) {
      if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
            count++;
         }
      }
   }
   return(count);
}

//
// закрываем все ордера
// встречное закрытие локированных позиций
void CloseAllOrders() {
   while (TRUE) {
      int ticket_Buy = -1;
      int ticket_Sell = -1;
      double OP_Buy = 0;
      double OP_Sell = 0;
      for (int cnt = OrdersTotal() - 1; cnt >= 0; cnt--) {
         if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) {
            if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
               if (OrderType() == OP_BUY) {
                  if (OrderOpenPrice() > OP_Buy) {
                     ticket_Buy = OrderTicket();
                     OP_Buy = OrderOpenPrice();
                  }
               } else if (OrderType() == OP_SELL) {
                  if (OrderOpenPrice() > OP_Sell) {
                     ticket_Sell = OrderTicket();
                     OP_Sell = OrderOpenPrice();
                  }
               } else {
                  OrderDelete(OrderTicket());
               }
            }
         }
      }
      if (ticket_Buy == -1 && ticket_Sell == -1) break;
      if (ticket_Buy == -1) {
         if (OrderSelect(ticket_Sell, SELECT_BY_TICKET)) OrderClose(ticket_Sell,OrderLots(),ND(Ask),slippage);
         break;
      }
      if (ticket_Sell == -1) {
         if (OrderSelect(ticket_Buy, SELECT_BY_TICKET)) OrderClose(ticket_Buy,OrderLots(),ND(Bid),slippage);
         break;
      }
      OrderCloseBy(ticket_Buy,ticket_Sell);
   }
   return;
}

//
// общий профит всех открытых позиций
//
double TotalProfit() {
   double ProfitPt = 0;
   for (int cnt = OrdersTotal() - 1; cnt >= 0; cnt--) {
      if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
            if (OrderType() == OP_BUY) {
               ProfitPt = ProfitPt + (Bid-OrderOpenPrice())/point4;
            } else if (OrderType() == OP_SELL) {
               ProfitPt = ProfitPt + (OrderOpenPrice()-Ask)/point4;
            }
         }
      }
   }
   return(ProfitPt);
}
  
double ND(double np) {
  return(NormalizeDouble(np,Digits));
}

int HandleError() {
   int error_0 = GetLastError();
   Print("ERROR (" + error_0 + ") : " + error(error_0));
   if (error_0 == 130/* INVALID_STOPS */ || error_0 == 129/* INVALID_PRICE */ || error_0 == 138/* REQUOTE */ || error_0 == 135/* PRICE_CHANGED */ || error_0 == 136/* OFF_QUOTES */) {
      RefreshRates();
      return (1);
   }
   if (error_0 == 146/* TRADE_CONTEXT_BUSY */ || error_0 == 133/* TRADE_DISABLED */ || error_0 == 128/* TRADE_TIMEOUT */ || error_0 == 139/* ORDER_LOCKED */) {
      Sleep(500);
      RefreshRates();
      return (1);
   }
   if (error_0 == 4/* SERVER_BUSY */ || error_0 == 137/* BROKER_BUSY */ || error_0 == 4022/* SYSTEM_BUSY */ || error_0 == 6/* NO_CONNECTION */ || error_0 == 141/* TOO_MANY_REQUESTS */ ||
      error_0 == 8/* TOO_FREQUENT_REQUESTS */) {
      Sleep(1500);
      RefreshRates();
      return (1);
   }
   if (error_0 == 147/* TRADE_EXPIRATION_DENIED */) {
      RefreshRates();
      return (1);
   }
   if (error_0 != 0/* NO_ERROR */) {
      Sleep(500);
      RefreshRates();
      return (0);
   }
   return (0);
}

//---
string error(int eer)
{
   string er;
   switch(eer)
     {
      //---- 
      case 0:
      case 1:   er="Нет ошибки, но результат неизвестен";                         break;
      case 2:   er="Общая ошибка";                                                break;
      case 3:   er="Неправильные параметры";                                      break;
      case 4:   er="Торговый сервер занят";                                       break;
      case 5:   er="Старая версия клиентского терминала";                         break;
      case 6:   er="Нет связи с торговым сервером";                               break;
      case 7:   er="Недостаточно прав";                                           break;
      case 8:   er="Слишком частые запросы";                                      break;
      case 9:   er="Недопустимая операция нарушающая функционирование сервера";   break;
      case 64:  er="Счет заблокирован";                                           break;
      case 65:  er="Неправильный номер счета";                                    break;
      case 128: er="Истек срок ожидания совершения сделки";                       break;
      case 129: er="Неправильная цена";                                           break;
      case 130: er="Неправильные стопы";                                          break;
      case 131: er="Неправильный объем";                                          break;
      case 132: er="Рынок закрыт";                                                break;
      case 133: er="Торговля запрещена";                                          break;
      case 134: er="Недостаточно денег для совершения операции";                  break;
      case 135: er="Цена изменилась";                                             break;
      case 136: er="Нет цен";                                                     break;
      case 137: er="Брокер занят";                                                break;
      case 138: er="Новые цены - Реквот";                                         break;
      case 139: er="Ордер заблокирован и уже обрабатывается";                     break;
      case 140: er="Разрешена только покупка";                                    break;
      case 141: er="Слишком много запросов";                                      break;
      case 145: er="Модификация запрещена, так как ордер слишком близок к рынку"; break;
      case 146: er="Подсистема торговли занята";                                  break;
      case 147: er="Использование даты истечения ордера запрещено брокером";      break;
      case 148: er="Количество открытых и отложенных ордеров достигло предела ";  break;
      //---- 
      case 4000: er="Нет ошибки";                                                 break;
      case 4001: er="Неправильный указатель функции";                             break;
      case 4002: er="Индекс массива - вне диапазона";                             break;
      case 4003: er="Нет памяти для стека функций";                               break;
      case 4004: er="Переполнение стека после рекурсивного вызова";               break;
      case 4005: er="На стеке нет памяти для передачи параметров";                break;
      case 4006: er="Нет памяти для строкового параметра";                        break;
      case 4007: er="Нет памяти для временной строки";                            break;
      case 4008: er="Неинициализированная строка";                                break;
      case 4009: er="Неинициализированная строка в массиве";                      break;
      case 4010: er="Нет памяти для строкового массива";                          break;
      case 4011: er="Слишком длинная строка";                                     break;
      case 4012: er="Остаток от деления на ноль";                                 break;
      case 4013: er="Деление на ноль";                                            break;
      case 4014: er="Неизвестная команда";                                        break;
      case 4015: er="Неправильный переход";                                       break;
      case 4016: er="Неинициализированный массив";                                break;
      case 4017: er="Вызовы DLL не разрешены";                                    break;
      case 4018: er="Невозможно загрузить библиотеку";                            break;
      case 4019: er="Невозможно вызвать функцию";                                 break;
      case 4020: er="Вызовы внешних библиотечных функций не разрешены";           break;
      case 4021: er="Недостаточно памяти для строки, возвращаемой из функции";    break;
      case 4022: er="Система занята";                                             break;
      case 4050: er="Неправильное количество параметров функции";                 break;
      case 4051: er="Недопустимое значение параметра функции";                    break;
      case 4052: er="Внутренняя ошибка строковой функции";                        break;
      case 4053: er="Ошибка массива";                                             break;
      case 4054: er="Неправильное использование массива-таймсерии";               break;
      case 4055: er="Ошибка пользовательского индикатора";                        break;
      case 4056: er="Массивы несовместимы";                                       break;
      case 4057: er="Ошибка обработки глобальныех переменных";                    break;
      case 4058: er="Глобальная переменная не обнаружена";                        break;
      case 4059: er="Функция не разрешена в тестовом режиме";                     break;
      case 4060: er="Функция не подтверждена";                                    break;
      case 4061: er="Ошибка отправки почты";                                      break;
      case 4062: er="Ожидается параметр типа string";                             break;
      case 4063: er="Ожидается параметр типа integer";                            break;
      case 4064: er="Ожидается параметр типа double";                             break;
      case 4065: er="В качестве параметра ожидается массив";                      break;
      case 4066: er="Запрошенные исторические данные в состоянии обновления";     break;
      case 4067: er="Ошибка при выполнении торговой операции";                    break;
      case 4099: er="Конец файла";                                                break;
      case 4100: er="Ошибка при работе с файлом";                                 break;
      case 4101: er="Неправильное имя файла";                                     break;
      case 4102: er="Слишком много открытых файлов";                              break;
      case 4103: er="Невозможно открыть файл";                                    break;
      case 4104: er="Несовместимый режим доступа к файлу";                        break;
      case 4105: er="Ни один ордер не выбран";                                    break;
      case 4106: er="Неизвестный символ";                                         break;
      case 4107: er="Неправильный параметр цены для торговой функции";            break;
      case 4108: er="Неверный номер тикета";                                      break;
      case 4109: er="Торговля не разрешена";                                      break;
      case 4110: er="Длинные позиции не разрешены";                               break;
      case 4111: er="Короткие позиции не разрешены";                              break;
      case 4200: er="Объект уже существует";                                      break;
      case 4201: er="Запрошено неизвестное свойство объекта";                     break;
      case 4202: er="Объект не существует";                                       break;
      case 4203: er="Неизвестный тип объекта";                                    break;
      case 4204: er="Нет имени объекта";                                          break;
      case 4205: er="Ошибка координат объекта";                                   break;
      case 4206: er="Не найдено указанное подокно";                               break;
      case 4207: er="Ошибка при работе с объектом";                               break;
      default:   er="unknown error";
     }
  return(er);
}

