SmartQuant Discussion
http://www.smartquant.com/forums/

OSL FIX
http://www.smartquant.com/forums/viewtopic.php?f=65&t=8993
Page 1 of 3

Author:  Dr. Anton Fokin [ Sat Mar 26, 2011 6:17 pm ]
Post subject:  OSL FIX

В OpenQuant 3.1.0 была добавлена поддержка OSL FIX (ФК Открытие , http://www.open.ru )

Author:  zyko [ Thu May 05, 2011 3:06 pm ]
Post subject:  Re: OSL FIX

Открою обсуждение :wink:

В коде есть такая логика: по OnQuote рассчитывается некий уровень и при уходе от цены активной заявки она реплейсится.
При реплейсе я проверяю статус заявки на order.IsPendingReplace, чтобы не дублировать реплейс.

Теперь, что происходит: дубли отправляются по нескольку штук, в логе это выглядит так:
Code:
11:22:50.2500000 | Переставляем заявку : PRICE=21291
11:22:50.2812500 | Переставляем заявку : PRICE=21291
11:22:50.4375000 | Переставляем заявку : PRICE=21291
затем дублирование прекращается. Введение дополнительного replace-флага решает проблему.

Собственно, вопрос: изменение статуса заявки с Replaced на новый PendingReplace происходит по сообщению из fix, или это изменение должно быть сразу после order.Replace()?

Author:  Alexei Kurov [ Thu May 05, 2011 3:15 pm ]
Post subject:  Re: OSL FIX

все статусы, в том числе и PendingReplace, приходят от брокера. сам опенквант, по своему желанию, статусы не меняет никогда.

P.S. такие статусы, как PendingReplace и PendingCancel, довольно опциональны по жизни - брокер их может и не слать, а сразу Replaced и Cancelled

Author:  zyko [ Thu May 05, 2011 3:24 pm ]
Post subject:  Re: OSL FIX

Отлично, тогда решение о доп флаге - верное, поскольку за время прихода PendingReplace успевает навалиться куча квот. При этом получается, что с Pending-статусов вообще снимается алгоритмическая нагрузка.
Спасибо!

Author:  zyko [ Tue May 10, 2011 4:05 pm ]
Post subject:  Re: OSL FIX

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

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

2. Стояла заявка в статусе Pending, я отправил Replace, от брокера пришёл PendingReplace, и... заявка так и осталась в этом статусе до конца сессии. После PendingReplace брокер отправлял сообщение о снятии, которое OQ не обработал:
Code:
8=FIX.4.2|9=167|35=9|49=...|56=...|34=4892|369=3126|52=20110505-11:38:36|11=110505153836 2153|37=NONE|39=4|41=110505153835 2152|58=Transaction checking failed|434=2|100=FORTS|10=242
Почему сообщение не было обработано (его нигде нет)? Могло ли это быть связано со значением 35=9 вместо 8? А как правильно?

3. Была отправлена заявка, затем, не дожидаясь статуса New, я отправил Cancel (проверку на статус я добавлю, речь о другом). Брокер прислал сначала реджект на снятие:
Code:
8=FIX.4.2|9=193|35=9|49=...|56=...|34=15995|369=8685|52=20110505-13:33:03|11=110505173303 7707|37=NONE|39=8|41=110505173302 7706|58=Order is not found by OrigClOrdID: 110505173302 7706|434=1|100=FORTS|10=039
затем прислал статус New на отправку заявки. Реджекта снова нигде нет в OQ, заявка стала New, но... проект "потерял" эту заявку до конца сессии. Что произошло?

4. Похожая на предыдущую ситуация, только без снятия и реджектов: 8 заявок остались в статусе New до конца сессии. Через какое-то время я снял их вручную через Quik, то есть невидимо для OQ, и получил в главный log.txt восемь ошибок вида:
Code:
05.05.2011 18:24:20 Provider: OSL FIX
Id: -1
Code: -1
Message: System.ApplicationException: Unknown order - ExecutionReport ExecType = Cancelled ClOrdId = 110505154054 2428 OrigClOrdId =
   at SmartQuant.Execution.OrderManager.QElMRjTw2(Object , ExecutionReportEventArgs )
   at SmartQuant.Providers.ProviderManager.xeNgOvy53(Object , ExecutionReportEventArgs )
   at SmartQuant.FIXApplication.QuickFIX42Provider.2VEjIKQ6p(Object , ExecutionReportEventArgs )
   at SmartQuant.FIXApplication.QuickFIX42Application.EmitExecutionReport(ExecutionReport report)
   at YoUQanmAvfsC0XjoPQ.uMQgnuDigfThtwgRSQ.onMessage(ExecutionReport , SessionID )
Солюшен за это время не останавливал. Что произошло?

5. По окончании торговой сессии активные заявки на бирже были сняты и брокер отправил соответствующие ExecutionReports:
Code:
8=FIX.4.2|9=337|35=8|49=...|56=...|34=22791|369=12081|52=20110505-14:45:35|1=...|6=0|11=110505182337 10694|14=0|15=SUR|17=20110505#96056_77QF_694606735856000|20=0|22=8|31=0|
32=0|37=20110505#96056_77QF_69|38=28|39=4|40=2|44=20537|48=GZM1|54=1|55=GZM1|59=0|60=20110505-18:23:37|109=...|110=0|150=4|151=0|167=CS|207=FORTS|100=FORTS|10=226|
однако они снова не были обработаны и заявки остались в своих статусах Replaced. Почему?

Author:  Alexei Kurov [ Tue May 10, 2011 5:49 pm ]
Post subject:  Re: OSL FIX

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

2 и 3. Причина скорее всего кроется в том, что реквесты идут на заявки, которые еще не подтверждены брокером. Надо пробовать воспроизводить и разбираться.

4. Тут все ясно - реквестов от опенкванта на снятие не было и поле OrigClOrdID пустое - опенквант не может понять, что за заявка снята.

5. Ситуация примерно похожая на пункт 4. Заявка отменена брокером без запроса и OrigClOrdID пустое, то есть опенквант опять не может найти заявку у себя. вопрос, почему брокер прислал cancelled а не expired, если, как я понял, он отменил их по time in force?

Author:  zyko [ Tue May 10, 2011 8:08 pm ]
Post subject:  Re: OSL FIX

Алексей, спасибо, вроде понял, что происходило. Все вопросы свелись к пропаданию Reject и пустому OrigClOrdID:

2. Почему заявка не стала Rejected? Ведь вот оно - сообщение об ошибке. Как следствие - остановившаяся стратегия, ожидающая смены статуса.

3. Вот как я реконструировал события:
- запрос на новую заявку, ClOrdID=1 (условно)
- запрос на снятие заявки, ClOrdID=2, OrigClOrdID=1
- получение ответа по новой заявке, ClOrdID=1 (здесь статус стал New)
- получение реджекта на снятие, ClOrdID=2, OrigClOrdID=1
Тот же вопрос, почему заявка не стала Rejected? Она "подвисла" в стратегии, не реагируя больше ни на какие алгоритмы.

4. Вы говорите, что без Cancel запроса фикс движок не будет обрабатывать Cancel ответ. Это особенность движка?
Ведь брокер зачем-то шлёт сообщения без OrigClOrdID, а в OQ есть New заявка с указанным ClOrdID! Да, запроса не было, но что важнее - запрос или заявка?

5. Так как заявки снимает не брокер, а РТС, то статус Cancelled просто транслируется оттуда. Проблема понятна, то же что п.4.

Author:  Alexei Kurov [ Wed May 11, 2011 11:45 am ]
Post subject:  Re: OSL FIX

2. Она не стала Rejected, потому что она стала Cancelled - так по-крайней мере прислал брокер в своем OrderCancelReject сообщении. Другое дело, что в этой ситуации не сработали колбеки OnOrderCancelled и OnOrderDone, а сработал только OnOrderStatusChanged. Связано это с тем, что получение OrderCancelReject не может по идее считаться последним сообщением в жизни заявки (либо оно приходит уже после смерти) и поэтому в его обработке не предусмотренно все то, что касается OnOrderDone.
3. Причина почти такая же. Сработал только OnOrderStatusChanged на Rejected, а потом благополучно он же на статус New. Вообще, мне кажется, что в данной ситуации все случилось более-менее правильно, ибо став Rejected, заявка должна была умереть и дальнейший репорт со статусом New привел бы либо к неправильной логике либо опять-таки к тому, что не найдена заявка.
4 и 5. Нет, движку в прицнипе все равно до логики сообщений - он следит только за правильностью формата этих сообщений. (если речь о квикфиксе)
Но наш менеждер заявок имеет алгоритм, который подразумевает, что получение кенселов или реджектов на них, следует за запросами на эти кенселы. Подразумевает в том плане, что ему надо находить заявку для которой пришло это сообщение, а ищет он ее по ClrOrdID и по OrigClOrdID в случае репортов касающихся снятия/реплейса заявок. Вполне естественно, что заявка снятая не по фиксу может не иметь этого OrigClOrdID, ввиду отсутствия реквеста так такового. Тут вопрос, как этот момент должен быть обыгран - то ли брокер может в этом случае ставить OrigClOrdID равным ClOrdID, раз он решает послать репорт(без реквеста) по фикс сессии, либо плагин может этим заниматься, если OrigClOrdID пустой в репортах такого типа.

Author:  zyko [ Wed May 11, 2011 2:39 pm ]
Post subject:  Re: OSL FIX

2. Вы говорите, что OnOrderStatusChanged срабатывал. Я не обрабатывал это событие в коде, но вижу, что заявка осталась PendingReplace!
Для OrderCancelRequest и OrderCancel/ReplaceRequest предусмотрен один OrderCancelReject, для снятия он действительно не может быть последним сообщением по заявке, однако для реплейса - может. Брокер реализует реплейс по-своему. В данном случае я отправил реплейс, брокер снял заявку, не смог выставить новую и прислал реджект с Cancel статусом заявки - вроде всё верно. Адаптер может в этом случае сгенерить OnOrderStatusChanged, OnOrderCancelled и OnOrderDone?

3. У этой заявки в транзакциях всего один статус - New! Reject пришёл уже после. Как и в п.2, заявка осталась в прежнем статусе, проигнорировав реджект. Мне кажется, статус 39=8 в этом OrderCancelReject не относился к заявке, поскольку она осталась активной на бирже. Поэтому заявка должна была продолжить жить в статусе New. Мы потеряли бы запрос на снятие, но в этом нет ничего страшного - сгенерировали бы новый. Но в том-то и дело, что она "зависла" в непонятном статусе и стратегия не считала заявку New, не могла её снять или переставить. Почему? Такое ощущение, что ордерменеджер среагировал бы только на Cancel.

4 и 5. В реалиях конкретных бирж и брокера такие репорты через фикс возможны. Хочу попросить вас апдейтить плагин для пустого OrigClOrdID в ExecutionReport.

Author:  Alexei Kurov [ Wed May 11, 2011 3:14 pm ]
Post subject:  Re: OSL FIX

почти готов согласиться с тем, что в реалии возможно, что реплейс обломился на половине, хотя по идее, это атомарная операция и брокер должен быть уверен что выставит новую цену или размер, а не говорить - упс, текущую отменил, а новую не удалось выставить.:-) реквест на реплейс все-таки не должен заканчиваться тем, что я остался совсем без заявки. ну да ладно - это теория, а в жизни бывает, как я теперь вижу.
да, можно поправить плагин чтобы шли события из серии "OnOrderDone" в случае внезапной смерти заявки на реплейсе и подменяло OrigClOrdID в случае пустого.
для меня остается странным то, что не поменялся статус заявки(хотя бы визуально в ордер манагере) после этих реджектов. но, Вы уверены в этом? Вы просто не видите реджекты - их не показывает в списке репортов - надо смотреть на саму заявку, на колонку статуса.

Author:  zyko [ Wed May 11, 2011 3:53 pm ]
Post subject:  Re: OSL FIX

Вот два скриншота, иллюстрирующих п.п.2 и 3.

По поводу корректности реплейса, ну вот на ММВБ в принципе нет такой транзакции, брокер не может заранее гарантировать перестановку, потому что новая заявка может быть отвергнута по всяким причинам. Почему он переставляет на FORTS двумя транзакциями - этот вопрос я брокеру задам, но не сегодня.

Вам стал понятен п.3? Почему заявка "зависла" в статусе New?

Я почему так дотошно: потому что мне до сих пор непонятно, почему 39=4 в одном случае относится к заявке, а 39=8 в другом случае относится к реквесту. Во втором случае, по идее, заявка не должна стать Rejected, а должна продолжить слушать ExecReport.

Attachments:
oq_2_pendingreplace.jpg
oq_2_pendingreplace.jpg [ 75.02 KiB | Viewed 14668 times ]
oq_3_new.jpg
oq_3_new.jpg [ 25.99 KiB | Viewed 14668 times ]

Author:  Alexei Kurov [ Wed May 11, 2011 5:06 pm ]
Post subject:  Re: OSL FIX

zyko wrote:
Вам стал понятен п.3? Почему заявка "зависла" в статусе New?

