Navigation:Home > Content >

Универсал_1.52.mq4

Time: 2018-06-18 | Download file:Универсал_1.52.mq4

//+------------------------------------------------------------------+
//|                                               Универсал_1.52.mq4 |
//|                                                            Drknn |
//|                   12.02.2007                       drknn@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Drknn"
#property link      "drknn@mail.ru"
#define MAGIC 5692576358
/*

            !!!!!!!!!!!!!! Внимание!!!!!!!!!!!!!
            
      В режиме отлова процента внесены изменения. Теперь вместо удаления ордеров будет выскакивать
      окно с сообщением, что заданный процент достигнут. И пользоваетль долже решать сам, что ему
      делать с образовавшимся порфитом.   

  Советник умеет:
- тралить ордера любого типа (как рыночные, так и отложенные)
- пипсовать
- Ловить увеличение депозита на нужное количество процентов и, поймав закрыть сделки
  по всем валютным парам и, если нужно, удалить и отложенные ордера.
- Устанавливать те отложенные ордера, которые разрешил пользователь, если советник вдруг
  обнаружит, что ордера такого в рынке нет (например, ордер сработал - стал рыночным - 
  или были удалены ордера после отлова процента)
- показывает на экране что и как у него настрено, чтоб каждый раз не лазить в настройки
 Советник задумывался как универсальный трейлинг, а всё остальное добавлено лишь для удобства.
 Ненужные функции можно легко отключить в окне свойств советника.
  Если пользователь разрешил советнику устанавливать отложенный ордер какого либо типа,
  то этот ордер будет установлен от текущей цены на расстоянии Step для ордеров данного типа.
*/

// ================ Параметры, настраиваимые пользователем ===========================
// ----- Параметры, общие для всех ордеров --------------------------------------------
extern double   Lot=1.0;//Лот для установки ордера
// ----- Разрешение установить тот или иной ордер ------------------------------------- 
extern string   VID="----------------------------------";
extern bool     Ustan_BuyStop=false;   //можно ли ставиь БайCтоп если в рынке такого у нас нет
extern bool     Ustan_SellLimit=false; //можно ли ставиь CеллЛимит если в рынке такого у нас нет
extern bool     Ustan_SellStop=false;  //можно ли ставиь CеллCстоп если в рынке такого у нас нет
extern bool     Ustan_BuyLimit=false;  //можно ли ставиь БайЛимит если в рынке такого у нас нет
// ----- Параметры рыночных ордеров ---------------------------------------------
extern string   RYNOCHNYE="----------------------------------";
extern int      ryn_TakeProfit=200; //Тейк-Профит  рыночного ордера 
extern int      ryn_StopLoss=100; //Стоп-Лосс  рыночного ордера
extern int      ryn_TrStop=100; //Трейлинг-Стоп рыночного ордера. Если = 0 то тарла нет
extern int      ryn_TrStep=10; //Шаг трала рыночного ордера
extern bool     WaitProfit = true; // Если true, то ждать профит = значению TrailingStop и только потом начинать тралить
                                    //Иначе, трейлинговать не дожидаясь положительного профита
// ----- Параметры стоповых ордеров ---------------------------------------------
extern string   STOPOVYE="----------------------------------";
extern int      st_Step=50;//Расстояние в пунктах от уровня текущей цены до уорвня установки стопового ордера
extern int      st_TakeProfit=200; //Тейк-Профит  стоповых ордеров
extern int      st_StopLoss=100; //Стоп-Лосс  стоповых ордеров
extern int      st_TrStop=0; //Трейлинг-Стоп стоповых ордеров. Если = 0 то тарла нет и st_TrStep не важен
extern int      st_TrStep=3; //Шаг трала стоповых ордеров

// ----- Параметры лимитных ордеров ---------------------------------------------
extern string   LIMITNYE="----------------------------------";
extern int      lim_Step=50;//Расстояние в пунктах от уровня текущей цены до уорвня установки лимитного ордера
extern int      lim_TakeProfit=200; //Тейк-Профит лимитных ордеров 
extern int      lim_StopLoss=100; //Стоп-Лосс лимитных ордеров
extern int      lim_TrStop=0; //Трейлинг-Стоп лимитных ордеров. Если = 0 то тарла нет и lim_TrStep не важен
extern int      lim_TrStep=3; //Шаг трейлинга лимитных ордеров

//------ Открыть (устаовить) ордера в заданное время ----------------------------------------------------------
extern string   ONLY_FOR_TIME="----------------------------------";
extern bool     UseTime=true;//вкл/выкл привязку к указанноу времени. Если=false, то все таймовые параметры не важны, 
                             // а именно, параметры: Hhour, Mminute, Popravka_Hhour, TIME_Buy, TIME_Sell, TIME_BuyStop,
                             // TIME_SellLimit, TIME_SellStop, TIME_BuyLimit.
extern int      Hhour=23;//терминальные часы совершения сделки
extern int      Mminute=59;//терминальные минуты совершения сделки
extern bool     TIME_Buy=false;//вкл/выкл открываться ли на покупку в заданное время
extern bool     TIME_Sell=false;//вкл/выкл открываться ли на продажу
extern bool     TIME_BuyStop=true;    //можно ли установить БайCтоп в заданное время
extern bool     TIME_SellLimit=false; //можно ли установить CеллЛимит в заданное время
extern bool     TIME_SellStop=true;   //можно ли установить CеллCстоп в заданное время
extern bool     TIME_BuyLimit=false;  //можно ли установить БайЛимит в заданное время

// ----- Параметры пипсовки ----------------------------------------------------
extern string   PIPSOVKA="----------------------------------";
extern int      PipsProfit=0; //профит при пипсовке можно ставить 1, 2, 3, ...
extern int      Proskalz = 3; //Проскальзывание в пунктах (нужно только когда PipsProfit>0)

// -----------   Отлавливаем увеличение депозита --------------------------
extern string   OTLOV="----------------------------------";
extern bool     Otlov=false;//отловить увеличение депозита на Pojmat процентов и закрыть все ордера
                             //если Otlov=false, то значениt Pojmat не важно.
extern double    Pojmat=2.0;//процент желаемого увеличения депозита

// ----- Прочие установки ------------------------------------------------------ 
extern string   OTHER="----------------------------------";
extern bool     UseOrderSound = true;  // Использовать звуковой сигнал для установки ордеров
extern bool     UseTrailingSound = true;  // Использовать звуковой сигнал для трейлинга
extern string   NameOrderSound  = "alert.wav";  // Наименование звукового файла для ордеров
extern string   NameTrallingSound  = "expert.wav";// Наименование звукового файла для трейлинга

// =======================================================================================

// ================== Глобальные переменные ===============================================================  
string     Comm1,Comm2,Comm3,Comm4,Comm5,Comm6,Comm7,Comm8,Comm9,ED; 
double     PNT,NewPrice,SL,TP,Balans,Free;
int        MinLevel,i,SchBuyStop,SchSellStop,SchBuyLimit,SchSellLimit,SchSell,SchBuy,SBid,SAsk,BBid,BAsk,Ts,GLE,total;
bool       fm,Rezult,TrailBuyStop,TrailSellStop,TrailBuyLimit,TrailSellLimit,SigBuy,SigSell,NewOrder;
bool       SigTIME_Buy,SigTIME_Sell,SigTIME_BuyStop,SigTIME_SellLimit,SigTIME_SellStop,SigTIME_BuyLimit;
// ========================================================================================================

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   if(!IsExpertEnabled())//если ложь 
   {Alert("Ошибка! Не нажата кнопка *Советники*"); Comment("Ошибка! Не нажата кнопка *Советники*"); return(0);}
   else {Comment("Как только цена изменится, Советник начнёт работу."); Print("Как только цена изменится, Советник начнёт работу.");}
   PNT=MarketInfo(Symbol(),MODE_POINT);//Размер пункта в валюте котировки. Для текущего инструмента хранится в предопределенной переменной Point
   MinLevel=MarketInfo(Symbol(),MODE_STOPLEVEL);//Минимально допустимый уровень стоп-лосса/тейк-профита в пунктах
   Proverka();
   
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----

RefreshRates();
//----Первичные проверки данных
if(!IsTradeAllowed())
{Comment("Торговля запрещена в настройках терминала, либо торговый поток занят");
return(0);}
Proverka();
//----Конец первичных проверок данных
 

if(ryn_TrStop>0 && ryn_TrStop>=MinLevel) Comm1="Трал рыночных - Вкл."; else Comm1="Трал рыночных - Откл.";
if (lim_TrStop>0 && lim_TrStop>=MinLevel) Comm2="Трал лимитных - Вкл."; else Comm2="Трал лимитных - Откл.";
if (st_TrStop>0 && st_TrStop>=MinLevel) Comm3="Трал стоповых - Вкл."; else Comm3="Трал стоповых - Откл.";
if (PipsProfit>0) Comm4="Пипсовка - Вкл"; else Comm4="Пипсовка - Откл";
double Otl=(Balans/100*Pojmat+Balans);
Otl=NormalizeDouble(Otl, 2);
Ts=MathCeil(Otl);
if (Otlov) {Comm5="Отлов процента - Вкл"; Comm6="Ловим сумму = "+Ts+" $";} else {Comm5="Отлов процента - Откл";Comm6="";}
SchOrders();
 Comment("Ордеров сейчас для ",Symbol()," :","\n","Buy = ",SchBuy,"       Sell = ",SchSell,"\n","BuyStop = ",SchBuyStop,
        "   SellLimit = ",SchSellLimit,"\n","SellStop = ",SchSellStop,"    BuyLimit = ",SchBuyLimit,"\n",Comm1,
        "\n",Comm2,"\n",Comm3,"\n",Comm4,"\n",Comm5,"\n",Comm6);


