Открытие двух ордеров при ограничении на один открытый ордер

 

 Здравствуйте! Описание ситуации: Используя, ф-цию OrderSend, открываем ордера. Используем счётчик открытых ордеров, чтоб позволить держать открытым не более одного ордера.

 Вопрос: может ли возникнуть какая-либо ситуация, что откроется два ордера?

К примеру, такая: поступил сигнал на открытие и функция OrderSend сработала, но не получила ещё ответ от сервера (и сделка, соответственно не открыта), наступил ещё один тик и поступил ещё один сигнал на открытие - OrderSend срабатывает ещё раз (так как первый ордер ещё не открыт и, соответственно, ограничение счётчика по открытым ордерам ещё не действует) и возвращается ответ и на первое открытие и на второе, в итоге мы получаем две открытых сделки вместо одной. 

 int BuyOrderCount(int Magic)
{
   int count = 0;
   for(int i = OrdersTotal()-1; i>=0; i--)
   {
   if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true &&
   OrderMagicNumber() == Magic && OrderType() == OP_BUY)
      {
      count++;
      }
   }

return(count);
}

void BuyOrderOpenAndModify(int Magic, string comment, color clr)

 if (BuyOrderCount(int Magic) == 0)

{
   SL1 = Ask - SL;
   TP1 = Ask + TP;
    
   ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage1, 0, 0, comment, Magic, 0, clr);
   if (ticket > 0)
    {
      if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES) == true)
       {
         ModifTicket = OrderModify(ticket, OrderOpenPrice(), SL1, TP1, 0, clr);
       } 
   
    }

}    
return;
}

 
Konstantin Kulikov:

 Здравствуйте! Описание ситуации: Используя, ф-цию OrderSend, открываем ордера. Используем счётчик открытых ордеров, чтоб позволить держать открытым не более одного ордера.

 Вопрос: может ли возникнуть какая-либо ситуация, что откроется два ордера?

К примеру, такая: поступил сигнал на открытие и функция OrderSend сработала, но не получила ещё ответ от сервера (и сделка, соответственно не открыта), наступил ещё один тик и поступил ещё один сигнал на открытие - OrderSend срабатывает ещё раз (так как первый ордер ещё не открыт и, соответственно, ограничение счётчика по открытым ордерам ещё не действует) и возвращается ответ и на первое открытие и на второе, в итоге мы получаем две открытых сделки вместо одной. 

 int BuyOrderCount(int Magic)
{
   int count = 0;
   for(int i = OrdersTotal()-1; i>=0; i--)
   {
   if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == true &&
   OrderMagicNumber() == Magic && OrderType() == OP_BUY)
      {
      count++;
      }
   }

return(count);
}

void BuyOrderOpenAndModify(int Magic, string comment, color clr)

 if (BuyOrderCount(int Magic) == 0)

{
   SL1 = Ask - SL;
   TP1 = Ask + TP;
    
   ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage1, 0, 0, comment, Magic, 0, clr);
   if (ticket > 0)
    {
      if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES) == true)
       {
         ModifTicket = OrderModify(ticket, OrderOpenPrice(), SL1, TP1, 0, clr);
       } 
   
    }

}    
return;
}

Может, особенно на реале.
 

Здесь эта тема поднималась. 

Как правильно работать в MT5 с OrderSend
Как правильно работать в MT5 с OrderSend
  • www.mql5.com
Форум трейдеров MQL5.community
 
fxsaber:

Здесь эта тема поднималась. 

 Я находил только для MT5 (mql5), а меня интересует MT4 (mql4). Вы кинули ссылку как раз MT5.

 
Konstantin Kulikov:

 Я находил только для MT5 (mql5), а меня интересует MT4 (mql4). Вы кинули как раз MT5.

На MT4 описанная Вами ситуация возможна только в случае запуска нескольких советников. Например, две копии одного и того же советника.

В других случаях - нет. 

 
Vladimir Zubov:
Может, особенно на реале.

 Известны уже проверенные способы как избежать этого? У меня есть идея насчёт проверки переменной ticket в моём коде выше (ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage1, 0, 0, comment, Magic, 0, clr);) если предположить, что при отсутствии ответа сервера остаётся прежнее значение переменной, но я не знаю как это проверить.

 
Konstantin Kulikov:

 Известны уже проверенные способы как избежать этого? У меня есть идея насчёт проверки переменной ticket в моём коде выше (ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage1, 0, 0, comment, Magic, 0, clr);) если предположить, что при отсутствии ответа сервера остаётся прежнее значение переменной, но я не знаю как это проверить.

к примеру так: 

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void BuyOrderOpenAndModify(int Magic,string comment,color clr)
  {
   if(BuyOrderCount(int Magic)==0)
     {
      SL1 = Ask - SL;
      TP1 = Ask + TP;
      if(ticket!=-2)
        {
         ticket=-2;
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage1,0,0,comment,Magic,0,clr);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)==true)
              {
               ModifTicket=OrderModify(ticket,OrderOpenPrice(),SL1,TP1,0,clr);
              }
           }
        }
     }
   return;
  }
 
Konstantin Kulikov:


Пожалуйста вставляйте код правильно: Правильно вставляем код на форуме.

Я, на первый раз, отредактировал Ваше сообщение и ещё применил к коду Стилизатор (Стилизатор - Работа с исходным кодом - Разработка программ - MetaEditor) - теперь код смотрится намного опрятнее, а также код стал очень хорошо восприниматься визуально.

 
Konstantin Kulikov:

 Здравствуйте! Описание ситуации: Используя, ф-цию OrderSend, открываем ордера. Используем счётчик открытых ордеров, чтоб позволить держать открытым не более одного ордера.

 Вопрос: может ли возникнуть какая-либо ситуация, что откроется два ордера?

К примеру, такая: поступил сигнал на открытие и функция OrderSend сработала, но не получила ещё ответ от сервера (и сделка, соответственно не открыта), наступил ещё один тик и поступил ещё один сигнал на открытие - OrderSend срабатывает ещё раз (так как первый ордер ещё не открыт и, соответственно, ограничение счётчика по открытым ордерам ещё не действует) и возвращается ответ и на первое открытие и на второе, в итоге мы получаем две открытых сделки вместо одной. 


В МТ4 OrderSend(...) синхронная функция, пока не получен ответ от сервера, никакие OnTick и OnTimer не сработают. 
 
Может получиться, что OrderSend отработает с неопределенным кодом (сервер занят, потеря связи, неизвестная ошибка и т.д.). Значит ордер или выставился, или нет.
Причина обращения: