ФОРТС: баг "exchange/instant" в размещении ордеров для фьючерса на РТС - страница 2

 
Сергей Лебедев:

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

Что касается СTrade – вероятно в большинстве ситуаций библиотека  на ФОРТС сработает нормально, несмотря на указанные выше странности с заполнением цен у рыночных заявок.

Но у меня при тестировании появляется конкретная проблема - выпадают заявки с [invalid price], которые пропадают, т.е. последующая проверка позиции показывает,  что они не выполнились.

Более того выяснилось, такие заявки даже не попадают в список заявок, который по итогам тестирования можно получить с использованием HistoryOrdersTotal. Соответственно без написания специальных функции предварительной регистрации всех вызовов СTrade::Sell/Buy невозможно оценить сколько заявок пропало, и уж тем более понять как их выполнение на бирже повлияло бы на итоговую доходность.

Такого явно быть не должно , т.к. в реальных условиях все рыночные заявки, попавшие на сервер  должны передаться для выполнения на бирже и там выполниться (случаи возникновения реальных технических сбоев терминала/брокера/биржи я тут не рассматриваю, т.к. речь идет о тестировании).

Заявки без подтверждения кодом попадают под растрельную статью.
 

Сейчас работаю  над кодом, который позволит моему советнику обойти данную ошибку. Если уж ни у кого из пользователей МТ5 на ФОРТС пока она не возникала, то после завершения своих работ  специально уделю время чтобы подготовить сливной советник, который продемонстрирует данную ошибку.

 
Сергей Лебедев:

Такого явно быть не должно , т.к. в реальных условиях все рыночные заявки, попавшие на сервер  должны передаться для выполнения на бирже и там выполниться (случаи возникновения реальных технических сбоев терминала/брокера/биржи я тут не рассматриваю, т.к. речь идет о тестировании).

С какого перепугу они Вам что-то должны?

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

 
Сергей Лебедев:

Cоветник вызывает функцию СTrade::Sell без указания цены, так как заявки рыночные).

Баг в стандартной библиотеке МТ5 в классе СTrade - в функциях Sell/Buy, которые предназначены для торговли по рынку, оказалось что в них идет заполнение заявки некими ценами. Это в принципе неверно, т.к. если заявка рыночная, то должна уходить на сервер без указания цены.

Более того, выяснилось, что даже если заранее рассчитать округленную цену и указать ее в заявке размещение, то МТ5 тестер сам ее портит - "корректирует" и заменяет на негодную цену!!!

12:30:54.097      Core 1   2014.01.06 11:00:42   Расчетная цена на покупку: 140900.0000

12:30:54.097      Core 1   2014.01.06 11:00:42   price corrected from 140900 to 140891, deviation: 10 (instant buy 7.00 RTS Splice at 140900)(140881 / 140891 / 140881)

12:30:54.097      Core 1   2014.01.06 11:00:42   CTrade::OrderSend: instant buy 7.00 RTS Splice at 140900 [invalid price]

При этом корректировка идет за пределами класса  СTrade, видимо в самой функции OrderSend. Это вообще двойной баг.

Проверил, все работает,

2016.02.21 00:17:02.656 2016.01.18 13:49:40   CTrade::OrderSend: instant sell 2.00 RTS Splice at 64490 [done at 64490]
2016.02.21 00:17:02.656 2016.01.18 13:49:40   order performed sell 2.00 at 64490 [#85 sell 2.00 RTS Splice at 64490]
2016.02.21 00:17:02.656 2016.01.18 13:49:40   deal performed [#85 sell 2.00 RTS Splice at 64490]
2016.02.21 00:17:02.656 2016.01.18 13:49:40   deal #85 sell 2.00 RTS Splice at 64490 done (based on order #85)
2016.02.21 00:17:02.656 2016.01.18 13:49:40   instant sell 2.00 RTS Splice at 64490 (64490 / 64500 / 64490)
2016.02.21 00:17:02.511 2016.01.18 13:46:40   CTrade::OrderSend: instant buy 2.00 RTS Splice at 64390 [done at 64390]
2016.02.21 00:17:02.511 2016.01.18 13:46:40   order performed buy 2.00 at 64390 [#84 buy 2.00 RTS Splice at 64390]
2016.02.21 00:17:02.511 2016.01.18 13:46:40   deal performed [#84 buy 2.00 RTS Splice at 64390]
2016.02.21 00:17:02.511 2016.01.18 13:46:40   deal #84 buy 2.00 RTS Splice at 64390 done (based on order #84)
2016.02.21 00:17:02.511 2016.01.18 13:46:40   instant buy 2.00 RTS Splice at 64390 (64380 / 64390 / 64380)
2016.02.21 00:17:02.366 2016.01.18 13:43:40   CTrade::OrderSend: instant sell 2.00 RTS Splice at 64410 [done at 64410]
2016.02.21 00:17:02.366 2016.01.18 13:43:40   order performed sell 2.00 at 64410 [#83 sell 2.00 RTS Splice at 64410]
2016.02.21 00:17:02.366 2016.01.18 13:43:40   deal performed [#83 sell 2.00 RTS Splice at 64410]
2016.02.21 00:17:02.366 2016.01.18 13:43:40   deal #83 sell 2.00 RTS Splice at 64410 done (based on order #83)
2016.02.21 00:17:02.366 2016.01.18 13:43:40   instant sell 2.00 RTS Splice at 64410 (64410 / 64420 / 64410)
2016.02.21 00:17:02.269 2016.01.18 13:41:40   CTrade::OrderSend: instant buy 2.00 RTS Splice at 64290 [done at 64290]
2016.02.21 00:17:02.269 2016.01.18 13:41:40   order performed buy 2.00 at 64290 [#82 buy 2.00 RTS Splice at 64290]
2016.02.21 00:17:02.269 2016.01.18 13:41:40   deal performed [#82 buy 2.00 RTS Splice at 64290]
2016.02.21 00:17:02.269 2016.01.18 13:41:40   deal #82 buy 2.00 RTS Splice at 64290 done (based on order #82)

ни одной ошибки.

Был неправ, топикстартер что то перемудрил.

Код в студию. 

Вот мой код для проверки:

//+------------------------------------------------------------------+
//|                                                TestCtradeBuy.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>

input double Lot = 1.0;

CTrade trade;
double close[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   ArraySetAsSeries(close,true);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   double poslot=0.0;
   bool posselect=false;
   ENUM_POSITION_TYPE postyp=-1;
   CopyClose(_Symbol,PERIOD_CURRENT,0,3,close);
   double lot=Lot;
   if(PositionSelect(_Symbol))
     {
      posselect=true;
      postyp=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
      poslot=PositionGetDouble(POSITION_VOLUME);
      if(postyp==POSITION_TYPE_SELL) poslot*=-1.0;
     }
   if(close[1]>close[2])
     {
      if(!posselect || postyp==POSITION_TYPE_SELL)
        {
         trade.Buy(Lot-poslot);
        }
     }
   if(close[1]<close[2])
     {
      if(!posselect || postyp==POSITION_TYPE_BUY)
        {
         trade.Sell(Lot+poslot);
        }
     }
  }
//+------------------------------------------------------------------+
 

Была такая проблема раньше в тестере, это точно. У меня в СД заявка была:

10015 (TRADE_RETCODE_INVALID_PRICE)
Ошибки, MetaTrader 5 MQL5, Закрыта, Начата: 2013.10.05 23:33, #857784

Описание проблемы

На инструменте с шагом цены равным 5 пунктов при попытке открытия позиции с использованием стандартной библиотеки периодически вываливается ошибка 10015.

Support Team 2013.10.21 11:21
Слава, проверяй - похоже ты генерированный поток цен где то не нормализуешь по размеру тика....

 

Потом ошибку исправили (точное время или билд не скажу, они забыли отписаться и выяснилось это уже в 2015-м):

Support Team 2015.09.16 07:32

komposter #

Еще одна старая заявка. Будете проверять?

Так уже исправили давно.

На момент исправления данная заявка ушла куда-то далеко, поэтому сюда и не отписались

 
Yury Reshetov:

С какого перепугу они Вам что-то должны?

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

Маркет-приказ не подразумевает указания цены и допустимого отклонения.

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

Поэтому и понятие requote ("пере-котирование", "новая котировка") к нему не применимо. 

 
Сергей Лебедев:

заявки по "RTS Splice" размещаются  с типом "instant" и 40% из них НЕ  исполняются, тестер выдает ошибку "invalid price".

Попробуйте установить тип заливки для этого инструмента перед отправкой приказа:

CTrade trade;

void SetFillingType( string aSymbol )
{
        ENUM_SYMBOL_TRADE_EXECUTION exec=(ENUM_SYMBOL_TRADE_EXECUTION)SymbolInfoInteger( aSymbol, SYMBOL_TRADE_EXEMODE);
        if(exec==SYMBOL_TRADE_EXECUTION_REQUEST || exec==SYMBOL_TRADE_EXECUTION_INSTANT)
        {
                trade.SetTypeFilling( ORDER_FILLING_FOK );
        }
        else
        {
                //--- get possible filling policy types by symbol
                uint filling=(uint)SymbolInfoInteger(aSymbol,SYMBOL_FILLING_MODE);
        
                //--- for the MARKET execution mode
                if(exec==SYMBOL_TRADE_EXECUTION_MARKET)
                {
                        //--- in case of instant execution order
                        //--- if the required filling policy is supported, add it to the request
                        if((filling & SYMBOL_FILLING_ALL_OR_NONE)!=0)
                        {
                                trade.SetTypeFilling( ORDER_FILLING_FOK );
                        }
                        else if((filling & SYMBOL_CANCEL_REMAIND)!=0)
                        {
                                trade.SetTypeFilling( ORDER_FILLING_IOC );
                        }
                }
                //--- EXCHANGE execution mode
                else
                {
                        //--- in case of limit order or instant execution order
                        //--- if the required filling policy is supported, add it to the request
                        if((filling & SYMBOL_FILLING_ALL_OR_NONE)!=0)
                        {
                                trade.SetTypeFilling( ORDER_FILLING_FOK );
                        }
                        //--- in case of limit order or instant execution order
                        //--- if the required filling policy is supported, add it to the request
                        else if((filling & SYMBOL_CANCEL_REMAIND)!=0)
                        {
                                trade.SetTypeFilling( ORDER_FILLING_IOC );
                        }
                        else
                        {
                        //--- add filling policy to the request
                                trade.SetTypeFilling( ORDER_FILLING_RETURN );
                        }
                }
        }
}

Или, по крайней мере, посмотрите, что показывает "SYMBOL_TRADE_EXEMODE".

 

 Sergey Chalyshev, да в вашем примере ошибка не возникает, но это не значит что она не возникает вообще.

В своем советнике я наблюдаю данную проблему, и вижу то что она возникает где-то вовне (либо в проверочных функциях CTrade, либо в функции OrderSend). Поэтому в ближайшие дни я постараюсь сделать демонстрационный советник, который ее воспроизведет.

 

Andrey Khatimlianskii, благодарю за информацию – действительно ценный пост.

По факту выяснилось, что в "Открытии" следующий расклад:

 - торгуемые фьючерсы и склейки Si, SBRF, BR, GOLD, ED имеют тип SYMBOL_TRADE_EXECUTION_EXCHANGE,

 - торгуемые фьючерсы RTS имеют SYMBOL_TRADE_EXECUTION_EXCHANGE, а склейка RTS имеет тип SYMBOL_TRADE_EXECUTION_INSTANT.

У "БКС" у меня реальные счета на всех секциях, поэтому выяснилось следующее:

 - на валютной секции USDRUB_TOM, EURRUB_TOM имеют тип SYMBOL_TRADE_EXECUTION_EXCHANGE,

- на фондовой секции все бумаги имеют тип SYMBOL_TRADE_EXECUTION_EXCHANGE,

 - на секции ФОРТС торгуемые фьючерсы  имеют тип SYMBOL_TRADE_EXECUTION_EXCHANGE, а все склейки Si, SBRF, BR, GOLD, ED, RTS имеет тип SYMBOL_TRADE_EXECUTION_INSTANT.

Тут конечно сам собой наращивается общий вопрос - зачем вообще сервер MT5 предоставляется брокерам возможность установить режим "EXECUTION_INSTANT" для склеек биржевых фьючерсов???

С точки зрения здравой логики у всех склеек  должен быть тот же тип что и у базовых фьючерсов - "EXECUTION_EXCHANGE". Тем более что на моем советнике видно, что иной тип исполнения приводит к появлению при тестировании ошибок  не свойственных биржевым инструментам.

 
Сергей Лебедев:

 Sergey Chalyshev, да в вашем примере ошибка не возникает, но это не значит что она не возникает вообще.

В своем советнике я наблюдаю данную проблему, и вижу то что она возникает где-то вовне (либо в проверочных функциях CTrade, либо в функции OrderSend). Поэтому в ближайшие дни я постараюсь сделать демонстрационный советник, который ее воспроизведет.

На самом деле формирование цены прозрачно и элементарно отслеживается в режиме "Отладка на истории" в MetaEditor'e:

Поставить точку останова и запустить отладку на истории

и уже будет видно, что цена берётся:

Откуда берётся цена 

Ничего сверхъестественного.

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