//+------------------------------------------------------------------+
//|                                                Generic A-TLP.mq4 |
//|                                                 Trade Like A Pro |
//|                                          http://tradelikeapro.ru |
//+------------------------------------------------------------------+
#property copyright "Trade Like A Pro"
#property link      "http://tradelikeapro.ru"
#property version   "5.00"
#property strict

#include <ErrorFile.mqh>

enum _EventYesNo{
      YES            = 1,
      NO             = 2
      };
enum _EventFilter{
      ON             = 1,
      OFF            = 2
      };

input    int            MagicNumber                = 25042016;
input    string         Comm                       = "DPS";             //Комментарий
input    double         Max_Spread                 = 3;
input    int            Slipage                    = 1;
input    bool           Auto_GMT                   = TRUE;
extern   bool           Calculate_DST              = TRUE;
input    int            Manual_GMT_Offset          = 2;
extern   double         Stop_Loss                  = 38;
extern   double         Take_Profit                = 35;
input    bool           use_din_TP                 = true;             //использовать динамический TP
input    int            TP_perc                    = 80;                //%% TP от размера канала
input    int            min_TP                     = 10;
input    bool           use_BE                     = true;             //использовать перевод в безубыток
input    double         X                          = 7;                //Если текущая цена лучше цены входа на Х пунктов
input    double         Y                          = 1;                 //перемещаем СЛ на Y пунктов в профит
input    int            Channel_Period             = 13;
input    int            Entry_Break                = 1;
input    int            Exit_Distance              = -13;
//input    int            Start_Trade_Hour           = 17;
//input    int            End_Trade_Hour             = 23;
input    int            MaxDailyRange              = 1000;
input    double         Lots                       = 0.1;
input    double         Auto_Risk                  = 0.0;
input    int            Min_Volatility             = 20;
input    int            Exit_Profit_Pips           = -12;
         int            ma_period                  = 2;
input    int            Reverse_Profit             = 20;
input    int            Exit_Minutes               = 140;
input    int            Time_Profit_Pips           = 0;
input    _EventFilter   Filter_1                   = 1;                 //Фильтр №1 (на выход из сделки)
input    _EventFilter   Filter_2                   = 1;                 //Фильтр №2 (на выход из сделки)
input    _EventFilter   Filter_3                   = 1;                 //Фильтр №3 (на выход из сделки)
input    _EventYesNo    one_trade                  = 2;                 //одна сделка за торговый интервал
input    color          Col_info                   = C'176,162,168';    //Цвет инфо панели
         
         double         maxlot                     = 0.01;
         double         lotstep                    = 0.01;
         double         old_point                  = 0.0001;
         double         minlot                     = 0.0;
         int            lotsize                    = 0;
         int            stoplevel                  = 0;
         int            gmt_offset                 = 0;
         int            dst_koef                   = 0;
         bool           trade_flag;
         //int            cmd;
         int            count_sell;
         datetime       day_of_trade;
         datetime       need_to_verify_market_info;
//--- параметры для записи данных в файл
         string         InpFileName;                                    // Имя файла
         string         fileName                   = "EA_Generic";      // Имя файла
         string         InpDirectoryName           = "LOGS";            // Имя каталога

extern string S1  =             " DayOfWeek Filter";
extern bool monday       = true;
extern string monday_open = "01:00";
extern string monday_pause_start = "0";
extern string monday_pause_stop = "0";
extern string monday_close = "23:50";

extern bool tuesday      = true;
extern string tuesday_open = "00:00";
extern string tuesday_pause_start = "0";
extern string tuesday_pause_stop = "0";
extern string tuesday_close = "23:50";

extern bool wednesday    = true;
extern string wednesday_open = "00:00";
extern string wednesday_pause_start = "0";
extern string wednesday_pause_stop = "0";
extern string wednesday_close = "23:50";

extern bool thursday     = true;
extern string thursday_open = "00:00";
extern string thursday_pause_start = "0";
extern string thursday_pause_stop = "0";
extern string thursday_close = "23:50";

extern bool friday       = false;
extern string friday_open = "08:30";
extern string friday_pause_start = "15:30";
extern string friday_pause_stop = "17:55";
extern string friday_close = "21:35";

extern bool sunday       = false; 
extern string sunday_open = "08:30";
extern string sunday_pause_start = "15:30";
extern string sunday_pause_stop = "17:55";
extern string sunday_close = "21:35";

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   need_to_verify_market_info = iTime(NULL,PERIOD_W1,1);
   day_of_trade = iTime(NULL,PERIOD_D1,1);
   trade_flag = false;
   fRectLabelCreate(0,"info_panel",0,0,28,150,262,Col_info);
   string s = "";
   switch(Period()){
      case PERIOD_M1:   s = "M1";
                        break;
      case PERIOD_M5:   s = "M5";
                        break;
      case PERIOD_M15:  s = "M15";
                        break;
      case PERIOD_M30:  s = "M30";
                        break;
      case PERIOD_H1:   s = "H1";
                        break;
      case PERIOD_H4:   s = "H4";
                        break;
      case PERIOD_D1:   s = "D1";
                        break;
      case PERIOD_W1:   s = "W1";
                        break;
      case PERIOD_MN1:  s = "MN1";
                        break;
   }
   
   InpFileName = fileName + "_" + Symbol() + "_" + s + ".txt";
   Comment("");
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");
   fRectLabelDelete(0,"info_panel");
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   long     tick_volume = iVolume(NULL, PERIOD_M1, 0);
   if (DayOfWeek() == 1 && iVolume(NULL, PERIOD_D1, 0) < 5) return;
   double   lots = 0;
   string   gmt_info;
   string   dst_info;
   int      slippage;
   //int      start_hour;
   //int      end_hour;
   double   channel_upper;
   double   channel_lower;
   double   channel_upper_M1;
   double   channel_lower_M1;
   double   ma_shift_1;
   double   ma_shift_2;
   double   channel_width;
   double   channel_width_M1;
   int      ticket;
   int      count_buy;
   double   stoploss;
   double   takeprofit;
   string   order_type;
   color    order_color = clrNONE;
   double   price = 0.0;
   string   info_panel = "";
   if(need_to_verify_market_info != iTime(NULL,PERIOD_W1,0)){
      need_to_verify_market_info = iTime(NULL,PERIOD_W1,0);
      stoplevel = (int)MarketInfo(Symbol(), MODE_STOPLEVEL);
      minlot = MarketInfo(Symbol(), MODE_MINLOT);
      maxlot = MarketInfo(Symbol(), MODE_MAXLOT);
      lotsize = (int)MarketInfo(Symbol(), MODE_LOTSIZE);
      lotstep = MarketInfo(Symbol(), MODE_LOTSTEP);
      if (Digits <= 3) old_point = 0.01;
      else old_point = 0.0001;
      gmt_offset = fGetGMTOffset();
      dst_koef = 0;
      if(IsTesting()) Calculate_DST = FALSE;
      if(IsTesting() || Auto_GMT == FALSE) gmt_offset = Manual_GMT_Offset;
      if(!IsTesting() && Auto_GMT == TRUE && Calculate_DST == TRUE && (Month() > 3 && Month() < 11))
         dst_koef--;
      /*
      if (!IsTesting() && Auto_GMT == TRUE && Calculate_DST == TRUE && (Month() <= 3 || Month() >= 11)) {
      }
      if (!IsTesting() && Auto_GMT == TRUE && Calculate_DST == FALSE) {
      }
      */
   }
   if(!IsTesting() && IsDllsAllowed() == FALSE) {
      Comment("Warning: Set Parameter **AllowDLL Imports** ON in menu Tools -> Options -> ExpertAdvisors.");
      Print("Warning: Set Parameter **AllowDLL Imports** ON in menu Tools -> Options -> ExpertAdvisors.");
      Sleep(30000);
      return;
   }
   
   if(Auto_Risk > 0.0)
      lots = MathMax(minlot, MathMin(maxlot, MathCeil(MathMin(100, Auto_Risk) / 100.0 *
         AccountFreeMargin() / lotstep / (lotsize / 100)) * lotstep));
   else lots = Lots;

   if(Auto_GMT)
      gmt_info = "Auto GMT - ON";
   else
      gmt_info = "Auto GMT - OFF !!!";
   if(IsTesting()) Calculate_DST = FALSE;
   if(Calculate_DST == TRUE) dst_info = "YES";
   if(Calculate_DST == FALSE) dst_info = "NO";
   
   //start_hour = Start_Trade_Hour + gmt_offset + dst_koef;
   //end_hour = End_Trade_Hour + gmt_offset + dst_koef;
   //if(start_hour > 23) start_hour -= 24;
   //if(start_hour < 0) start_hour += 24;
   //if(end_hour > 23) end_hour -= 24;
   //if(end_hour < 0) end_hour += 24;
   /*
   if(trade_flag){
      if(day_of_trade != iTime(NULL,PERIOD_D1,0)){
         trade_flag = false;
         day_of_trade = iTime(NULL,PERIOD_D1,0);
      }
      if(end_hour == 23){
         if(TimeHour(TimeCurrent()) < end_hour && TimeHour(TimeCurrent()) < start_hour)
            trade_flag = false;
      }
      else{
         if(start_hour <= end_hour){
            if(TimeHour(TimeCurrent()) > end_hour || TimeHour(TimeCurrent()) < start_hour)
               trade_flag = false;
         }
         else{
            if(TimeHour(TimeCurrent()) < start_hour && TimeHour(TimeCurrent()) > end_hour)
               trade_flag = false;
         }
      }
   }
   */
   if(!IsTesting() && !IsOptimization()){
      info_panel = info_panel 
         + "\n -----------------------------------------------" 
         + "\n           GENERIC A-TLP" 
         + "\n -----------------------------------------------" 
         + "\n  A FREE PRODUCT POWERED" 
         + "\n                    BY" 
         + "\n     http://TRADELIKEAPRO.ru" 
         + "\n -----------------------------------------------" 
         + "\n         USE ON M15 CHART" 
         + "\n -----------------------------------------------" 
         + "\n  " + gmt_info 
         + "\n  Calculate DST - " + dst_info 
         + "\n  Broker GMT = " + IntegerToString(gmt_offset)
         //+ "\n  Start Hour (Broker Time) = " + IntegerToString(start_hour)
         //+ "\n  End Hour (Broker Time) = " + IntegerToString(end_hour)
         + "\n  Stop Loss = " + DoubleToStr(Stop_Loss,1) + " pips" 
         + "\n  Take Profit = " + DoubleToStr(Take_Profit,1) + " pips"
         + "\n  Max Spread = " + DoubleToStr(Max_Spread,1) + " pips"
         + "\n  Spread = " + DoubleToStr((Ask - Bid) / old_point, 1) + " pips";
      
      if(Ask - Bid > Max_Spread * old_point) info_panel = info_panel + " - HIGH !!!";
      else info_panel = info_panel + " - NORMAL";
      if(Auto_Risk > 0.0){
         info_panel = info_panel 
            + "\n  AutoRisk - Activated" 
         + "\n  Risk = " + DoubleToStr(Auto_Risk, 1) + "%";
      }
      info_panel = info_panel 
      + "\n  Trading Lots = " + DoubleToStr(lots, 2);
      info_panel = info_panel 
      + "\n  -----------------------------------------------";
      Comment(info_panel);
   }
   if(IsTradeAllowed()){
      if(IsTradeContextBusy() == FALSE){
         slippage = (int)NormalizeDouble(Slipage / Point * old_point,0);
         
         HideTestIndicators(TRUE);
         channel_upper = iMA(NULL, PERIOD_M15, Channel_Period, 0, MODE_SMA, PRICE_CLOSE, 1) +
            2.0 * iStdDev(NULL, PERIOD_M15, Channel_Period, 0, MODE_SMA, PRICE_CLOSE, 1);
         channel_lower = iMA(NULL, PERIOD_M15, Channel_Period, 0, MODE_SMA, PRICE_CLOSE, 1) -
            2.0 * iStdDev(NULL, PERIOD_M15, Channel_Period, 0, MODE_SMA, PRICE_CLOSE, 1);
            
         ma_shift_1 = iMA(NULL, PERIOD_M1, ma_period, 0, MODE_SMA, PRICE_CLOSE, 1);
         ma_shift_2 = iMA(NULL, PERIOD_M1, ma_period, 0, MODE_SMA, PRICE_CLOSE, 2);
         
         channel_upper_M1 = iMA(NULL, PERIOD_M1, Channel_Period, 0, MODE_SMA, PRICE_CLOSE, 1) +
            2.0 * iStdDev(NULL, PERIOD_M1, Channel_Period, 0, MODE_SMA, PRICE_CLOSE, 1);
         channel_lower_M1 = iMA(NULL, PERIOD_M1, Channel_Period, 0, MODE_SMA, PRICE_CLOSE, 1) -
            2.0 * iStdDev(NULL, PERIOD_M1, Channel_Period, 0, MODE_SMA, PRICE_CLOSE, 1);
         HideTestIndicators(FALSE);
         channel_width = channel_upper - channel_lower;
         channel_width_M1 = channel_upper_M1 - channel_lower_M1;
         
         if(use_din_TP){
            Take_Profit = MathMax(NormalizeDouble(channel_width/old_point /100 * TP_perc,1), min_TP);
         }
         if(Take_Profit < stoplevel * Point / old_point)
            Take_Profit = stoplevel * Point / old_point;
         if(Stop_Loss < stoplevel * Point / old_point)
            Stop_Loss = stoplevel * Point / old_point;
         
         count_buy = 0;
         count_sell = 0;
         for(int pos = OrdersTotal() - 1; pos >= 0; pos--){
            if(!OrderSelect(pos, SELECT_BY_POS, MODE_TRADES)){
               string q = __FUNCTION__ + ": не удалось выделить ордер! " + fMyErDesc();
               Print(q);
               fWriteDataToFile(q);
            }
            else{
               if(OrderType() <= OP_SELL && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber){
                  RefreshRates();
                  //if(one_trade == 1 /*&& !trade_flag*/) trade_flag = true;
                  
                  if(OrderType() == OP_BUY){
                     count_buy++;
                     if (OrderStopLoss() == 0.0){
                        Print("TakeProfit = ",Take_Profit);
                        stoploss = NormalizeDouble(OrderOpenPrice() - Stop_Loss * old_point, Digits);
                        takeprofit = NormalizeDouble(OrderOpenPrice() + Take_Profit * old_point, Digits);
                        Print("takeprofit = ",takeprofit);
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), stoploss, takeprofit, 0, Green)){
                           string q = __FUNCTION__ + ": не удалось модифицировать ордер #" +
                              IntegerToString(OrderTicket()) + "! " + fMyErDesc();
                           Print(q);
                           fWriteDataToFile(q);
                        }
                        continue;
                     }
                     
                     if(use_BE && X > Y && Bid - OrderOpenPrice() >= X * old_point && OrderStopLoss() < OrderOpenPrice()){
                        stoploss = NormalizeDouble(OrderOpenPrice() + Y * old_point, Digits);
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), stoploss, OrderTakeProfit(), 0, Green)){
                           string q = __FUNCTION__ + ": не удалось модифицировать ордер #" +
                              IntegerToString(OrderTicket()) + "! " + fMyErDesc();
                           Print(q);
                           fWriteDataToFile(q);
                        }
                     }
                     
                     bool condition_for_the_exit_1 = false;
                     bool condition_for_the_exit_2 = false;
                     bool condition_for_the_exit_3 = false;
                     
                     if(tick_volume <= 1.0){                          //
                        
                        if(Filter_1 == 1 &&
                           TimeCurrent() - OrderOpenTime() > 60 * Exit_Minutes &&      // ордер открыт более Exit_Minutes (2 ч 20 мин) И
                           Bid - OrderOpenPrice() > Time_Profit_Pips * old_point){     // плавающая прибыль более Time_Profit_Pips (0)
                              condition_for_the_exit_1 = true;
                              string q = "BUY: ордер #" + IntegerToString(OrderTicket()) +
                                       " Фильтр на выход №1 сработал. Ордер открыт более " +
                                       IntegerToString(Exit_Minutes) + " минут и плавающая прибыль более " +
                                       DoubleToStr(Time_Profit_Pips,1) + " пунктов.";
                              Print(q);
                              fWriteDataToFile(q);
                        }
                        
                        if(Filter_2 == 1 &&
                           Bid >= channel_upper + Exit_Distance * old_point &&         // цена вышла за верхнюю границу канала И
                           Bid - OrderOpenPrice() > Exit_Profit_Pips * old_point){     // плавающая прибыль более Exit_Profit_Pips (-12)
                              condition_for_the_exit_2 = true;
                             string q = "BUY: ордер #" + IntegerToString(OrderTicket()) +
                                       " Фильтр на выход №2 сработал. Цена поднялась выше " +
                                       DoubleToStr(channel_upper,Digits) + "(верхняя граница канала) на " + 
                                       DoubleToStr(Exit_Distance,1) + " пунктов и плавающая прибыль более " +
                                       DoubleToStr(Exit_Profit_Pips,1) + " пунктов.";
                              Print(q);
                              fWriteDataToFile(q);
                        }
                        
                        if(Filter_3 == 1 &&
                           ma_shift_1 < ma_shift_2 &&                                  // скользящая средняя снижается И
                           Bid - OrderOpenPrice() > Reverse_Profit * old_point){       // плавающая прибыль более Reverse_Profit (20)
                              condition_for_the_exit_3 = true;
                              string q = "BUY: ордер #" + IntegerToString(OrderTicket()) +
                                       " Фильтр на выход №3 сработал. Скользящая средняя снижается" +
                                       " и плавающая прибыль более " +
                                       DoubleToStr(Reverse_Profit,1) + " пунктов.";
                              Print(q);
                              fWriteDataToFile(q);
                        }
                        
                        if(condition_for_the_exit_1 || condition_for_the_exit_2 || condition_for_the_exit_3){
                           RefreshRates();
                           if(!OrderClose(OrderTicket(), OrderLots(), NormalizeDouble(Bid, Digits), slippage, Violet)){
                              string q = __FUNCTION__ + ": Ордер " + OrderSymbol() + " #" +
                                    IntegerToString(OrderTicket()) + " не был закрыт! " + fMyErDesc();
                              Print(q);
                              fWriteDataToFile(q);
                           }
                           else{
                              Sleep(1000);
                              return;
                           }
                           Sleep(5000);
                           continue;
                        }
                     }
                     count_buy++;
                     continue;
                  }
                  
                  if(OrderType() == OP_SELL){
                     count_sell++;
                     if (OrderStopLoss() == 0.0){
                        Print("TakeProfit = ",Take_Profit);
                        stoploss = NormalizeDouble(OrderOpenPrice() + Stop_Loss * old_point, Digits);
                        takeprofit = NormalizeDouble(OrderOpenPrice() - Take_Profit * old_point, Digits);
                        Print("takeprofit = ",takeprofit);
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), stoploss, takeprofit, 0, Green)){
                           string q = __FUNCTION__ + ": не удалось модифицировать ордер #" +
                                 IntegerToString(OrderTicket()) + "! " + fMyErDesc();
                           Print(q);
                           fWriteDataToFile(q);
                        }
                        continue;
                     }
                     
                     if(use_BE && X > Y && OrderOpenPrice() - Ask >= X * old_point && OrderStopLoss() > OrderOpenPrice()){
                        stoploss = NormalizeDouble(OrderOpenPrice() - Y * old_point, Digits);
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), stoploss, OrderTakeProfit(), 0, Green)){
                           string q = __FUNCTION__ + ": не удалось модифицировать ордер #" +
                              IntegerToString(OrderTicket()) + "! " + fMyErDesc();
                           Print(q);
                           fWriteDataToFile(q);
                        }
                     }
                     
                     bool condition_for_the_exit_1 = false;
                     bool condition_for_the_exit_2 = false;
                     bool condition_for_the_exit_3 = false;
                     
                     if(tick_volume <= 1.0){                          //
                        
                        if(Filter_1 == 1 &&
                           TimeCurrent() - OrderOpenTime() > 60 * Exit_Minutes &&      // ордер открыт более Exit_Minutes (2 ч 20 мин) И
                           OrderOpenPrice() - Ask > Time_Profit_Pips * old_point){     // плавающая прибыль более Time_Profit_Pips (0)
                              condition_for_the_exit_1 = true;
                              string q = "SELL: ордер #" + IntegerToString(OrderTicket()) +
                                       " Фильтр на выход №1 сработал. Ордер открыт более " +
                                       IntegerToString(Exit_Minutes) + " минут и плавающая прибыль более " +
                                       DoubleToStr(Time_Profit_Pips,1) + " пунктов.";
                              Print(q);
                              fWriteDataToFile(q);
                        }
                        
                        if(Filter_2 == 1 &&
                           Bid <= channel_lower - Exit_Distance * old_point &&         // цена вышла за нижнюю границу канала И
                           OrderOpenPrice() - Ask > Exit_Profit_Pips * old_point){     // плавающая прибыль более Exit_Profit_Pips (-12)
                              condition_for_the_exit_2 = true;
                             string q = "SELL: ордер #" + IntegerToString(OrderTicket()) +
                                       " Фильтр на выход №2 сработал. Цена опустилась ниже " +
                                       DoubleToStr(channel_lower,Digits) + "(нижняя граница канала) на " + 
                                       DoubleToStr(Exit_Distance,1) + " пунктов и плавающая прибыль более " +
                                       DoubleToStr(Exit_Profit_Pips,1) + " пунктов.";
                              Print(q);
                              fWriteDataToFile(q);
                        }
                        
                        if(Filter_3 == 1 &&
                           ma_shift_1 > ma_shift_2 &&                                  // скользящая средняя повышается И
                           OrderOpenPrice() - Ask > Reverse_Profit * old_point){       // плавающая прибыль более Reverse_Profit (20)
                              condition_for_the_exit_3 = true;
                              string q = "SELL: ордер #" + IntegerToString(OrderTicket()) +
                                       " Фильтр на выход №3 сработал. Скользящая средняя повышается" +
                                       " и плавающая прибыль более " +
                                       DoubleToStr(Reverse_Profit,1) + " пунктов.";
                              Print(q);
                              fWriteDataToFile(q);
                        }
                        
                        if(condition_for_the_exit_1 || condition_for_the_exit_2 || condition_for_the_exit_3){
                           RefreshRates();
                           if(!OrderClose(OrderTicket(), OrderLots(), NormalizeDouble(Ask, Digits), slippage, Violet)){
                              string q = __FUNCTION__ + ": Ордер " + OrderSymbol() + " #" +
                                    IntegerToString(OrderTicket()) + " не был закрыт! " + fMyErDesc();
                              Print(q);
                              fWriteDataToFile(q);
                           }
                           else{
                              Sleep(1000);
                              return;
                           }
                           Sleep(5000);
                           continue;
                        }
                     }
                     count_sell++;
                     continue;
                  }
               }   //if (OrderType() <= OP_SELL && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
            }     // else   if (!OrderSelect(pos, SELECT_BY_POS, MODE_TRADES))
         }        //for (int pos = OrdersTotal() - 1; pos >= 0; pos--)
         
         //if(start_hour <= end_hour && (TimeHour(TimeCurrent()) < start_hour || TimeHour(TimeCurrent()) > end_hour))
         //   return;
         //if(start_hour > end_hour && TimeHour(TimeCurrent()) < start_hour && TimeHour(TimeCurrent()) > end_hour)
         //   return;
         if(!IsTime())
            return;
         day_of_trade = iTime(NULL,PERIOD_D1,0);
         if(tick_volume <= 1.0 && !trade_flag) {
            RefreshRates();
            double spread = Ask - Bid;
            if(spread > Max_Spread * old_point){
               string q = Symbol() + ": Spread = " +
                        DoubleToStr((spread) / old_point, 1) + " pips" + " - HIGH !!!";
               Print(q);
               return;
            }
            if(count_buy < 1 &&
               Bid < channel_lower - Entry_Break * old_point &&
               channel_width >= Min_Volatility * old_point &&
               iOpen(NULL,PERIOD_D1,0) - Ask < MaxDailyRange * old_point){
                  
                  RefreshRates();
                  ticket = OrderSend(Symbol(), OP_BUY, lots, Ask, slippage, 0, 0, Comm,
                                       MagicNumber, 0, clrAqua);
                  order_type = "BUY";
                  Sleep(5000);
                  if (ticket > 0) {
                     if (!OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)){
                        string q = __FUNCTION__ + ": не удалось выделить ордер " +
                                 IntegerToString(ticket) + "! " + fMyErDesc();
                        Print(q);
                        fWriteDataToFile(q);
                     }
                     else{
                        string q = __FUNCTION__ + ": ордер " + order_type + " открыт по цене " +
                                 DoubleToStr(OrderOpenPrice(),Digits) + "; DailyRange = (" +
                                 DoubleToStr((iOpen(NULL,PERIOD_D1,0) - Ask)/old_point,1) + ") пипс.";
                        Print(q);
                        fWriteDataToFile(q);
                     }
                  } 
                  else{
                     string q = __FUNCTION__ + ": ордер " + order_type +
                                 " не был открыт!: " + fMyErDesc();
                     Print(q);
                     fWriteDataToFile(q);
                  }
            }
            if(count_sell < 1 &&
               Bid > channel_upper + Entry_Break * old_point &&
               channel_width >= Min_Volatility * old_point &&
               Bid - iOpen(NULL,PERIOD_D1,0) < MaxDailyRange * old_point){
                  
                  RefreshRates();
                  ticket = OrderSend(Symbol(), OP_SELL, lots, Bid, slippage, 0, 0, Comm,
                                       MagicNumber, 0, clrRed);
                  order_type = "SELL";
                  Sleep(5000);
                  if (ticket > 0) {
                     if (!OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)){
                        string q = __FUNCTION__ + ": не удалось выделить ордер " +
                                 IntegerToString(ticket) + "! " + fMyErDesc();
                        Print(q);
                        fWriteDataToFile(q);
                     }
                     else{
                        string q = __FUNCTION__ + ": ордер " + order_type + " открыт по цене " +
                                 DoubleToStr(OrderOpenPrice(),Digits) + "; DailyRange = (" +
                                 DoubleToStr((Bid - iOpen(NULL,PERIOD_D1,0))/old_point,1) + ") пипс.";
                        Print(q);
                        fWriteDataToFile(q);
                     }
                  } 
                  else{
                     string q = __FUNCTION__ + ": ордер " + order_type +
                                 " не был открыт!: " + fMyErDesc();
                     Print(q);
                     fWriteDataToFile(q);
                  }
            }
         }
      }
   }
}
/////////////////////////////////////////////////////////////////////////

bool IsTime()
{
   switch(DayOfWeek())
   {
        case 0: {
                     return(sunday && IsNow(sunday_open,sunday_pause_start,sunday_pause_stop,sunday_close));                     
                     break;
                }
        case 1: {
                     return(monday && IsNow(monday_open,monday_pause_start,monday_pause_stop,monday_close));                     
                     break;
                }
        case 2: {
                     return(tuesday && IsNow(tuesday_open,tuesday_pause_start,tuesday_pause_stop,tuesday_close));                     
                     break;
                }
        case 3: {
                     return(wednesday && IsNow(wednesday_open,wednesday_pause_start,wednesday_pause_stop,wednesday_close));                     
                     break;
                }        
        case 4: {
                     return(thursday && IsNow(thursday_open,thursday_pause_start,thursday_pause_stop,thursday_close));                     
                     break;
                }
        case 5: {
                     return(friday && IsNow(friday_open,friday_pause_start,friday_pause_stop,friday_close));                     
                     break;
                }
        default:{
                     return(false);
                }                                                
   }

}

bool IsNow(string open,string pause_start,string pause_stop,string close)
{
     if((pause_start == "0")||((pause_start == open)&&(pause_stop == close)))
     {
          //no pause
          return((TimeCurrent() >= StrToTime(open)) && (TimeCurrent() <StrToTime(close)));
          
     }
     else // pause
     {
          return(((TimeCurrent() >= StrToTime(open)) && (TimeCurrent() <StrToTime(pause_start)))||
                 ((TimeCurrent() >= StrToTime(pause_stop)) && (TimeCurrent() <StrToTime(close))));
     }
     return(false);
}
//+------------------------------------------------------------------+
int fGetGMTOffset() {
   int time = (int)(TimeCurrent() - TimeGMT());
   double offset = time;
   offset *= 0.01;
   offset = MathCeil(offset) * 100;
   offset = offset/3600;
   int gmtoffset = (int)NormalizeDouble(offset,0);
   return(gmtoffset);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|          Записывает строку 's' в файл InpFileName                |
//+------------------------------------------------------------------+
void fWriteDataToFile(string s){
   if(IsTesting() || IsOptimization()) return;
   //--- откроем файл для записи данных (если его нет, то создастся автоматически)
   ResetLastError();
   string data = "";
   data = IntegerToString(Day()) + "." + IntegerToString(Month()) + "." + IntegerToString(Year()) + "  " +
         IntegerToString(Hour()) + ":" + IntegerToString(Minute());
   int file_handle = FileOpen(InpDirectoryName+"//"+InpFileName,FILE_TXT|FILE_READ|FILE_WRITE);
   if(file_handle != INVALID_HANDLE){
      PrintFormat("Файл %s открыт для записи",InpFileName);
      PrintFormat("Путь к файлу: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
      
      FileSeek(file_handle,0,SEEK_END);        //переставляем курсор в конец файла
      
      s = data + "   " + s;
      
      //--- запишем значения в файл
      FileWrite(file_handle,s);
      //--- закрываем файл
      FileClose(file_handle);
      PrintFormat("Данные записаны, файл %s закрыт",InpFileName);
     }
   else
      PrintFormat("Не удалось открыть файл %s, " + fMyErDesc(),InpFileName);
}
//+------------------------------------------------------------------+ 
//| Создает прямоугольную метку                                      | 
//+------------------------------------------------------------------+ 
bool fRectLabelCreate(const long             chart_ID    = 0,                 // ID графика 
                      const string           name        = "RectLabel",       // имя метки 
                      const int              sub_window  = 0,                 // номер подокна 
                      const int              x           = 0,                 // координата по оси X 
                      const int              y           = 0,                 // координата по оси Y 
                      const int              width       = 50,                // ширина 
                      const int              height      = 18,                // высота 
                      const color            back_clr    = C'236,233,216',    // цвет фона 
                      const ENUM_BORDER_TYPE border      = BORDER_SUNKEN,     // тип границы 
                      const ENUM_BASE_CORNER corner      = CORNER_LEFT_UPPER, // угол графика для привязки 
                      const color            clr         = clrRed,            // цвет плоской границы (Flat) 
                      const ENUM_LINE_STYLE  style       = STYLE_SOLID,       // стиль плоской границы 
                      const int              line_width  = 1,                 // толщина плоской границы 
                      const bool             back        = false,             // на заднем плане 
                      const bool             selection   = false,             // выделить для перемещений 
                      const bool             hidden      = true,              // скрыт в списке объектов 
                      const long             z_order     = 0)                 // приоритет на нажатие мышью 
{ 
//--- сбросим значение ошибки 
   ResetLastError(); 
//--- создадим прямоугольную метку 
   if(!ObjectCreate(chart_ID,name,OBJ_RECTANGLE_LABEL,sub_window,0,0)) 
     { 
      Print(__FUNCTION__, 
            ": не удалось создать прямоугольную метку! " + fMyErDesc()); 
      return(false); 
     } 
//--- установим координаты метки 
   ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x); 
   ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y); 
//--- установим размеры метки 
   ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width); 
   ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height); 
//--- установим цвет фона 
   ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr); 
//--- установим тип границы 
   ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_TYPE,border); 
//--- установим угол графика, относительно которого будут определяться координаты точки 
   ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner); 
//--- установим цвет плоской рамки (в режиме Flat) 
   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); 
//--- установим стиль линии плоской рамки 
   ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style); 
//--- установим толщину плоской границы 
   ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,line_width); 
//--- отобразим на переднем (false) или заднем (true) плане 
   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); 
//--- включим (true) или отключим (false) режим перемещения метки мышью 
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection); 
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); 
//--- скроем (true) или отобразим (false) имя графического объекта в списке объектов 
   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); 
//--- установим приоритет на получение события нажатия мыши на графике 
   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); 
//--- успешное выполнение 
   return(true); 
}
//+------------------------------------------------------------------+ 
//| Удаляет прямоугольную метку                                      | 
//+------------------------------------------------------------------+ 
bool fRectLabelDelete(const long   chart_ID   = 0,           // ID графика 
                      const string name       = "RectLabel") // имя метки 
{ 
//--- сбросим значение ошибки 
   ResetLastError(); 
//--- удалим метку 
   if(!ObjectDelete(chart_ID,name)) 
     { 
      Print(__FUNCTION__, 
            ": не удалось удалить прямоугольную метку! " + fMyErDesc()); 
      return(false); 
     } 
//--- успешное выполнение 
   return(true); 
} 
