//+------------------------------------------------------------------+
//|                                                   my_m_v1_03.mq4 |
//|                                           Copyright 2015, PavelG |
//|                                                                  |
//+------------------------------------------------------------------+

// 06.11.2015 - можно установить ТП последнего ордера отличный от остальных
// 28.06.2015 - Исправлены неточности. Добавлена выводимая информация (Мин.лот, открытый лот, открытое кол-во, плечо)

#property copyright "Copyright 2015,PavelG"
#property link      ""
#property version   "1.03"


extern int magic = 100;
extern bool open_buy=true;
extern bool open_buylmt=true;
extern bool open_sell=true;
extern bool open_selllmt=true;
extern int typeorder=2; //0-buy, 1-sell, 2-все
extern double Lots = 0.01; // начальный лот (минимальный для ММ)
extern bool lotmm = true;
extern int minlotmoney = 6000;
extern double k_lot=1.9;   // увеличение объема ~ 1.5-2;
extern int kn=12;
extern int n_lm=3;
extern double prf_plus=1200; // от нейтр. до уровня профита // ~ 40-50 пт.
extern double prf_plus_end=1200; //профит для последнего ордена
extern double stp=10000;
extern double chag=750;     // начальный шаг  //31  ~ 30-37
extern string gsname = "my_m_v1_03";
extern int pausa=0;
extern int MaxAttempts = 5;
extern int slip = 30;
extern bool UseSound = false;
extern string SoundSuccess = "ok.wav";
extern string SoundError = "alert.wav";
extern color clOpenBuy = clrBlue;
extern color clOpenSell = clrRed;
extern color clStop = clrRed;
extern color clDelete = clrYellow;
extern color   FontColor   = clrSilver;
extern int     FontSize    = 14;
extern string  FontType    = "Calibri";//"Comic Sans MS";
extern int     WhatCorner  = 2;
extern int     Win         = 0;//в каком окне отображать
extern double  xx          = 5;//позиция окна
extern double  yy          = 35;//позиция окна
extern int     zz          = 20;//смещение следующего окна  

#include <stdlib.mqh>        	// Стандартная библиотека МТ4

/*
extern string _a1 =  "==================================================================================";
extern string  _useexit      = "Параметры закрытия поз";
extern bool    useexit       = false;
extern int     TypeofClose   = 2; // 1 - по достижению количества пунктов
                                // 2 - по проценту от депозита
                                // 3 - сумма профита;
extern double  PointForClose = 2.0; // величина ПП, %%, $$ соответственно ... для выхода
extern int kn1 = 9;
*/

bool    useexit       = false;
int     TypeofClose   = 2; // 1 - по достижению количества пунктов
                                // 2 - по проценту от депозита
                                // 3 - сумма профита;
double  PointForClose = 2.0; // величина ПП, %%, $$ соответственно ... для выхода
int kn1 = 9;

/*
extern bool use_chag_delta = false; // true - использование шага, определенного пользователем
                                    // false - как было (фиксированный шаг - chag)
extern double s2 = 750; // расстояние от 1 до 2 ордера (если 0 или меньше, лимитник и следующие не ставятся...)
extern double s3 = 750; // расстояние от 2 до 3 ордера
extern double s4 = 750; // расстояние от 3 до 4 ордера
extern double s5 = 750; // расстояние от 4 до 5 ордера
extern double s6 = 750; // расстояние от 5 до 6 ордера
extern double s7 = 750; // расстояние от 6 до 7 ордера
extern double s8 = 750; // расстояние от 7 до 8 ордера
extern double s9 = 750; // расстояние от 8 до 9 ордера
extern double s10 = 750; // расстояние от 9 до 10 ордера
extern double s11 = 750; // расстояние от 10 до 11 ордера
extern double s12 = 750; // расстояние от 11 до 12 ордера
//extern double lot_max=100; // максимальный лот
*/

bool use_chag_delta = false; // true - использование шага, определенного пользователем
                                    // false - как было (фиксированный шаг - chag)
double s2 = 750; // расстояние от 1 до 2 ордера (если 0 или меньше, лимитник и следующие не ставятся...)
double s3 = 750; // расстояние от 2 до 3 ордера
double s4 = 750; // расстояние от 3 до 4 ордера
double s5 = 750; // расстояние от 4 до 5 ордера
double s6 = 750; // расстояние от 5 до 6 ордера
double s7 = 750; // расстояние от 6 до 7 ордера
double s8 = 750; // расстояние от 7 до 8 ордера
double s9 = 750; // расстояние от 8 до 9 ордера
double s10 = 750; // расстояние от 9 до 10 ордера
double s11 = 750; // расстояние от 10 до 11 ордера
double s12 = 750; // расстояние от 11 до 12 ордера

//bool MarketWatch = false;
double minStop;
int y;
string nnn, nnn1;
bool glcloseb = false, glcloses = false;
double Gda_300[2];
double GLOT[2];
int G_slippage_304;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
//---
   if (!IsTradeAllowed()) 
   {
      Message("Для нормальной работы советника необходимо\n"+
               "Разрешить советнику торговать");
      return(INIT_FAILED);
   }
   if (!IsLibrariesAllowed()) 
   {
      Message("Для нормальной работы советника необходимо\n"+
            "Разрешить импорт из внешних экспертов");
      return(INIT_FAILED);;
   }
   if (!IsTesting()) 
   {
      if (!IsConnected())
      {
         Message("Ожидание соединения");
         while (true)
         {
            if (IsConnected()) break;
         }
      }
      if (pausa>0) {Message("Пауза в инициализации "+DoubleToStr(pausa/1000,0)+" секунд"); Sleep(pausa);}
      if (!IsConnected())
      {
         Message("Ожидание соединения");
         while (true)
         {
            if (IsConnected()) break;
         }
      }
      if (IsExpertEnabled()) { Message("Советник будет запущен следующим тиком");  }
      else { Message("Отжата кнопка \"Разрешить запуск советников\""); }
   }

   minStop=MarketInfo(Symbol(),MODE_STOPLEVEL);
   
   if(lotmm)
   {
      nnn = "LMM1";
      ObjectCreate(nnn, OBJ_LABEL, Win, 0, 0);
      ObjectSet(nnn, OBJPROP_CORNER, WhatCorner);
      ObjectSet(nnn, OBJPROP_XDISTANCE, xx);
      ObjectSet(nnn, OBJPROP_YDISTANCE, yy);
   }

   nnn1 = "LMM2";
   ObjectCreate(nnn1, OBJ_LABEL, Win, 0, 0);
   ObjectSet(nnn1, OBJPROP_CORNER, WhatCorner);
   ObjectSet(nnn1, OBJPROP_XDISTANCE, xx);
   ObjectSet(nnn1, OBJPROP_YDISTANCE, yy+zz);


//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
   Comment("");
   if(lotmm)
   {
      if(ObjectFind(nnn)>-1) ObjectDelete(nnn);
   }
   if(ObjectFind(nnn1)>-1) ObjectDelete(nnn1);
   return;
//---   
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   Comment("");

   int y_sel, y_buy, y_slm, y_blm, tick_s, tick_b, tick_slm, tick_blm, oo, kk;
   double lots_b, lots_s, lots_blm, lots_slm;
   double price_b, price_s, price_blm, price_slm;
   double tkprof_b, tkprof_s, tkprof_blm, tkprof_slm;
   int chag_buy, chag_sel;
   double st, pf, prc, lot;
   double stp_b, stp_s;
   double llot;
   string opis1;
   
   GLOT[0]=0.0;
   GLOT[1]=0.0;
   
   if(lotmm)
   {
      llot = normlot(MathMax(AccountBalance(),AccountEquity())*Lots/minlotmoney);
      if(llot < MarketInfo(Symbol(),MODE_MINLOT)) llot = MarketInfo(Symbol(),MODE_MINLOT);
      opis1 = "Мин. лот = "+DoubleToStr(llot,2);
      if(ObjectFind(nnn)>-1) ObjectSetText(nnn, opis1, FontSize, FontType, FontColor);
   }
   else
      llot = Lots;   

   int lnkolordb = 0, lnkolords = 0;
   lnkolordb = f0_1();
   lnkolords = f0_0();

   opis1 = "Buy = "+DoubleToStr(lnkolordb,0)+" / "+DoubleToStr(GLOT[0],2)+" Sell = "+DoubleToStr(lnkolords,0)+" / "+DoubleToStr(GLOT[1],2)+" Плечо = 1:"+DoubleToStr(AccountInfoInteger(ACCOUNT_LEVERAGE),0);
   if(ObjectFind(nnn1)>-1) ObjectSetText(nnn1, opis1, FontSize, FontType, FontColor);

   if (useexit)
   {
      if (lnkolordb == 0) glcloseb = false;
      if (glcloseb == true)
      {
         f0_5(0);
         return;
      }
      if (lnkolords == 0) glcloses = false;
      if (glcloses == true)
      {
         f0_5(1);
         return;
      }
      if (lnkolordb > kn1 && f0_9() >= PointForClose && (typeorder==0 || typeorder==2))
      { 
         f0_5(0);
         glcloseb = true;
      }
      if (lnkolords > kn1 && f0_9() >= PointForClose && (typeorder==1 || typeorder==2))
      { 
         f0_5(1);
         glcloses = true;
      }
   }

//==================// проверка установки ТП и СЛ у лимитников //===========================//  
   for (y=0;y<OrdersTotal();y++)
   {
      if(OrderSelect(y,SELECT_BY_POS,MODE_TRADES))
      {
         if(Symbol()!=OrderSymbol()||OrderMagicNumber()!=magic) continue;
         if(OrderType()==OP_BUYLIMIT || OrderType()==OP_SELLLIMIT)
         {
            if(OrderType()==OP_BUYLIMIT && (typeorder==0 || typeorder==2))
            {
               st=NormalizeDouble(OrderStopLoss(),Digits); 
               pf=NormalizeDouble(OrderTakeProfit(),Digits);
               if(st==0.0 || pf==0.0)
               {
                  if(st==0.0)
                  {
                     if(OrderType()==OP_BUYLIMIT) st=OrderOpenPrice()-stp*Point;
                     if(OrderType()==OP_SELLLIMIT) st=OrderOpenPrice()+stp*Point;
                  }
                  if(pf==0.0)
                  {
                     if(OrderType()==OP_BUYLIMIT) pf=OrderOpenPrice()+prf_plus*Point;
                     if(OrderType()==OP_SELLLIMIT) pf=OrderOpenPrice()-prf_plus*Point;
                  }
                  if(ModifyOrder(OrderOpenPrice(), st, pf)==false) return;
               }
            }
            if(OrderType()==OP_SELLLIMIT && (typeorder==1 || typeorder==2))
            {
               st=NormalizeDouble(OrderStopLoss(),Digits); 
               pf=NormalizeDouble(OrderTakeProfit(),Digits);
               if(st==0.0 || pf==0.0)
               {
                  if(st==0.0)
                  {
                     if(OrderType()==OP_BUYLIMIT) st=OrderOpenPrice()-stp*Point;
                     if(OrderType()==OP_SELLLIMIT) st=OrderOpenPrice()+stp*Point;
                  }
                  if(pf==0.0)
                  {
                     if(OrderType()==OP_BUYLIMIT) pf=OrderOpenPrice()+prf_plus*Point;
                     if(OrderType()==OP_SELLLIMIT) pf=OrderOpenPrice()-prf_plus*Point;
                  }
                  if(ModifyOrder(OrderOpenPrice(), st, pf)==false) return;
               }
            }
         }
      }
   }

   int total=OrdersTotal();
   for (y=0;y<total;y++)
   {
      oo=OrderSelect(y,SELECT_BY_POS,MODE_TRADES);
      if(Symbol()!=OrderSymbol()||OrderMagicNumber()!=magic) continue;      
//      if (OrderType()==OP_BUY) 
//      if (OrderType()==OP_SELL) y_sel++;

      if (OrderType()==OP_BUY) 
      {
         y_buy++;
         if (lots_b<OrderLots())
         {
            tick_b=OrderTicket();
            price_b=OrderOpenPrice();
            lots_b=OrderLots();
            tkprof_b=OrderTakeProfit();
            stp_b=OrderStopLoss(); 
         }
      }
      
      if (OrderType()==OP_SELL) 
      {
         y_sel++;
         if (lots_s<OrderLots())
         {
            tick_s=OrderTicket();
            price_s=OrderOpenPrice();
            lots_s=OrderLots();
            tkprof_s=OrderTakeProfit();
            stp_s=OrderStopLoss(); 
         }
      }     
 
      if (OrderType()==OP_BUYLIMIT)
      {
         y_blm++;
         if ( lots_blm<OrderLots())
         {
            tick_blm = OrderTicket();
            price_blm=OrderOpenPrice();
            lots_blm=OrderLots();
            tkprof_blm=OrderTakeProfit();
         }
      }
      
      if (OrderType()==OP_SELLLIMIT)
      {
         y_slm++;
         if ( lots_slm<OrderLots())
         {
            tick_slm = OrderTicket();
            price_slm=OrderOpenPrice();
            lots_slm=OrderLots();
            tkprof_slm=OrderTakeProfit();
         }
      }
   } 
   
   chag_sel=chag; chag_buy=chag;
   
   //==================// для open buy
   if(tick_b==0)
   { 
      if(tick_blm!=0)
      {
         if (y_blm > 0 && (typeorder==0 || typeorder==2))
         {
            if (DeleteOrders(Symbol(), OP_BUYLIMIT, magic)) y_blm = 0;
            else return;
         }
      }     // open_buy
      if(open_buy)
      {
         kk = OpenPosition(Symbol(), OP_BUY,llot, 0, 0, magic);
         if(kk>0)
         {
            if (OrderSelect(kk,SELECT_BY_TICKET))
            {
               y_buy++; 
               st=OrderOpenPrice()-stp*Point; 
               pf=OrderOpenPrice()+prf_plus*Point; 
               ModifyOrder(OrderOpenPrice(), st, pf);
               tick_b = kk;
               tkprof_b=pf;//OrderTakeProfit();
               stp_b=st;//OrderStopLoss();
            }
         }  // для kk>0           
         else
            return;
      }  // для open_buy
   }  // для tick_b==0

   //==================// для open sell
   if(tick_s==0)
   { 
      if(tick_slm!=0)
      {
         if (y_slm>0 && (typeorder==1 || typeorder==2))
         {
            if (DeleteOrders(Symbol(), OP_SELLLIMIT, magic)) y_slm=0;
            else return;
         }
      }     // open_sell
      if(open_sell)
      {
         kk = OpenPosition(Symbol(), OP_SELL, llot, 0, 0, magic);
         if(kk>0)
         {
            if (OrderSelect(kk,SELECT_BY_TICKET))
            {
               y_sel++;
               st=OrderOpenPrice()+stp*Point; 
               pf=OrderOpenPrice()-prf_plus*Point; 
               ModifyOrder(OrderOpenPrice(), st, pf); 
               tick_s = kk;
               tkprof_s=pf;//OrderTakeProfit();
               stp_s=st;//OrderStopLoss(); 
            }
         }  // для kk>0           
         else return;
      }  // для open_sell
   }  // для tick_s==0

// байлимиты
   for (y=1;y<=n_lm;y++)
   {
// 1 байлимит
      if(tick_b>0&&y_blm<n_lm&&(y_buy+y_blm)<kn&&open_buylmt)
      { 
         prc=0;
         if(y_blm>0)
         {
            if(OrderSelect(tick_blm,SELECT_BY_TICKET))
            {
               if (OrderCloseTime()==0)
               {
                  if(use_chag_delta==false)
                     prc=OrderOpenPrice()-chag_buy*Point;
                  else
                     prc=GetPrc(OrderOpenPrice(),y_buy+y_blm,0);
                  if(y_buy+y_blm+1==kn)
                     pf=prc+prf_plus_end*Point;
                  else
                     pf=prc+prf_plus*Point;
                  st=prc-stp*Point;
                  lot=normlot(OrderLots()*k_lot);
               }
            }
         }
         else
         {
            if(OrderSelect(tick_b,SELECT_BY_TICKET))
            {
               if (OrderCloseTime()==0)
               {
                  if(use_chag_delta==false)
                     prc=OrderOpenPrice()-chag_buy*Point;
                  else
                     prc=GetPrc(OrderOpenPrice(),y_buy+y_blm,0);
                  if(y_buy+y_blm+1==kn)
                     pf=prc+prf_plus_end*Point;
                  else
                     pf=prc+prf_plus*Point;
                  st=prc-stp*Point;
                  lot=normlot(OrderLots()*k_lot);
                  if (lot==0.01) lot=0.02;
               }
            }
         }
         if (prc>0)
         {
            kk = OpenPosition(Symbol(), OP_BUYLIMIT, lot, 0, 0, magic, prc);
            if(kk>0)
            {
               if (OrderSelect(kk,SELECT_BY_TICKET))
               {
                  ModifyOrder(OrderOpenPrice(), st, pf); 
                  tick_blm = OrderTicket();
                  price_blm=OrderOpenPrice();
                  lots_blm=OrderLots();
                  tkprof_blm=OrderTakeProfit();
                  y_blm++;
               }
            }  // для kk>0
            else return;
         }
      }
   }

//селлимиты
   for (y=1;y<n_lm;y++)
   {
   // 1 селлимит
      if(tick_s>0&&y_slm<n_lm&&(y_sel+y_slm)<kn&&open_selllmt)
      { 
         prc=0;
         if(y_slm>0)
         {
            if(OrderSelect(tick_slm,SELECT_BY_TICKET))
            {
               if (OrderCloseTime()==0)
               {
                  if(use_chag_delta==false)
                     prc=OrderOpenPrice()+chag_sel*Point;
                  else
                     prc=GetPrc(OrderOpenPrice(),y_buy+y_blm,1);
                  if(y_sel+y_slm+1==kn)
                     pf=prc-prf_plus_end*Point;
                  else
                     pf=prc-prf_plus*Point;
                  st=prc+stp*Point;
                  lot=normlot(OrderLots()*k_lot);
               }
            }
         }
         else
         {
            if(OrderSelect(tick_s,SELECT_BY_TICKET))
            {
               if (OrderCloseTime()==0)
               {
                  if(use_chag_delta==false)
                     prc=OrderOpenPrice()+chag_sel*Point;
                  else
                     prc=GetPrc(OrderOpenPrice(),y_buy+y_blm,1);
                  if(y_sel+y_slm+1==kn)
                     pf=prc-prf_plus_end*Point;
                  else
                     pf=prc-prf_plus*Point;
                  st=prc+stp*Point;
                  lot=normlot(OrderLots()*k_lot);
                  if (lot==0.01) lot=0.02;
               }
            }
         }
         if (prc>0)
         {
            kk = OpenPosition(Symbol(), OP_SELLLIMIT, lot, 0, 0, magic, prc);
            if(kk>0)
            {
               if (OrderSelect(kk,SELECT_BY_TICKET))
               {
                  ModifyOrder(OrderOpenPrice(), st, pf); 
                  tick_slm = OrderTicket();
                  price_slm=OrderOpenPrice();
                  lots_slm=OrderLots();
                  tkprof_slm=OrderTakeProfit();
                  y_slm++;
               }
            }  // для kk>0
            else return;
         }
      }
   }   
//==================// модиф открытых buy ордеров //===========================//   
   
   for (y=0;y<OrdersTotal();y++)
   {
      oo = OrderSelect(y,0);
      if(Symbol()!=OrderSymbol()||OrderMagicNumber()!=magic) continue;
      st=NormalizeDouble(OrderStopLoss(),Digits); 
      pf=NormalizeDouble(OrderTakeProfit(),Digits);
      stp_b=NormalizeDouble(stp_b,Digits); 
      tkprof_b=NormalizeDouble(tkprof_b,Digits);
      stp_s=NormalizeDouble(stp_s,Digits); 
      tkprof_s=NormalizeDouble(tkprof_s,Digits);

      if(OrderType()==OP_BUY && tick_b!=0 && ((stp_b!=st && stp_b!=0.0)||(tkprof_b!=pf && tkprof_b!=0.0)) && 
         (open_buy || (open_buy==false && open_sell==false) || open_buylmt) && (typeorder==0 || typeorder==2)) 
      {
         ModifyOrder(OrderOpenPrice(), stp_b, tkprof_b);
      }
//==================// модиф открытых sell ордеров //===========================//  
      if(OrderType()==OP_SELL && tick_s!=0 && ((stp_s!=st && stp_s!=0.0)||(tkprof_s!=pf && tkprof_s!=0.0)) &&
         (open_sell || (open_buy==false && open_sell==false) || open_selllmt) && (typeorder==1 || typeorder==2) ) 
      {
         ModifyOrder(OrderOpenPrice(), stp_s, tkprof_s);
      }
   }

   return;
}
//+------------------------------------------------------------------+

int OpenPosition(string sy, int op, double ll, double sl=0, double tp=0, int mn=0, double pr=0) 
{
   color    clOpen;
   datetime ot;
   double   pp, pa, pb;
   int      dg, err, it, ticket=0;
   string   lsComm=gsname+" "+DoubleToStr(magic,0);
 
   if (sy=="" || sy=="0") sy=Symbol();
   if (op==OP_BUY) clOpen=clOpenBuy;
   if (op==OP_SELL) clOpen=clOpenSell;
   if (op==OP_BUYLIMIT) clOpen=clOpenBuy;
   if (op==OP_SELLLIMIT) clOpen=clOpenSell;
   for (it=1; it<=MaxAttempts; it++) 
   {
      if (!IsTesting() && IsStopped()) 
      {
         Print("OpenPosition(): Остановка работы функции");
         break;
      }
      while (!IsTradeAllowed()) Sleep(1000);
      dg=Digits;
      if(op==OP_BUY || op==OP_SELL)
      {
         pa=Ask;
         pb=Bid;
         if (op==OP_BUY) pp=pa; else pp=pb;
      }
      else
      {
         if(pr==0.0) break;
         pp=pr;
      }
      pp=NormalizeDouble(pp, dg);
      sl=NormalizeDouble(sl, dg);
      tp=NormalizeDouble(tp, dg);
      ot=TimeCurrent();
//      if (MarketWatch)
         ticket=OrderSend(sy, op, ll, pp, slip, 0, 0, lsComm, mn, 0, clOpen);
//      else
//         ticket=OrderSend(sy, op, ll, pp, slip, sl, tp, lsComm, mn, 0, clOpen);
      if (ticket>0) 
      {
         if (UseSound) PlaySound(SoundSuccess); 
         break;
      } 
      else 
      {
         err=GetLastError();
         if (pa==0 && pb==0) Message("Проверьте в Обзоре рынка наличие символа "+sy);
         // Вывод сообщения об ошибке
         Print("Error(",err,") opening position: ",ErrorDescription(err)," try ",it);
         Print("Ask=",pa," Bid=",pb," sy=",sy," ll=",ll," op=",GetNameOP(op),
            " pp=",pp," sl=",sl," tp=",tp," mn=",mn);
         // Блокировка работы советника
         if (err==2 || err==64 || err==65 || err==133) 
         {
            break;
         }
         // Длительная пауза
         if (err==4 || err==131 || err==132) 
         {
            Sleep(1000); 
            break;
         }
         if (err==128 || err==142 || err==143) 
         {
            Sleep(1000);
            if (ExistPositions(sy, op, mn, ot)) 
            {
               if (UseSound) PlaySound(SoundSuccess); 
               break;
            }
         }
         if (err==140 || err==148 || err==4110 || err==4111) break;
         if (err==141) Sleep(1000);
         if (err==145) Sleep(1000);
         if (err==146) while (IsTradeContextBusy()) Sleep(1000);
         if (err!=135) Sleep(1000);
      }
      RefreshRates();
   }
//   if (MarketWatch && ticket>0 && (sl>0 || tp>0)) 
//   {
//      if (OrderSelect(ticket, SELECT_BY_TICKET)) ModifyOrder(-1, sl, tp);
//   }
   return (ticket);
}

bool ModifyOrder(double pp=-1, double sl=0, double tp=0, datetime ex=0) 
{
   double op, pa, pb, os, ot;
   int    dg=Digits, er, it;
   bool   fm=true;
   
   if (pp<=0) pp=OrderOpenPrice();
   if (sl<0 ) sl=OrderStopLoss();
   if (tp<0 ) tp=OrderTakeProfit();
  
   pp=NormalizeDouble(pp, dg);
   sl=NormalizeDouble(sl, dg);
   tp=NormalizeDouble(tp, dg);
   op=NormalizeDouble(OrderOpenPrice() , dg);
   os=NormalizeDouble(OrderStopLoss()  , dg);
   ot=NormalizeDouble(OrderTakeProfit(), dg);

   if (pp!=op || sl!=os || tp!=ot) 
   {
      for (it=1; it<=MaxAttempts; it++) 
      {
         if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
         while (!IsTradeAllowed()) Sleep(5000);
         RefreshRates();
         fm=OrderModify(OrderTicket(), pp, sl, tp, ex, clStop);
         if (fm) 
         {
            if (UseSound) PlaySound(SoundSuccess); 
            break;
         } 
         else 
         {
            er=GetLastError();
            if (UseSound) PlaySound(SoundError);
            pa=Ask;
            pb=Bid;
            Print("Error(",er,") modifying order: ",ErrorDescription(er),", try ",it);
            Print("Ask=",pa,"  Bid=",pb,"  sy=",OrderSymbol(),
              "  op="+GetNameOP(OrderType()),"  pp=",pp,"  sl=",sl,"  tp=",tp);
            Sleep(1000);
         }
      }
   }
   return (fm);
}

bool DeleteOrders(string sy="", int op=-1, int mn=-1) 
{
   bool fd = true;
   int err, i, it, k=OrdersTotal(), ot;
  
   if (sy=="0") sy=Symbol();
   for (i=k-1; i>=0; i--) 
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) 
      {
         ot=OrderType();
         if (ot>1 && ot<6) 
         {
            if ((OrderSymbol()==sy || sy=="") && (op<0 || ot==op)) 
            {
               if (mn<0 || OrderMagicNumber()==mn) 
               {
                  for (it=1; it<=MaxAttempts; it++) 
                  {
                     if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
                     while (!IsTradeAllowed()) Sleep(5000);
                     fd=OrderDelete(OrderTicket(), clDelete);
                     if (fd) 
                     {
                        if (UseSound) PlaySound(SoundSuccess); 
                        break;
                     } 
                     else 
                     {
                        err=GetLastError();
                        Print("Error(",err,") delete order ",GetNameOP(ot),
                           ": ",ErrorDescription(err),", try ",it);
                        Sleep(1000*5);
                     }
                  }
               }
            }
         }
      }
   }
   return (fd);
}

bool ExistPositions(string sy="", int op=-1, int mn=-1, datetime ot=0) 
{
  int i, k=OrdersTotal();

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) 
  {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) 
    {
      if (OrderSymbol()==sy || sy=="") 
      {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) 
        {
          if (op<0 || OrderType()==op) 
          {
            if (mn<0 || OrderMagicNumber()==mn) 
            {
              if (ot<=OrderOpenTime()) return(True);
            }
          }
        }
      }
    }
  }
  return(False);
}

double normlot(double ad) 
{
   double lotstep = MarketInfo(Symbol(), MODE_LOTSTEP);
   return (MathFloor(ad / lotstep + 0.5) * lotstep);
}

void Message(string m) 
{
  Comment(m);
  if (StringLen(m)>0) Print(m);
}

string GetNameOP(int op) 
{
   switch (op) 
   {
      case OP_BUY      : return("Buy");
      case OP_SELL     : return("Sell");
      case OP_BUYLIMIT : return("BuyLimit");
      case OP_SELLLIMIT: return("SellLimit");
      case OP_BUYSTOP  : return("BuyStop");
      case OP_SELLSTOP : return("SellStop");
      default          : return("Unknown Operation");
   }
}

int f0_1() 
{
   int count_0 = 0;
   for (int pos_4 = OrdersTotal() - 1; pos_4 >= 0; pos_4--) {
      if (OrderSelect(pos_4, SELECT_BY_POS, MODE_TRADES))
      {
         if (OrderSymbol() == Symbol())
         {
            if (OrderType() == OP_BUY) 
            {
               if (OrderMagicNumber() == magic)
               {
                  count_0++;
                  GLOT[0]=GLOT[0]+OrderLots();
               }
            }
         }
      }
   }
   return (count_0);
}

int f0_0() 
{
   int count_0 = 0;
   for (int pos_4 = OrdersTotal() - 1; pos_4 >= 0; pos_4--) {
      if (OrderSelect(pos_4, SELECT_BY_POS, MODE_TRADES))
      {
         if (OrderSymbol() == Symbol())
         {
            if (OrderType() == OP_SELL)
            {
               if (OrderMagicNumber() == magic)
               {
                  count_0++;
                  GLOT[1]=GLOT[1]+OrderLots();
               }
            }
         }
      }
   }
   return (count_0);
}

void f0_5(int tt = -1) 
{
   int Li_0 = OrdersTotal() - 1;

   for (int pos_4 = Li_0; pos_4 >= 0; pos_4--)
   {
      if (OrderSelect(pos_4, SELECT_BY_POS, MODE_TRADES) 
         && (OrderSymbol() == Symbol())
         && (OrderMagicNumber() == magic) 
         && OrderType() <= OP_SELL && f0_2()
         && (tt<0 || (tt==0 && OrderType()== OP_BUY) || (tt==1 && OrderType()==OP_SELL))) 
      {
         if(!OrderClose(OrderTicket(), OrderLots(), Gda_300[1 - OrderType()], G_slippage_304, clrYellow)) Print(f0_4());
         Sleep(200);
      }
   }

}

