Синхронный OrderSend сообщает об успешном выполнении быстрее, чем пинг до торгового сервера - страница 4

 
Повторно прошу разработчиков сообщить о билде с исправлением этого бага. Воспроизведение осталось без ответа.
 
fxsaber:
Повторно прошу разработчиков сообщить о билде с исправлением этого бага. Воспроизведение осталось без ответа.

Спасибо, проверим.

 

Раз обратили внимание на OrderSend, то на всякий случай подниму забытые темы.

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

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

fxsaber, 2018.06.18 22:49

// Воспроизведение ситуации, когда OrderSend успешно выполнилась, но ордера нет ни среди живых, ни среди мертвых.

#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define PRINT(A) Print(#A + " = " + (string)(A))

void OnStart()
{
/*
  // Посылаем поочередно ордера на открытие/закрытие позиций
  while (!IsStopped() &&
         (OrderSend(_Symbol, OP_SELL, 1, Bid, 0, 0, 0) != -1) &&
         OrderSelect(0, SELECT_BY_POS) && OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0))
    ;
*/

  MqlTradeResult Result;
  MqlTradeRequest Request = {0};

  Request.action = TRADE_ACTION_DEAL;
  Request.symbol = _Symbol;
  
  do
  {
    Request.position = PositionSelect(Request.symbol) ? PositionGetInteger(POSITION_TICKET) : 0;  
    Request.type = Request.position ? (ENUM_ORDER_TYPE)(1 - PositionGetInteger(POSITION_TYPE)) : ORDER_TYPE_SELL;
    Request.price = Request.position ? PositionGetDouble(POSITION_PRICE_CURRENT) : Bid;
    Request.volume = Request.position ? PositionGetDouble(POSITION_VOLUME) : 1;
          
  } // Посылаем поочередно ордера на открытие/закрытие позиций
  while (!IsStopped() && (OrderSend(Request, Result) ? OrderSelect(Result.order) || HistoryOrderSelect(Result.order) : true));
  
  PRINT(Result.order);
  PRINT(OrderSelect(Result.order));
  PRINT(HistoryOrderSelect(Result.order));
}


Результат на ForexTimeFXTM-Demo01

Result.order = 2210942086
OrderSelect(Result.order) = false
HistoryOrderSelect(Result.order) = false


Скрипт открывает и закрывает позиции до тех пор, пока не обнаружит "фантомный ордер" - нет ни среди текущих, ни в истории. Считать это багом или фишкой платформы?


ЗЫ Скрипт написан так, что может открыться несколько позиций из-за данного нюанса. Но это не мешает получению "фантомного ордера".


Дополнение.

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

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

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 (значительно реже) типах транзакций.


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


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

 
Вишенка без кода.

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

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

fxsaber, 2018.11.26 13:37

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

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

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

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

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

 
TheXpert:

а в чем смысл такого переноса? я так понимаю

1. нигде кроме вышеупомянутого брокера такое не прокатит, т.к. ордер будет заморожен (т.к. цена ордера за пределами спреда)

2. вероятность срабатывания со старой ценой больше (т.к. по новой уже реджектнули)

Пример народился с подобным переносом TP.

Цена дошла до тейка 1.80463 - реджект. Тейк тут же сдвинулся на 1.80458 - реджект. Тейк тут же сдвинулся на 1.80461 - исполнение. Итого вместо 1.80463 тейк перешел на 1.80461 и исполнился, что дало 2 пипса дополнительной прибыли. На картинке это все видно.


Однако, на картинке виден баг. И не ясно, это MT5 или брокер. Выделил числами на картинке проблемы, которые поясню ниже.

  1. Первый реджект тейка без какого-либо комментария. Хотя второй - с комментарием.
  2. Второй реджект тейка лишился мэджика!
  3. MT5 ошибочно полагает, что тейк другой, поэтому не подсвечивает зеленым цену исполнения. Т.е. DEAL_REASON иной.
Это баг MT5 или брокера?
 
fxsaber:
  1. Первый реджект тейка без какого-либо комментария. Хотя второй - с комментарием.
  2. Второй реджект тейка лишился мэджика!
Это баг MT5 или брокера?

Еще два случая отсутствия комментариев при реджекте тейка и обнуления мэджика.


Обнуление мэджика тейка происходит с таким ORDER_REASON.

2020.10.14 12:27:44.893 : Ticket = 1572252
2020.10.14 12:27:44.893 : HistoryOrderGetInteger(Ticket,ORDER_POSITION_ID) = 1570776
2020.10.14 12:27:44.893 : HistoryOrderGetInteger(Ticket,ORDER_MAGIC) = 3
2020.10.14 12:27:44.893 : EnumToString((ENUM_ORDER_REASON)HistoryOrderGetInteger(Ticket,ORDER_REASON)) = ORDER_REASON_TP
2020.10.14 12:27:44.893 
2020.10.14 12:27:44.893 : Ticket = 1572255
2020.10.14 12:27:44.893 : HistoryOrderGetInteger(Ticket,ORDER_POSITION_ID) = 1570776
2020.10.14 12:27:44.893 : HistoryOrderGetInteger(Ticket,ORDER_MAGIC) = 0
2020.10.14 12:27:44.893 : EnumToString((ENUM_ORDER_REASON)HistoryOrderGetInteger(Ticket,ORDER_REASON)) = ORDER_REASON_CLIENT
2020.10.14 12:27:44.893 
2020.10.14 12:27:44.893 : Ticket = 1572257
2020.10.14 12:27:44.893 : HistoryOrderGetInteger(Ticket,ORDER_POSITION_ID) = 1570776
2020.10.14 12:27:44.893 : HistoryOrderGetInteger(Ticket,ORDER_MAGIC) = 3
2020.10.14 12:27:44.893 : EnumToString((ENUM_ORDER_REASON)HistoryOrderGetInteger(Ticket,ORDER_REASON)) = ORDER_REASON_TP
2020.10.14 12:27:44.893 
2020.10.14 12:27:44.893 : Ticket = 1572258
2020.10.14 12:27:44.893 : HistoryOrderGetInteger(Ticket,ORDER_POSITION_ID) = 1570776
2020.10.14 12:27:44.893 : HistoryOrderGetInteger(Ticket,ORDER_MAGIC) = 3
2020.10.14 12:27:44.893 : EnumToString((ENUM_ORDER_REASON)HistoryOrderGetInteger(Ticket,ORDER_REASON)) = ORDER_REASON_TP
2020.10.14 12:27:44.893 
2020.10.14 12:27:44.893 : Ticket = 1572259
2020.10.14 12:27:44.893 : HistoryOrderGetInteger(Ticket,ORDER_POSITION_ID) = 1570776
2020.10.14 12:27:44.893 : HistoryOrderGetInteger(Ticket,ORDER_MAGIC) = 0
2020.10.14 12:27:44.893 : EnumToString((ENUM_ORDER_REASON)HistoryOrderGetInteger(Ticket,ORDER_REASON)) = ORDER_REASON_CLIENT
2020.10.14 12:27:44.893 
2020.10.14 12:27:44.893 : Ticket = 1572262
2020.10.14 12:27:44.893 : HistoryOrderGetInteger(Ticket,ORDER_POSITION_ID) = 1570776
2020.10.14 12:27:44.893 : HistoryOrderGetInteger(Ticket,ORDER_MAGIC) = 3
2020.10.14 12:27:44.893 : EnumToString((ENUM_ORDER_REASON)HistoryOrderGetInteger(Ticket,ORDER_REASON)) = ORDER_REASON_TP
 

На реале столкнулся с висящим несколько часов маркет-ордером (не позиция). Анализ позволил догадаться до причины и написать проверочный советник для демо.

// Создание висячего маркет-ордера (не позиции).

#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

bool OrderScan( const int Type )
{
  bool Res = false;
  
  for (int i = OrdersTotal() - 1; (i >= 0) && !Res; i--)
    Res = OrderSelect(i, SELECT_BY_POS) && (OrderType() == Type) && (OrderSymbol() == _Symbol);
      
  return(Res);      
}

void OnInit()
{
  MT4ORDERS::OrderSend_MaxPause = 0;
}

void OnTick()
{
  if (OrderScan(OP_BUY))
  {
    const TICKET_TYPE TicketBuy = OrderTicket();
    
    if (!OrderScan(OP_SELL))
    {
      const TICKET_TYPE TicketSell = OrderSend(_Symbol, OP_SELL, 0.01, Bid, 0, 0, Ask);
      
      if (TicketSell != -1)
        OrderCloseBy(TicketBuy, TicketSell);
    }
    else if ((OrderTakeProfit() <= Bid) || OrderModify(OrderTicket(), OrderOpenPrice(), 0, Bid, 0))
      OrderCloseBy(TicketBuy, OrderTicket());    
  }
  else
    OrderSend(_Symbol, OP_BUY, 0.01, Ask, 0, 0, 0);
}


Результат (использовал эту инструкцию).


Маркет-ордер висит вечно, при этом его не удалить.

2020.10.22 15:56:32.070 Trades  '': failed cancel order #1595426 buy 0.01 GBPUSD at 1.30968 [Invalid request]
2020.10.22 15:56:33.653 Trades  '': failed cancel order #1595426 buy 0.01 GBPUSD at 1.30968 [Invalid request]
2020.10.22 15:56:34.995 Trades  '': failed cancel order #1595426 buy 0.01 GBPUSD at 1.30968 [Invalid request]
 
fxsaber:

На реале столкнулся с висящим несколько часов маркет-ордером (не позиция). Анализ позволил догадаться до причины и написать проверочный советник для демо.


Результат (использовал эту инструкцию).


Маркет-ордер висит вечно, при этом его не удалить.

Можете пояснить для тех кто в танке - почему он стал неудаляемым?

Это как-то связано  с тем, что у OP_SELL ордера tp=Ask?

 
mktr8591:

Можете пояснить для тех кто в танке - почему он стал неудаляемым?

Это как-то связано  с тем, что у OP_SELL ордера tp=Ask?

Совсем не помню.

 
fxsaber:
Повторно прошу разработчиков сообщить о билде с исправлением этого бага. Воспроизведение осталось без ответа.
А этот баг пофиксили?
Причина обращения: