#property copyright "Epst"
#property link      "http://digitalbankonline.com"


#include <WinUser32.mqh>
#define WM_COMMAND  0x0111

#import "user32.dll"
   int GetAncestor(int hWnd, int gaFlags);
   int PostMessageA(int hWnd,int Msg,int wParam,int lParam);
#import
extern int Step = 170;
extern string инкремент_шага = "На сколько увеличивать Step (0 - не увеличивать)";
extern int IncStep = 0;
extern string количество_ордеров = "После скольки ордеров увеличивать Step";
extern int CountOrders = 10;
extern string метод_установки_первого_ордера = "1 - фиксированным шагом, 2- по минимуму-максимуму диапазона, 3 - по фракталам";
extern int MethodStep = 1;
extern string метод_установки_первого_ордера1 = "Фиксированный шаг";
extern int StartStep = 170;
extern string метод_установки_первого_ордера2 = "Максимум-минимум для N-баров";
extern int CountBars = 20;


extern double FirstLot = 0.01;
extern double IncLot = 0.0;

extern int TradeStartHour = 0;
extern int TradeStartMinutes = 0;
extern int TradeEndHour = 0;
extern int TradeEndMinutes = 0;

extern string закрыть_ордера = "Принудительно закрывать ордера по окончанию торгового времени";
extern bool ForceCloseOrders = false;


extern string метод_подсчета_профита = "1 - по сумме средств, 2- в пипсах, 3 - в процентах от депозита";
extern int MinProfitMethod = 1;
extern double MinProfit1 = 1.5; //Прибыль по достижению которой закрыть ордера
extern double MinProfit2 = 100; //Прибыль по достижению которой закрыть ордера
extern double MinProfit3 = 1; //Прибыль по достижению которой закрыть ордера


extern string профит_перед_новостями = "Профит, при котором закрывать ордера перед новостями и окончании торгового диапазона";
extern double MinNewsProfit1 = 1.5; //Прибыль по достижению которой закрыть ордера
extern double MinNewsProfit2 = 100; //Прибыль по достижению которой закрыть ордера
extern double MinNewsProfit3 = 1; //Прибыль по достижению которой закрыть ордера



extern string метод_закрытия_убытков = "1 - по сумме средств, 2- в пипсах, 3 - в процентах от депозита";
extern int MaxLossMethod = 1;
extern string убыток1 = "Убыток в валюте баланса по достижению которого закрыть все ордера (метод 1)";
extern double MaxLoss1 = 300; //Убыток по достижению которого закрыть все ордера
extern string убыток2 = "Убыток в пипсах по достижению которого закрыть все ордера (метод 2)";
extern double MaxLoss2 = 30.0; //Убыток по достижению которого закрыть все ордера
extern string убыток3 = "Убыток в процентах по достижению которого закрыть все ордера (метод 3)";
extern double MaxLoss3 = 10; //Убыток по достижению которого закрыть все ордера


extern bool ForceCloseOrdersBeforeNews = false;
extern string Новостной_фильтр = "Отключать советник во время новостей?";
extern bool    UseNewsFilter = false;
extern string До_новостей = "Отключать советник за ... минут до новости";
extern int     MinsBeforeNews = 60; 
extern string После_новостей = "Не включать советник ... минут после новости";
extern int     MinsAfterNews  = 30;
extern int slippage = 2;
extern int Magic = 22211123345;

bool NewsTime;
int TimeToNews = 0;
bool Trading = true;

string PlaceTradesFrom;
string PlaceTradesTo;

double LastSellLot;
double LastBuyLot;

int countSellOrders = 0;
int countBuyOrders = 0;

int init()
  {
   Object_field("Info", "СТАРТ!", 2, 30, 12, "Arial", Lime, Lime);
   if (TradeStartHour < 0 || TradeStartHour > 23) {
      Trading = false;
      Object_field("ОШИБКА","ОШИБКА! TradeStartHour должен быть в пределах от 0 до 23",2,10,12, "Arial", Red,Red);
      Print("Переменная TradeStartHour (Час старта торговли) должна быть от 0 до 23" );
      return;
   }

   if (TradeEndHour < 0 || TradeEndHour > 23) {
      Trading = false;
      Object_field("ОШИБКА","ОШИБКА! TradeEndHour должен быть в пределах от 0 до 23",2,10,12, "Arial", Red,Red);
      Print("Переменная TradeEndHour (Час окончания торговли) должна быть от 0 до 23" );
      return;
   }

   if (TradeStartMinutes < 0 || TradeStartMinutes > 59) {
      Trading = false;
      Object_field("ОШИБКА","ОШИБКА! TradeStartMinutes должен быть в пределах от 0 до 59",2,10,12, "Arial", Red,Red);
      Print("Переменная TradeStartMinutes (Минута старта торговли) должна быть от 0 до 59" );
      return;
   }

   if (TradeEndMinutes < 0 || TradeEndMinutes > 59) {
      Trading = false;
      Object_field("ОШИБКА","ОШИБКА! TradeEndMinutes должен быть в пределах от 0 до 59",2,10,12, "Arial", Red,Red);
      Print("Переменная TradeEndMinutes (Минута окончания торговли) должна быть от 0 до 59" );
      return;
   }

/*
   if (Step <= MarketInfo(Symbol(),MODE_STOPLEVEL)) {
      Trading = false;
      Object_field("ОШИБКА","ОШИБКА! Step должен быть больше " + MarketInfo(Symbol(),MODE_STOPLEVEL),2,10,12, "Arial", Red,Red);
      Print("ОШИБКА! Step должен быть больше " + MarketInfo(Symbol(),MODE_STOPLEVEL));
      return;
   }
*/
   if (MaxLossMethod < 1 || MaxLossMethod > 3) {
      Trading = false;
      Object_field("ОШИБКА","ОШИБКА! MaxLossMethod должен быть в диапазоне от 1 до 3",2,10,12, "Arial", Red,Red);
      Print("ОШИБКА! MaxLossMethod должен быть в диапазоне от 1 до 3");
      return;
   }



   if (MaxLoss3 < 0 || MaxLoss3 > 100) {
      Trading = false;
      Object_field("ОШИБКА","ОШИБКА! MaxLoss3 должен быть в диапазоне от 0 до 100",2,10,12, "Arial", Red,Red);
      Print("ОШИБКА! MaxLoss3 должен быть в диапазоне от 0 до 100");
      return;
   }



   
    if ( !IsDllsAllowed() ) {
         ObjectSetText("Info","Разрешите импорт DLL в настройках", 10,"Arial",Red);
         Trading = false;
         return;
      }
   Object_field("РАБОТА","Приступаем к работе!",2,10,14, "Arial", Lime,Lime);   
   
   PlaceTradesFrom = TimeToStr(StrToTime(TradeStartHour + ":" + TradeStartMinutes),TIME_MINUTES);
   PlaceTradesTo = TimeToStr(StrToTime(TradeEndHour + ":" + TradeEndMinutes),TIME_MINUTES);
   ObjectSetText("Info","Баланс: "+DoubleToStr(AccountBalance(), 2), 10,"Arial",Lime);

   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
   clear();
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   if (!Trading) return;
   if (!IsConnected() && !IsTesting()) {
       ObjectSetText("Info","ОБРЫВ СВЯЗИ! Пересканирую серверы", 10,"Arial",Red);  
       reconn(); //пересканировать серверы в случае обрыва связи
       return;
   }
   
   int repeat =0;
   ObjectSetText("Info","Баланс: "+DoubleToStr(AccountBalance(), 2), 10,"Arial",Lime);
   while (IsTradeContextBusy()) {
     Sleep(60000);
      repeat++;
      if (repeat >= 10) {
             Print("Торговый поток занят");
             ObjectSetText("Info","ТОРГОВЫЙ ПОТОК ЗАНЯТ!", 12,"Arial",Red);  
             return;
      }
   }
   
   
 switch (MinProfitMethod) {
      case 1:
            
            if (GetTotalProfit(Magic) >= MinProfit1) {
               CloseAllOrders(Magic);
               DeleteAllPendingOrders(Magic);
               ObjectSetText("Info","ПРОФИТ ПОЛУЧЕН! Начинаем заново", 10,"Arial",Lime);
            }
           
            break;

      case 2:
            
            if (GetProfitOpenPosInPoint(Symbol(), -1, Magic) >= MinProfit2) {
               CloseAllOrders(Magic);
               DeleteAllPendingOrders(Magic);
               ObjectSetText("Info","ПРОФИТ ПОЛУЧЕН! Начинаем заново", 10,"Arial",Lime);
            }
           
            break;

      case 3:
            
            if (GetTotalProfit(Magic) >=  AccountBalance() * MinProfit3 / 100.0) {
               CloseAllOrders(Magic);
               DeleteAllPendingOrders(Magic);
               ObjectSetText("Info","ПРОФИТ ПОЛУЧЕН! Начинаем заново", 10,"Arial",Lime);
            }
           
            break;
   }   
   //Если заданный профит получен - закроем ордера
/*
   if (GetTotalProfit(Magic) >= MinProfit) {
      CloseAllOrders(Magic);
      DeleteAllPendingOrders(Magic);
      ObjectSetText("Info","ПРОФИТ ПОЛУЧЕН! Начинаем заново", 10,"Arial",Lime);  
   }
*/   
   //Если убыток велик закрываемся
   
   switch (MaxLossMethod) {
      case 1:
            
            if (GetTotalProfit(Magic) <= -1.0 * MathAbs(MaxLoss1)) {
               CloseAllOrders(Magic);
               DeleteAllPendingOrders(Magic);
               ObjectSetText("Info","УБЫТОК! Закрыл все ордера", 10,"Arial",Red);        
            }
           
            break;

      case 2:
            
            if (GetProfitOpenPosInPoint(Symbol(), -1, Magic) <= -1.0 * MathAbs(MaxLoss2)) {
               CloseAllOrders(Magic);
               DeleteAllPendingOrders(Magic);
               ObjectSetText("Info","УБЫТОК! Закрыл все ордера", 10,"Arial",Red);        
            }
           
            break;

      case 3:
            
            if (GetTotalProfit(Magic) <= (-1.0 * AccountBalance()) * MaxLoss3 / 100.0) {
               CloseAllOrders(Magic);
               DeleteAllPendingOrders(Magic);
               ObjectSetText("Info","УБЫТОК! Закрыл все ордера", 10,"Arial",Red);        
            }
           
            break;
   }
    
   

   
   if (!isWorkTime(PlaceTradesFrom,PlaceTradesTo))  {
      DeleteAllPendingOrders(Magic);
      if (ForceCloseOrders) CloseAllOrders(Magic);
      
        switch (MinProfitMethod) {
      case 1:
            if (MinNewsProfit1 < 0) {
               if (GetTotalProfit(Magic) <= MinNewsProfit1) {
                  CloseAllOrders(Magic);
                  ObjectSetText("Info","ЗАКРЫЛИСЬ! ВЫШЛИ ИЗ ТОРГОВОГО ДИАПАЗОНА", 10,"Arial",Lime);
               }
            } else {
               if (GetTotalProfit(Magic) >= MinNewsProfit1) {
                  CloseAllOrders(Magic);
                  ObjectSetText("Info","ЗАКРЫЛИСЬ! ВЫШЛИ ИЗ ТОРГОВОГО ДИАПАЗОНА", 10,"Arial",Lime);
               }
            }
            break;

      case 2:
      
      
            if (MinNewsProfit1 < 0) {
            if (GetProfitOpenPosInPoint(Symbol(), -1, Magic) <= MinNewsProfit2) {
                  CloseAllOrders(Magic);
                  ObjectSetText("Info","ЗАКРЫЛИСЬ! ВЫШЛИ ИЗ ТОРГОВОГО ДИАПАЗОНА", 10,"Arial",Lime);
               }
            } else {
            if (GetProfitOpenPosInPoint(Symbol(), -1, Magic) >= MinNewsProfit2) {
                  CloseAllOrders(Magic);
                  ObjectSetText("Info","ЗАКРЫЛИСЬ! ВЫШЛИ ИЗ ТОРГОВОГО ДИАПАЗОНА", 10,"Arial",Lime);
               }
            }
      
            break;

      case 3:


            if (MinNewsProfit1 < 0) {
            if (GetTotalProfit(Magic) <=  AccountBalance() * MinNewsProfit3 / 100.0) {
                  CloseAllOrders(Magic);
                  ObjectSetText("Info","ЗАКРЫЛИСЬ! ВЫШЛИ ИЗ ТОРГОВОГО ДИАПАЗОНА", 10,"Arial",Lime);
               }
            } else {
            if (GetTotalProfit(Magic) >=  AccountBalance() * MinNewsProfit3 / 100.0) {
                  CloseAllOrders(Magic);
                  ObjectSetText("Info","ЗАКРЫЛИСЬ! ВЫШЛИ ИЗ ТОРГОВОГО ДИАПАЗОНА", 10,"Arial",Lime);
               }
            }
      
            break;
   }   

      
      
      ObjectSetText("РАБОТА","НЕ ВРЕМЯ ДЛЯ РАБОТЫ!", 14,"Arial",Red);        
      return;
   }
   else {
      ObjectSetText("РАБОТА","РАБОТАЕМ!", 14,"Arial",Red);        
   }
   
   
   // Обрабатываем новости
   if (UseNewsFilter && !IsTesting()) {    
      NewsHandling();
      if (NewsTime)  {
         DeleteAllPendingOrders(Magic);
         if (ForceCloseOrdersBeforeNews) CloseAllOrders(Magic);
         
         
         
         
         
  switch (MinProfitMethod) {
      case 1:
            if (MinNewsProfit1 < 0) {
               if (GetTotalProfit(Magic) <= MinNewsProfit1) {
                  CloseAllOrders(Magic);
                  ObjectSetText("Info","ЗАКРЫЛИСЬ ПЕРЕД НОВОСТЯМИ!", 10,"Arial",Lime);
               }
            } else {
               if (GetTotalProfit(Magic) >= MinNewsProfit1) {
                  CloseAllOrders(Magic);
                  ObjectSetText("Info","ЗАКРЫЛИСЬ ПЕРЕД НОВОСТЯМИ!", 10,"Arial",Lime);
               }
            }
            break;

      case 2:
      
      
            if (MinNewsProfit1 < 0) {
            if (GetProfitOpenPosInPoint(Symbol(), -1, Magic) <= MinNewsProfit2) {
                  CloseAllOrders(Magic);
                  ObjectSetText("Info","ЗАКРЫЛИСЬ ПЕРЕД НОВОСТЯМИ!", 10,"Arial",Lime);
               }
            } else {
            if (GetProfitOpenPosInPoint(Symbol(), -1, Magic) >= MinNewsProfit2) {
                  CloseAllOrders(Magic);
                  ObjectSetText("Info","ЗАКРЫЛИСЬ ПЕРЕД НОВОСТЯМИ!", 10,"Arial",Lime);
               }
            }
      
            break;

      case 3:


            if (MinNewsProfit1 < 0) {
            if (GetTotalProfit(Magic) <=  AccountBalance() * MinNewsProfit3 / 100.0) {
                  CloseAllOrders(Magic);
                  ObjectSetText("Info","ЗАКРЫЛИСЬ ПЕРЕД НОВОСТЯМИ!", 10,"Arial",Lime);
               }
            } else {
            if (GetTotalProfit(Magic) >=  AccountBalance() * MinNewsProfit3 / 100.0) {
                  CloseAllOrders(Magic);
                  ObjectSetText("Info","ЗАКРЫЛИСЬ ПЕРЕД НОВОСТЯМИ!", 10,"Arial",Lime);
               }
            }
      
            break;
   }   
        
         
         
         
         
         
         
         if (TimeToNews < 0) ObjectSetText("РАБОТА","НОВОСТИ! Ждем, до новости: "+MathAbs(TimeToNews)+" минут", 14,"Arial",Red);
         else ObjectSetText("РАБОТА","НОВОСТИ! Ждем, после новости : "+MathAbs(TimeToNews)+" минут", 14,"Arial",Red);
         return;
      }
   }
   
   //Открываем ордера
   double LastBuyPrice = GetLastBuy(Magic);
   double LastSellPrice = GetLastSell(Magic);
   
   if (LastBuyPrice == 0) {
      switch (MethodStep) {
         case 1: OpenOrder(Symbol(), OP_BUYLIMIT, FirstLot, Bid - StartStep * Point, 0,0,Magic,"Order BuyLimit");
         break;
         case 2: 
             //int high_index = iHighest(Symbol(), PERIOD_M5, MODE_HIGH, PERIOD,0);
            int low_index = iLowest(Symbol(), 0, MODE_LOW, CountBars,0);
      
            //CalcHigh = iHigh(Symbol(), PERIOD_M5, high_index);
            double CalcLow  =  MathMin(iLow(Symbol(), 0, low_index),Bid - MarketInfo(Symbol(),MODE_STOPLEVEL) * Point);
            OpenOrder(Symbol(), OP_BUYLIMIT, FirstLot, CalcLow, 0,0,Magic,"Order BuyLimit");
            
            break;
         case 3: 
            double upf=iFractals(NULL, 0, MODE_LOWER, 3);
            upf = MathMin(upf,Bid - MarketInfo(Symbol(),MODE_STOPLEVEL) * Point);
            if ( upf > 0 )OpenOrder(Symbol(), OP_BUYLIMIT, FirstLot, upf, 0,0,Magic,"Order BuyLimit");
         break;
      }
   }
   else {
      //if (Ask - LastBuyPrice <= 5.0 * Point) OpenOrder(Symbol(), OP_BUYLIMIT, FirstLot, LastBuyPrice - Step * Point, 0,0,Magic,"Order BuyLimit");
      int BuyStep = Step + MathCeil(GetCountOpenBuy(Magic) / CountOrders) * IncStep;
      
      if (Ask < LastBuyPrice) OpenOrder(Symbol(), OP_BUYLIMIT, LastBuyLot + IncLot, Bid - BuyStep * Point, 0,0,Magic,"Order BuyLimit");
   }
   //OrderSend(Symbol(), OP_BUYLIMIT, FirstLot, Ask - Step * Point, 3, 0, 0, "Cable Run", Magic, 0, Red);
   if (LastSellPrice == 0) 
        switch (MethodStep) {
         case 1: OpenOrder(Symbol(), OP_SELLLIMIT, FirstLot, Ask + StartStep * Point, 0,0,Magic,"Order SellLimit");
         break;
         case 2: 
            int high_index = iHighest(Symbol(), 0, MODE_HIGH, CountBars,0);
            //int low_index = iLowest(Symbol(), 0, MODE_LOW, CountBars,0);
      
            //double CalcHigh = iHigh(Symbol(), 0, high_index);
            double CalcHigh  =  MathMax(iHigh(Symbol(), 0, high_index),Ask + MarketInfo(Symbol(),MODE_STOPLEVEL) * Point);
            OpenOrder(Symbol(), OP_SELLLIMIT, FirstLot, CalcHigh, 0,0,Magic,"Order SellLimit");
            
            break;
         case 3: 
            double upfl=iFractals(NULL, 0, MODE_UPPER, 3);
            upfl = MathMax(upfl,Ask + MarketInfo(Symbol(),MODE_STOPLEVEL) * Point);
            if ( upfl > 0 ) OpenOrder(Symbol(), OP_SELLLIMIT, FirstLot, upfl, 0,0,Magic,"Order SellLimit");
         break;
      }
   
   else {
      //if (LastSellPrice - Bid <= 5.0 * Point) OpenOrder(Symbol(), OP_SELLLIMIT, FirstLot, LastSellPrice + Step * Point, 0,0,Magic,"Order SellLimit");
      int SellStep = Step + MathCeil(GetCountOpenSell(Magic) / CountOrders) * IncStep;
      if (LastSellPrice < Bid) OpenOrder(Symbol(), OP_SELLLIMIT, LastSellLot + IncLot, Ask + SellStep * Point, 0,0,Magic,"Order SellLimit");
   }
   //OrderSend(Symbol(), OP_SELLLIMIT, FirstLot, Bid + Step * Point, 3, 0, 0, "Cable Run", Magic, 0, Red);
   
   return(0);
  }
  
  
//+------------------------------------------------------------------+
//|     ФУНКЦИЯ ВОЗВРАЩАЕТ СУММАРНЫЙ ПРОФИТ В ПУНКТАХ
//+------------------------------------------------------------------+
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    symbol - наименование инструмента   (""   - любой символ,               |
//|                                     NULL - текущий символ)                 |
//|    cmd - операция                   (-1   - любая позиция)                 |
//|    magic - MagicNumber                (-1   - любой магик)                 |
//+----------------------------------------------------------------------------+
int GetProfitOpenPosInPoint(string symbol="", int cmd=-1, int magic=-1) {
  double point;
  
 if (symbol == "0") symbol = Symbol();
  
  int result = 0;

  
  for (int i=0; i<OrdersTotal(); i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if ((OrderSymbol() == symbol || symbol == "") && (cmd < 0 || OrderType() == cmd) && (magic < 0 || OrderMagicNumber() == magic)) {

          point = MarketInfo(OrderSymbol(), MODE_POINT);
          
          if (OrderType() == OP_BUY) {
            result += (MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice() ) / point;
          }
          if (OrderType() == OP_SELL) {
            result += (OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_ASK)) / point;
          }
        }

    }
  }
  return(result);
}


//+------------------------------------------------------------------+
//|     ФУНКЦИЯ ОТКРЫТИЯ ОРДЕРА
//+------------------------------------------------------------------+
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    symbol - наименование инструмента   (NULL или "" - текущий символ)      |
//|    cmd - операция                                                          |
//|    lot - лот                                                               |
//|    price - цена                                                            |
//|    sl - уровень стоп                                                       |
//|    tp - уровень тейк                                                       |
//|    magic - Magic Number                                                    |
//|    comment - комментарий                                                   |
//|                                                                            |
//+----------------------------------------------------------------------------+

int OpenOrder(string symbol,int cmd,double lot, double price, double sl, double tp, int magic,string comment) {

   int repeat = 25;
   int countRepeat = 0;
   int err, ticket;
   
   if (symbol=="" || symbol=="0") symbol = Symbol();
   
   while (!IsTradeAllowed()) {
      Print("ТОРГОВЛЯ ЗАПРЕЩЕНА!");
      Sleep(5000);
   }

      while (true) {
         countRepeat++;
         if (countRepeat > repeat) break;
         //Print(countRepeat);
         RefreshRates();
         ticket=OrderSend(symbol, cmd, lot, price, slippage, sl, tp, comment, magic,0, Red);
         err = GetLastError();
         if (err == 0/* NO_ERROR */) {
            Print("Open Order. Ордер открыт");
            Sleep(1000);
            return (true);
         }
         
         if (err==128 || err==142 || err==143 || err==135 || err==127 ||err==16 || err==93) {
           Sleep(1000*62);
           Print("Не могу открыть ордер по символу ", Symbol(), " Ошибка № ", err);
           continue;
         }

         // Блокировка работы советника
          if (err==2 || err==64 || err==65 || err==133) {
            break;
          }         

          if (err==4 || err==131 || err==132) {
           Sleep(1000*60); break;
         }
         
         if (err==8 || err==141) Sleep(1000*100);
         if (err==139 || err==140 || err==148) break;
         if (err==146) while (IsTradeContextBusy()) Sleep(1000*10);
         
         if (err == 130) {
            Print("Неправильные стопы!");
            break;
         }
      }

      Print("Не смог открыть ордер по символу ", Symbol(), " Ошибка № ", err);
      Alert("Не смог открыть ордер");
      ObjectSetText("Info","Не смог открыть ордер! Ошибка № " + err, 10,"Arial",Red);
      return(false);
}


