Уведомление о каждой открытой и закрытой сделки

 

Нужно что-бы эксперт отправлял сообщения после каждой открытой и закрытой сделки в терминале. Сделки открывает не этот эксперт а другие. Возможно открытие и закрытие сделок вручную. После этого тоже должно быть сообщение. Думаю тема не из новых, возможно уже есть готовое решение. Если кто знает, поделитесь пожалуйста.

 Я вот попробовал сам написать, но есть одна проблемка Если запустить на каком-то символе, и долгое время не будет тика по этому символу, то за все это время можно открыть кучу позиций и закрыть их (по других инструментах), а советник увидит только последнюю позицию и отправит ее в сообщении.

 


int    OpenOrderTicket;
int    CloseOrderTicket;
double MaxLot = 3;

//+------------------------------------------------------------------+
int OnInit()
{
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnTick()
{
   int    type;
   string stype;
   string message;
   string symbol;
   double open_price;
   double profit;
   double close_price;
   double lot;
   double sl;
   double tp;  
   double digits;

   int ticket = GetTicketLastPos();
   if(OpenOrderTicket != ticket)  
   {
      OpenOrderTicket = ticket;
      if(OrderSelect(ticket, SELECT_BY_TICKET))
      {
         symbol     = OrderSymbol();
         digits     = MarketInfo(symbol, MODE_DIGITS);
         open_price = NormalizeDouble(OrderOpenPrice(), digits);
         lot        = OrderLots();
         sl         = NormalizeDouble(OrderStopLoss(), digits);
         tp         = NormalizeDouble(OrderTakeProfit(), digits);
         type       = OrderType();
        

         if(type == OP_BUY)       stype = "BUY";
         if(type == OP_SELL)      stype = "SELL";
         if(type == OP_BUYLIMIT)  stype = "BUYLIMIT";
         if(type == OP_SELLLIMIT) stype = "SELLLIMIT";
         if(type == OP_BUYSTOP)   stype = "BUYSTOP";
         if(type == OP_SELLSTOP)  stype = "SELLSTOP";
        
         message = "Відкрито ордер " + stype + " по " + symbol + " price = " + open_price + " lot = " + lot + " sl = " + sl + " tp = " + tp;
         SendMail("експерт", message);        
         Print(message);
         if(lot >= MaxLot)  CloseOrder(ticket);
      }
   }
  
   int close_ticket = GetLastOrderHist();
   if(close_ticket != CloseOrderTicket)
   {
      CloseOrderTicket = close_ticket;
      if(OrderSelect(close_ticket, SELECT_BY_TICKET))
      {
        
         symbol      = OrderSymbol();
         digits      = MarketInfo(symbol, MODE_DIGITS);
         close_price = NormalizeDouble(OrderClosePrice(), digits);
         lot         = OrderLots();
         sl          = NormalizeDouble(OrderStopLoss(), digits);
         tp          = NormalizeDouble(OrderTakeProfit(), digits);
         type        = OrderType();
         profit      = NormalizeDouble(OrderProfit(), digits);
        
         if(type == OP_BUY)       stype = "BUY";
         if(type == OP_SELL)      stype = "SELL";
         if(type == OP_BUYLIMIT)  stype = "BUYLIMIT";
         if(type == OP_SELLLIMIT) stype = "SELLLIMIT";
         if(type == OP_BUYSTOP)   stype = "BUYSTOP";
         if(type == OP_SELLSTOP)  stype = "SELLSTOP";
        
         message = "Закрито ордер " + stype + " по " + symbol + " close_price = " + close_price + " lot = " + lot + " sl = " + sl + " tp = " + tp
                   + "  profit = " + profit + "$";
         SendMail("експерт", message);
         Print(message);
      }
   }

}

//+------------------------------------------------------------------+

// Описание : Возвращает тикет последней открытой позиции или -1  
int GetTicketLastPos()
{
  datetime o;
  int  i,  k=OrdersTotal(), r=-1;
  
   for (i=0; i<k; i++)
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if (o<OrderOpenTime())
         {
            o=OrderOpenTime();
            r=OrderTicket();
         }
      }
   }
  return(r);
}


//Получить тикет последнего закрытого ордера из истории.
//Если тип ордера не указан, берется самый последний ордер любого типа.
//Если ордеров, отвечающих указанным критерию не найдено, возвращает -1.
int GetLastOrderHist(int type = -1)
{
  int ticket = -1;
  datetime dt = 0;
  int cnt = OrdersHistoryTotal();
    
  for (int i=0; i < cnt; i++)
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;    
    if (OrderCloseTime() > dt)
    {
      dt = OrderCloseTime();
      ticket = OrderTicket();
    }
  }
  
  return (ticket);
}

void CloseOrder(int ticket)
{
   RefreshRates();
   if(OrderSelect(ticket, SELECT_BY_TICKET))
   if(OrderType()==OP_BUY) OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(), MODE_BID),10,0);
   if(OrderType()==OP_SELL)OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(), MODE_ASK),10,0);
}


 

 

OnTimer() есть же. 

Или зацикленный скрипт можно написать,  он на тики не смотрит.

 
В настройках терминала можно галочку поставить, чтобы отправлял уведомления об открытых позициях. 
То есть в советнике можно реализовать, только оставшуюся часть идеи, пуш по закрытию сделок.
 
Ramiz Mavludov:
В настройках терминала можно галочку поставить, чтобы отправлял уведомления об открытых позициях. 
То есть в советнике можно реализовать, только оставшуюся часть идеи, пуш по закрытию сделок.

Еще нужно проверять лот открытой, если больше 3 например, то закрывать 

if(lot >= MaxLot)  CloseOrder(ticket); 

Может делать в OnTimer() каждых пол секунды. Не знаю