// ========================== Установка отложенных ордеров ====================================
if(Ustan_BuyStop || Ustan_SellLimit || Ustan_SellStop || Ustan_BuyLimit) {UstanOtlozh();}
//=============================================================================================

//==========================  Работа по заданному времени   =======================
 if(UseTime)
  {
      SigTIME_Buy=false;  SigTIME_BuyStop=false;   SigTIME_SellStop=false;
      SigTIME_Sell=false; SigTIME_SellLimit=false; SigTIME_BuyLimit=false;
   if(Hour()==Hhour && Minute()==Mminute)//если текущие час и минута совпадают
    {   
      if(TIME_Buy)
       {SigTIME_Buy=true; UstanRyn();}
      if(TIME_Sell)
       {SigTIME_Sell=true; UstanRyn();}
      if(TIME_BuyStop)
       {SigTIME_BuyStop=true; UstanOtlozh();}
      if(TIME_SellLimit)
       {SigTIME_SellLimit=true; UstanOtlozh();}
      if(TIME_SellStop)
       {SigTIME_SellStop=true; UstanOtlozh();} 
      if(TIME_BuyLimit)
       {SigTIME_BuyLimit=true; UstanOtlozh();}
    }
  }  
//==================================================================================

//============== Отлавливаем увеличение депозита на Pojmat процентов =========================

        if(Otlov)//Если разрешено отловить процент увеличения депозита
        {
          Balans=AccountBalance();//Баланс счёта
          Free=AccountEquity();//Текущее количество денег в статье "Средства"
          if ((Free-Balans)>=(Balans/100*Pojmat))//Если денег стало достаточно 
            {
              Print("Депозит увеличен на ",Pojmat," процентов.","\n","Суммарный профит = ",Free);
              Comment("Депозит увеличен на ",Pojmat," процентов.","\n","Суммарный профит = ",Free);
              Alert("Депозит увеличен на ",Pojmat," процентов.","\n","Суммарный профит = ",Free);
            }
        }
//============================================================================================



//=================Начало пипсовки==========================
if (PipsProfit>0)
{
int total = OrdersTotal();
   for (int i = 0; i=(OrderOpenPrice()+PipsProfit*Point))
                     {OrderClose(OrderTicket(),OrderLots(),Bid,Proskalz);}
                    
                  }
          if(OrderType()==OP_SELL)// если он открытый в продажу, то...
                  {
                     if(Ask<=(OrderOpenPrice() - PipsProfit*Point))
                     OrderClose(OrderTicket(),OrderLots(),Ask,Proskalz);
                  }
        
          } // конец работы с выбранным ордером  
        
          
     }// Конец цикла, мы просмотрели все ордера. ----------------------------------------------------------
}
//================Конец пипсовки ======================================



 
                      

// ================= Трейлинг Рыночных ордеров ==================================================================================
RefreshRates(); SchOrders();      
if(ryn_TrStop>=MinLevel && ryn_TrStep>0 && (SchBuy>0 || SchSell>0)) 
     {    
        for (i=0; i=MinLevel && ryn_TrStep==0)
 Alert("Трейлинг невозможен - ноль в настройках советника");
// ===============================================================================================================================

 
 

 
 
 //============ Трейлинг отложенных ордеров =============================================================
  
RefreshRates();  SchOrders();//Обновляем счётчики количества ордеров
   
 if((st_TrStop>0 && SchBuyStop+SchSellStop>0) || (SchBuyLimit+SchSellLimit>0 && lim_TrStop>0))
   {
    TrailBuyStop=false; TrailSellStop=false; TrailBuyLimit=false; TrailSellLimit=false;
  
  for (i=OrdersTotal()-1;i>=0;i--)//Цикл. Проходим по всем ордерам от 0 до total
     {//Начало цикла
       if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {WriteError();}
       if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true)// выбрали очередной ордер
         {//начало работы с выбранным ордером
           if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=MAGIC || OrderType()==OP_BUY || OrderType()==OP_SELL) continue; // Если не наш - смотрим следующий
           if(OrderType()==OP_BUYSTOP) // Он наверху и едет вниз
             {
              if(AskOrderOpenPrice()+(st_TrStop+st_TrStep)*Point)
              TrailSellStop=true;
             }
           if(OrderType()==OP_BUYLIMIT) // Он внизу и едет вверх
             {
              if(Ask>OrderOpenPrice()+(st_TrStop+st_TrStep)*Point)
              TrailBuyLimit=true;
             }
         }//конец работы с выбранным ордером 
      }//Конец цикла
 
 
 if (TrailSellLimit || TrailBuyLimit || TrailSellStop || TrailBuyStop)   TrailingOtlozh();
 
 
   }
 //====================================================================================================
 
 
 
 
//----
   return(0);
  }
//+ ========================== Конец работы советника ========================================================================== +



// ___________________________________________________________________________________________
//|                                                                                           |
//|                                                                                           |
//|                       Далее идут подпрограммы (функции),                                  |
//|                  которые в случае надобности вызываются из тела советника                 |
//|                                                                                           |
//|___________________________________________________________________________________________|



//===================== Установка отложенных ордеров ===========================================================================
// Функция UstanOtlozh() устанавливает нужный отложенный ордер 
//------------------------------------------------------------

// 

void UstanOtlozh()
{
 
RefreshRates(); SchOrders(); 

 if(SchSellStop==0 && ((Ustan_SellStop && st_Step>=MinLevel) || (SigTIME_SellStop && st_Step>=MinLevel)))
 {
                        NewPrice=Bid-st_Step*Point;
                        if(st_StopLoss==0) SL=0.0000;
                        else SL=NewPrice+st_StopLoss*Point;
                        if(st_TakeProfit==0) TP=0.0000;
                        else TP=NewPrice-st_TakeProfit*Point;
                        fm=OrderSend(Symbol(),OP_SELLSTOP,Lot,NewPrice,3,SL,TP,NULL,MAGIC,0,CLR_NONE);
/*Сигналим*/            if(fm!=0 && fm!=-1 && UseOrderSound) PlaySound(NameOrderSound);
/*Комментируем*/        if(fm!=0 && fm!=-1)
                         {
                          SigTIME_SellStop=false;
                          Print("Ордер SellStop установлен");
                          Comment("Ордер SellStop установлен");
                          Sleep(5000); RefreshRates();
                         }
                     
                        if(fm==0 || fm==-1)//Если установить не удалось
                        {
                        GLE=GetLastError();
                        ED=ErrorDescription(GLE);
                        Print("Ошибка № ",GLE," установки SellStop-ордера"); 
                        Print ("Описание ошибки - ",ED);
                        }
 
 }
 
  if(SchBuyStop==0 && ((Ustan_BuyStop && st_Step>=MinLevel) || (SigTIME_BuyStop && st_Step>=MinLevel)))
 {
                        NewPrice=Ask+st_Step*Point;
                        if(st_StopLoss==0) SL=0.0000;
                        else SL=NewPrice-st_StopLoss*Point;
                        if(st_TakeProfit==0) TP=0.0000;
                        else TP=NewPrice+st_TakeProfit*Point;
                        fm=OrderSend(Symbol(),OP_BUYSTOP,Lot,NewPrice,3,SL,TP,NULL,MAGIC,0,CLR_NONE);
/*Сигналим*/            if(fm!=0 && fm!=-1 && UseOrderSound) PlaySound(NameOrderSound);
/*Комментируем*/        if(fm!=0 && fm!=-1)
                         {
                          SigTIME_BuyStop=false;
                          Print("Ордер BuyStop установлен");
                          Comment("Ордер BuyStop установлен");
                          Sleep(5000); RefreshRates();
                         }
                     
                        if(fm==0 || fm==-1)//Если установить не удалось
                        {
                        GLE=GetLastError();
                        ED=ErrorDescription(GLE);
                        Print("Ошибка № ",GLE," установки BuyStop-ордера"); 
                        Print ("Описание ошибки - ",ED);
                        }
 
 }
 

  if(SchBuyLimit==0 && ((Ustan_BuyLimit && lim_Step>=MinLevel) || (SigTIME_BuyLimit && lim_Step>=MinLevel)))
 {
                        NewPrice=Ask-lim_Step*Point;
                        if(lim_StopLoss==0) SL=0.0000;
                        else SL=NewPrice-lim_StopLoss*Point;
                        if(lim_TakeProfit==0) TP=0.0000;
                        else TP=NewPrice+st_TakeProfit*Point;
                        fm=OrderSend(Symbol(),OP_BUYLIMIT,Lot,NewPrice,3,SL,TP,NULL,MAGIC,0,CLR_NONE);
/*Сигналим*/            if(fm!=0 && fm!=-1 && UseOrderSound) PlaySound(NameOrderSound);
/*Комментируем*/        if(fm!=0 && fm!=-1)
                          {
                           SigTIME_BuyLimit=false;
                           Print("Ордер BuyLimit установлен");
                           Comment("Ордер BuyLimit установлен");
                           Sleep(5000); RefreshRates();
                          }
                        if(fm==0 || fm==-1)//Если установить не удалось
                        {
                        GLE=GetLastError();
                        ED=ErrorDescription(GLE);
                        Print("Ошибка № ",GLE," установки BuyLimit-ордера"); 
                        Print ("Описание ошибки - ",ED);
                        }
 
 }
 
  if(SchSellLimit==0 && ((Ustan_SellLimit && lim_Step>=MinLevel) || (SigTIME_SellLimit && lim_Step>=MinLevel)))
 {
                        NewPrice=Bid+lim_Step*Point;
                        if(lim_StopLoss==0) SL=0.0000;
                        else SL=NewPrice+lim_StopLoss*Point;
                        if(lim_TakeProfit==0) TP=0.0000;
                        else TP=NewPrice-lim_TakeProfit*Point;
                        fm=OrderSend(Symbol(),OP_SELLLIMIT,Lot,NewPrice,3,SL,TP,NULL,MAGIC,0,CLR_NONE);
/*Сигналим*/            if(fm!=0 && fm!=-1 && UseOrderSound) PlaySound(NameOrderSound);
/*Комментируем*/        if(fm!=0 && fm!=-1)
                          {
                           SigTIME_SellLimit=false;
                           Print("Ордер SellLimit установлен");
                           Comment("Ордер SellLimit установлен");
                           Sleep(5000); RefreshRates();
                          }
                        if(fm==0 || fm==-1)//Если установить не удалось
                        {
                        GLE=GetLastError();
                        ED=ErrorDescription(GLE);
                        Print("Ошибка № ",GLE," установки SellLimit-ордера"); 
                        Print ("Описание ошибки - ",ED);
                        }
 
 }
}  
 //==============================================================================================================================

// =============== Открытие рыночных ордеров ===============================================================
//   Функция UstanRyn() открывает рыночные ордера
//------------------------------------------------ 
void UstanRyn()
{
  bool NewOrderSell,NewOrderBuy;
  int  OldTimeBuy,OldTimeSell;
      RefreshRates(); SchOrders();     
//==== Контроль времени последнего открытого ордера ============
//  Этот блок контроля нужен для того, чтобы на одной свече открывалась только одна сделка
//  Если в работе по заданному времени будет стоять разрешение открыть и Buy и Sell ордер,
//  то если советник успеет за тиками, он откроет обе сделки на одной сече 


   for ( i = OrdersTotal()-1; i>0; i-- )
     {//Начало цикла
       if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {WriteError();}
       if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true)// выбрали очередной ордер
         {//начало работы с выбранным ордером
          if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=MAGIC) {continue;} // Если не наш - смотрим следующий
          if(OrderType()==OP_BUY)
           {  
            if(OrderOpenTime()>=OldTimeBuy)//если время открытия у этого ордера больше чем у последнего открытого, то...
            {OldTimeBuy=OrderOpenTime();}//запоминаем время последнего открытого Buy-ордера
           }
          if(OrderType()==OP_SELL)
           {  
            if(OrderOpenTime()>=OldTimeSell)//если время открытия у этого ордера больше чем у последнего открытого, то...
            {OldTimeSell=OrderOpenTime();}//запоминаем время последнего открытого Sell-ордера
           }
         }//Конец работы с выбранным ордером
      }//Конец цикла  OldTimeBuy,OldTimeSell
      
      if(OldTimeBuy>=Time[0]) {NewOrderBuy=false;}
      if(OldTimeBuy=Time[0]) {NewOrderSell=false;}
      if(OldTimeSell=0;i--)//Цикл. Проходим по всем ордерам от 0 до total
     {//Начало цикла
       if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {WriteError();}
       if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))// выбрали очередной ордер
         {//начало работы с выбранным ордером
           if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=MAGIC) continue; // Если не наш - смотрим следующий
           if(OrderType()==OP_BUYSTOP) // если он BUYSTOP, то... 
              SchBuyStop++;//увеличиваем значение счётчиков на 1
           if(OrderType()==OP_SELLSTOP) // если он SELLSTOP, то... 
              SchSellStop++; //увеличиваем значение счётчиков на 1 
           if(OrderType()==OP_SELLLIMIT)
           SchSellLimit++;
           if(OrderType()==OP_BUYLIMIT)
           SchBuyLimit++;
           if(OrderType()==OP_BUY) // если он открытый в покупку, то... 
             SchBuy++;//увеличиваем значение счётчиков на 1
           if(OrderType()==OP_SELL)// если он открытый в продажу, то...
            SchSell++;//увеличиваем значение счётчиков на 1
         }//конец работы с выбранным ордером
      }//Конец цикла
}                  

//==========================================================================================================



//+------------------------------------------------------------------+
//| Сопровождение позиции простым тралом                             |
//+------------------------------------------------------------------+
void TrailingPositions()//Описание (объявление) пользовательской функции
{
  if(OrderType()==OP_BUY)//Если выбранный в цикле ордер в покупку 
   {
    
    if(!WaitProfit || (Bid-OrderOpenPrice())>ryn_TrStop*Point)
      {
        if (OrderStopLoss()ryn_TrStop*Point) {
      if(OrderStopLoss()>Ask+(ryn_TrStop+ryn_TrStep-1)*Point || OrderStopLoss()==0)
      {ModifyStopLoss(Ask+ryn_TrStop*Point);}
    }
  }
}

//+------------------------------------------------------------------+
//| Перенос уровня StopLoss                                          |
//| Параметры:                                                       |
//|   ldStopLoss - уровень StopLoss                                  |
//+------------------------------------------------------------------+
void ModifyStopLoss(double ldStopLoss)
{
 
  fm=OrderModify(OrderTicket(),OrderOpenPrice(),ldStopLoss,OrderTakeProfit(),0,CLR_NONE);
  if(fm!=0 && fm!=-1 && UseTrailingSound) PlaySound(NameTrallingSound);
  if(fm==0 || fm==-1) {ModifError();}
}
//+------------------------------------------------------------------+


//======== Подтягивание отложенного ордера вслед ценой  ============================================
// Функция TrailingOtlozh() подтягивает отложенный ордер вслед за ценой
//--------------------------------------------------------------------------------------------------

void TrailingOtlozh()
{  
   RefreshRates();
   for (i=OrdersTotal()-1;i>=0;i--)//Цикл. Проходим по всем ордерам
     {//Начало цикла
       if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {WriteError();}
       if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))// выбрали очередной ордер
         {//начало работы с выбранным ордером
           if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=MAGIC) {continue;} // Если не наш - смотрим следующий
           if(OrderType()==OP_BUYSTOP)//находится вверху, едет вниз
                {  
                     if(TrailBuyStop)
                      {   
                        NewPrice=Ask+st_TrStop*Point;
                        if(st_StopLoss==0) {SL=0.0000;}
                        else {SL=NewPrice-st_StopLoss*Point;}
                        if(st_TakeProfit==0) {TP=0.0000;}
                        else {TP=NewPrice+st_TakeProfit*Point;}
                        fm=OrderModify(OrderTicket(),NewPrice,SL,TP,0,CLR_NONE);
                        if(fm!=0 && fm!=-1 && UseTrailingSound) {PlaySound(NameTrallingSound);}
                        if(fm!=0 && fm!=-1) {Sleep(5000); RefreshRates();}
                        if(fm==0 || fm==-1) {ModifError();}
                      }
                }
                  
         
           if(OrderType()==OP_SELLSTOP) // Находится внизу, едет вверх
                  
                    { 
                      if(TrailSellStop)
                       {
                        NewPrice=Bid-st_TrStop*Point;
                        if(st_StopLoss==0) {SL=0.0000;}
                        else {SL=NewPrice+st_StopLoss*Point;}
                        if(st_TakeProfit==0) {TP=0.0000;}
                        else {TP=NewPrice-st_TakeProfit*Point;}
                        fm=OrderModify(OrderTicket(),NewPrice,SL,TP,0,CLR_NONE);
                        if(fm!=0 && fm!=-1 && UseTrailingSound) {PlaySound(NameTrallingSound);}
                        if(fm!=0 && fm!=-1) {Sleep(5000); RefreshRates();}
                        if(fm==0 || fm==-1)  {ModifError();}
                       } 
                    }
          if(OrderType()==OP_BUYLIMIT) // Находится внизу, едет вверх
                {  
                     if(TrailBuyLimit)
                      {   
                        NewPrice=Ask-st_TrStop*Point;
                        if(lim_StopLoss==0) {SL=0.0000;}
                        else {SL=NewPrice-lim_StopLoss*Point;}
                        if(lim_TakeProfit==0) {TP=0.0000;}
                        else {TP=NewPrice+lim_TakeProfit*Point;}
                        fm=OrderModify(OrderTicket(),NewPrice,SL,TP,0,CLR_NONE);
                        if(fm!=0 && fm!=-1 && UseTrailingSound) {PlaySound(NameTrallingSound);}
                        if(fm!=0 && fm!=-1) {Sleep(5000); RefreshRates();}
                        if(fm==0 || fm==-1) {ModifError();}
                      }
                }
                
          if(OrderType()==OP_SELLLIMIT)//находится вверху, едет вниз
                {  
                     if(TrailSellLimit)
                      {   
                        NewPrice=Bid+st_TrStop*Point;
                        if(lim_StopLoss==0) {SL=0.0000;}
                        else {SL=NewPrice+lim_StopLoss*Point;}
                        if(lim_TakeProfit==0) {TP=0.0000;}
                        else {TP=NewPrice-lim_TakeProfit*Point;}
                        fm=OrderModify(OrderTicket(),NewPrice,SL,TP,0,CLR_NONE);
                        if(fm!=0 && fm!=-1 && UseTrailingSound) {PlaySound(NameTrallingSound);}
                        if(fm!=0 && fm!=-1) {Sleep(5000); RefreshRates();}
                        if(fm==0 || fm==-1) {ModifError();}
                      }
                }
          
          
          
                                      
      }//конец работы с выбранным ордером
    
  }//Конец цикла
 
}//конец функции
//=========================================================================================

//========= Словестное описание ошибок =========================================================================================
// Функция возвращает не код ошибки а её словестное описание
//-----------------------------------------------------------
string ErrorDescription(int error_code)
     {
      string error_string;
   //----
      switch(error_code)
        {
         //---- codes returned from trade server
           case 0:    error_string=" Нет ошибки"; break;
           case 1:   error_string=" Нет ошибки, но результат неизвестен"; break;
           case 2:   error_string=" Общая ошибка"; break;
           case 3:    error_string=" Неправильные параметры"; break;
           case 4:    error_string=" Торговый сервер занят"; break;
           case 5:    error_string=" Старая версия клиентского терминала"; break;
           case 6:    error_string=" Нет связи с торговым сервером"; break;
           case 7:    error_string=" Недостаточно прав"; break;
           case 8:    error_string=" Слишком частые запросы"; break;
           case 9:    error_string=" Недопустимая операция нарушающая функционирование сервера"; break;
           case 64:    error_string=" Счет заблокирован"; break;
           case 65:    error_string=" Неправильный номер счета"; break;
           case 128:    error_string=" Истек срок ожидания совершения сделки"; break;
           case 129:    error_string=" Неправильная цена"; break;
           case 130:    error_string=" Неправильные стопы"; break;
           case 131:    error_string=" Неправильный объем"; break;
           case 132:    error_string=" Рынок закрыт"; break;
           case 133:    error_string=" Торговля запрещена"; break;
           case 134:    error_string=" Недостаточно денег для совершения операции"; break;
           case 135:    error_string=" Цена изменилась"; break;
           case 136:    error_string="  Нет цен"; break;
           case 137:    error_string=" Брокер занят"; break;
           case 138:    error_string=" Новые цены"; break;
           case 139:    error_string=" Ордер заблокирован и уже обрабатывается"; break;
           case 140:    error_string="  Разрешена только покупка"; break;
           case 141:    error_string="  Слишком много запросов"; break;
           case 145:    error_string=" Модификация запрещена, так как ордер слишком близок к рынку"; break;
           case 146:    error_string="  Подсистема торговли занята"; break;
           case 147:    error_string=" Использование даты истечения ордера запрещено брокером"; break;
           case 148:    error_string=" Количество открытых и отложенных ордеров достигло предела, установленного брокером"; break;
           case 4000:    error_string=" Нет ошибки"; break;
           case 4001:    error_string="  Неправильный указатель функции"; break;
           case 4002:    error_string="  Индекс массива - вне диапазона"; break;
           case 4003:    error_string="  Нет памяти для стека функций"; break;
           case 4004:    error_string=" Переполнение стека после рекурсивного вызова"; break;
           case 4005:    error_string=" На стеке нет памяти для передачи параметров"; break;
           case 4006:    error_string="  Нет памяти для строкового параметра"; break;
           case 4007:    error_string=" Нет памяти для временной строки"; break;
           case 4008:    error_string=" Неинициализированная строка"; break;
           case 4009:    error_string=" Неинициализированная строка в массиве"; break;
           case 4010:    error_string=" Нет памяти для строкового массива"; break;
           case 4011:    error_string="  Слишком длинная строка"; break;
           case 4012:    error_string=" Остаток от деления на ноль"; break;
           case 4013:    error_string="  Деление на ноль"; break;
           case 4014:    error_string=" Неизвестная команда"; break;
           case 4015:    error_string="  Неправильный переход"; break;
           case 4016:    error_string=" Неинициализированный массив"; break;
           case 4017:    error_string=" Вызовы DLL не разрешены"; break;
           case 4018:    error_string=" Невозможно загрузить библиотеку"; break;
           case 4019:    error_string=" Невозможно вызвать функцию"; break;
           case 4020:    error_string=" Вызовы внешних библиотечных функций не разрешены"; break;
           case 4021:    error_string=" Недостаточно памяти для строки, возвращаемой из функции"; break;
           case 4022:    error_string=" Система занята"; break;
           case 4050:    error_string=" Неправильное количество параметров функции"; break;
           case 4051:    error_string=" Недопустимое значение параметра функции"; break;
           case 4052:    error_string=" Внутренняя ошибка строковой функции"; break;
           case 4053:    error_string=" Ошибка массива"; break;
           case 4054:    error_string=" Неправильное использование массива-таймсерии"; break;
           case 4055:    error_string=" Ошибка пользовательского индикатора"; break;
           case 4056:    error_string=" Массивы несовместимы"; break;
           case 4057:    error_string=" Ошибка обработки глобальныех переменных"; break;
           case 4058:    error_string=" Глобальная переменная не обнаружена"; break;
           case 4059:    error_string=" Функция не разрешена в тестовом режиме"; break;
           case 4060:    error_string=" Функция не подтверждена"; break;
           case 4061:    error_string=" Ошибка отправки почты"; break;
           case 4062:    error_string=" Ожидается параметр типа string"; break;
           case 4063:    error_string=" Ожидается параметр типа integer"; break;
           case 4064:    error_string=" Ожидается параметр типа double"; break;
           case 4065:    error_string=" В качестве параметра ожидается массив"; break;
           case 4066:    error_string=" Запрошенные исторические данные в состоянии обновления"; break;
           case 4067:    error_string=" Ошибка при выполнении торговой операции"; break;
           case 4099:    error_string=" Конец файла"; break;
           case 4100:    error_string=" Ошибка при работе с файлом"; break;
           case 4101:    error_string=" Неправильное имя файла"; break;
           case 4102:    error_string=" Слишком много открытых файлов"; break;
           case 4103:    error_string=" Невозможно открыть файл"; break;
           case 4104:    error_string=" Несовместимый режим доступа к файлу"; break;
           case 4105:    error_string=" Ни один ордер не выбран"; break;
           case 4106:    error_string=" Неизвестный символ"; break;
           case 4107:    error_string=" Неправильный параметр цены для торговой функции"; break;
           case 4108:    error_string=" Неверный номер тикета"; break;
           case 4109:    error_string=" Торговля не разрешена"; break;
           case 4110:    error_string=" Длинные позиции не разрешены"; break;
           case 4111:    error_string=" Короткие позиции не разрешены"; break;
           case 4200:    error_string=" Объект уже существует"; break;
           case 4201:    error_string=" Запрошено неизвестное свойство объекта"; break;
           case 4202:    error_string=" Объект не существует"; break;
           case 4203:    error_string=" Неизвестный тип объекта"; break;
           case 4204:    error_string=" Нет имени объекта"; break;
           case 4205:    error_string=" Ошибка координат объекта"; break;
           case 4206:    error_string=" Не найдено указанное подокно"; break;
           case 4207:    error_string=" Ошибка при работе с объектом"; break;
           
           
           
        }
   //----
      return(error_string);
     }
//===============================================================================================================================

// ======================= Вызов номера и описания ошибки выбора  ==========================================
//   Функция WriteError() пишет номер возникшей ошибки выбора и её русское описание
// --------------------------------------------------------------------------------

void WriteError()
{
 GLE=GetLastError();
 ED=ErrorDescription(GLE);
 Print("Ошибка ", GLE, " при выборе ордера номер ",i);
 Print ("Описание ошибки - ",ED);
}
// =========================================================================================================


// ======================= Ошибка модификации =====================================================
//  Функция ModifError() пишет номер возникшей ошибки модификации и её русское описание
// ------------------------------------------------------------------------------------
void ModifError()
{
GLE=GetLastError();
ED=ErrorDescription(GLE);
Print("Модификация SellLimit-ордера № ",OrderTicket(), " вернула ошибку № ",GLE);
Print ("Описание ошибки: ",ED);
}
// ================================================================================================


// ======================= Проверка корректности пользовательских установок =============================================
void Proverka()
{
if(ryn_TrStop

Recommend