//+------------------------------------------------------------------+
//|                                                    Обучение .mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+  на покупку зделал, на продажу сам сделаешь.
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

extern double  Lots          = 0.1;
extern int     Step          = 15;
extern int     Magic         = 011116;
extern int     Slippage      = 6;
extern int     StopLoss      = 20; 
extern int     TakeProfit    = 15;  
       int     Profit; 
       int     Loss;
extern int     SELL_LIMIT    =10;
extern int     BUY_LIMIT     =10;
extern bool    CloseAll      =false;  // отвечает за закрытие отложеных ордеров на покупку при закрытий основного ордера

int Step_1; 
double price; 
double SL, TP;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   Loss=StopLoss;
   Profit=TakeProfit;
   if (Digits == 3 || Digits == 5)
   Step       *= 10;
   Step_1     *= 10;
   Slippage   *= 10;
   Profit     *= 10;
   Loss       *= 10;
   Profit     *= 10;
   Loss       *= 10;
   
   Step_1=Step;
   return(INIT_SUCCEEDED);
 
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{

   //-- Открытие сетки ордеров на покупку 

   if (CountBuy() == 1)
   {
      if(CountBuy_1()<= BUY_LIMIT)// при превышений лимита новые отложеники открыватся не будут, но есть некий нюанс, если выставить например 3, то
      {                           //откроется 4 отложеника, я эту проблему знаю но нет времени искать описание и решение проблемы в учебнике,имей ввиду
          SL=NormalizeDouble(Ask-Loss*Point,Digits);
          TP=NormalizeDouble(Ask+Profit*Point,Digits); 
               
          double Step_2=NormalizeDouble(OrderOpenPriceBuy() - Step_1*Point,Digits);
          
           if (OrderSend(Symbol(), OP_BUYLIMIT, Lots, Step_2, 0, SL, TP, "", Magic, 0, clrBlue) < 1)
             { Print ("Не удалось открыть ордер на покупку!",GetLastError());}
           Step_1=Step_1+Step; // здесь счетчик шага, плюсуем к открытию основного ордера  шаг сетки
      }
   }
//+-------------------------------+
   if(CountBuy()==0)
   {
     Step_1=Step;
     if(CloseAll==true)  //  если true то при закрытий основного ордера все отложки закроются и все метки удалятся
     {                   //  если хоть один отложеник сработает он превращается в рыночный ордер и не будет удален
     CloseOrderAll();
     ObjectsDeleteAll();
     }
   }
//+------------------------------------------------------------------+ 
   //-- Открытие сетки ордеров на продажу

   if (CountSell() == 1) 
   {
      price = FindLastSellPrice();
      if ((Bid - price) >= Step*Point)
      {
          SL=NormalizeDouble(Ask-Loss*Point,Digits);
          TP=NormalizeDouble(Ask+Profit*Point,Digits);
         if (OrderSend(Symbol(), OP_SELLLIMIT, Lots, Bid, Slippage, StopLoss, TakeProfit, "", Magic, 0, clrRed) < 1)
         Print ("Не удалось открыть ордер на продажу!");
      }
   }
     
   //--- Закрытие всех ордеров по профиту
   double pr = CalculateProfit();
   if (pr >= Profit || pr <= -Loss) 
   {
      CloseAll(); 
   } 
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void CloseAll ()
   {
      for (int i = OrdersTotal () - 1; i>=0; i--)
      {
        if (OrderSelect (i, SELECT_BY_POS, MODE_TRADES))
        {
          if (OrderSymbol() == Symbol () && OrderMagicNumber() == Magic )
           {
              if (OrderType() == OP_BUY) 
              {
                 if (!OrderClose(OrderTicket(), OrderLots(), Bid, Slippage))
                 Print ("Не удалось закрыть ордер на покупку");
              }
              if (OrderType() == OP_SELL) 
              {
                 if (!OrderClose(OrderTicket(), OrderLots(), Ask, Slippage))
                 Print ("Не удалось закрыть ордер на продажу");
              }
           }
        }
      }
   }
//+------------------------------------------------------------------+
double CalculateProfit ()
{
  double oProfit = 0;
   for (int i=OrdersTotal() - 1; i>=0; i--)
   {
     if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
     {
         if (OrderSymbol () == Symbol () && OrderMagicNumber() == Magic)
         {
            if (OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLLIMIT)
            {
                oProfit += OrderProfit ();
            }
         }
     }
   }
   return (oProfit);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
double FindLastBuyPrice()
{
     int oldticket, ticket = 0;
     double oldopenpice = 0;
     
     for (int cnt = OrdersTotal()-1; cnt>=0; cnt--)
     {
      if (OrderSelect(cnt, SELECT_BY_POS,MODE_TRADES)) 
         {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType()== OP_BUY)
          {
           oldticket = OrderTicket();
           if (oldticket > ticket)
           {
           ticket = oldticket;
           oldopenpice = OrderOpenPrice ();
           }
         }
      }
   }
   return (oldopenpice);
}
//+------------------------------------------------------------------+
double FindLastSellPrice()
{
     int oldticket, ticket = 0;
     double oldopenpice = 0;
     
     for (int cnt = OrdersTotal()-1; cnt>=0; cnt--)
     {
      if (OrderSelect(cnt, SELECT_BY_POS,MODE_TRADES)) 
         {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == OP_SELL)
          {
           oldticket = OrderTicket();
           if (oldticket > ticket)
           {
           ticket = oldticket;
           oldopenpice = OrderOpenPrice ();
           }
         }
      }
   }
   return (oldopenpice);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int CountBuy()
  {
    int count = 0;
    for (int trade = OrdersTotal() - 1; trade>=0; trade--) 
    {
     if  (OrderSelect (trade,SELECT_BY_POS, MODE_TRADES) == true) 
            {
             if (OrderSymbol () == Symbol() && OrderType() == OP_BUY)
             count++; 
            }
    }
    return (count);
}
//+------------------------------------------------------------------+
int CountSell()
  {
    int count = 0;
    for (int trade = OrdersTotal() - 1; trade>=0; trade--) 
    {
     if  (OrderSelect (trade,SELECT_BY_POS, MODE_TRADES) == true) 
            {
             if (OrderSymbol () == Symbol() && OrderType() == OP_SELL)
             count++; 
            }
    }
    return (count);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int CountBuy_1()
  {
   int count=0;
     for(int i=OrdersTotal(); i>=0; i--)
     {
       if  (OrderSelect (i,SELECT_BY_POS, MODE_TRADES) == true) 
       {
          if (OrderSymbol () == Symbol() && OrderMagicNumber () == Magic && OrderType() == OP_BUYLIMIT)
          count++; 
       }
    }
    return (count);
}
//+------------------------------------------------------------------+
int CountSell_1()
  {
    int count = 0;
    for (int trade = OrdersTotal() - 1; trade>=0; trade--) 
    {
     if  (OrderSelect (trade,SELECT_BY_POS, MODE_TRADES) == true) 
            {
             if (OrderSymbol () == Symbol() && OrderMagicNumber () == Magic && OrderType() == OP_SELL)
             count++; 
            }
    }
    return (count);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
   double OrderOpenPriceBuy() 
   {
      double OpenPriceBuy=0.0;
      for(int i=OrdersTotal(); i>=0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         {
           if(OrderSymbol()==Symbol() && OrderType()==OP_BUY)
             OpenPriceBuy=OrderOpenPrice();
         }
      }return(OpenPriceBuy);     
   }
//==================================================================================+   
   void CloseOrderAll()
   {
      for(int i=OrdersTotal(); i>=0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS ,MODE_TRADES ))
         {
            if(OrderType()==OP_BUYLIMIT)//------------------------------------------------------------------------+   BUY
            {                                                                                         
                  if(OrderDelete(OrderTicket(),Black)==false)
                     Print("Ордер  не закрыт, код ошибки",GetLastError());
            }
            if(OrderType()==OP_SELLLIMIT)//-----------------------------------------------------------------------+   SELL
            {                                             
                  if(OrderDelete(OrderTicket(),Black)==false)
                     Print("Ордер продажу не закрыт, код ошибки",GetLastError());
            }
         }
      }
   }
//==================================================================================+   