Новая версия платформы MetaTrader 5 build 2360: Расширение интеграции с SQLite - страница 21

 

Последняя релизная версия MT5 2361.

Очень неприятный косяк с потерей позиций, порой приводит к невозможности узнать, сколько позиций открыто, что ведёт к двойному открытию.

Как это выглядит внешне:

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

Библиотеки: MT4Orders

traveller00, 2020.04.15 09:44

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

Был выставлен ордер на BUY, тикет 216684. Через некоторое время пришла пора закрыть позицию, был выставлен лимитник на SELL для закрытия и ещё лимитник на SELL на открытие обратной позиции, тикеты 216975 и 216978. Все ордера одинаковой лотности. Когда лимитник 216978 сработал, 216684 и 216978 были схлопнуты через CloseBy и остался только 216975.

Часть лога из Журнала

2020.04.15 07:33:24.203 : deal #107485 sell 0.15 XXXXXX at 1.05555 done (based on order #216978)
2020.04.15 07:33:24.203 : close position #216684 buy 0.15 XXXXXX by position #216978 sell 0.15 XXXXXX
2020.04.15 07:33:24.305 : accepted close position #216684 buy 0.15 XXXXXX by position #216978
2020.04.15 07:33:24.307 : deal #107487 sell 0.15 XXXXXX at 1.05555 done (based on order #216986)
2020.04.15 07:33:24.307 : close position #216684 buy 0.15 XXXXXX by position #216978 done in 103.841 ms
2020.04.15 07:33:24.309 : deal #107489 sell 0.15 XXXXXX at 1.05563 done (based on order #216975)

Часть лога из советника

2020.04.15 07:33:24.180 OrdersTotal 216978 216975 216684
2020.04.15 07:33:24.305 OrdersTotal

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

Ордера получаю через следующий код

  int PrevTotal;
  ulong OrderTickets[];
  do
  {
    PrevTotal=OrdersTotal();
    for(int i=PrevTotal-1;i>=0;--i)
    {
      int Total=OrdersTotal();
      if(Total!=PrevTotal)
      {
        PrevTotal=Total;
        i=PrevTotal;
        ArrayFree(OrderTickets);
        continue;
      }
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES) || OrderMagicNumber()!=inTradeMagic)
        continue;

      ArrayResize(OrderTickets,ArraySize(OrderTickets)+1);
      OrderTickets[ArraySize(OrderTickets)-1]=OrderTicket();
    }
  }while(PrevTotal!=OrdersTotal());

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

Описание ситуации изнутри

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

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

fxsaber, 2018.11.26 13:37

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

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

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

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

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

Повторяется нечасто, как повторить специально, неизвестно. Возможно, ситуация гонки. Но ситуация крайне неприятная, просьба исправить. Спасибо.
 
Igor Makanu:

всегда так МТ работал с принтами - "проглатывает" часть принтов если было много вывода на одном тике

можно паузу Sleep() поставить между итерациями цикла в Вашем коде

ну или смотрите в самом файле лога через правую КМ открыть, в файле пропусков принтов пока никто не замечал

В посте приведена часть лога именно из файла. Вопрос не в пропуске в логе. Вопрос в том, что вызван один Print из советника. Я ожидаю, что он одной пачкой и будет в логе/файле. Но он прерывается другими Print-ами, разделить потом такую кучу становится трудно.

 
traveller00:

Очень неприятный косяк с потерей позиций, порой приводит к невозможности узнать, сколько позиций открыто, что ведёт к двойному открытию.

Повторяется нечасто, как повторить специально, неизвестно. Возможно, ситуация гонки. Но ситуация крайне неприятная, просьба исправить. Спасибо.

Вряд ли это будет исправлено в ближайший год. Нужно писать свой обход.

 

Почему здесь отсутствует галка по-умолчанию?


 

В заголовке чарта сделали показ тикера и описания в одну строку.

Места хватило.


Количество активных символов в обзоре рынка увеличили до 5000. Этого достаточно для написания скринеров
 
С многострочным принтом разберемся
 
fxsaber:

Почему здесь отсутствует галка по-умолчанию?


Риск малый для тех, кто использует это апи

 
Renat Fatkhullin:
С многострочным принтом разберемся

Спасибо.

 
traveller00:

Последняя релизная версия MT5 2361.

Очень неприятный косяк с потерей позиций, порой приводит к невозможности узнать, сколько позиций открыто, что ведёт к двойному открытию.

Как это выглядит внешне:

Описание ситуации изнутри

Повторяется нечасто, как повторить специально, неизвестно. Возможно, ситуация гонки. Но ситуация крайне неприятная, просьба исправить. Спасибо.

Проверим, но причина в асинхронности транзакций.

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

Даже если между ними микросекунда, а вы сразу же проверяете позицию, то есть вероятность влезть между этими событиями. Плюс не забывайте про сетевую задержку.

Обходной путь - перепроверять позицию несколько раз, если вы сразу же анализируете позиции.


Мы проанализируем возможность выдачи данных о позиции с ожиданием до 10(например) миллисекунд, если перед этим прилетала транзакция о сделке. Это позволит избежать вашего случая в 99% случаев. Контролировать будем на микросекундном уровне, чтобы не вносить необоснованных задержек.
 
Renat Fatkhullin:

Проверим, но причина в асинхронности транзакций.

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

Даже если между ними микросекунда, а вы сразу же проверяете позицию, то есть вероятность влезть между этими событиями. Плюс не забывайте про сетевую задержку.

Обходной путь - перепроверять позицию несколько раз, если вы сразу же анализируете позиции.


Мы проанализируем возможность выдачи данных о позиции с ожиданием до 10(например) миллисекунд, если перед этим прилетала транзакция о сделке. Это позволит избежать вашего случая в 99% случаев. Контролировать будем на микросекундном уровне, чтобы не вносить необоснованных задержек.

В момент активации отложенного ордера такой код с завидной регулярностью печатает количество ордеров 0. В чём может быть проблема? Похожая на потерю позиции, о которой Вы говорите, или я что-то не так делаю?

  if(trans.type == TRADE_TRANSACTION_DEAL_ADD)
   {
    if(!HistoryDealSelect(trans.deal))
      Print(GetLastError());
    if(trans.symbol == _Symbol)
     {
      if(HistoryDealGetInteger(trans.deal, DEAL_ENTRY) == DEAL_ENTRY_IN)
       {
        if(HistorySelectByPosition(HistoryDealGetInteger(trans.deal, DEAL_POSITION_ID)))
         {
          Print("********** ", HistoryOrdersTotal());
         }
       }
     }
   }