//+------------------------------------------------------------------+
//|                                                      EA_BILL.mq4 |
//|                                                   VMQL Solutions |
//|                                               http://www.vmql.ru |
//+------------------------------------------------------------------+
#property copyright "UNIVERSAL"
#property link      "dtstrannik@mail.ru"
#property version   "6.6"

extern string EA = "Общие настройки советника";
enum type_open_trend {ONLY_BUY, ONLY_SELL, ALL};
extern type_open_trend Type_trend_orders = ALL; //В какую сторону открывать ордера. ALL - в обе.
extern bool Trade_opposite = true; // открывать ли противоположные ордера
extern int MaxTrades_main = 3; // Сколько первичных ордеров открывать
extern ENUM_TIMEFRAMES Upper_period = PERIOD_CURRENT; // По фракталам какого периода открывать сделки. Линии аллигатора расчитываются тоже с этим параметром.
extern double Lot = 0.1;
extern int Delta = 10; // отступ от фрактала для первичных ордеров
enum Type_lot_trend{ Exp, Regress, Parabola, NONE_lot_trend };
extern Type_lot_trend Lot_type = Parabola; // Тип расчета лота для второго и последующего ордеров по тренду.
extern double LotExTrend = 1.5; // Умоножение лота
extern double Lots_regress_N = 5; // на сколько умножать первичный лот по параметру регресс. Дальше ордера идут с уменьшиением 0,5 , 0,4 , 0,3  
extern double Lots_regress = 0.1; // до какого лота уменьшать до лота 0,1. 
extern double Lots_parabola = 0.1; // На сколько прибавлять первичный лот 
extern double Lots_parabola_stop = 0.5; // До какого лота прибавлять
extern int TakeProfit = 200;  // первичных ордеров
extern int ID = 111; 
extern string ContrOrd = "Настройки контр-ордеров";
extern bool Work_OpenContrOrder = true; // Устанавливать ли контр-ордера
enum TypeOpenContrOrder {fractal, moment}; // При параметре moment включается функция фильтрацции установки контр ордера по RSI. Выше или ниже уровня RSI
extern TypeOpenContrOrder OpenContrOrder_type = fractal; // При фрактале фильтра RSI нет. Открытие по фракталу с расчетом линий аллигатора, по ТФ Upper_period
extern bool RSImoment = true; //Включение фильтра RSI для установки контр ордеров по параметру moment
enum TypeContrLot {classic, user}; // расчет лота контр-ордеров: classic - умножаем на ContrLotExponent, user - сразу ставиться ContrLot
extern TypeContrLot ContrLot_type = classic;
extern double ContrLot = 2.0;
extern double ContrLotExponent = 2.0;
extern int ContrTakeProfit = 300; // Тейк для контр-ордеров
extern int ContrStopLoss = 0; // Стоп-лосс контр-ордеров
extern string ILAN = "Настройки Ilan";
extern int MaxTrades = 5; // Количество ступеней
extern int LotExponent_count = 2; // С какой ступени умножать лот. Влияет и на контр- ордера.
extern double LotExponent = 2; // На сколько умножать ордера Илан
enum Type_open_next_order {BY_pipstep, BY_delta, BY_RSI};
extern Type_open_next_order Type_next_open = BY_pipstep; // Функция расчета метода открытия Илан ордеров. BY_pipstep - через определенное кол-во пунктов, BY_delta - по фракталу
extern int PipStep = 10; // Кол-во пунктов
extern double PipsExp = 1.5; // На сколько Умножать параметр PipStep для следующего ордера Илан
extern int BY_delta_add = 50; // через какое расстояние в пунктах от последнего ордера искать фрактал
extern int DeltaILAN = 12; // Отступ от фрактала
extern bool Use_dop_filter_AO = true; // Фильтр По 3 бару АО для открытия фрактала.
extern int Ilan_TakeProfit_zero_count = 6; // На коком колене выставлять Тейкпрофит на уровень безубытка
extern int Ilan_TakeProfit = 200; // Тейк для ордеров Илан
extern string STOP = "Настройки Stop-loss первичных ордеров";
enum ISLBoss_type {Fix, Fractal, Candle};
extern ISLBoss_type StopLoss_type = Fix; // Метод ля расчета стопа по первичным ордерам
extern int StopLoss = 0; // Стоп для первичных ордеров
extern ENUM_TIMEFRAMES StopLoss_fr_tf = PERIOD_CURRENT; // ТФ для расчета фрактала для стоп-лосса
extern string IlanSTOP = "Настройки Stop-loss ордеров Илан";
enum IS_type {Fixx, xFractal};
extern IS_type Ilan_StopLoss_type = Fixx; // Метод ля расчета стопа по ордерам Илан
extern ENUM_TIMEFRAMES Ilan_StopLoss_fractal_tf = PERIOD_CURRENT; // ТФ для расчета фрактала для стоп-лосса
extern int Ilan_StopLoss_count = 0; // С какого колена Илан ставить
extern int Ilan_StopLoss = 0; // Параметре Fix - на сколько пунктов
extern string Bezubtrail = "Настройки Bezubtrail";
extern int Ilan_Trailing_count = 6; 
extern int Ilan_Trailing_step = 350; // Кол-во пунктов на которое ппередвигать трал
extern int Bezub_plus_point_value = 400; // Через какое кол-во пунктов от уровня безбытка ставить Трал. При влюченном параметре Line_to_trail
extern string TRAL = "Настройки профит трала";
extern bool ProfitTral = true; // Включает профит трал. Нужен при отключении параметра Line_to_trail
extern bool TralOpenPrice = true; // Трал от цены открытия. При отключении трал от Уровня ТЕйкпрофит
extern int TrStop = 30; // Отступ от цены открытия
extern int TrStep = 10; // Шаг трала
extern string RSI = "Настройки RSI";
extern ENUM_TIMEFRAMES RSITF = PERIOD_CURRENT;
extern int PeriodRSI = 13;
extern ENUM_APPLIED_PRICE RSIPRICE = PRICE_CLOSE; // ТФ для расчета RSI
extern int RsiMaximum = 70; // Верхняя граница RSI выше которой открываются контр-ордера SELL 
extern int RsiMinimum = 30; // Нижняя граница RSI ниже которой открываются ордера BUY
extern double RSIExp = 1.5; // Увеличение лота Илан при открытии по RSI
extern int DeltaRSI = 10; // Расстояние между ордерами Илан, открытыми по RSI
extern string ATR = "Настройки ATR";
extern ENUM_TIMEFRAMES ATRTF = PERIOD_CURRENT;
extern bool ATRTral = true; // Включает ATR для профит трала. Профит трал расчитывается по ATR
extern int PeriodATR = 13; // 
extern int ATRshift1 = 1; // С какой свечи назад считать. 0 - текущая свеча. Рекомендовано 1
extern double indaTR = 2.8; // на сколько умножать полученный параметр ATR. Рекомендовано 2.8
extern string IND = "Настройки Alligator";
enum Type_Line_to_open { Line_red_open, Line_green_open, Line_blue_open, NONE_open};
extern Type_Line_to_open Line_to_open = Line_red_open; // Линия аллигатора по которой учитываются фракталы для открытия первичных ордеров
enum Type_Line_to_close { Line_red_close, Line_green_close, Line_blue_close, NONE_close};
extern Type_Line_to_close Line_to_close = Line_red_close; // Линия для первичных ордеров.
enum Type_trail {Bezub, Bezub_plus_point};
extern Type_trail Trail_type = Bezub_plus_point; // Установка трала с уровня безубытка Bezub. Bezub_plus_point - установка трала с уровня отступа от уровня безубытка
enum Type_Line_to_trail { Line_red_trail, Line_green_trail, Line_blue_trail, NONE_trail};
extern Type_Line_to_trail Line_to_trail = Line_red_trail; // Линия для закрытия Илан ордеров
extern int jaw_period = 13;
extern int jaw_shift = 8;
extern int teeth_period = 8;
extern int teeth_shift = 5;
extern int lips_period = 5;
extern int lips_shift = 3;
extern ENUM_MA_METHOD ma_method = MODE_SMMA;
extern ENUM_APPLIED_PRICE applied_price = PRICE_MEDIAN;

bool MarketExecution = false;
bool gap_close = true;
bool OCH = true;
int number_try = 20;
int time_period_try = 1;
string main_id;

int OnInit()
{
   main_id = "@" + DoubleToStr(ID,0) + "@"; // устанавливает идентификационный номер ордеров
   
   if (Digits ==3 || Digits == 5) // Если у брокера 3 или 5 значений после запятой, то параметры умножаются на 10.
      {
       TakeProfit *= 10;
       BY_delta_add *= 10;
       PipStep *= 10;
       DeltaILAN *= 10;
       Ilan_TakeProfit *= 10;
       Ilan_StopLoss *= 10;
       Ilan_Trailing_step *= 10;
       Delta *= 10; 
       Bezub_plus_point_value *= 10;
      }   
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
   if ( reason == REASON_CHARTCLOSE || reason == REASON_REMOVE )delete_glob ( main_id );
   if ( IsTesting() ) delete_glob ( main_id );
}

double l_bid = 0, l_ask = 0;
void OnTick()
{
   if ( l_bid == 0 )
   {
      l_bid = Bid;
      l_ask = Ask;
      return;
   }
   
   bool flag;
   datetime time;
   int type, ticket; //sl
   double lot;
   double rsi1 = NormalizeDouble (iRSI(Symbol (), RSITF, PeriodRSI, RSIPRICE, 1), 2);
      
   if ( Work_OpenContrOrder )
   {
      check_loss();
      if ( OpenContrOrder_type == moment && GlobalVariableCheck(main_id + "EVENT_LOSS") )
      {
         if ( OrderSelect((int)GlobalVariableGet(main_id + "EVENT_LOSS"), SELECT_BY_TICKET) )
         {
            GlobalVariableDel(main_id + "EVENT_LOSS");
            if ( ContrLot_type == classic )lot = NormalizeDouble(OrderLots() * ContrLotExponent, 2);
            if ( ContrLot_type == user )lot = ContrLot;
            type = MathAbs(OrderType() - 1);
            if ( (Type_trend_orders == ALL || Type_trend_orders == type) && order_total_main() < MaxTrades_main && (order_total_main(MathAbs(type - 1)) == 0 || Trade_opposite))
            {
               if (RSImoment == false || (RSImoment == true && (RsiMaximum > rsi1 && rsi1 > RsiMinimum)))
               {
               ticket = open( type, lot, ContrStopLoss, ContrTakeProfit, "!" + IntegerToString(Time[1]) + "#MAIN_1");
               if ( ticket > 0 )GlobalVariableSet(main_id + "CONTR:" + IntegerToString(ticket), 0);
               Print ("RSI= false" +rsi1);
               return;
               }
               if (RSImoment == true)
               {
               if (rsi1 > RsiMaximum)
               {
               ticket = open( OP_SELL, lot, ContrStopLoss, ContrTakeProfit, "!" + IntegerToString(Time[1]) + "#MAIN_1");
               if ( ticket > 0 )GlobalVariableSet(main_id + "CONTR:" + IntegerToString(ticket), 0);             
               Print ("Контр-ордер" +"RSI= "+rsi1);
               return;
               }
               if (rsi1 < RsiMinimum)
               {
               ticket = open( OP_BUY, lot, ContrStopLoss, ContrTakeProfit, "!" + IntegerToString(Time[1]) + "#MAIN_1");
               if ( ticket > 0 )GlobalVariableSet(main_id + "CONTR:" + IntegerToString(ticket), 0);             
               Print ("Контр-ордер" +"RSI= "+rsi1);
               return;
               }
               }
            }
            
         }
      }
   }
   
    
   if ( Type_trend_orders == ALL || Type_trend_orders == ONLY_BUY )if ( check_trade(OP_BUY, time) && order_total_by_comment("!" + IntegerToString(time) + "#") == 0 && order_total_main() < MaxTrades_main && (order_total_main(OP_SELL) == 0 || Trade_opposite) )
   {
      if ( Type_next_open == BY_delta )GlobalVariableSet(main_id + "!" + IntegerToString(time) + "#", iHigh(NULL,Upper_period,iBarShift(NULL,Upper_period,time)));
      //if (rsi1 < RsiMinimumBoss) 
      {
      //sl = (StopLoss_type == Fix)?StopLoss:((int)((Ask - get_fract_boss(MODE_LOWER)) / Point));
      ticket = open( OP_BUY, get_lot(OP_BUY, flag), get_sl(OP_BUY), TakeProfit, "!" + IntegerToString(time) + "#MAIN_1");
      Print ("Ордер на покупку. RSI " +rsi1); 
      }
      if ( ticket > 0 && flag )GlobalVariableSet(main_id + "CONTR:" + IntegerToString(ticket), 0);
   }
   
   
   if ( Type_trend_orders == ALL || Type_trend_orders == ONLY_SELL )if ( check_trade(OP_SELL, time) && order_total_by_comment("!" + IntegerToString(time) + "#") == 0 && order_total_main() < MaxTrades_main && (order_total_main(OP_BUY) == 0 || Trade_opposite) )
   {
      if ( Type_next_open == BY_delta )GlobalVariableSet(main_id + "!" + IntegerToString(time) + "#", iLow(NULL,Upper_period,iBarShift(NULL,Upper_period,time)));
      //if (rsi1 > RsiMaximumBoss)  
      {
      //sl = (StopLoss_type == Fix)?StopLoss:((int)((get_fract_boss(MODE_UPPER) - Bid) / Point));
      ticket = open( OP_SELL, get_lot(OP_SELL, flag), get_sl(OP_SELL), TakeProfit, "!" + IntegerToString(time) + "#MAIN_1");
      Print ("Ордер на продажу. RSI " +rsi1); 
      }
      if ( ticket > 0 && flag )GlobalVariableSet(main_id + "CONTR:" + IntegerToString(ticket), 0);
   }
   
   profittral ();
   close_orders_by_alligator();
   if ( Line_to_trail != NONE_trail )trail_orders_by_alligator();
   work_ilan_module();
   reopen_close_orders();
   OrderCloseHistori (); 
   

   
   l_bid = Bid;
   l_ask = Ask;
   
   
   string openorders;
   if (Type_trend_orders ==ALL)
       openorders = "ALL";
   if (Type_trend_orders ==ONLY_SELL)
       openorders = "SELL";    
   if (Type_trend_orders ==ONLY_BUY)
       openorders = "BUY";    
   Comment ("ID =" +ID +"\n"+
            "Разрешено открывать ордера =" +openorders);   
}
//-----------------------------------------------
int get_sl (int type)
{
   int sl=0;
     
   if ( StopLoss_type == Fix ) sl = StopLoss;
   if ( StopLoss_type == Fractal) 
      {  
      if (type == OP_SELL) sl =(get_fract_boss(MODE_UPPER) - Bid) / Point;
      if (type == OP_BUY) sl =(Ask - get_fract_boss(MODE_LOWER)) / Point;
      }
      
   if ( StopLoss_type == Candle) 
      {  
      if (type == OP_SELL) sl = (get_HighLow(OP_SELL) - Bid)/Point; // iHigh(Symbol(), StopLoss_fr_tf, 1)
      if (type == OP_BUY) sl = (Ask - get_HighLow (OP_BUY)) / Point; //iLow(Symbol(), StopLoss_fr_tf,1
      }
   return(sl);
}
//-----------------------------------------------
//-----------------------------------------------
double get_lot( int type, bool &flag )
{
   int i, direction = -1, count = 0;
   double l_lot = Lot;
   datetime l_time = 0, last_time;
   flag = false;
   
   if ( Work_OpenContrOrder && OpenContrOrder_type == fractal && GlobalVariableCheck(main_id + "EVENT_LOSS") && OrderSelect((int)GlobalVariableGet(main_id + "EVENT_LOSS"), SELECT_BY_TICKET) )
   if ( OrderType() == MathAbs(type - 1) )
   {
      flag = true;
      GlobalVariableDel(main_id + "EVENT_LOSS");
      if ( ContrLot_type == classic  )l_lot = NormalizeDouble(OrderLots() * ContrLotExponent, 2);
      if ( ContrLot_type == user )l_lot = ContrLot;
      return(l_lot);
   }

   if ( Bid > iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORTEETH,1) )
   {
      direction = 0;
      i = 1;
      last_time = iTime(NULL,Upper_period,i);
      while ( iLow(NULL,Upper_period,i) > iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORTEETH,i) )
      {
         i ++;
         last_time = iTime(NULL,Upper_period,i);
      }
   }
   
   if ( Bid < iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORTEETH,1) )
   {
      direction = 1;
      i = 1;
      last_time = iTime(NULL,Upper_period,i);
      while ( iHigh(NULL,Upper_period,i) < iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORTEETH,i) )
      {
         i ++;
         last_time = iTime(NULL,Upper_period,i);
      }
   }
   
   l_time = last_time;
   for( i = OrdersTotal() - 1; i >= 0; i -- )       
   {
      if ( !OrderSelect(i,SELECT_BY_POS,MODE_TRADES) )continue;
      if ( OrderMagicNumber() == ID && StringSubstr(OrderComment(), StringFind(OrderComment(),"#")) == "#MAIN_1" && OrderType() == type )
      {
         if
         (
            (
               (direction == 0 && OrderOpenPrice() > iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORTEETH,iBarShift(NULL,0,OrderOpenTime()))) ||
               (direction == 1 && OrderOpenPrice() < iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORTEETH,iBarShift(NULL,0,OrderOpenTime())))
            )
         )
         {
            if ( OrderOpenTime() > last_time )count ++;
            if ( OrderOpenTime() > l_time )
            {
               l_time = OrderOpenTime();
               l_lot = OrderLots();
            }
         }
      }
   }
   
   if ( count == 0 )l_lot = Lot;
   else
   {
      if ( Lot_type == Exp )l_lot = NormalizeDouble(l_lot * LotExTrend, 2);
      if ( Lot_type == Regress )
      {
         if ( count == 1 )l_lot = Lot * Lots_regress_N;
         else l_lot = MathMax((Lot * Lots_regress_N) - Lots_regress * (count - 1), Lot);
      }
      if ( Lot_type == Parabola )
      {
         if ( NormalizeDouble(Lot + Lots_parabola * count, 2) <= NormalizeDouble(Lots_parabola_stop, 2) )l_lot += Lots_parabola;
         else l_lot -= Lots_parabola;
         l_lot = MathMax(l_lot, Lot);
      }
   }
   
   return(l_lot);
}