//+------------------------------------------------------------------+
//|     ИЩЕМ ПОСЛЕДНИЙ ОТКРЫТЫЙ ОРДЕР BUY
//+------------------------------------------------------------------+
double GetLastBuy(int magic) {
   double profit = 0;
      for (int i = OrdersTotal() - 1; i >= 0; i--) {
         OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
         if (OrderMagicNumber() == magic && OrderSymbol() == Symbol() && OrderType() == OP_BUY ||OrderType() == OP_BUYLIMIT) {
            LastBuyLot = OrderLots();
            return (OrderOpenPrice());
         }
      }
   return (0);
}

//+------------------------------------------------------------------+
//|     ИЩЕМ КОЛИЧЕСТВО ОТКРЫТЫХ ОРДЕРОВ BUY
//+------------------------------------------------------------------+
double GetCountOpenBuy(int magic) {
  int count = 0;
      for (int i = OrdersTotal() - 1; i >= 0; i--) {
         OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
         if (OrderMagicNumber() == magic && OrderSymbol() == Symbol() && OrderType() == OP_BUY) {
            count ++;
         }
      }
   return (count);
}

//+------------------------------------------------------------------+
//|     ИЩЕМ КОЛИЧЕСТВО ОТКРЫТЫХ ОРДЕРОВ SELL
//+------------------------------------------------------------------+
double GetCountOpenSell(int magic) {
  int count = 0;
      for (int i = OrdersTotal() - 1; i >= 0; i--) {
         OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
         if (OrderMagicNumber() == magic && OrderSymbol() == Symbol() && OrderType() == OP_SELL) {
            count ++;
         }
      }
   return (count);
}




//+------------------------------------------------------------------+
//|     ИЩЕМ ПОСДЕНИЙ ОТКРЫТЫЙ ОРДЕР SELL
//+------------------------------------------------------------------+
double GetLastSell(int magic) {
   double profit = 0;
      for (int i = OrdersTotal() - 1; i >= 0; i--) {
         OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
         if (OrderMagicNumber() == magic && OrderSymbol() == Symbol() && OrderType() == OP_SELL ||OrderType() == OP_SELLLIMIT) {
            LastSellLot = OrderLots();
            return (OrderOpenPrice());
        }
      }
   return (0);
}






//+------------------------------------------------------------------+
//|     ПОДСЧЕТ ПРОФИТА ОТКРЫТЫХ ОРДЕРОВ
//+------------------------------------------------------------------+
double GetTotalProfit(int magic) {
   double profit = 0;
      for (int i = OrdersTotal() - 1; i >= 0; i--) {
         OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
         if (OrderMagicNumber() == magic && OrderSymbol() == Symbol() && OrderType() == OP_BUY || OrderType() == OP_SELL) profit += OrderProfit();
      }
   return (profit);
}



//+------------------------------------------------------------------+
//|     УДАЛЕНИЕ ВСЕХ ОТЛОЖЕННЫХ ОРДЕРОВ
//+------------------------------------------------------------------+
int DeleteAllPendingOrders(int magic) {
     int err;
     for (int i=OrdersTotal()-1; i>=0; i--) {
         if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
         if (OrderMagicNumber() == magic && OrderSymbol() == Symbol() && OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLLIMIT) {
            CloseLimit();
         }
      }
   return (0);
}


//+------------------------------------------------------------------+
//|     ЗАКРЫТИЕ ВСЕХ ОТКРЫТЫХ ОРДЕРОВ
//+------------------------------------------------------------------+
int CloseAllOrders(int magic) {
     int err;
     for (int i=OrdersTotal()-1; i>=0; i--) {
         if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
         if (OrderMagicNumber() == magic && OrderSymbol() == Symbol()) {
            if (OrderType() == OP_BUY) CloseBuy();
            if (OrderType() == OP_SELL) CloseSell();
         }
      }
   return (0);
}



//+------------------------------------------------------------------+
//|     УДАЛЕНИЕ ОТЛОЖЕННОГО ОРДЕРА
//+------------------------------------------------------------------+
bool CloseLimit() {
int repeat = 25;
int countRepeat = 0;
int err;
   while (true) {
      OrderDelete(OrderTicket());
      err = GetLastError();
      if (err == 0/* NO_ERROR */) {
         Print("Close Limit Order. Лимит ордер закрыт");
         return (true);
      }

      Print("Не могу закрыть лимит ордер по символу ", Symbol(), " Ошибка № ", err);
      Sleep(5000);
      RefreshRates();
      countRepeat++;
      if (countRepeat <= repeat) continue;
      break;
   }
   Alert("Не смог закрыть ордер");
   ObjectSetText("Info","Не смог закрыть ордер! Ошибка № " + err, 10,"Arial",Red);
   return(false);
}


//+------------------------------------------------------------------+
//|     УДАЛЕНИЕ ОРДЕРА BUY
//+------------------------------------------------------------------+
bool CloseBuy() {
int repeat = 25;
int countRepeat = 0;
int err;
   while (true) {
      OrderClose(OrderTicket(), OrderLots(), NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID), Digits), slippage, White);
      err = GetLastError();
      if (err == 0/* NO_ERROR */) {
         Print("Ордер Buy закрыт успешно");
         return (true);
      }

      Print("Не могу закрыть Buy ордер # ",OrderTicket()," по символу ", Symbol(), " Ошибка № ", err);
      Sleep(500);
      RefreshRates();
      countRepeat++;
      if (countRepeat <= repeat) continue;
      break;
   }
   Alert("Не могу закрыть ордер Buy");
   ObjectSetText("Info","Не могу закрыть ордер Buy! Ошибка № " + err, 10,"Arial",Red);
   return(false);
}

