В общем, я тут добрался до изучения серверных стопов. И я в печали. Не знаю, как там было в 2012, но точно знаю как всё работает сейчас. Исходные данные: демо-квик версия 7.6.1.1, винда 7х32 бита, свежее API 4.3.19.5, плюс для контроля старенькое API 4.3.13. Ну погнали. Сперва рассмотрим, что не работает из вышеописанного.
Memory Т.е. через Order.DerivedOrder? Его отслеживать? И все равно не понятно почему по исполнению стоп зяаявки не создается событие NewMyTrade? ИМХО это вполне логично.
Всё верно, в API 4.3.19.5 событие NewMyTrade после срабатывания лимитки, которую породил стоп, не реагирует никак. Зато в старом API 4.3.13 - всё работает как надо, т.е. после срабатывания лимитки, даннео соыбтие отрабатывает сделки по ней.
esper Да, при срабатывании стопа выставляется новая лимитка, которая записывается в DerivedOrder, и именно по ней уже будут приходить сделки.
Данное свойство всё время нулл. Даже после того как реальная лимитка, которую породил стоп, - исполнилась, свойство всё равно нулл.
esper При использовании правила Order.WhenNewTrades должно все работать.
Должно, но не работает ))). Правило не реагирует никак. Вообще никак.
Mikhail Sukhov Есть еще правило WhenActivated
Не работает, как в API 4.3.13, так и в API 4.3.19.5. Данное правило вообще никак не реагирует на стоп. В иходниках данного правила заложена проверка свойства Order.DerivedOrder. Но данное свойство всегда нулл: как до срабатывания стопа, так и после срабатывания стопа и выставления реальной лимитки. Данное свойство всегда нулл. Судя по исходникам, как я понял, данное свойство должен наполнять именно коннектор, оно вроде как не рассчётное.
Alexander esper paveld Можно создать соответствующие правила для заявки, например так:
Code
stopOrder.WhenMatched().Do(StopOrderMatched).Once().Sync(new object()).Apply(this); // Полное исполнение
stopOrder.WhenPartiallyMatched().Do(StopOrderPartiallyMatched).Apply(this); // Частичное исполнение
Эти правила сработают тоже только при активации стопа, а не при исполнении порожденной заявки.
Для квика и для смарта это правила срабатывает именно при полном и частичном исполнении порождённой заявки, Павел всё верно написал.
Нет. Выше было верно сказало: правила сработают лишь при активации стопа. Порождённую заявку они никак не учитывают.
Вот такая вот ситуация. Как я высянял всё вышеописанное? Вообще, мне как и автору поста, нужна была обратная связь об исполнении стопа. Изучив документацию, я решил воспользоватсья свойством Order.DerivedOrder, ну чтобы получить реальную лимитную заявку для последующего отслеживания её состояния. Для этого я через метод WhenActivated() создал "правило на событие активации стоп-заявки", заснулул туда логику с Order.DerivedOrder и тупо начал ждать счастия ))). Ждал час, два, сутки, год - так и не дождался ))). Не сработало данное событие. Тогда я дополнительно подписался на 8 событий и начал ждать чуда там ))). В итоге, получились следующие подписки:
1. var oslRule = orderServerStopLoss.WhenActivated(Connector)...
2. var oslRule2 = orderServerStopLoss.WhenMatched(Connector)...
3. var oslRule3 = orderServerStopLoss.WhenNewTrade(Connector)...
4. var oslRule4 = orderServerStopLoss.WhenAllTrades(Connector)...
5. Connector.NewOrders += (newOrdersCollArg) => ...
6. Connector.NewStopOrders += (newStopOrdersCollArg) => ...
7. Connector.StopOrdersChanged += (stopOrdersChangedArg) =>...
8. Connector.NewMyTrades += (newMyTradesCollArg) => ...
9. Connector.NewTrades += (newTradesCollArg) =>...
В 8ми вышеописанных событиях, я поставил по точке останова для изучения поведения всей системы. В 9м событии - не стал пока ставить точку останова, я её поставлю позднее, для итогового контроля содержимых коллекции. Стратегия была простая: выставляем лимитку на покупку, по лучшему биду, объёмом 1 конь. После её исполнения выставляется стоп с ценой активации на 5 шагов ниже. Причём, чтобы отследить отработку всех событий, я цену селл-лимитки, которую стоп отправит в стакан - загнул не ниже цены активаци стопа, ну как все делают обычно, а выше - чтобы стопик повисел в стакане какое-то время. То есть, при активации стопа, порождённая селл-лимитка не исполнится мгновенно, т.к. будет выставлена на 5 шагов выше лучшего аска. Чтобы её исполнить, цене надо будет подрасти.
Что получилось в итоге?
Этап 1. После запуска робота, лимитка на покупку ушла в стакан. После её исполнения, отработало событие "Connector.NewMyTrades += (newMyTradesCollArg) => ..." ну как положено. Следом выставился серверный стоп и отработали события "Connector.NewStopOrders += (newStopOrdersCollArg) => ..." и "Connector.StopOrdersChanged += (stopOrdersChangedArg) =>..."
Этап 2. Спустя пару минут сработал стоп. И в стакан полетела лимитка, которую он породил. Сразу сработало 2 события: "var oslRule2 = orderServerStopLoss.WhenMatched(Connector)..." и "Connector.StopOrdersChanged += (stopOrdersChangedArg) =>..."
Этап 3. Спустя 10-15 минут, лимитку которую породил стоп - скушали. При этом никаких событий вызвано не было.
Вот такие дела, обстоят с новым API 4.3.19.5. Ниже я приложил скрин со всем этим безобразием. На втором этапе, когда стоп породил лимитку, СтокШарп на неё никак не отреагировал, т.е. не было вызвано событие "Connector.NewOrders += (newOrdersCollArg) =>...", хотя в старом API 4.3.13 - оно вызывается, как и положено и данная лимитка нормально отображается в системе, т.е. через данное событие раньше можно было поймать лимитку которую выставил стоп. Но в API 4.3.19.5 её как бы и нет. Хотя если после отрабатотки стратегии, поставить точку останова на 9м событии и глянуть коллекцию Connector.Orders, то там мы найдём 5 заявок, из которых последние три штуки: это как раз какие-то битые клоны данной заявки, но со статусом "Ноне", типа биржа их отвергла. Причём, данные битые клоны не отображаются в стандартной табличке OrderGrid, там мы найдём лишь одну заяву на покупку. А вторую стоп-заявку найдём в другой таблице OrderConditionalGrid. То есть, эти три полу-пустых объекта заявок, кроме коллекции Connector.Orders - больше нигде не видно. Вот какие дела. То же самое и с третим этапом, после того как лимитку скушали, в новом API 4.3.19.5 не было никакой реакции. Вообще ничего. Хотя в старом API 4.3.13 было вызвано событие "Connector.NewMyTrades += (newMyTradesCollArg) => ..." через которое прошли сделки от этой лимитки. В новом API ничего такого не было: лимитку скушали, а СтокШарп этого не заметил. Если заглянуть в коллекцию Connector.Trades то там мы обнаружим всего 1 сделку, ту которая открывала позу. Сделки от лимитки, которую породил стоп, и которая закрыла позу - там нет. То есть, СтокШарп проморгал и её.
Вот такие дела. Больше никакие события не срабатывали. Свойство Order.DerivedOrder - всегда было нулл, как на новом, так и на старом API. Соотвевенно никак не срабатывало и правило созданное методом WhenActivated. События не работают, реальные заявки(попадают битыми) и сделки - не попадают в коллекции. В общем, надо править данные баги. Ниже я представил скрин, как всё работает в новом API 4.3.19.5.
http://stocksharp.ru/file/104085