void trail_orders_by_alligator()
{
   int close = -1;
   int i, i1, ticket, kol, type;
   double Blue_0, Red_0, Green_0, profit, buffer, l, l_op;
   string unic_number, comment, name;
   
   Blue_0 = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORJAW,1);
   Red_0 = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORTEETH,1);
   Green_0 = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORLIPS,1);
   
   if ( Line_to_trail == Line_blue_trail )buffer = Blue_0;
   if ( Line_to_trail == Line_red_trail )buffer = Red_0;
   if ( Line_to_trail == Line_green_trail )buffer = Green_0;
   
   if ( NormalizeDouble(Close[1], Digits) <= NormalizeDouble(buffer, Digits) && Green_0 > Blue_0 && Green_0 > Red_0)close = OP_BUY;
   if ( NormalizeDouble(Close[1], Digits) >= NormalizeDouble(buffer, Digits) && Green_0 < Blue_0 && Green_0 < Red_0)close = OP_SELL;
   
   if ( Trail_type == Bezub_plus_point )
   {
      for( i = ObjectsTotal() - 1; i >= 0; i -- )
      {
         name = ObjectName(i);
         if ( StringFind(name, main_id) >= 0 && StringFind(name, "_LEVEL_TRAL") >= 0 && !GlobalVariableCheck(name) )ObjectDelete(name);
      }
      
      for( i = OrdersTotal() - 1; i >= 0; i -- )       
      {
         if ( !OrderSelect(i,SELECT_BY_POS,MODE_TRADES) )continue;
         if ( OrderMagicNumber() != ID || StringFind(OrderComment(), "MAIN") < 0 )continue;
         
         unic_number = StringSubstr(OrderComment(), 0, StringFind(OrderComment(),"#") + 1);
         comment = OrderComment();
         ticket = OrderTicket();
         profit = OrderProfit();
         l_op = OrderLots() * OrderOpenPrice();
         l = OrderLots();
         type = OrderType();
         kol = 1;
         if ( StringSubstr(OrderComment(), StringFind(OrderComment(),"#") + 1) == "MAIN_1" && !GlobalVariableCheck(main_id + "CONTR:" + IntegerToString(OrderTicket())) )kol = 0;
         
         for( i1 = OrdersTotal() - 1; i1 >= 0; i1 -- )       
         {
            if ( !OrderSelect(i1,SELECT_BY_POS,MODE_TRADES) )continue;
            if ( OrderMagicNumber() != ID || StringFind(OrderComment(), unic_number) < 0 || OrderType() != type || OrderTicket() == ticket )continue;
            l_op += OrderLots() * OrderOpenPrice();
            l += OrderLots();
            kol ++;
         }
         
         if ( GlobalVariableCheck(main_id + comment + "_LEVEL_TRAL") )
         {
            name = main_id + comment + "_LEVEL_TRAL";
            if ( ObjectFind(name) < 0 )ObjectCreate(0, name, OBJ_HLINE, 0, Time[0], GlobalVariableGet(main_id + comment + "_LEVEL_TRAL"));
            ObjectSet(name, OBJPROP_PRICE1, GlobalVariableGet(main_id + comment + "_LEVEL_TRAL"));
            ObjectSet(name, OBJPROP_COLOR, (type == OP_BUY)?Lime:Orange);
         }
         else if ( ObjectFind(main_id + comment + "_LEVEL_TRAL") >= 0 )ObjectDelete(main_id + comment + "_LEVEL_TRAL");
         
         if
         (
            kol != 0 &&
            (
               ( type == OP_BUY && Bid > NormalizeDouble((l_op / l) + Bezub_plus_point_value * Point, Digits)) ||
               ( type == OP_SELL && Bid < NormalizeDouble((l_op / l) - Bezub_plus_point_value * Point, Digits))
            )
         )
         {
            if ( !GlobalVariableCheck(main_id + comment + "_LEVEL_BEZUB") )GlobalVariableSet(main_id + comment + "_LEVEL_BEZUB", (l_op / l));
            else if ( NormalizeDouble(l_op / l, Digits) != NormalizeDouble(GlobalVariableGet(main_id + comment + "_LEVEL_BEZUB"), Digits) )
            {
               GlobalVariableSet(main_id + comment + "_LEVEL_BEZUB", (l_op / l));
               if ( GlobalVariableCheck(main_id + comment + "_LEVEL_TRAL") )GlobalVariableDel(main_id + comment + "_LEVEL_TRAL");
            }
         }
         
         if ( !GlobalVariableCheck(main_id + comment + "_LEVEL_TRAL") && GlobalVariableCheck(main_id + comment + "_LEVEL_BEZUB") )GlobalVariableSet(main_id + comment + "_LEVEL_TRAL", GlobalVariableGet(main_id + comment + "_LEVEL_BEZUB"));
         if ( GlobalVariableCheck(main_id + comment + "_LEVEL_TRAL") )
         {
            if ( type == OP_BUY && NormalizeDouble( Bid - Ilan_Trailing_step * Point, Digits) > NormalizeDouble( GlobalVariableGet(main_id + comment + "_LEVEL_TRAL"), Digits) )GlobalVariableSet(main_id + comment + "_LEVEL_TRAL", NormalizeDouble( Bid - Ilan_Trailing_step * Point, Digits));
            if ( type == OP_SELL && NormalizeDouble( Bid + Ilan_Trailing_step * Point, Digits) < NormalizeDouble( GlobalVariableGet(main_id + comment + "_LEVEL_TRAL"), Digits) )GlobalVariableSet(main_id + comment + "_LEVEL_TRAL", NormalizeDouble( Bid + Ilan_Trailing_step * Point, Digits));
            
            if
            (
               (type == OP_BUY && NormalizeDouble(Bid, Digits) <= NormalizeDouble(GlobalVariableGet(main_id + comment + "_LEVEL_TRAL"), Digits)) ||
               (type == OP_SELL && NormalizeDouble(Bid, Digits) >= NormalizeDouble(GlobalVariableGet(main_id + comment + "_LEVEL_TRAL"), Digits))
            )
            {
               if ( GlobalVariableCheck(main_id + comment + "_LEVEL_BEZUB") )GlobalVariableDel(main_id + comment + "_LEVEL_BEZUB");
               if ( GlobalVariableCheck(main_id + comment + "_LEVEL_TRAL") )GlobalVariableDel(main_id + comment + "_LEVEL_TRAL");
               
               Print("Закрытие по тралу: безубыток с плюсом");
               
               close(ticket);
               for( i1 = OrdersTotal() - 1; i1 >= 0; i1 -- )       
               {
                  if ( !OrderSelect(i1,SELECT_BY_POS,MODE_TRADES) )continue;
                  if ( OrderMagicNumber() != ID || StringFind(OrderComment(), unic_number) < 0 || OrderType() != type || OrderTicket() == ticket )continue;
                  close(OrderTicket());
               }
            }
         }
      }            
   }
}

void close_orders_by_alligator()
{
   bool res;
   int close = -1;
   int i, i1, ticket, ticket_1, kol;
   double Blue_0, Red_0, Green_0, profit, buffer;
   string unic_number, comment;
   
   Blue_0 = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORJAW,1);
   Red_0 = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORTEETH,1);
   Green_0 = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORLIPS,1);
   
   if ( Line_to_close == Line_blue_close )buffer = Blue_0;
   if ( Line_to_close == Line_red_close )buffer = Red_0;
   if ( Line_to_close == Line_green_close )buffer = Green_0;
   
   if ( (NormalizeDouble(l_bid, Digits) >= NormalizeDouble(buffer, Digits) && NormalizeDouble(Bid, Digits) <= NormalizeDouble(buffer, Digits)) )close = OP_BUY;
   if ( (NormalizeDouble(l_bid, Digits) <= NormalizeDouble(buffer, Digits) && NormalizeDouble(Bid, Digits) >= NormalizeDouble(buffer, Digits)) )close = OP_SELL;
   
   if ( close != -1 && Line_to_close != NONE_close )
   {
      for( i = OrdersTotal() - 1; i >= 0; i -- )       
      {
         if ( !OrderSelect(i,SELECT_BY_POS,MODE_TRADES) )continue;
         if ( OrderMagicNumber() != ID || StringFind(OrderComment(), "MAIN") < 0 || OrderType() != close || GlobalVariableCheck(main_id + "CONTR:" + IntegerToString(OrderTicket())) )continue;
         unic_number = StringSubstr(OrderComment(), 0, StringFind(OrderComment(),"#") + 1);
         ticket = OrderTicket();
         profit = OrderProfit();
         
         kol = 0;
         for( i1 = OrdersTotal() - 1; i1 >= 0; i1 -- )       
         {
            if ( !OrderSelect(i1,SELECT_BY_POS,MODE_TRADES) )continue;
            if ( OrderMagicNumber() != ID || StringFind(OrderComment(), unic_number) < 0 || OrderType() != close || OrderTicket() == ticket )continue;
            kol++;
         }
         
         if ( kol == 0 && profit >= 0)  
         {
            Print("Закрытие тренд-ордеров по линии аллигатора");
            close(ticket);
         }
      }
   }
   
   close = -1;
   if ( Line_to_trail == Line_blue_trail )buffer = Blue_0;
   if ( Line_to_trail == Line_red_trail )buffer = Red_0;
   if ( Line_to_trail == Line_green_trail )buffer = Green_0;
   
   if ( Green_0 > Red_0 && Red_0 > Blue_0 && Green_0 > Blue_0 && (NormalizeDouble(l_bid, Digits) >= NormalizeDouble(buffer, Digits) && NormalizeDouble(Bid, Digits) <= NormalizeDouble(buffer, Digits)) )close = OP_BUY;
   if ( Blue_0 > Green_0 && Red_0 > Green_0 && Blue_0 > Red_0 && (NormalizeDouble(l_bid, Digits) <= NormalizeDouble(buffer, Digits) && NormalizeDouble(Bid, Digits) >= NormalizeDouble(buffer, Digits)) )close = OP_SELL;
   
   if ( Line_to_trail != NONE_trail )
   {
      if ( close != -1 )
      for( i = OrdersTotal() - 1; i >= 0; i -- )       
      {
         if ( !OrderSelect(i,SELECT_BY_POS,MODE_TRADES) )continue;
         if ( OrderMagicNumber() != ID || StringFind(OrderComment(), "MAIN") < 0 || OrderType() != close )continue;
         
         unic_number = StringSubstr(OrderComment(), 0, StringFind(OrderComment(),"#") + 1);
         ticket = OrderTicket();
         comment = OrderComment();
         
         if ( GlobalVariableCheck(main_id + comment + "_LEVEL_BEZUB") || GlobalVariableCheck(main_id + comment + "_LEVEL_TRAL") )continue;
         
         for( i1 = OrdersTotal() - 1; i1 >= 0; i1 -- )       
         {
            if ( !OrderSelect(i1,SELECT_BY_POS,MODE_TRADES) )continue;
            if ( OrderMagicNumber() != ID || StringFind(OrderComment(), unic_number) < 0 || OrderType() != close || OrderTicket() == ticket )continue;
            ticket_1 = OrderTicket();
            if ( OrderProfit() > 0 )
            {
               Print("Закрытие ордеров Илан по тралу");
               res = close(ticket_1);
               if ( res && OrderSelect(ticket_1, SELECT_BY_TICKET) )GlobalVariableSet(main_id + unic_number + "_CLOSE:" + IntegerToString(ticket_1), ticket_1);
            }
         }
      }
      
      for( i = OrdersHistoryTotal() - 1; i >= 0; i -- )       
      {
         if ( !OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) )continue;
         if ( OrderMagicNumber() != ID || OrderType() > 1 || StringFind(OrderComment(), "MAIN") < 0 )continue;
         comment = OrderComment();
         if ( StringFind(OrderComment(), "[") >= 0 )comment = StringSubstr(OrderComment(), 0, StringFind(OrderComment(), "["));
         if ( GlobalVariableCheck(main_id + comment + "_LEVEL_BEZUB") )GlobalVariableDel(main_id + comment + "_LEVEL_BEZUB");
         if ( GlobalVariableCheck(main_id + comment + "_LEVEL_TRAL") )GlobalVariableDel(main_id + comment + "_LEVEL_TRAL");
      }
   }
}

int order_total_main(int type = -1)
{
   int i, res = 0;
   
   for( i = OrdersTotal() - 1; i >= 0; i -- )       
   {
      if ( !OrderSelect(i,SELECT_BY_POS,MODE_TRADES) )continue;
      if ( OrderMagicNumber() == ID && StringSubstr(OrderComment(), StringFind(OrderComment(),"#")) == "#MAIN_1" && (type == -1 || OrderType() == type) )res ++;
   }
   
   return (res);
}

void reopen_close_orders()
{
   int i, count, sl;
   double fractal;
   datetime time;
   string name, unic_number;
   
   for ( i = GlobalVariablesTotal() - 1; i >= 0; i -- )
   {
      name = GlobalVariableName(i);
      if ( StringFind(name, main_id) < 0 || StringFind(name, "_CLOSE:") < 0 )continue;
      unic_number = StringSubstr(name, StringFind(name,"@",1) + 1, StringFind(name,"#") + 1 - (StringFind(name,"@",1) + 1));
      
      if ( order_total_by_comment(unic_number, false) == 0 )
      {
         GlobalVariableDel(name);
         continue;
      }
      
      if ( !OrderSelect((int)GlobalVariableGet(name), SELECT_BY_TICKET) )continue;
      if ( OrderCloseTime() == 0 )continue;
      
      if ( StringFind(OrderComment(), "[") < 0 )count = StrToInteger(StringSubstr(OrderComment(), StringFind(OrderComment(),"_") + 1));
      else
      {
         if ( StringFind(OrderComment(), "[") < StringFind(OrderComment(),"_") )count = StrToInteger(StringSubstr(OrderComment(), StringFind(OrderComment(),"_") + 1));
         else count = StrToInteger(StringSubstr(OrderComment(), StringFind(OrderComment(),"_") + 1, StringFind(OrderComment(), "[") - (StringFind(OrderComment(),"_") + 1)));
      }
      
      if ( check_trade ( OrderType(), time ) )
      {
         if ( OrderType() == OP_BUY )
         {
            fractal = iHigh(NULL,Upper_period,iBarShift(NULL,Upper_period,time));
            if ( fractal > OrderClosePrice() )
            {
               sl = (Ilan_StopLoss_type == Fixx)?Ilan_StopLoss:((int)((Ask - get_near_fract(MODE_LOWER)) / Point));
               open(OrderType(), OrderLots(), sl, 0, unic_number + "_" + IntegerToString(count) ); 
               Print ("Переоткрыт ордер Илан");
               GlobalVariableDel(name);
            }
         }
         else if ( OrderType() == OP_SELL )
         {
            fractal = iLow(NULL,Upper_period,iBarShift(NULL,Upper_period,time));
            if ( fractal < OrderClosePrice() )
            {
               sl = (Ilan_StopLoss_type == Fixx)?Ilan_StopLoss:((int)((get_near_fract(MODE_UPPER) - Bid) / Point));
               open(OrderType(), OrderLots(), sl, 0, unic_number + "_" + IntegerToString(count) );
               Print ("Переоткрыт ордер Илан");
               GlobalVariableDel(name);
            }
         }
      }
   }
}

void work_ilan_module()
{
   bool res;
   int i, i1, count, l_ticket, type, orders, ticket;
   double lot, buffer, ext, sl;
   string unic_number;
   
   for( i = OrdersHistoryTotal() - 1; i >= 0; i -- )       
   {
      if ( !OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) )continue;
      if ( OrderMagicNumber() != ID || StringFind(OrderComment(), "MAIN") < 0 )continue;
      unic_number = StringSubstr(OrderComment(), 0, StringFind(OrderComment(),"#MAIN") + 1);
      if ( GlobalVariableCheck(main_id + unic_number) )GlobalVariableDel(main_id + unic_number);
      if ( GlobalVariableCheck(main_id + unic_number + "_TRAL") )GlobalVariableDel(main_id + unic_number + "_TRAL");
   }
 
   for( i = OrdersTotal() - 1; i >= 0; i -- )       
   {
      if ( !OrderSelect(i,SELECT_BY_POS,MODE_TRADES) )continue;
      if ( OrderMagicNumber() != ID || StringFind(OrderComment(), "MAIN") < 0 )continue;
      type = OrderType();
      unic_number = StringSubstr(OrderComment(), 0, StringFind(OrderComment(),"#") + 1);
      l_ticket = OrderTicket();
      
      if ( GlobalVariableCheck(main_id + unic_number + "_TRAL") )
      {
         buffer = GlobalVariableGet(main_id + unic_number + "_TRAL");
         sl = NormalizeDouble(Bid - ((type == OP_BUY)?1:(-1)) * Ilan_Trailing_step * Point, Digits);
         
         for( i1 = OrdersTotal() - 1; i1 >= 0; i1 -- )       
         {
            if ( !OrderSelect(i1,SELECT_BY_POS,MODE_TRADES) )continue;
            if ( OrderMagicNumber() != ID || StringFind(OrderComment(), unic_number) < 0 || type != OrderType() )continue;

            if
            (
               (type == OP_BUY && (NormalizeDouble(sl, Digits) > NormalizeDouble(OrderStopLoss(), Digits) || NormalizeDouble(OrderStopLoss(), Digits) == 0) && NormalizeDouble(sl, Digits) > NormalizeDouble(buffer, Digits)) ||
               (type == OP_SELL && (NormalizeDouble(sl, Digits) < NormalizeDouble(OrderStopLoss(), Digits) || NormalizeDouble(OrderStopLoss(), Digits) == 0) && NormalizeDouble(sl, Digits) < NormalizeDouble(buffer, Digits))
            )
            {
               while ( IsTradeContextBusy() )Sleep(500);
               GlobalVariableSet(main_id + unic_number + "_TRAL", NormalizeDouble(sl, Digits));
               res = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(sl, Digits),OrderTakeProfit(),0,((type == OP_BUY)?Blue:Red));
            }
         }
      }
      
      for( i1 = OrdersTotal() - 1; i1 >= 0; i1 -- )       
      {
         if ( !OrderSelect(i1,SELECT_BY_POS,MODE_TRADES) )continue;
         if ( OrderMagicNumber() != ID || StringFind(OrderComment(), unic_number) < 0 || OrderTicket() < l_ticket || type != OrderType() )continue;
         l_ticket = OrderTicket();
      }
      
      if ( !OrderSelect(l_ticket,SELECT_BY_TICKET) )continue;
      count = StrToInteger(StringSubstr(OrderComment(), StringFind(OrderComment(),"_") + 1));
      if
      (
         (
            (Type_next_open == BY_pipstep && (OrderProfit() / (OrderLots() * MarketInfo(Symbol(), MODE_TICKVALUE))) <= (-1) * PipStep * MathPow(PipsExp, count - 1)) ||
            (Type_next_open == BY_delta && check_trade_2(type, unic_number, ext) && (use_dop_filter(type) || !Use_dop_filter_AO)) ||
            (Type_next_open == BY_RSI && BY_rsiIlan(type, unic_number) && (OrderProfit() / (OrderLots() * MarketInfo(Symbol(), MODE_TICKVALUE))) <= (-1) * DeltaRSI * MathPow(RSIExp, count - 1))
            
         )
         && count < MaxTrades
      )
      {
         lot = NormalizeDouble(OrderLots() * ((count >= LotExponent_count - 1)?LotExponent:1), 2);
         ticket = open( type, lot, 0, 0, unic_number + "_" + IntegerToString(count + 1) ); Print ("ордер Илан открыт ");
         if ( ticket > 0 && Type_next_open == BY_delta )GlobalVariableSet(main_id + unic_number, ext);
         
         buffer = 0;
         lot = 0;
         orders = 0;
         
         for( i1 = OrdersTotal() - 1; i1 >= 0; i1 -- )       
         {
            if ( !OrderSelect(i1,SELECT_BY_POS,MODE_TRADES) )continue;
            if ( OrderMagicNumber() != ID || StringFind(OrderComment(), unic_number) < 0 || type != OrderType() )continue;
            buffer += OrderOpenPrice() * OrderLots();
            lot += OrderLots();
            orders ++;
         }
         
         if ( NormalizeDouble(lot, 2) != 0.0 )buffer = NormalizeDouble(buffer / lot, Digits);
         
            if ( !OrderSelect(ticket,SELECT_BY_TICKET) )continue;
            
            if ( OrderType() == OP_BUY )sl = (Ilan_StopLoss_type == Fixx)?NormalizeDouble(OrderOpenPrice() - Ilan_StopLoss * Point, Digits):get_near_fract(MODE_LOWER);
            if ( OrderType() == OP_SELL )sl = (Ilan_StopLoss_type == Fixx)?NormalizeDouble(OrderOpenPrice() + Ilan_StopLoss * Point, Digits):get_near_fract(MODE_UPPER);
         }
         
         if ( count >= Ilan_Trailing_count - 1 && Ilan_Trailing_count != 0 )GlobalVariableSet(main_id + unic_number + "_TRAL", buffer);
         
         for( i1 = OrdersTotal() - 1; i1 >= 0; i1 -- )       
         {
            if ( !OrderSelect(i1,SELECT_BY_POS,MODE_TRADES) )continue;
            if ( OrderMagicNumber() != ID || StringFind(OrderComment(), unic_number) < 0 || type != OrderType() )continue;
            
         sl = 0;
         if ( count >= Ilan_StopLoss_count - 1 && Ilan_StopLoss_count != 0 )
         {
            if
            (
               NormalizeDouble(OrderTakeProfit(), Digits) != NormalizeDouble(buffer + ((type == OP_BUY)?1:(-1)) * ((orders < Ilan_TakeProfit_zero_count)?Ilan_TakeProfit:0) * Point, Digits) ||
               (NormalizeDouble(sl, Digits) != 0 && NormalizeDouble(OrderStopLoss(), Digits) != NormalizeDouble(sl, Digits))
            )
            {
               while ( IsTradeContextBusy() )Sleep(500);
               res = OrderModify(OrderTicket(),OrderOpenPrice(),(NormalizeDouble(sl, Digits)== 0)?OrderStopLoss():sl,NormalizeDouble(buffer + ((type == OP_BUY)?1:(-1)) * ((orders < Ilan_TakeProfit_zero_count)?Ilan_TakeProfit:0) * Point, Digits),0,((type == OP_BUY)?Blue:Red));
            }
         } 
      }
   }
}

int order_total_by_comment ( string comment, bool history = true )
{
   int i, result = 0;
   
   for( i = OrdersTotal() - 1; i >= 0; i -- )       
   {
      if ( !OrderSelect(i,SELECT_BY_POS,MODE_TRADES) )continue;
      if( OrderMagicNumber() == ID && StringFind(OrderComment(), comment) >= 0 )result ++;
   }
   
   if ( history )
   for( i = OrdersHistoryTotal() - 1; i >= 0; i-- )
   {
      if ( !OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) )continue;
      if( OrderMagicNumber() == ID && StringFind(OrderComment(), comment) >= 0 )result ++;
   }
   
   return(result);   
}

bool check_trade ( int type, datetime &time )
{
   bool res = false;
   int i;
   double buffer, Blue_0, Blue_i, Red_0, Red_i, Green_0, Green_i;
   
   Blue_0 = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORJAW,1);
   Red_0 = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORTEETH,1);
   Green_0 = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORLIPS,1);
   
   buffer = 0;
   i = 2;
   while ( NormalizeDouble(buffer, Digits) == 0 )
   {
      i++;
      buffer = iFractals(NULL, Upper_period, MODE_UPPER, i);
      time = iTime(NULL,Upper_period, i);
   }
   
   Blue_i = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORJAW,i);
   Red_i = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORTEETH,i);
   Green_i = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORLIPS,i);

   if
   (
      type == OP_BUY &&
      (NormalizeDouble(l_ask, Digits) <= NormalizeDouble(buffer + Delta * Point, Digits) && NormalizeDouble(Ask, Digits) >= NormalizeDouble(buffer + Delta * Point, Digits)) &&
      (
         (Line_to_open == NONE_open) ||
         (
            (Line_to_open == Line_red_open && buffer > Red_i) ||
            (Line_to_open == Line_green_open && buffer > Green_i) ||
            (Line_to_open == Line_blue_open && buffer > Blue_i)
         )
      )
   )res = true;
   
   if ( type == OP_BUY )return(res);
   
   buffer = 0;
   i = 2;
   while ( NormalizeDouble(buffer, Digits) == 0 )
   {
      i++;
      buffer = iFractals(NULL, Upper_period, MODE_LOWER, i);
      time = iTime(NULL,Upper_period, i);
   }
   
   Blue_i = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORJAW,i);
   Red_i = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORTEETH,i);
   Green_i = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORLIPS,i);

   if
   (
      type == OP_SELL &&
      (NormalizeDouble(l_bid, Digits) >= NormalizeDouble(buffer - Delta * Point, Digits) && NormalizeDouble(Bid, Digits) <= NormalizeDouble(buffer - Delta * Point, Digits)) &&
      (
         (Line_to_open == NONE_open) ||
         (
            (Line_to_open == Line_red_open && buffer < Red_i) ||
            (Line_to_open == Line_green_open && buffer < Green_i) ||
            (Line_to_open == Line_blue_open && buffer < Blue_i)
         )
      )
   )res = true;
   
   return (res);
}

bool check_trade_2 ( int type, string unic_number, double &op_pr )
{
   int i;
   double buffer;
   datetime time = StrToInteger(StringSubstr(unic_number, 1, StringFind(unic_number,"#") - 1));

   buffer = 0;
   i = 2;
   
   if ( type == OP_BUY )
   while ( NormalizeDouble(buffer, Digits) == 0 )
   {
      i++;
      if ( Time[i] < time )return(false);
      buffer = iFractals(NULL, 0, MODE_UPPER, i);
   }

   if
   (
      type == OP_BUY &&
      (NormalizeDouble(l_ask, Digits) <= NormalizeDouble(buffer + DeltaILAN * Point, Digits) && NormalizeDouble(Ask, Digits) >= NormalizeDouble(buffer + DeltaILAN * Point, Digits)) &&
      NormalizeDouble(GlobalVariableGet(main_id + unic_number), Digits) > NormalizeDouble(buffer + BY_delta_add * Point, Digits)
   )
   {
      op_pr = NormalizeDouble(buffer, Digits);
      return(true);
   }

   buffer = 0;
   i = 2;
   
   if ( type == OP_SELL )
   while ( NormalizeDouble(buffer, Digits) == 0 )
   {
      i++;
      if ( Time[i] < time )return(false);
      buffer = iFractals(NULL, 0, MODE_LOWER, i);
   }

   if
   (
      type == OP_SELL &&
      (NormalizeDouble(l_bid, Digits) >= NormalizeDouble(buffer - DeltaILAN * Point, Digits) && NormalizeDouble(Bid, Digits) <= NormalizeDouble(buffer - DeltaILAN * Point, Digits)) &&
      NormalizeDouble(GlobalVariableGet(main_id + unic_number), Digits) < NormalizeDouble(buffer - BY_delta_add * Point, Digits)
   )
   {
      op_pr = NormalizeDouble(buffer, Digits);
      return(true);
   }
   
   return (false);
}
//---------------------------------------------------
double get_near_fract ( int type )
{
   int i;
   double buffer = 0.0;
   
   while ( NormalizeDouble(buffer, Digits) == 0 )
   {
      i++;
      buffer = iFractals(NULL, Ilan_StopLoss_fractal_tf, type, i);
   }
   
   return (buffer);
}
//---------------------------------------------------
double get_fract_boss ( int type )
{
   int i;
   double buffer = 0.0;
   
   while ( NormalizeDouble(buffer, Digits) == 0 )
   {
      i++;
      buffer = iFractals(NULL, StopLoss_fr_tf, type, i);
   }
   
   return (buffer);
}
//---------------------------------------------------
//---------------------------------------------------
double get_HighLow ( int type )
{
   int i;
   double buffer = 0.0;
   if (type == OP_BUY)
   {
      for (i=0; i<2; i++) 
      {
      buffer = iLow(Symbol(), StopLoss_fr_tf,i);
      }
   }    

   if (type == OP_SELL) 
    {
    for (i=0; i<2; i++) 
      {
      buffer = iHigh(Symbol(), StopLoss_fr_tf, i);
      }
    } 
   return (buffer);
}
//---------------------------------------------------
bool use_dop_filter( int type )
{
   bool res = false;
   int i;
   
   for ( i = 1; i < 1000; i ++ )
   {
      if ( iAO(NULL,0,i + 2) > iAO(NULL,0,i + 1) && iAO(NULL,0,i + 1) < iAO(NULL,0,i) )
      {
         if ( type == OP_BUY && NormalizeDouble(Bid, Digits) >= NormalizeDouble(High[i - 2], Digits) && i > 2 )res = true;
         break;
      }
      
      if ( iAO(NULL,0,i + 2) < iAO(NULL,0,i + 1) && iAO(NULL,0,i + 1) > iAO(NULL,0,i) )
      {
         if ( type == OP_SELL && NormalizeDouble(Bid, Digits) <= NormalizeDouble(Low[i - 2], Digits) && i > 2 )res = true;
         break;
      }
   }
   
   return (res);
}

double check_lot(double &lo)
{
   double l = MarketInfo(Symbol(),MODE_LOTSTEP);
   int ok = 0;
   while ( l < 1 ){l*=10;ok++;}
   if( lo < MarketInfo(Symbol(),MODE_MINLOT) )lo = MarketInfo(Symbol(),MODE_MINLOT);
   if( lo > MarketInfo(Symbol(),MODE_MAXLOT) )lo = MarketInfo(Symbol(),MODE_MAXLOT);
   return(NormalizeDouble(lo,ok));
}

int open( int type, double l, double sl = 0, double tp = 0, string comm = "")
{
   bool res;
   int isOpened = 0, try = 0;
   double s = 0,t = 0;
   color color_order;
   
   while ( IsTradeContextBusy() )Sleep(500);
   RefreshRates();
   if ( sl != 0 && sl < MarketInfo(Symbol(),MODE_STOPLEVEL) )sl = MarketInfo(Symbol(),MODE_STOPLEVEL);
   if ( tp != 0 && tp < MarketInfo(Symbol(),MODE_STOPLEVEL) )tp = MarketInfo(Symbol(),MODE_STOPLEVEL);
   if ( type == 0 )
   {
      if ( tp == 0 )t = 0;
      if ( tp != 0 )t = Ask + tp * Point;
      if ( sl == 0 )s = 0;
      if ( sl != 0 )s = Ask - sl * Point;
   }
   if ( type == 1 )
   {
      if ( tp == 0 )t = 0;
      if ( tp != 0 )t = Bid - tp * Point;
      if ( sl == 0 )s = 0;
      if ( sl != 0 )s = Bid + sl * Point;
   }
   
   s = NormalizeDouble(s,Digits);
   t = NormalizeDouble(t,Digits);
   
   if ( MarketExecution )
   {
      if(type == 0)isOpened = OrderSend(Symbol(),type,check_lot(l),NormalizeDouble(Ask,Digits),100,0,0,comm,ID,0,Blue);
      if(type == 1)isOpened = OrderSend(Symbol(),type,check_lot(l),NormalizeDouble(Bid,Digits),100,0,0,comm,ID,0,Red);
   }
   else
   {
      if(type == 0)isOpened = OrderSend(Symbol(),type,check_lot(l),NormalizeDouble(Ask,Digits),100,s,t,comm,ID,0,Blue);
      if(type == 1)isOpened = OrderSend(Symbol(),type,check_lot(l),NormalizeDouble(Bid,Digits),100,s,t,comm,ID,0,Red);
   }
   
   while( isOpened < 0 )
   {
      Sleep(time_period_try * 1000);
      while ( IsTradeContextBusy() )Sleep(500);
      RefreshRates();
      if ( type == 0 )
      {
         if ( tp == 0 )t = 0;
         if ( tp != 0 )t = Ask + tp * Point;
         if ( sl == 0 )s = 0;
         if ( sl != 0 )s = Ask - sl * Point;
      }
      if ( type == 1 )
      {
         if ( tp == 0 )t = 0;
         if ( tp != 0 )t = Bid - tp * Point;
         if ( sl == 0 )s = 0;
         if ( sl != 0 )s = Bid + sl * Point;
      }
      s = NormalizeDouble(s,Digits);
      t = NormalizeDouble(t,Digits);
      try++;
      if ( MarketExecution )
      {
         if(type == 0)isOpened = OrderSend(Symbol(),type,check_lot(l),NormalizeDouble(Ask,Digits),100,0,0,comm,ID,0,Blue);
         if(type == 1)isOpened = OrderSend(Symbol(),type,check_lot(l),NormalizeDouble(Bid,Digits),100,0,0,comm,ID,0,Red);
      }
      else
      {
         if(type == 0)isOpened = OrderSend(Symbol(),type,check_lot(l),NormalizeDouble(Ask,Digits),100,s,t,comm,ID,0,Blue);
         if(type == 1)isOpened = OrderSend(Symbol(),type,check_lot(l),NormalizeDouble(Bid,Digits),100,s,t,comm,ID,0,Red);
      }
      if(try > number_try || isOpened >= 0) break;
   }
   
   if( isOpened < 0 ) Print("Ордер не открыт, ошибка :", GetLastError());
   else if ( MarketExecution )
   {
      if ( !OrderSelect(isOpened,SELECT_BY_TICKET) )return(0);
      if ( OrderType() == 0 )color_order = Blue;
      if ( OrderType() == 1 )color_order = Red;
      try = 0;
      
      if ( NormalizeDouble(OrderStopLoss(),Digits) != NormalizeDouble(s,Digits) || NormalizeDouble(OrderTakeProfit(),Digits) != NormalizeDouble(t,Digits) )
      {
         while ( IsTradeContextBusy() )Sleep(500);
         res = OrderModify(OrderTicket(),OrderOpenPrice(),s,t,0,color_order);
         while ( !res )
         {
            while ( IsTradeContextBusy() )Sleep(500);
            res = OrderModify(OrderTicket(),OrderOpenPrice(),s,t,0,color_order);
            Sleep(time_period_try * 1000);
            try ++;
            Print("Ордер с типом " + DoubleToStr(OrderType(),0) + " по цене " + DoubleToStr(OrderOpenPrice(),Digits) + " не модифицирован по OPEN, попытка " + DoubleToStr(try,0));
            if ( try > number_try || res )break;
         }
      }
   }
   return (isOpened);
}

bool close( int ticket, double part_lot = 0 )
{
   bool isClosed = false;
   int try = 0;
   while ( IsTradeContextBusy() )Sleep(500);
   if ( !OrderSelect(ticket,SELECT_BY_TICKET) )return(false);
   if ( NormalizeDouble(part_lot,2) == 0 )part_lot = OrderLots();
   RefreshRates();
   if ( OrderType() < 2 )isClosed = OrderClose(OrderTicket(), part_lot,NormalizeDouble(OrderClosePrice(),Digits), 100, 0);
   if ( OrderType() >= 2 )isClosed = OrderDelete(OrderTicket());
   while(!isClosed)
   {
      Sleep(1000);
      while ( IsTradeContextBusy() )Sleep(500);
      RefreshRates();
      try++;
      if ( OrderType() < 2 )isClosed = OrderClose(OrderTicket(), part_lot,NormalizeDouble(OrderClosePrice(),Digits), 100, 0);
      if ( OrderType() >= 2 )isClosed = OrderDelete(OrderTicket());
      if(try > 10 || isClosed) break;
   }
   if(!isClosed) Print("Ордер ", ticket, " не закрыт, ошибка:", GetLastError());
   return (isClosed);
}

void close_all( int type_1 = -1,int type_2 = -1, int bars = 0 )
{
   int i;
   bool flag = false;
   if ( bars != 0 )flag = true;
   for( i = OrdersTotal() - 1; i >= 0; i-- )
   {
      if ( !OrderSelect(i,SELECT_BY_POS,MODE_TRADES) )continue;
      if( OrderMagicNumber() == ID && ((OrderType() == type_1 || OrderType() == type_2) || (type_1 == -1 && type_2 == -1)) && !flag )close(OrderTicket());   
      if( OrderMagicNumber() == ID && ((OrderType() == type_1 || OrderType() == type_2) || (type_1 == -1 && type_2 == -1)) && flag && (iBarShift(OrderSymbol(),Period(),OrderOpenTime()) - bars) >= 0 )close(OrderTicket());
   }
}

void delete_glob ( string c )
{
   int i;
   for ( i = GlobalVariablesTotal()-1; i>= 0 ; i-- )if ( StringFind(GlobalVariableName(i),c) >= 0 )GlobalVariableDel(GlobalVariableName(i));
   for ( i = ObjectsTotal()-1; i>= 0 ; i-- )if ( StringFind(ObjectName(i),c) >= 0 )ObjectDelete(ObjectName(i));
}

void check_loss ()
{
   if ( !GlobalVariableCheck(main_id + "L_TIME") )GlobalVariableSet(main_id + "L_TIME" , 0);
   
   int i;
   
   for( i = OrdersHistoryTotal() - 1; i >= 0; i-- )
   {
      if ( !OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) )continue;
      if ( OrderMagicNumber() == ID && OrderCloseTime() > GlobalVariableGet(main_id + "L_TIME") && OrderProfit() < 0 && NormalizeDouble(OrderStopLoss(), Digits) == NormalizeDouble(OrderClosePrice(), Digits) && OrderType() < 2 )
      {
         GlobalVariableSet(main_id + "EVENT_LOSS", OrderTicket());
         GlobalVariableSet(main_id + "L_TIME", OrderCloseTime());         
      }
   }
}
//--------Трейлинг-----------//
void profittral ()
{
   double atr1 = iATR(Symbol(),ATRTF,PeriodATR,ATRshift1);
   int aTR = (atr1 * 10000) * indaTR;
   if (ProfitTral == true)
   {
     for (int i=OrdersTotal() -1; i>=0; i--)
         {
          if (OrderSelect (i, SELECT_BY_POS, MODE_TRADES))
            {
             if (OrderSymbol () == Symbol() && OrderMagicNumber () == ID)
               {
                if (OrderType () == OP_BUY)
                  { 
                 if (TralOpenPrice == true)
                  {
                  if (Bid - OrderOpenPrice () > TrStop*Point)
                   {
                   if (ATRTral == true)
                     {
                      if (OrderStopLoss () < Bid - aTR* Point || OrderStopLoss () == 0)
                        {
                        if (OrderModify (OrderTicket(), OrderOpenPrice (), NormalizeDouble(Bid - aTR*Point, Digits), 0, 0, clrWhite))
                           {
                           Print ("ATR= " +aTR);
                           }
                         }
                     }  
                    else if (OrderStopLoss () < Bid - (TrStep+TrStop)* Point || OrderStopLoss () == 0)
                         {
                         if (OrderModify (OrderTicket(), OrderOpenPrice (), NormalizeDouble (Bid - TrStep*Point, Digits), 0, 0, clrWhite))
                           {
                           Print ("Профиттрал по ордерам на покупку");
                           }                        
                         }
                   }   
                  }
                  else if ( OrderTakeProfit () - Bid < TrStop*Point)
                   {
                   if (ATRTral == true)
                     {
                      if (OrderStopLoss () < Bid - aTR* Point || OrderStopLoss () == 0)
                        {
                        if (OrderModify (OrderTicket(), OrderOpenPrice (), NormalizeDouble(Bid - aTR*Point, Digits), NormalizeDouble (Ask + aTR*Point, Digits), 0, clrWhite))
                           {
                           Print ("ATR= " +aTR);
                           }
                         }
                     }  
                    else if (OrderStopLoss () < Bid - (TrStep+TrStop)* Point || OrderStopLoss () == 0)
                         {
                         if (OrderModify (OrderTicket(), OrderOpenPrice (), NormalizeDouble (Bid - TrStep*Point, Digits), NormalizeDouble (Ask + TrStep*Point, Digits), 0, clrWhite))
                           {
                           Print ("Профиттрал по ордерам на покупку");
                           }                        
                         }
                   }
                  } 
                if (OrderType () == OP_SELL)
                  {
                    if (TralOpenPrice == true)
                      {
                    if (OrderOpenPrice () - Ask > TrStop*Point)
                      {
                      if (ATRTral == true)  // если включен АТР  
                       {
                        if (OrderStopLoss () > Ask + aTR* Point || OrderStopLoss () == 0)
                        {
                        if (OrderModify (OrderTicket(), OrderOpenPrice (), NormalizeDouble(Ask + aTR*Point,Digits), 0, 0, clrWhite))
                           {
                           Print ("ATR= " +aTR);
                           }
                        }
                        }
                      else if (OrderStopLoss () > Ask + aTR* Point || OrderStopLoss () == 0)
                            {
                           if (OrderModify (OrderTicket(), OrderOpenPrice (), NormalizeDouble (Ask + TrStep*Point, Digits), 0, 0, clrBlue))
                           {
                           Print ("Профиттрал по ордерам на продажу");
                           }
                           }
                       }   
                      }
                      else if ( Ask - OrderTakeProfit () < TrStop*Point)
                      {
                      if (ATRTral == true)  // если включен АТР  
                       {
                        if (OrderStopLoss () > Ask + aTR* Point || OrderStopLoss () == 0)
                        {
                        if (OrderModify (OrderTicket(), OrderOpenPrice (), NormalizeDouble(Ask + aTR*Point,Digits), NormalizeDouble (Bid - aTR*Point, Digits), 0, clrWhite))
                           {
                           Print ("ATR= " +aTR);
                           }
                        }
                        }
                      else if (OrderStopLoss () > Ask + (TrStep+TrStop)* Point || OrderStopLoss () == 0)
                            {
                           if (OrderModify (OrderTicket(), OrderOpenPrice (), NormalizeDouble (Ask + TrStep*Point, Digits), NormalizeDouble (Bid - TrStep*Point, Digits), 0, clrBlue))
                           {
                           Print ("Профиттрал по ордерам на продажу");
                           }
                           }
                       }   
                      }      
                  }          
               } 
            } 
         }
  }       
//---RSI_BY---///
bool BY_rsiIlan ( int type, string unic_number )
{
   int i=0;
   double Brsi1, Brsi2, preClose, curClose;
   datetime time = StrToInteger(StringSubstr(unic_number, 1, StringFind(unic_number,"#") - 1));

   preClose = Close[2];
   curClose = Close[1];
   Brsi1 = iRSI(Symbol (), RSITF, PeriodRSI, RSIPRICE, 1);
   Brsi2 = iRSI(Symbol (), RSITF, PeriodRSI, RSIPRICE, 2);
     
   if ( type == OP_BUY )
    {
      if ( curClose <  NormalizeDouble(Ask, Digits))
       {
        if ( Time[i] > time )
          {
          if (  type == OP_BUY && curClose > preClose && Brsi2 < RsiMinimum && Brsi1 > Brsi2 && Brsi1 > RsiMinimum)return (true);
          }
         else if( Time[i] < time )return(false); 
      }   
   }
   
   if ( type == OP_SELL )
   {
      if ( curClose >  NormalizeDouble(Bid, Digits))
      {
      if ( Time[i] > time )
        {
        if( curClose < preClose && Brsi2 > RsiMaximum && Brsi2 > Brsi1 && Brsi1 < RsiMaximum )return(true);
        }
      else if( Time[i] < time )return(false); 
      }
   }
   return (false);
}
//-----------------------------------------------------------------------------
/*bool RSIBossBuy ()
{
   int i=0;
   double Brsi1, Brsi2, preClose, curClose;
   
   preClose = Close[2];
   curClose = Close[1];
   Brsi1 = iRSI(Symbol (), RSITFBoss, PeriodRSIBoss, RSIPRICEBoss, 1);
   Brsi2 = iRSI(Symbol (), RSITFBoss, PeriodRSIBoss, RSIPRICEBoss, 2);
     
   if (curClose > preClose && Brsi2 < RsiMinimumBoss && Brsi1 > RsiMinimumBoss && Brsi1 > Brsi2) //(curClose > preClose && Brsi2 > RsiMaximumBoss && Brsi2 < Brsi1 && Brsi2 > RsiMaximumBoss) ||)
    {
       return (true);
    }  
 return (false);
}
//----------------------------------------------------
bool RSIBossSell ()
{
   int i=0;
   double Brsi1, Brsi2, preClose, curClose;
   
   preClose = Close[2];
   curClose = Close[1];
   Brsi1 = iRSI(Symbol (), RSITFBoss, PeriodRSIBoss, RSIPRICEBoss, 1);
   Brsi2 = iRSI(Symbol (), RSITFBoss, PeriodRSIBoss, RSIPRICEBoss, 2);
     
  if (curClose < preClose && Brsi2 > RsiMaximumBoss && Brsi1 < RsiMaximumBoss && Brsi2 > Brsi1) //(Brsi2 < RsiMinimumBoss && curClose < preClose && Brsi2 > Brsi1 && Brsi1 < RsiMinimumBoss)
   {
      return(true);
   }
 return (false);
}
*/
//---------------------------------------------------------
/*int OrdersChart (int cont)
{
 int ticket, type;
 string unic_number;
 
 for( int x = OrdersTotal() - 1; x >= 0; x -- )       
         {
            if ( !OrderSelect(x,SELECT_BY_POS,MODE_TRADES) )continue;
            if ( OrderMagicNumber() != ID || StringFind(OrderComment(), unic_number) < 0 || type != OrderType() )continue;
            ticket = OrderTicket();
            cont ++;
         }
 return (cont);
}
*/
bool OrderCloseHistori ()
{
   int i, kol, ticket;
   int close = -1;
   double profit, buffer, Blue_0, Red_0, Green_0;
   string unic_number;
   
   
   Blue_0 = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORJAW,1);
   Red_0 = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORTEETH,1);
   Green_0 = iAlligator(NULL,Upper_period,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price,MODE_GATORLIPS,1);
   
   if ( Line_to_close == Line_blue_close )buffer = Blue_0;
   if ( Line_to_close == Line_red_close )buffer = Red_0;
   if ( Line_to_close == Line_green_close )buffer = Green_0;
   
   if ( (NormalizeDouble(l_bid, Digits) >= NormalizeDouble(buffer, Digits) && NormalizeDouble(Bid, Digits) <= NormalizeDouble(buffer, Digits)) )close = OP_BUY;
   if ( (NormalizeDouble(l_bid, Digits) <= NormalizeDouble(buffer, Digits) && NormalizeDouble(Bid, Digits) >= NormalizeDouble(buffer, Digits)) )close = OP_SELL;
   
   
   if ( close != -1 && Line_to_close != NONE_close )
   {
   for( i = OrdersTotal() - 1; i >= 0; i -- )       
      {
         if ( !OrderSelect(i,SELECT_BY_POS,MODE_TRADES) )continue;
         if ( OrderMagicNumber() != ID || StringFind(OrderComment(), "MAIN") < 0 || OrderType() != close || GlobalVariableCheck(main_id + "CONTR:" + IntegerToString(OrderTicket())) )continue;
         unic_number = StringSubstr(OrderComment(), 0, StringFind(OrderComment(),"#") + 1);
         ticket = OrderTicket();
         profit = OrderProfit();

     kol = 0;
     for( i = OrdersHistoryTotal() - 1; i >= 0; i -- )       
      {
         if ( !OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) )continue;
         if ( OrderMagicNumber() != ID || OrderType() > 1 || StringFind(OrderComment(), "MAIN") < 0)continue;
         kol++;
      } 
       
    if ( kol > 0 && profit < 0)  
         {
            Print("закрытие по линии аллигатора без профита");
            close (ticket);
            //MaxTrades_main = 1;
         }
     }
   }
   return (false);
}