Непонятная ситуация при срабатывании отложенных ордеров.

 

Ситуация следующая.

МТ5. Когда срабатывает отложенный ордер, то сначала открывается позиция (появляется в списке открытых позиций), и только через некоторое время отложенный ордер удаляется из списка отложенных ордеров. Причем, отложенный ордер за все время нахождения в списке, имеет такие свойства, как будто он срабатывал, а именно: ORDER_TIME_DONE=0, ORDER_STATE=ORDER_STATE_PLACED, ORDER_POSITION_ID=0, а объемы ордера не меняется.

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

Я придумал, как детектировать такую ситуацию. А именно: когда выделяем позицию, то ищем отложенный ордер с таким же тикетом в списке отложенников. Да, это решение, но это явно не оптимально, т.к. после выявления такой ситуации, приходится искусственно ожидать некоторое время и по новой получать списки открытых позиций и отложенных ордеров.

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

Не совсем понятно, баг это или так и задумано. Если так и задумано, тогда возможно, я что-то упускаю. Может кто-то знает, как можно проще решить такую ситуацию?

Чтобы воссоздать эту ситуацию достаточно запустить этот скрипт и вручную выставить отложенные ордера. Затем ждать когда один из них сработает, тогда прозвенит алерт...

//+------------------------------------------------------------------+
//|                                                      Test001.mq5 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   ulong  PosTicket;
   string Info;
   
   while (!_StopFlag)
   {
      for (int i=0; i<PositionsTotal(); i++)
      {
         if (!(PosTicket=PositionGetTicket(i)))
            continue;
         
         if (!OrderSelect(PosTicket))
            continue;
         
         Info = "Position#"+(string)PosTicket+" found the Order#"+(string)PosTicket+" in the pedning orders list. Order: "+
                "done_time("+(string)OrderGetInteger(ORDER_TIME_DONE)+") "+
                "state("+(string)EnumToString((ENUM_ORDER_STATE)OrderGetInteger(ORDER_STATE))+") "+
                "pos_id("+(string)OrderGetInteger(ORDER_POSITION_ID)+").";
         
         Alert(Info);
         
         Sleep(100);
      }
      
      Sleep(1);
   }
}
//+------------------------------------------------------------------+


 

https://www.mql5.com/ru/articles/211

Или подключите МТ4ордерс и не ходите по граблям.

Ордерa, позиции и сделки в MetaTrader 5
Ордерa, позиции и сделки в MetaTrader 5
  • www.mql5.com
Конечной целью трейдера является извлечение прибыли посредством торговых операций на финансовых рынках. В этой статье дается описание терминов и процессов торговой платформы MetaTarder 5, знание которых необходимо для правильного понимания работы торговых функций языка MQL5. Ордера — это принятые торговым сервером запросы на совершение...
 
Marat Sultanov:

***


Перед подачей торгового сигнала ставьте флаг ожидания. Когда в OnTradeTransaction поймаете транзакцию с типом TRADE_TRANSACTION_DEAL_ADD - снимайте флаг. 

 
Vladimir Karputov:


Перед подачей торгового сигнала ставьте флаг ожидания. Когда в OnTradeTransaction поймаете транзакцию с типом TRADE_TRANSACTION_DEAL_ADD - снимайте флаг. 

А для чего этот флаг? Ведь кроме активации отложки или открытия позиции по рынку, так-же можно отловить и удаление ордера в историю. Так и обрабатывать можно по этим событиям и позиции, и ордера...

 

Я все понял. Значит, так и задумано.

Хорошо, тогда проще и надежнее того способа, что я сделал, я не вижу. Ну не страшно, главное, что работает без сбоев. Усложнять более не стану.

Благодарю всех за информацию!

 
Есть и такие приколы

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

fxsaber, 2018.06.20 23:18

Решил проверить, как долго длятся такие ситуации фантомных ордеров, когда ордер есть в системе, но нет в Терминале.

// Советник отслеживает длительность ситуаций, когда ордер отсутствует среди текущих и исторических

#define TOSTRING(A)  #A + " = " + (string)(A) + "\n"
#define TOSTRING2(A) #A + " = " + EnumToString(A) + " (" + (string)(A) + ")\n"

bool OrderIsExist( const ulong &OrderTicket )
{
  return(OrderTicket ? OrderSelect(OrderTicket) || HistoryOrderSelect(OrderTicket) : true);
}

void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest&, const MqlTradeResult& )
{
  static bool PrevIsExist = true;
  static ulong StartTime = 0;
  static ulong MaxInterval = 0;
  
  const ulong NowTime = GetMicrosecondCount();
  const bool IsExist = OrderIsExist(Trans.order);
    
  if (!IsExist)
  {
    Print(TOSTRING2(Trans.type) + TOSTRING(Trans.order) +
          TOSTRING(OrderSelect(Trans.order)) + TOSTRING(HistoryOrderSelect(Trans.order)));       
  
    if (PrevIsExist) 
      StartTime = NowTime;
  }
  else if (!PrevIsExist)
  {
    const ulong Interval = NowTime - StartTime;
    
    Print(TOSTRING(Interval) + TOSTRING2(Trans.type) + TOSTRING(Trans.order) +
          TOSTRING(OrderSelect(Trans.order)) + TOSTRING(HistoryOrderSelect(Trans.order)));       
    
    if (Interval > MaxInterval)
    {
      MaxInterval = Interval;
      
      Comment(TOSTRING(MaxInterval) + TOSTRING(Trans.order)); // mcs.
    }
  }
          
  PrevIsExist = IsExist;
}


Результат

2018.06.21 00:10:31.047 Trans.type = TRADE_TRANSACTION_ORDER_DELETE (2)
2018.06.21 00:10:31.047 Trans.order = 2210967406
2018.06.21 00:10:31.047 OrderSelect(Trans.order) = false
2018.06.21 00:10:31.047 HistoryOrderSelect(Trans.order) = false
2018.06.21 00:10:31.047 
2018.06.21 00:10:31.080 Interval = 32643
2018.06.21 00:10:31.080 Trans.type = TRADE_TRANSACTION_HISTORY_ADD (3)
2018.06.21 00:10:31.080 Trans.order = 2210967406
2018.06.21 00:10:31.080 OrderSelect(Trans.order) = false
2018.06.21 00:10:31.080 HistoryOrderSelect(Trans.order) = true


32 миллисекунды ордер есть, но его в Терминале нет! Только представьте себе, какие это может нести последствия, если в этом интервале выполнялась торговая логика...


Интересно, что фантомные ордера чаще всего присутствуют только при TRADE_TRANSACTION_ORDER_DELETE и при TRADE_TRANSACTION_DEAL_ADD (значительно реже) типах транзакций.


Очень нехороший нюанс платформы.


ЗЫ Сомнительное быстродействие торговых операций на пятерке, к сожалению.

 
Marat Sultanov:

Ситуация следующая.

МТ5. Когда срабатывает отложенный ордер, то сначала открывается позиция (появляется в списке открытых позиций), и только через некоторое время отложенный ордер удаляется из списка отложенных ордеров. Причем, отложенный ордер за все время нахождения в списке, имеет такие свойства, как будто он срабатывал, а именно: ORDER_TIME_DONE=0, ORDER_STATE=ORDER_STATE_PLACED, ORDER_POSITION_ID=0, а объемы ордера не меняется.

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

Я придумал, как детектировать такую ситуацию. А именно: когда выделяем позицию, то ищем отложенный ордер с таким же тикетом в списке отложенников.

На неттинге такое не прокатит.

Стоит BUY на 2 лота и SellLimit на 1 лот. По итогу получите в какой-то момент, что будет BUY на 1 лот, SellLimit на 1 лот и тикеты позиции и лимитника будут разными.

 

Еще бывает такая ситуация:

  1. Выставили открывающий позицию маркет-ордер и OrdersTotal увеличился на единицу.
  2. Он исполнился и OrdersTotal уменьшился на единицу, но при этом PositionsTotal не увеличился на единицу. Т.е. существует позиция, но Терминал о ней не знает.

Например, нет ни позиций, ни ордеров - PositionsTotal = 0, OrdersTotal = 0.

Выставляете маркет-ордер. При этом PositionsTotal = 0, OrdersTotal = 1.

Маркет-ордер исполнился - OrdersTotal = 0. Но PositionsTotal = 0!

 

fxsaber,

Интересно! Похоже нюансов о которых я не знал больше, чем я думал. Благодарю за инфу.

Причина обращения: