//+------------------------------------------------------------------+
//|                                          Road_Map_expert_v04.mq4 |
//|  нач. 10/04/2016                                                 |
//+------------------------------------------------------------------+
#property copyright "Inkov Evgeni"
#property link      "ew123@mail.ru"
//+------------------------------------------------------------------+
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
#define           Razm_Mas_Prizn         7
//+------------------------------------------------------------------+
input ENUM_TIMEFRAMES TF              = PERIOD_M1;
input string     s1_______________    = "------------------------------------";
input double     Lots                 = 0;
input double     Proc_Lot             = 10;
input bool       Risk_from_Balance    = true;
input string     s2_______________    = "------------------------------------";
input int        TP                   = 1700;
input int        SL                   = 204; 
input string     s3_______________    = "------------------------------------";
input int        Minute_start_trade   = 0;
input int        Minute_end_trade     = 1440;
input string     s4_______________    = "------------------------------------";
input int        Magic                = 1234568;
input int        Slippage             = 50;
input string     s5_______________    = "------------------------------------";
input bool       Sound                = true;
input bool       Inf_RUS              = true;
input bool       Trade                = true;
input string     s6_______________    = "====================================";
input int        Max_Bars             = 300;
input color      clr_Series_Up        = clrBlue;
input color      clr_Series_Dw        = clrPurple;
input color      clr_Tail_ZZ          = clrGreen;
input color      clr_Fibo             = clrDarkOrange;
input color      clr_Prob_UP          = clrGreen;
input color      clr_Prob_DW          = clrRed;
input bool       On_Nom_Series        = true;
input bool       On_Fibo              = true;
extern string     s7                         = "=== Трейлинг ===";
extern bool       TrailingStop_Use           = false;     // включение функции трейлингстопа
extern int        TrailingStopStart          = 150;       // прибыль ордера при которой начинает работать трейлингстоп
extern int        TrailingStop               = 50;      // уровень трейлингстопа
extern string     s8                         = "=== Безубыток ===";
extern bool       BreakEven_Use              = false;
extern int        BBUSize                    = 3;       //размер в пунктах после которого стоп переносим в безубыток. 0 - отключен.
extern int        BBUSizepip                 = 1;        //безубыток в пунктах
//+------------------------------------------------------------------+
double      lot;
double      min_l, max_l;
int         dig_lot;
int         koef_dig;
bool        out_obj;
string      pref="RM_";

string      com_err="";
int         mas_ord[6];// 0-5 по типу - кол.ордеров

int         kol_ord, kol_otl, pred_kol_ord=0, pred_kol_otl=0;
int         pred_spread,spread,max_spread;
string      ss="";
bool        pause;
double      StopLevel, max_StopLevel;
string      sdv="                                                      ";
//......................
double pred_Bid,pred_Ask,tek_Bid,tek_Ask;
int st_;
bool no_connect;
datetime na4_open_ord, end_open_ord;
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
int Mas_Fract[];  // знач.фрактала: 1,2,3-макс, 0 - нет фракт, -1,-2,-3 - мин. (1-истиный фракт., 2- доп., 3-начало)
int M_Bars;
int Sgat_ZZ_0[][Razm_Mas_Prizn];
                     // 0 - номер бара, 
                     // 1 - знач.фракт. как в Mas_Fract, 
                     // 2 - (1 - имп.волна вверх, -1 - имп.волна вниз, 0 - корр.волна)
                     // 3 - (1 - слож.корр.вверх, -1 - слож.корр.вниз, 0 - нет слож.корр.), - число - кол.волн коррекции
                     // 4 - (1 - серия волн вверх, -1 - серия волн вниз, 0) - число - кол.волн в серии
                     // 5 - процент ценового диапазона тек.волны от пред. волны *100
                     // 6 - процент временого диапазона тек. волны от пред. волны *100