string f0_4() 
{
   int error_0 = GetLastError();
   return (StringConcatenate("Order:", OrderTicket(), " GetLastError()=", error_0, " ", ErrorDescription(error_0)));
}

int f0_2() {
   RefreshRates();
   Gda_300[0] = MarketInfo(OrderSymbol(), MODE_ASK);
   Gda_300[1] = MarketInfo(OrderSymbol(), MODE_BID);
   double point_0 = MarketInfo(OrderSymbol(), MODE_POINT);
   if (point_0 == 0.0) return (0);
   G_slippage_304 = (Gda_300[0] - Gda_300[1]) / point_0;
   return (Gda_300[0] > 0.0 && Gda_300[1] > 0.0);
}

double f0_9(int typer = -1) {
   double Ld_0;
   double Ld_8;
   double Ld_16;
//   double Ld_24;
   double Ld_32;
   double point_40;
   double Ld_48;
   double Ld_56;
   double Ld_64;
   double Ld_72 = 0.0;
   int Li_80;
   int Li_84;
   int Li_88;
   int TypeofClose1;
   if (typer > 0) TypeofClose1 = typer;
   else TypeofClose1 = TypeofClose;
   
   for (int pos_128 = 0; pos_128 < OrdersTotal(); pos_128++) 
   {
      if (OrderSelect(pos_128, SELECT_BY_POS, MODE_TRADES)) 
      {
         if (OrderSymbol() == Symbol()) 
         {
            if (OrderMagicNumber() == magic)
            {
               if (OrderType() == OP_SELL) {
                  point_40 = MarketInfo(OrderSymbol(), MODE_POINT);
                  Ld_0 = MathRound(MarketInfo(OrderSymbol(), MODE_ASK) / point_40);
                  Ld_16 = MathRound(OrderOpenPrice() / point_40);
                  Ld_56 += OrderProfit() + OrderSwap() + OrderCommission();
                  Li_88 += Ld_16 - Ld_0;
               }
               if (OrderType() == OP_BUY) {
                  point_40 = MarketInfo(OrderSymbol(), MODE_POINT);
                  Ld_8 = MathRound(MarketInfo(OrderSymbol(), MODE_BID) / point_40);
                  Ld_16 = MathRound(OrderOpenPrice() / point_40);
                  Ld_48 += OrderProfit() + OrderSwap() + OrderCommission();
                  Li_84 += Ld_8 - Ld_16;
               }
            }
         }
      }
   }
   Li_80 = Li_84 + Li_88;
   Ld_64 = Ld_48 + Ld_56;
//   Ld_24 = NormalizeDouble(100.0 * Ld_64 / AccountEquity(), 2);
   Ld_32 = NormalizeDouble(100.0 * Ld_64 / AccountBalance(), 2);

   switch (TypeofClose1) 
   {
      case 1:
//"пунктам";
         Ld_72 = Li_80;
         break;
         
      case 2:
//"%баланс";
         Ld_72 = Ld_32;
         break;
         
      case 3:
//"профит";
         Ld_72 = Ld_64;
         break;
         
//               case 4:
//"%эквити";
//                  Ld_72 = Ld_24;
//                  break;

      default:
//"НЕ УКАЗАНО";
         break;
   }
   return (Ld_72);
}

double GetPrc(double lvp=0.0, int lvkol=0, int lvtype=-1)
{
   double lnret = 0.0;
   if(lvp==0.0 || lvkol==0 || lvtype<0 || lvtype>1) return(lnret);
   
   double lns;
   if(lvkol==1) lns=s2;
   if(lvkol==2) lns=s3;
   if(lvkol==3) lns=s4;
   if(lvkol==4) lns=s5;
   if(lvkol==5) lns=s6;
   if(lvkol==6) lns=s7;
   if(lvkol==7) lns=s8;
   if(lvkol==8) lns=s9;
   if(lvkol==9) lns=s10;
   if(lvkol==10) lns=s11;
   if(lvkol==11) lns=s12;
   
   if(lns<=0.0) return(lnret);

   if(lvtype==0) lnret = lvp - lns*Point;
   if(lvtype==1) lnret = lvp + lns*Point;
   
   return (lnret);
}