Теперь нет. Вы же пару постов назад писали, что послали кенсел на еще неподтвержденную заявку, на что брокер Вам сначала прислал корректный реджект(неизвестное OrigClOrdID), а потом пришел репорт со статусом New.
Я вроде нашел обьяснение данному феномену - заявка стала Rejected, а потом New, а Вы этого не заметили по причине того, что CancelReject'ы не пишутся в таблицу репортов и Вы видите только один New.
И вдруг вопрос - почему "зависла" в статусе New :roll:

Author:  Dr. Anton Fokin [ Wed May 11, 2011 7:04 pm ]
Post subject:  Re: OSL FIX

А давайте писать CancelReject в таблицу репортов? :wink:

Author:  zyko [ Wed May 11, 2011 8:13 pm ]
Post subject:  Re: OSL FIX

Алексей, для проверки самого себя я накатал простенькую программку и прогнал её в ливе. При этом писал логи, чтобы иметь их на руках. Вот итоги:
- Вы правы, событие OnOrderStatusChanged отрабатывает реджект
- этот реджект нигде больше не отрабатывается и не отображается в заявке
- после прихода New вслед за реджектом не отрабатывается событие OnNewOrder, не знаю почему
- заявка готова к работе, все "подвисания" были нарушениями у меня в алгоритме

Quote:
да, можно поправить плагин чтобы шли события из серии "OnOrderDone" в случае внезапной смерти заявки на реплейсе и подменяло OrigClOrdID в случае пустого
Тогда буду ждать обновлений?

P.S. Последним неясным моментом всё-таки является несрабатывание OnNewOrder (может, и других) по событию New после реджекта. Если надо - могу залогировать вообще все события и прогнать ситуацию в ливе.

Author:  Alexei Kurov [ Thu May 12, 2011 9:41 am ]
Post subject:  Re: OSL FIX

zyko wrote:
Тогда буду ждать обновлений?

P.S. Последним неясным моментом всё-таки является несрабатывание OnNewOrder (может, и других) по событию New после реджекта. Если надо - могу залогировать вообще все события и прогнать ситуацию в ливе.


Да, мы поправим. В следующий релиз опенкванта войдет. Думаю, завтра.

OnNewOrder - Вас ввело в заблуждение слово New.
На самом деле, это событие вызывается, когда во фреймворке появляется новая заявка.
Возникает оно между order.Send() и получением плагином для реальной отправки брокеру. Его смысл, чтобы все кому интересно, могли начать отслеживать заявку с самого начала, а не с первого по ней репорта типа New. Согласен, небольшая путаница тут есть, раз начальное состояние заявки PendingNew, но так уж есть.
Кстати, обратите внимание, что все-таки евент называется OnNewOrder, а не OnOrderNew(по аналогии с другими событиями по заявкам).
С другой стороны, только что понял, что у нас нет что-то вроде OnOrderAccepted и пока можно ловить статус New только в OnOrderStatusChanged

Page 1 of 3 All times are UTC + 3 hours
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/