//+------------------------------------------------------------------+
//|     УДАЛЕНИЕ ОРДЕРА SELL
//+------------------------------------------------------------------+
bool CloseSell() {
int repeat = 25;
int countRepeat = 0;
int err;
   while (true) {
      OrderClose(OrderTicket(), OrderLots(), NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK), Digits), slippage, Red);
      err = GetLastError();
      if (err == 0/* NO_ERROR */) {
         Print("Ордер Sell закрыт успешно");
         return (true);
      }

      Print("Не могу закрыть Sell ордер # ",OrderTicket()," по символу ", Symbol(), " Ошибка № ", err);
      Sleep(500);
      RefreshRates();
      countRepeat++;
      if (countRepeat <= repeat) continue;
      break;
   }
   Alert("Не могу закрыть ордер Sell");
   ObjectSetText("Info","Не могу закрыть ордер Sell! Ошибка № " + err, 10,"Arial",Red);
   return(false);
}


//+------------------------------------------------------------------+
//|     ПРОВЕРКА НОВОСТЕЙ                                
//+------------------------------------------------------------------+
 void NewsHandling()
 {
     static int PrevMinute = -1;

     if (Minute() != PrevMinute)
     {
         PrevMinute = Minute();
         int minutesSincePrevEvent = iCustom(NULL, 0, "FFCal", true, true, false, true, true, 1, 0);
         int minutesUntilNextEvent = iCustom(NULL, 0, "FFCal", true, true, false, true, true, 1, 1);
         NewsTime = false;
         if (minutesUntilNextEvent <= MinsBeforeNews) {
             TimeToNews = - minutesUntilNextEvent;
             NewsTime = true;
         }
         
         if (minutesSincePrevEvent <= MinsAfterNews) {
             TimeToNews = minutesSincePrevEvent;
             NewsTime = true;
         }
     }
 }//newshandling


//+------------------------------------------------------------------+
//|     ВЫВОД ОБЪЕКТА С ЗАДАННЫМИ ПАРАМЕТРАМИ                                
//+------------------------------------------------------------------+
void Object_field(string name, string text, int X, int Y, int size, string font,color CL1, color CL2,int Angle=0) 
{
   if (ObjectFind(name) == -1 ) ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
   ObjectSet(name, OBJPROP_COLOR, CL1);
   ObjectSet(name, OBJPROP_XDISTANCE, X);
   ObjectSet(name, OBJPROP_YDISTANCE, Y);
   if (Angle>0) ObjectSet(name, OBJPROP_ANGLE,Angle);
   ObjectSetText(name,text, size,font,CL2);
return;   
}

//+------------------------------------------------------------------+
//|    СКАНИРОВАНИЕ СЕРВЕРОВ ПРИ ОБРЫВЕ СВЯЗИ                                
//+------------------------------------------------------------------+
void reconn()
{
     int hMetaTrader = GetAncestor(WindowHandle(Symbol(),Period()),2); // фокус на окно терминала
     if (hMetaTrader !=0) PostMessageA (hMetaTrader, WM_COMMAND, 33324, 0); // эмулируем тик 
     if (hMetaTrader !=0) PostMessageA (hMetaTrader, WM_COMMAND, 37400, 0); // команда пересканировать все серверы
     Sleep(2000);
return;
}

//+------------------------------------------------------------------+   
//    ОЧИСТКА ОКНА СОВЕТНИКА 
//+------------------------------------------------------------------+
void clear()
{
  int total = ObjectsTotal();  
  for (int i=total-1; i >= 0; i--) 
   {
    string name = ObjectName(i);
    ObjectDelete(name);
   }
return;
}

bool isWorkTime(string t1, string t2)
{
   string tc = TimeToStr(TimeCurrent(), TIME_MINUTES);
   if (t2 > t1)
      return (tc >= t1 && tc <= t2);
   else 
      return (tc >= t1 || tc <= t2);
}