datetime time_end_urov;
bool prob_up,prob_dw;
double sl_Buy_prob,sl_Sell_prob;
double pr_BS_H=0,pr_SS_H=0;
datetime time_bar0;
//+------------------------------------------------------------------+
int OnInit()
{  
   M_Bars=0;
   //.............................
   time_end_urov=0;
   //......................................
   st_=55;
   //......................................
   if (UninitializeReason()!=REASON_CHARTCHANGE)
   {
      pred_spread=0;
      max_spread=0;
      max_StopLevel=0;
   }
   //.............................................
   out_obj=!IsTesting() || IsVisualMode();
   //.............................................
   min_l=MarketInfo(Symbol(),MODE_MINLOT);
   max_l=MarketInfo(Symbol(),MODE_MAXLOT);
   //.............................................
   koef_dig=1;
   if (Digits==5 || Digits==3)koef_dig=10;
   {
       TrailingStopStart*=10;
            TrailingStop*=10;
            BBUSize   *=10;                
            BBUSizepip  *=10;    
   }
   //.............................................
   double n_lot=MarketInfo(Symbol(),MODE_LOTSTEP);
   if (n_lot>0)
      dig_lot=(int)NormalizeDouble(MathLog(1.0/n_lot)/MathLog(10.0),0);
   else
      dig_lot=2;
   //.............................................
   EventSetTimer(1);
   //.............................................
   OnTick();
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   remove_objects(pref);
   EventKillTimer();
}
//+------------------------------------------------------------------+
void OnTimer()
{
   if (IsConnected())
      no_connect=false;
   else
   {
      put_txt(pref+IntegerToString(st_), RusLat(Inf_RUS,"Нет связи !","No connection !"),200,100,clrRed, 10);
      no_connect=true;
   }
}
//--------------------------------
bool Stop_Expert()
{
   if (!IsExpertEnabled())
   {
      put_txt(pref+IntegerToString(st_), RusLat(Inf_RUS,"Отжата кнопка \"Авто-торговля\" !","Button is pressed \"AutoTrading\" !"),200,100,clrRed, 10);
      return(true);
   }
   if (!IsTradeAllowed())
   {
      put_txt(pref+IntegerToString(st_), RusLat(Inf_RUS,"Советнику запрещено торговать !","Expert prohibited from trading !"),200,100,clrRed, 10);
      return(true);
   }
   return(false);
   if (!IsConnected())
   {
      put_txt(pref+IntegerToString(st_), RusLat(Inf_RUS,"Нет связи !","No connection !"),200,100,clrRed, 10);
      return(true);
   }
   return(false);
}
//---------------------------------
void OnTick()
{
   if (Max_Bars>0)
      M_Bars=MathMin(Max_Bars,iBars(_Symbol,0));
   else
      M_Bars=iBars(_Symbol,0);

   ArrayResize(Mas_Fract,M_Bars);
   ArrayResize(Sgat_ZZ_0,M_Bars);

   if (Minute_start_trade>Minute_end_trade)return;
   //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   bool New_Bar=false;
   if (time_bar0!=iTime(_Symbol,TF,0))
   {
      New_Bar=true;
      time_bar0=iTime(_Symbol,TF,0);
   }
   if (Period()<=TF)Form_ZZ(TF, Sgat_ZZ_0, New_Bar);
   //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   na4_open_ord = iTime(Symbol(),PERIOD_D1,0) + Minute_start_trade*60;
   end_open_ord = iTime(Symbol(),PERIOD_D1,0) + Minute_end_trade*60;
   //.............................
   pred_spread=spread;
   spread=(int)MathRound((Ask-Bid)/Point);
   //.............................
   if (out_obj)
   {
      if (Stop_Expert())return;
      if (no_connect)return;
      StopLevel=MarketInfo(_Symbol,MODE_STOPLEVEL);
      if (StopLevel>max_StopLevel)max_StopLevel=StopLevel;
      //.....................
      if (spread>max_spread)max_spread=spread;
   }
   //.............................
   if (Bid==0)
   {
      if (out_obj)Out_Comm(); 
      return;
   }
   //........................................................
   com_err="";  // обнулить строку комментария ошибок открытия ордеров
   //........................................................
   put_mas_ord();
   //........................................................
   bool open_BS_H=false,open_SS_H=false;
   if (out_obj)opred_napravl_start(open_BS_H,open_SS_H,pr_BS_H,pr_SS_H);
   //........................................................
   if (Trade)
   {
      pause=true;
      if (TimeCurrent()>=na4_open_ord && TimeCurrent()<end_open_ord)
      {
         pause=false;
         if (!out_obj)opred_napravl_start(open_BS_H,open_SS_H,pr_BS_H,pr_SS_H);
         //....................................
         if(open_BS_H)
            if (mas_ord[OP_BUY]==0 && mas_ord[OP_SELL]==0)
            {
               opred_begin_lot();
               Open_ord_Buy ();
            }
         //.......................................   
         if(open_SS_H)
            if (mas_ord[OP_BUY]==0 && mas_ord[OP_SELL]==0)
            {
               opred_begin_lot();
               Open_ord_Sell(); 
            }
      }
   }
   if (out_obj)
   {
      opred_begin_lot();
      Out_Comm();   // вывод комментария
      if (com_err!="")Comment(com_err);
   }
}
//+------------------------------------------------------------------+
void opred_napravl_start(bool& open_buy, bool& open_sell, double& sl_buy, double& sl_sell)
{

   open_buy =false;
   open_sell=false;
   
   RefreshRates();
   if (prob_up && ND(sl_buy)!=ND(sl_Buy_prob))
   {
      open_buy=true;
      sl_buy=sl_Buy_prob;
   }
   //.....................................
   if (prob_dw && ND(sl_sell)!=ND(sl_Sell_prob))
   {
      open_sell=true;
      sl_sell=sl_Sell_prob;
   }
}
//--------------------------
void opred_begin_lot()
{
   if (Lots>0)           // определить начальный лот
      lot=Ogran_min_lot(NDL(Lots));
   else
      lot=Ogran_min_lot(GetLot(Proc_Lot));
}
//------------------------------
double GetLot(double proc)
{
   double free_magrin;
   
   if (Risk_from_Balance)
      free_magrin = AccountBalance();
   else
      free_magrin = AccountFreeMargin();

   double lot1 = NDL(free_magrin * proc/100000.0);
   
   return (lot1);
}
//---------------------------------------------------------------
double Ogran_min_lot(double lot1)
{
   if (lot1 < min_l)lot1 = min_l;
   return(lot1);
}
//---------------------------------------------------------------
double Ogran_max_lot(double lot1)
{
   if (lot1 > max_l)lot1 = max_l;
   return(lot1);
}
//---------------------------------------------------------------
void put_mas_ord()
{        // посчитать кол. ордеров
   ArrayInitialize(mas_ord,0);
   kol_ord=0;
   kol_otl=0;
   bool M;
   
   for(int i=0; i<OrdersTotal(); i++)
      if (OrderSelect(i,SELECT_BY_POS)==true)
      {
         if (!Good_ord(i,MODE_TRADES))continue;
         
         if (OrderStopLoss()==0)
            if (OrderType()==OP_BUY || OrderType()==OP_BUYSTOP || OrderType()==OP_BUYLIMIT)
               M=OrderModify(OrderTicket(),OrderOpenPrice(),ND(OrderOpenPrice()-SL*Point),OrderTakeProfit(),0);
            else
               M=OrderModify(OrderTicket(),OrderOpenPrice(),ND(OrderOpenPrice()+SL*Point),OrderTakeProfit(),0);
         //...............................      
         if (OrderTakeProfit()==0)
            if (OrderType()==OP_BUY || OrderType()==OP_BUYSTOP || OrderType()==OP_BUYLIMIT)
               M=OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),ND(OrderOpenPrice()+TP*Point),0);
            else
               M=OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),ND(OrderOpenPrice()-TP*Point),0);
         //...............................      
         if (OrderType()>1)
            kol_otl++;
         else
            kol_ord++;
         mas_ord[OrderType()]++;
   if(TrailingStop_Use)
   fTrailingWithStart();
   if(BreakEven_Use)BBU();
      }
   //..........................................
   if (out_obj && Sound)
      if(kol_ord!=pred_kol_ord)
      {
         PlaySound("news.wav");
         pred_kol_ord=kol_ord;
      }
      else
         if(kol_otl!=pred_kol_otl)
         {
            if(kol_otl>pred_kol_otl)
               PlaySound("expert.wav");
            else
               PlaySound("timeout.wav");
            pred_kol_otl=kol_otl;
         }
}
//-----------------------------------------------
bool Good_ord(int i, int mode)
{
   if (!OrderSelect(i,SELECT_BY_POS,mode))return(false);
   if (OrderSymbol()!=Symbol())return(false);
   if (OrderMagicNumber()==Magic)return(true);
   
   return(false);
}
//---------------------
double ND(double n)
{
   return(NormalizeDouble(n,Digits));
}
//---------------------------------------------------------------
double NDL(double n)
{
   return(NormalizeDouble(n,dig_lot));
}
//---------------------------------------------------------------
double ND2(double n)
{
   return(NormalizeDouble(n,2));
}
//---------------------------------------------------------------
void Out_Comm()
{     // вывод комментария
   string s="",s1="";
   int st=st_;
   //..........................................................
   if (Trade || IsTesting())
   {
      s1="Prof= "+DoubleToStr(AccountProfit(),2)+" => ";
      if(AccountMargin()>0)
         s1=s1+DoubleToStr(AccountEquity()/AccountMargin()*100.0,2)+" %";
      else
         s1=s1+"0.00 %";
   }
   else
      s1="Trade close";
   put_txt(pref+IntegerToString(st), (pause?"PAUSE...  ":"")+s1,10,st,clrMagenta, 10); st-=15;
   //..........................................................
   put_txt(pref+IntegerToString(st), "TF= "+str_TF(TF)+"    Lot = "+DoubleToStr(lot,dig_lot), 10,st,clrMagenta, 10); st-=15;
   put_txt(pref+IntegerToString(st), "TP = "+IntegerToString(TP) +"    SL = "+IntegerToString(SL),10,st,clrBlue, 10); st-=15;
   put_txt(pref+IntegerToString(st), "Time Trade= "+TimeToString(na4_open_ord,TIME_MINUTES) +" - "+
                                      TimeToString(end_open_ord,TIME_MINUTES),10,st,clrBlue, 10); st-=15;
}
//-------------------------------------------
void put_txt(string name, string vol, int X,int Y,color col1, int shr)
{
   if (ObjectFind(name)<0)ObjectCreate(name, OBJ_LABEL, 0,0,0);
   ObjectSet(name, OBJPROP_CORNER, 3);
   ObjectSet(name, OBJPROP_XDISTANCE, X);
   ObjectSet(name, OBJPROP_YDISTANCE, Y);
   ObjectSetText(name, vol, shr, "Arial Black", col1);
}
//----------------------------------------------
string nom_str(double n, bool plus=false, bool plus0=false)
{
   if (ND2(n)<0)return(" - "+DoubleToString(-n,2));
   if (ND2(n)>0)
   {
      if (plus)return(" + "+DoubleToString(n,2));
      return(DoubleToString(n,2));
   }
   if (plus0)return(" + 0.00");
   return("0.00");
}
//------------------------------------------
void remove_objects(string PreName)
{
   string Obj_Name,Head;
   for(int k=ObjectsTotal()-1; k>=0; k--) 
   {
      Obj_Name=ObjectName(k);
      Head=StringSubstr(Obj_Name,0,StringLen(PreName));
      if (Head==PreName)ObjectDelete(Obj_Name);
   }
}
//----------------------------------------------
void Open_ord_Buy()
{     // открыть ордер Buy
   RefreshRates();
   double pr=Ask;
   ust_order(Symbol(), OP_BUY, lot, ND(pr), Slippage, 0, 0, "", Magic);
   
   put_mas_ord();
}
//-------------------------------------------
void Open_ord_Sell()
{     // открыть ордер Sell
   RefreshRates();
   double pr=Bid;
   ust_order(Symbol(), OP_SELL, lot, ND(pr), Slippage, 0, 0, "", Magic);
   
   put_mas_ord();
}
//-------------------------------------------
int ust_order(string sym,int Tip, double lot1, double pr, int slippage, double sl, double tp, string com2, int mag, int dt=0, color col=clrNONE)
{
   double tek_lot;
   double ust_lot=lot1;
   int err=0;
   while (ust_lot>0)
   {
      tek_lot=Ogran_max_lot(ust_lot);
      err = OrderSend(sym, Tip, tek_lot, pr, slippage, sl, tp, com2, mag, dt, col);
      if (err<0)break;
      ust_lot-=tek_lot;
   }
   if (err<0)IsError(tip_str(Tip)+": pr="+DoubleToStr(pr,Digits)+" sl="+DoubleToStr(sl,Digits)+" tp="+DoubleToStr(tp,Digits));

   return(err);
}
//-----------------------------------------------
string tip_str (int tip)
{
   switch(tip)
   {
      case 0: return("Buy");
      case 1: return("Sell");
      case 2: return("BuyLimit");
      case 3: return("SellLimit");
      case 4: return("BuyStop");
      case 5: return("SellStop");
   }
   return("?");
}
//-----------------------------------------------
int IsError(string Whose)  
{
   int ierr = GetLastError(); 
   
   bool result = (ierr > 1);
   if(result)com_err=com_err+Whose+ " error = "+ IntegerToString(ierr)+ "; desc = "+ error(ierr)+"\n";
      
   return(ierr);
}
//-----------------------------------------------
string error(int eer)
{
   string er;
   switch(eer)
   {
      case 0:   break;
      case 1:   er="Нет ошибки, но результат неизвестен";                         break;
      case 2:   er="Общая ошибка";                                                break;
      case 3:   er="Неправильные параметры";                                      break;
      case 4:   er="Торговый сервер занят";                                       break;
      case 5:   er="Старая версия клиентского терминала";                         break;
      case 6:   er="Нет связи с торговым сервером";                               break;
      case 7:   er="Недостаточно прав";                                           break;
      case 8:   er="Слишком частые запросы";                                      break;
      case 9:   er="Недопустимая операция нарушающая функционирование сервера";   break;
      case 64:  er="Счет заблокирован";                                           break;
      case 65:  er="Неправильный номер счета";                                    break;
      case 128: er="Истек срок ожидания совершения сделки";                       break;
      case 129: er="Неправильная цена";                                           break;
      case 130: er="Неправильные стопы";                                          break;
      case 131: er="Неправильный объем";                                          break;
      case 132: er="Рынок закрыт";                                                break;
      case 133: er="Торговля запрещена";                                          break;
      case 134: er="Недостаточно денег для совершения операции";                  break;
      case 135: er="Цена изменилась";                                             break;
      case 136: er="Нет цен";                                                     break;
      case 137: er="Брокер занят";                                                break;
      case 138: er="Новые цены - Реквот";                                         break;
      case 139: er="Ордер заблокирован и уже обрабатывается";                     break;
      case 140: er="Разрешена только покупка";                                    break;
      case 141: er="Слишком много запросов";                                      break;
      case 145: er="Модификация запрещена, так как ордер слишком близок к рынку"; break;
      case 146: er="Подсистема торговли занята";                                  break;
      case 147: er="Использование даты истечения ордера запрещено брокером";      break;
      case 148: er="Количество открытых и отложенных ордеров достигло предела ";  break;
      //---- 
      case 4000: er="Нет ошибки";                                                 break;
      case 4001: er="Неправильный указатель функции";                             break;
      case 4002: er="Индекс массива - вне диапазона";                             break;
      case 4003: er="Нет памяти для стека функций";                               break;
      case 4004: er="Переполнение стека после рекурсивного вызова";               break;
      case 4005: er="На стеке нет памяти для передачи параметров";                break;
      case 4006: er="Нет памяти для строкового параметра";                        break;
      case 4007: er="Нет памяти для временной строки";                            break;
      case 4008: er="Неинициализированная строка";                                break;
      case 4009: er="Неинициализированная строка в массиве";                      break;
      case 4010: er="Нет памяти для строкового массива";                          break;
      case 4011: er="Слишком длинная строка";                                     break;
      case 4012: er="Остаток от деления на ноль";                                 break;
      case 4013: er="Деление на ноль";                                            break;
      case 4014: er="Неизвестная команда";                                        break;
      case 4015: er="Неправильный переход";                                       break;
      case 4016: er="Неинициализированный массив";                                break;
      case 4017: er="Вызовы DLL не разрешены";                                    break;
      case 4018: er="Невозможно загрузить библиотеку";                            break;
      case 4019: er="Невозможно вызвать функцию";                                 break;
      case 4020: er="eВызовы внешних библиотечных функций не разрешены";          break;
      case 4021: er="Недостаточно памяти для строки, возвращаемой из функции";    break;
      case 4022: er="Система занята";                                             break;
      case 4050: er="Неправильное количество параметров функции";                 break;
      case 4051: er="Недопустимое значение параметра функции";                    break;
      case 4052: er="Внутренняя ошибка строковой функции";                        break;
      case 4053: er="Ошибка массива";                                             break;
      case 4054: er="Неправильное использование массива-таймсерии";               break;
      case 4055: er="Ошибка пользовательского индикатора";                        break;
      case 4056: er="Массивы несовместимы";                                       break;
      case 4057: er="Ошибка обработки глобальныех переменных";                    break;
      case 4058: er="Глобальная переменная не обнаружена";                        break;
      case 4059: er="Функция не разрешена в тестовом режиме";                     break;
      case 4060: er="Функция не подтверждена";                                    break;
      case 4061: er="Ошибка отправки почты";                                      break;
      case 4062: er="Ожидается параметр типа string";                             break;
      case 4063: er="Ожидается параметр типа integer";                            break;
      case 4064: er="Ожидается параметр типа double";                             break;
      case 4065: er="В качестве параметра ожидается массив";                      break;
      case 4066: er="Запрошенные исторические данные в состоянии обновления";     break;
      case 4067: er="Ошибка при выполнении торговой операции";                    break;
      case 4099: er="Конец файла";                                                break;
      case 4100: er="Ошибка при работе с файлом";                                 break;
      case 4101: er="Неправильное имя файла";                                     break;
      case 4102: er="Слишком много открытых файлов";                              break;
      case 4103: er="Невозможно открыть файл";                                    break;
      case 4104: er="Несовместимый режим доступа к файлу";                        break;
      case 4105: er="Ни один ордер не выбран";                                    break;
      case 4106: er="Неизвестный символ";                                         break;
      case 4107: er="Неправильный параметр цены для торговой функции";            break;
      case 4108: er="Неверный номер тикета";                                      break;
      case 4109: er="Торговля не разрешена";                                      break;
      case 4110: er="Длинные позиции не разрешены";                               break;
      case 4111: er="Короткие позиции не разрешены";                              break;
      case 4200: er="Объект уже существует";                                      break;
      case 4201: er="Запрошено неизвестное свойство объекта";                     break;
      case 4202: er="Объект не существует";                                       break;
      case 4203: er="Неизвестный тип объекта";                                    break;
      case 4204: er="Нет имени объекта";                                          break;
      case 4205: er="Ошибка координат объекта";                                   break;
      case 4206: er="Не найдено указанное подокно";                               break;
      case 4207: er="Ошибка при работе с объектом";                               break;
      default:   er="Неизвестная ошибка";
   }
   return(er);
}
//==============================================================
string RusLat(bool inf_rus, string sR, string sL)
{
   if (inf_rus)return(sR);
   return(sL);
}
//-----------------------------------------------
void Close_ord(int tip=-1)
{
   bool C,usl=true,CL=false;
   while (usl)
   {
      usl=false;
      for(int i=0; i<OrdersTotal(); i++)
      {
         if (!Good_ord(i,MODE_TRADES))continue;
         
         if(OrderType()==OP_BUY && (tip==OP_BUY || tip==-1))
         {
            RefreshRates();
            C=OrderClose(OrderTicket(),OrderLots(),Bid,Slippage);
            CL=true;
            usl=true;
         }
         if (OrderType()==OP_SELL && (tip==OP_SELL || tip==-1))
         {
            RefreshRates();
            C=OrderClose(OrderTicket(),OrderLots(),Ask,Slippage);
            CL=true;
            usl=true;
         }
      }
   }
   if(CL)put_mas_ord();
}
//-----------------------------------------------
string str_TF(int n)
{
   if (n==0)n=Period();
   switch(n)
   {
      case PERIOD_M1:  return ("M1");
      case PERIOD_M5:  return ("M5");
      case PERIOD_M15: return ("M15");  
      case PERIOD_M30: return ("M30");
      case PERIOD_H1:  return ("H1");
      case PERIOD_H4:  return ("H4");
      case PERIOD_D1:  return ("D1");
      case PERIOD_W1:  return ("W1");
      case PERIOD_MN1: return ("MN1");
   }
   return("TF?");
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void Form_ZZ(int TF1,int& mas_sgat[][], bool new_bar)
{
   int n_sgat=0;
   
   Find_Fractal(TF1,new_bar);
   Dorab_Fract(TF1,mas_sgat, n_sgat,new_bar);
   Opred_Impuls_Wave(TF1,mas_sgat, n_sgat);
   Opred_Corr_wave(TF1,mas_sgat, n_sgat);
   Opred_Series_Wave(TF1,mas_sgat, n_sgat);
   
   if (out_obj)
   {
      Out_ZZ(TF1, mas_sgat, n_sgat);
      if (On_Nom_Series)Out_Nom_Series(TF1, mas_sgat, n_sgat);
   }
}
//-------------------------------------
void Opred_Series_Wave(int TF1, int& mas_sgat[][], int kol_sgat)
{  // найти серии волн
   int imp,impS=0,impS_beg=0,tek_series=0,kol_wave=0,b1,b0,b1S=0,b0S=0,b1S_beg=0,b0S_beg=0;
   double H,L,HS=0,LS=0;
   double HS_beg=0,LS_beg=0;
   double HS_prob,LS_prob;
   
   int n=0,m=0;
   
   for (int i=kol_sgat-1;i>=1;i--)
   {
      prob_up=0;
      prob_dw=0;
      imp = mas_sgat[i][2];   // текущая импульсная/корр. волна; 1 - имп.волна вверх, -1 - имп.волна вниз, 0 - корр.волна
      
      if (imp!=0) // найдена импульсная волна
      {
         b0=mas_sgat[i][0];
         b1=mas_sgat[i-1][0];
         
         if (imp>0)
         {
            L=iLow (_Symbol,TF1,b0);
            H=iHigh(_Symbol,TF1,b1);
         }
         else
         {
            L=iLow (_Symbol,TF1,b1);
            H=iHigh(_Symbol,TF1,b0);
         }
         prob_up=impS<0 && ND(H)>ND(HS);  // пробой вверх
         prob_dw=impS>0 && ND(L)<ND(LS);  // пробой вниз
         
         if (prob_up)
         {
            HS_prob=HS;
            if (out_obj)Out_TL(n,iTime(_Symbol,TF1,b0S), HS, iTime(_Symbol,TF1,b1)+2*TF1*60, HS, "prob_U", clr_Prob_UP, TF1, 1,2);
            n++;
         }
         if (prob_dw)
         {
            LS_prob=LS;
            if (out_obj)Out_TL(m,iTime(_Symbol,TF1,b0S), LS, iTime(_Symbol,TF1,b1)+2*TF1*60, LS, "prob_D", clr_Prob_DW, TF1, 1,2);
            m++;
         }
            
         if (HS==0 || prob_up || prob_dw) // или волн ещё не было или пробой вверх/вниз
         {
            HS=H;
            LS=L;
            b0S=b0;
            b1S=b1;
            impS=imp;
            
            HS_beg=H;
            LS_beg=L;
            sl_Sell_prob=H;
            sl_Buy_prob =L;
            b0S_beg=b0;
            b1S_beg=b1;
            impS_beg=imp;
            
            tek_series=imp; // 1 или -1
            kol_wave=0;
         }
         else
            if ((impS>0 && ND(H)>ND(HS)) || 
                (impS<0 && ND(L)<ND(LS)))// превышение вверх или вниз
            {  // обновляем исходную волну
               HS=H;
               LS=L;
               b0S=b0;
               b1S=b1;
            }
      }
         
      kol_wave++;
      mas_sgat[i][4]=tek_series*kol_wave;
   }
   if (out_obj)
   {
      Del_extra_obj(TF1,"prob_U",n+1);
      Del_extra_obj(TF1,"prob_D",m+1);
      
      if (On_Fibo)Out_Fibo(TF1,impS_beg,b0S_beg,b1S_beg,LS_beg,HS_beg);
      
      if (Sound)
      {
         datetime t=iTime(_Symbol,TF1,b0S);
         if (prob_up && t>time_end_urov)
         {
            time_end_urov=t;
            PlaySound("alert.wav");
         }
         if (prob_dw && t>time_end_urov)
         {
            time_end_urov=t;
            PlaySound("email.wav");
         }
      }
   }
}
//-------------------------------------
void Out_Fibo(int TF1,int dir,int b0, int b1, double L,double H)
{
   if (dir>0)
   {
      double p=L;
      L=H;
      H=p;
   }
   string name=pref+str_TF(TF1)+"_Fibo";
   
   double d=MathCeil(0.1*((1.0*WindowBarsPerChart()-WindowFirstVisibleBar())/5.0+b1));
   b0=b1-(int)d;
   datetime t0;;
   if (b0<0)
      t0=iTime(_Symbol,TF1,0)-b0*TF1*60;
   else
      t0=iTime(_Symbol,TF1,b0);
      
   if (ObjectFind(name))ObjectCreate(name,OBJ_FIBO,0,iTime(_Symbol,TF1,b1),L,t0,H);
      
   ObjectSet(name,OBJPROP_TIME1,iTime(_Symbol,TF1,b1));
   ObjectSet(name,OBJPROP_PRICE1,L);

   ObjectSet(name,OBJPROP_TIME2,t0);
   ObjectSet(name,OBJPROP_PRICE2,H);
   ObjectSet(name,OBJPROP_COLOR,clr_Fibo);
   ObjectSet(name,OBJPROP_WIDTH,1);
   ObjectSetInteger(0,name,OBJPROP_RAY_RIGHT,false);
   ObjectSetInteger(0,name,OBJPROP_LEVELCOLOR,0,clr_Fibo);
   ObjectSetInteger(0,name,OBJPROP_LEVELS,13);
   ObjectSetDouble(0,name,OBJPROP_LEVELVALUE,0,0);
   ObjectSetDouble(0,name,OBJPROP_LEVELVALUE,1,0.236);
   ObjectSetDouble(0,name,OBJPROP_LEVELVALUE,2,0.382);
   ObjectSetDouble(0,name,OBJPROP_LEVELVALUE,3,0.5);
   ObjectSetDouble(0,name,OBJPROP_LEVELVALUE,4,0.618);
   ObjectSetDouble(0,name,OBJPROP_LEVELVALUE,5,0.764);
   ObjectSetDouble(0,name,OBJPROP_LEVELVALUE,6,1.0);
   ObjectSetDouble(0,name,OBJPROP_LEVELVALUE,7,1.382);
   ObjectSetDouble(0,name,OBJPROP_LEVELVALUE,8,1.618);
   ObjectSetDouble(0,name,OBJPROP_LEVELVALUE,9,2.0);
   ObjectSetDouble(0,name,OBJPROP_LEVELVALUE,10,2.618);
   ObjectSetDouble(0,name,OBJPROP_LEVELVALUE,11,3.0);
   ObjectSetDouble(0,name,OBJPROP_LEVELVALUE,12,4.0);
   ObjectSetString(0,name,OBJPROP_LEVELTEXT,0,"0.0");
   ObjectSetString(0,name,OBJPROP_LEVELTEXT,1,"23.6");
   ObjectSetString(0,name,OBJPROP_LEVELTEXT,2,"38.2");
   ObjectSetString(0,name,OBJPROP_LEVELTEXT,3,"50.0");
   ObjectSetString(0,name,OBJPROP_LEVELTEXT,4,"61.8");
   ObjectSetString(0,name,OBJPROP_LEVELTEXT,5,"76.4");
   ObjectSetString(0,name,OBJPROP_LEVELTEXT,6,"100.0");
   ObjectSetString(0,name,OBJPROP_LEVELTEXT,7,"138.2");
   ObjectSetString(0,name,OBJPROP_LEVELTEXT,8,"161.8");
   ObjectSetString(0,name,OBJPROP_LEVELTEXT,9,"200.0");
   ObjectSetString(0,name,OBJPROP_LEVELTEXT,10,"261.8");
   ObjectSetString(0,name,OBJPROP_LEVELTEXT,11,"300.0");
   ObjectSetString(0,name,OBJPROP_LEVELTEXT,12,"400.0");
}
//------------------------------------
void Find_Fractal(int TF1, bool new_bar)
{
   int up,dw;
   int beg_bar;
   if (new_bar)
   {
      beg_bar=M_Bars-4;
      ArrayInitialize(Mas_Fract,0);
   }
   else
   {
      beg_bar=2;
      for (int i=0;i<=beg_bar;i++)Mas_Fract[i]=0;
   }
      
   for (int i=beg_bar;i>=2;i--)
   {
      up=0;
      dw=0;
      double H_2=iHigh(_Symbol,TF1,i-2);
      double H_1=iHigh(_Symbol,TF1,i-1);
      double H0 =iHigh(_Symbol,TF1,i);
      double H1 =iHigh(_Symbol,TF1,i+1);
      double H2 =iHigh(_Symbol,TF1,i+2);
      double H3 =iHigh(_Symbol,TF1,i+3);
      if (((ND(H0)> ND(H1) && ND(H0)> ND(H2)) ||
           (ND(H0)==ND(H1) && ND(H0)> ND(H2)) || 
           (ND(H0)> ND(H1) && ND(H0)==ND(H2)) ||
           (ND(H0)== ND(H1) && ND(H0)==ND(H2) && ND(H0)> ND(H3))) && 
            ND(H0)> ND(H_1)&& ND(H0)> ND(H_2))
         up=1;
      //......................................
      double L_2=iLow(_Symbol,TF1,i-2);
      double L_1=iLow(_Symbol,TF1,i-1);
      double L0 =iLow(_Symbol,TF1,i);
      double L1 =iLow(_Symbol,TF1,i+1);
      double L2 =iLow(_Symbol,TF1,i+2);
      double L3 =iLow(_Symbol,TF1,i+3);
      if (((ND(L0)< ND(L1) && ND(L0)< ND(L2)) ||
           (ND(L0)==ND(L1) && ND(L0)< ND(L2)) || 
           (ND(L0)< ND(L1) && ND(L0)==ND(L2)) ||
           (ND(L0)== ND(L1) && ND(L0)==ND(L2) && ND(L0)< ND(L3))) && 
            ND(L0)< ND(L_1)&& ND(L0)< ND(L_2))dw=1;
      //......................................
      if (up==1 && dw==0)
         Mas_Fract[i]=1;
      else
         if (up==0 && dw==1)
            Mas_Fract[i]=-1;
         else
            if (up==1 && dw==1)
            {
               double op0=iOpen (_Symbol,TF1,i);
               double cl0=iClose(_Symbol,TF1,i);
               if (ND(cl0)>=ND(op0))
                  Mas_Fract[i]=4;
               else
                  Mas_Fract[i]=-4;
            }
      
   }
}
//------------------------------------
void Dorab_Fract(int TF1, int& mas_sgat[][], int& kol_sgat, bool new_bar)
{
   obrab_begin_ZZ(TF1, Mas_Fract);  // обработать начало зиг-зага
   //..............................
   int Sgat_ZZ[][2]; // 0 - ном бара, 1 - знач.
   ArrayResize(Sgat_ZZ,2*M_Bars);
   int n=0;
   szhat_mas_ZZ (Mas_Fract,Sgat_ZZ,n);  // сжать массив ZZ
   Find_promezh_point (TF1, Mas_Fract, Sgat_ZZ, n); // найти точки между одинаковыми вершинами
   szhat_mas_ZZ (Mas_Fract,Sgat_ZZ,n);  // сжать массив ZZ
   ubrat_iskagen_ZZ (TF1, Mas_Fract, Sgat_ZZ, n); // убрать искажения ZZ
   //..............................
   ArrayInitialize(mas_sgat,0);
   szhat_mas_ZZ (Mas_Fract,mas_sgat,kol_sgat);  // сжать массив ZZ
}
//-------------------------------
void obrab_begin_ZZ(int TF1, int& mas_Fr[])
{
   int k,i;
   for (i=0;i<M_Bars;i++) // найти начало масива ZZ (i)
      if (mas_Fr[i]!=0)break;
   //..............................
   if (i>0) // найдено начало фракталов
            // смотрим на каком баре стоит начальный фрактал (i).
            // 1. Если на i-ом баре - вершина UP
            // 1.1. Если на 0-м баре High >  UP, то High[0]= 3
            // 1.2. Если на 0-м баре High <= UP, то Low [0]=-3
            // 2. (для DW - наоборот)
      if (mas_Fr[i]>0) // в начале линейки фракталов - максимум (UP)
      {
         if (iHigh(_Symbol,TF1,0)>iHigh(_Symbol,TF1,i)) // на 0-м баре High >  UP
         {
            k=iHighest(_Symbol,TF1,MODE_HIGH,i-1,1);
            if (iHigh(_Symbol,TF1,k)>iHigh(_Symbol,TF1,0))
            {
               mas_Fr[k]= 3; // минимум между вершинами найдется автоматом
               mas_Fr[0]=-3;
            }
            else
               mas_Fr[0]=3; // минимум между вершинами найдется автоматом
         }
         else
         {
            k=iLowest(_Symbol,TF1,MODE_LOW,i-1,1);
            if (iLow(_Symbol,TF1,k)<iLow(_Symbol,TF1,0))
            {
               mas_Fr[k]=-3;
               mas_Fr[0]= 3;
            }
            else
               mas_Fr[0]=-3;
         }
      }
      else
         if (mas_Fr[i]<0) // в начале линейки фракталов - минимум
         {
            if (iLow(_Symbol,TF1,0)<iLow(_Symbol,TF1,i)) // мин. 0-ого бара меньше мин. начального фрактала
            {
               k=iLowest(_Symbol,TF1,MODE_LOW,i-1,1);
               if (iLow(_Symbol,TF1,k)<iLow(_Symbol,TF1,0)) // есть ли между 1-м и i-1 барами минимум меньший минимума 0-ого бара ?
               {
                  mas_Fr[k]=-3; // максимум между низинами найдется автоматоматически
                  mas_Fr[0]= 3; // на 0-м баре макс.
               }
               else // на 0-м баре минимум
                  mas_Fr[0]=-3; // максимум между низинами найдется автоматом
            }
            else
            {
               k=iHighest(_Symbol,TF1,MODE_HIGH,i-1,1);
               if (iHigh(_Symbol,TF1,k)>iHigh(_Symbol,TF1,0))
               {
                  mas_Fr[k]= 3;
                  mas_Fr[0]=-3;
               }
               else
                  mas_Fr[0]=3;
            }
         }
}
//--------------------------------------
void Find_promezh_point(int TF1, int& mas_ish_ZZ[], int& mas_Szt[][], int kol_szt)
{ // найти точки между одинаковыми вершинами
   int k,b0,b1,z0,z1;
   for (int i=1;i<kol_szt;i++)
   {
      b0=mas_Szt[i-1][0];
      b1=mas_Szt[i]  [0];
      z0=mas_Szt[i-1][1];
      z1=mas_Szt[i]  [1];
      if (z0*z1>0)   // на вершинах одинаковые направления
         if (b1-b0-1>1)
            if (z1>0)
            {
               k=Main_iLowest(TF1,b1-b0-1,b0+1);
               mas_ish_ZZ[k]=-2;
            }
            else
            {
               k=Main_iHighest(TF1,b1-b0-1,b0+1);
               mas_ish_ZZ[k]=2;
            }
   }
}
//-------------------------------------
void ubrat_iskagen_ZZ(int TF1, int& mas_ish_ZZ[], int& mas_Szt[][], int kol_szt)
{   // убрать искажения ZZ: если максимум ниже пред. минимума и наоборот
   int i,b0,b1;
   double p0,p1;
   int f0,f1;
   for (i=1;i<kol_szt;i++)
   {
      b1=mas_Szt[i]  [0]; // тек.
      f1=mas_Szt[i]  [1];
      b0=mas_Szt[i-1][0]; // справа
      f0=mas_Szt[i-1][1];
      
      p1=iLow (_Symbol,TF1,b1);
      p0=iHigh(_Symbol,TF1,b0);
      if (f1<0 && f0>0 && ND(p1)>=ND(p0))
      {
         mas_ish_ZZ[b0]=0;
         mas_ish_ZZ[b1]=0;
         continue;
      }
      p1=iHigh(_Symbol,TF1,b1);
      p0=iLow (_Symbol,TF1,b0);
      if (f1>0 && f0<0 && ND(p1)<=ND(p0))
      {
         mas_ish_ZZ[b0]=0;
         mas_ish_ZZ[b1]=0;
      }
   }
}
//--------------------------
void szhat_mas_ZZ(int& masZZ_inp[], int& masZZ_out[][], int& kol_out)
{  // сжать массив ZZ
   kol_out=0;
   int n;
   for (int i=0;i<M_Bars;i++)
   {
      n=masZZ_inp[i];
      if (n!=0)
      {
         if (MathAbs(n)<4)
         {
            masZZ_out[kol_out][0]=i;
            masZZ_out[kol_out][1]=n;
            kol_out++;
         }
         else // двойной фрактал
            if (n==4)
            {
               masZZ_out[kol_out][0]=i;
               masZZ_out[kol_out][1]=1;
               kol_out++;
               masZZ_out[kol_out][0]=i;
               masZZ_out[kol_out][1]=-1;
               kol_out++;
            }
            else
            {
               masZZ_out[kol_out][0]=i;
               masZZ_out[kol_out][1]=-1;
               kol_out++;
               masZZ_out[kol_out][0]=i;
               masZZ_out[kol_out][1]=1;
               kol_out++;
            }
      }
   }
}
//---------------------------------
void Opred_Impuls_Wave(int TF1, int& mas_sgat[][], int kol_sgat)
{   // выделить импульсные волны
   int z1,z0,z_1,b1,b0,b_1;
   double p1,p_1;
   for (int i=kol_sgat-2;i>=1;i--)
   {
      z1 =mas_sgat[i+1][1];   // левый   фрактал
      z0 =mas_sgat[i]  [1];   // текущий фрактал
      z_1=mas_sgat[i-1][1];   // правый  фрактал
      
      b1 =mas_sgat[i+1][0];
      b0 =mas_sgat[i]  [0];
      b_1=mas_sgat[i-1][0];
      
      if (z0<0 && z_1>0) // линия вверх
      {
         p1 =iHigh(_Symbol,TF1,b1);
         p_1=iHigh(_Symbol,TF1,b_1);
         if (ND(p_1)>ND(p1))mas_sgat[i][2]=1;
      }
      else
         if (z0>0 && z_1<0) // линия вниз
         {
            p1 =iLow(_Symbol,TF1,b1);
            p_1=iLow(_Symbol,TF1,b_1);
            if (ND(p_1)<ND(p1))mas_sgat[i][2]=-1;
         }
   }
}
//---------------------------
void Opred_Corr_wave(int TF1, int& mas_sgat[][], int kol_sgat)
{  // найти сложные корректирующие волны
   int z1,z0,b0,b1;
   double p0,d0;
   int i=kol_sgat-2;
   int n_k;

   while (i>=1)
   {
      z1 =mas_sgat[i+1][1];   // левый   фрактал
      z0 =mas_sgat[i]  [1];   // текущий фрактал
      
      b0 =mas_sgat[i][0]; // текущий бар
      p0 =iHigh(_Symbol,TF1,b0);
      d0 =iLow (_Symbol,TF1,b0);
      
      // корр. волны вниз
      if (z1<0 && z0>0 && mas_sgat[i+1][2]>0 && mas_sgat[i][2]==0) // пред.линия импульс вверх, тек -корр.
      {
         mas_sgat[i][3]=-1; // обозначить начало сложной корр. линиии
         if (i>=2 && mas_sgat[i-1][2]==0) // след.-корр.
         {
            i--;
            mas_sgat[i][3]=-2;
            i--;
            n_k=3;
            while (i>0 && mas_sgat[i][2]==0)
            {
               mas_sgat[i][3]=-n_k;
               i--;
               n_k++;
               if (i<1)break;
               b1=mas_sgat[i-1][0];
               if (ND(iHigh(_Symbol,TF1,b1))>ND(p0))break; // превысили основной верхний фрактал
               mas_sgat[i][3]=-n_k;
               i--;
               n_k++;
            }
         }
         else
         {
            i--;
            continue;
         }
      }
      else // корр. волны вверх
         if (z1>0 && z0<0 && mas_sgat[i+1][2]<0 && mas_sgat[i][2]==0) // пред.линия импульс вниз, тек -корр.
         {
            mas_sgat[i][3]=1; // обозначить начало сложной корр. линиии
            if (i>=2 && mas_sgat[i-1][2]==0) // след.-корр.
            {
               i--;
               mas_sgat[i][3]=2;
               i--;
               n_k=3;
               while (i>0 && mas_sgat[i][2]==0)
               {
                  mas_sgat[i][3]=n_k;
                  i--;
                  n_k++;
                  if (i<1)break;
                  b1=mas_sgat[i-1][0];
                  if (ND(iLow(_Symbol,TF1,b1))<ND(d0))break; // превысили основной нижний фрактал
                  mas_sgat[i][3]=n_k;
                  i--;
                  n_k++;
               }
            }
            else
            {
               i--;
               continue;
            }
         }
         else
            i--;
   }
}
//-------------------------------------
void Out_ZZ(int TF1,int& mas_sgat[][], int kol_sgat)
{   // Вывести ZZ       
   int z0,z1,b0,b1,m0=0,m1=0;
   double L0,H0,L1,H1;
   datetime t0,t1;
      
   for (int i=1;i<kol_sgat;i++)
   {
      z1=mas_sgat[i][1]; // левый  фр.
      b1=mas_sgat[i][0];
      L1=iLow (_Symbol,TF1,b1);
      H1=iHigh(_Symbol,TF1,b1);
      t1=iTime(_Symbol,TF1,b1);
      
      z0=mas_sgat[i-1][1]; // правый фр.
      b0=mas_sgat[i-1][0];
      L0=iLow (_Symbol,TF1,b0);
      H0=iHigh(_Symbol,TF1,b0);
      t0=iTime(_Symbol,TF1,b0);
      //................................
      if (z1>0 && z0<0) // линия вниз
      {
         Out_TL(m0, t0, L0, t1, H1, "T_D", mas_sgat[i][4]>0?clr_Series_Up:clr_Series_Dw, TF1, mas_sgat[i][2]!=0,4);
         m0++;
      }
      else
         if (z1<0 && z0>0) // линия вверх
         {
            Out_TL(m1, t0, H0, t1, L1, "T_U", mas_sgat[i][4]>0?clr_Series_Up:clr_Series_Dw, TF1, mas_sgat[i][2]!=0,4);
            m1++;
         }
   }
   Del_extra_obj(TF1,"T_U",m0);
   Del_extra_obj(TF1,"T_D",m1);
}
//---------------------------------
void Del_extra_obj (int tf, string s, int n)
{
   string name;
   bool F;
   do
   {
      name=pref+str_TF(tf)+"_"+s+(string)n;
      F=ObjectFind(name)>=0;
      if(F)ObjectDelete(name);
      n++;
   }
   while (F);
}
//-------------------------------
int Main_iHighest(int tf, int n, int beg)
{
   double pr,pr_max=0.0;
   int n_max=beg;
   for (int i=beg;i<beg+n;i++)
   {
      pr=iHigh(_Symbol,tf,i);
      if (pr>pr_max)
      {
         pr_max=pr;
         n_max=i;
      }
   }
   return(n_max);
}
//-----------------------------
int Main_iLowest(int tf, int n, int beg)
{
   double pr,pr_min=999999.0;
   int n_min=beg;
   for (int i=beg;i<beg+n;i++)
   {
      pr=iLow(_Symbol,tf,i);
      if (pr<pr_min)
      {
         pr_min=pr;
         n_min=i;
      }
   }
   return(n_min);
}
//-----------------------------
void Out_Nom_Series(int TF1,int& mas_sgat[][], int kol_sgat)
{   // вывести фракталы
   int m=0,n=0,b,k;
   color clr;
         
   for (int i=0;i<kol_sgat-1;i++)
   {
      int z=mas_sgat[i][1];
      b=mas_sgat[i][0];
      k=mas_sgat[i+1][4];
      if (k!=0)
      {
         if (b>=Bars)break;
         
         if (b<=2 && i<=2)
            clr=clr_Tail_ZZ;
         else
            if (mas_sgat[i+1][4]>0)
               clr=clr_Series_Up;
            else
               clr=clr_Series_Dw;
               
         if (z>0){Out_txt(n,iTime(_Symbol,TF1,b),iHigh(_Symbol,TF1,b),"N_U",clr,TF1,ANCHOR_LOWER, k);n++;}
         if (z<0){Out_txt(m,iTime(_Symbol,TF1,b),iLow (_Symbol,TF1,b),"N_D",clr,TF1,ANCHOR_UPPER, k);m++;}
      }
   }
   Del_extra_obj(TF1,"N_U",n);
   Del_extra_obj(TF1,"N_D",m);
}
//------------------------------
void Out_TL(int i,datetime t1, double pr1, datetime t2, double pr2, string s, color col, int TF1, bool impuls, int width)
{
   string name=pref+str_TF(TF1)+"_"+s+(string)i;
   if (ObjectFind(name))ObjectCreate(name,OBJ_TREND,0,0,0,0,0);
      
   ObjectSet(name,OBJPROP_TIME1,t1);
   ObjectSet(name,OBJPROP_TIME2,t2);
   ObjectSet(name,OBJPROP_PRICE1,pr1);
   ObjectSet(name,OBJPROP_PRICE2,pr2);
   ObjectSet(name,OBJPROP_COLOR,col);
   ObjectSet(name,OBJPROP_RAY,0);
   if (impuls)
   {
      ObjectSet(name,OBJPROP_WIDTH,width);
      ObjectSet(name,OBJPROP_STYLE,STYLE_SOLID);
   }
   else
   {
      ObjectSet(name,OBJPROP_WIDTH,1);
      ObjectSet(name,OBJPROP_STYLE,STYLE_SOLID);
   }
}
//------------------------------------
void Out_Arrow(int i,datetime t, double pr,string s, color col, int cod,int TF1, int anchor)
{
   string name=pref+str_TF(TF1)+"_"+s+(string)i;
   if (ObjectFind(name))ObjectCreate(name,OBJ_ARROW,0,0,0);
      
   ObjectSet(name,OBJPROP_TIME1,t);
   ObjectSet(name,OBJPROP_PRICE1,pr);
   ObjectSet(name,OBJPROP_COLOR,col);
   ObjectSet(name,OBJPROP_WIDTH,1);
   ObjectSet(name,OBJPROP_ARROWCODE,cod);
   ObjectSetInteger(0,name,OBJPROP_ANCHOR,anchor);
}
//------------------------------------
void Out_txt(int i,datetime t, double pr,string s, color col, int TF1, int anchor, int n)
{
   string name=pref+str_TF(TF1)+"_"+s+(string)i;
   if (ObjectFind(name))ObjectCreate(name,OBJ_TEXT,0,0,0);
      
   ObjectSetText(name,IntegerToString(n),10,"Arial Black");
   ObjectSet(name,OBJPROP_TIME1,t);
   ObjectSet(name,OBJPROP_PRICE1,pr);
   ObjectSet(name,OBJPROP_COLOR,col);
   ObjectSet(name,OBJPROP_WIDTH,1);
   ObjectSetInteger(0,name,OBJPROP_ANCHOR,anchor);
}
//------------------------------------
//+------------------------------------------------------------------+
int  BBU()
{//описание функции http://fxnow.ru/blog/programming_mql4/2.html
int i;bool err;
double sl;
   for( i=1; i<=OrdersTotal(); i++) {     
      if(OrderSelect(i-1,SELECT_BY_POS)==true) {
        if(OrderSymbol()==Symbol() && (OrderMagicNumber()==Magic || Magic == 0))
         {

            if(OrderType()==OP_BUY && (OrderStopLoss()<OrderOpenPrice() || OrderStopLoss()==0))
            {
                if(Bid-OrderOpenPrice()>=BBUSize*Point)
                 {
                    Print("ПОРА В БезуБыток");
                    sl = NormalizeDouble(OrderOpenPrice()+BBUSizepip*Point, Digits);
                    err=OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,clrCrimson);
                    if(err==false) return(-1);
                }//if(Bid
            }//if(OrderType()
            
            if(OrderType()==OP_SELL && (OrderStopLoss()>OrderOpenPrice() || OrderStopLoss()==0))
              {
                if(OrderOpenPrice()-Ask>=BBUSize*Point) {
                    Print("ПОРА В БезуБыток");
                    sl = NormalizeDouble(OrderOpenPrice()-BBUSizepip*Point,Digits);
                    err=OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,clrGreen);
                    if(err==false) return(-1);
                } //if(OrderOpenPrice()
            }//if(OrderType()
       
        }//if(OrderSymbol()
      }//if(OrderSelect(
    }// for( i=1;
    return(0);
}
void fTrailingWithStart()
  {
   double slts;
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==OP_BUY)
              {
               RefreshRates();
               if(ND(Bid-OrderOpenPrice())>=ND(Point*TrailingStopStart))
                 {
                  slts=ND(Bid-Point*TrailingStop);
                  if(ND(OrderStopLoss())<slts)
                    {
                     if(!IsTradeContextBusy())
                       {
                        if(!OrderModify(OrderTicket(),OrderOpenPrice(),slts,OrderTakeProfit(),0,CLR_NONE))
                          {
                          // Print("Error trailingstop BUY "+OrderTicket()+" "+fMyErDesc(GetLastError()));
                          }
                       }
                     else
                       {
                        static int lt1=0;
                        if(lt1!=iTime(NULL,TF,0))
                          {
                          // lt1=iTime(NULL,TF,0);
                           //Print("Need trailingstop BUY "+OrderTicket()+". Trade Context Busy");
                          }
                       }
                    }
                 }
              }
            if(OrderType()==OP_SELL)
              {
               RefreshRates();
               if(ND(OrderOpenPrice()-Ask)>=ND(Point*TrailingStopStart))
                 {
                  slts=ND(Ask+Point*TrailingStop);
                  if(!IsTradeContextBusy())
                    {
                     if(ND(OrderStopLoss())>slts || ND(OrderStopLoss())==0)
                       {
                        if(!OrderModify(OrderTicket(),OrderOpenPrice(),slts,OrderTakeProfit(),0,CLR_NONE))
                          {
                           //Print("Error trailingstop SELL "+OrderTicket()+" "+fMyErDesc(GetLastError()));
                          }
                       }
                    }
                  else
                    {
                     static int lt2=0;
                     if(lt2!=iTime(NULL,TF,0))
                       {
                       // lt2=iTime(NULL,TF,0);
                       // Print("Need trailingstop SELL "+OrderTicket()+". Trade Context Busy");
                       }
                    }
                 }
              }
           }
        }
     }
  }

