Здравствуйте, коллеги.
Столкнулся с проблемой: в боевом режиме, т.е. при использовании объекта QuikTrader, не вызывается событие NewMyTrades у MarketQuotingStrategy, однако в демо режиме, т.е. при использовании new RealTimeEmulationTrader<QuikTrader>, событие вызывается как положено. В обоих случаях событие ITrader.NewMyTrades вызывается нормально.
Важный момент, проблема наблюдается в последних версиях, проверял в 13417, 12460. Однако все работает в версии 12366. К сожалению, точнее определить версию в которой начала наблюдаться ошибка не могу. Из-за неудобного способа получения новых версий (codeplex download archive) обновляюсь не часто. Пользуясь моментом, хочу попросить доступ на чтение к репозиторию (мой id на codeplex: akramarev).
Спасибо за помощь.
--
Значимые на мой взгляд детали.
Инициализация объекта типа ITrader:
if (rbFightMode.IsChecked.Value)
{
_trader = new QuikTrader(this.Path.Text);
}
else
{
_trader = new RealTimeEmulationTrader<QuikTrader>(new QuikTrader(this.Path.Text));
}
Выставление order'а внутри стратегии:
if (UseQuoting)
{
MarketQuotingStrategy marketQuotingStrategy = new MarketQuotingStrategy(order, new Unit(), new Unit());
marketQuotingStrategy.NewMyTrades += ProtectMyNewTrades;
base.ChildStrategies.Add(marketQuotingStrategy);
}
else
{
base.RegisterOrder(order);
}
Обработчик события marketQuotingStrategy.NewMyTrades (именно этот обработчик не вызвается в боевом режиме):
private void ProtectMyNewTrades(IEnumerable<MyTrade> trades)
{
var basket = new BasketStrategy(BasketStrategyFinishModes.All);
foreach (MyTrade trade in trades)
{
var s = new BasketStrategy(BasketStrategyFinishModes.First) { Name = "ProtectStrategy" };
var takeProfit = new TakeProfitStrategy(trade, this.TakeProfitUnit)
{
Name = "TakeProfitStrategy",
BestPriceOffset = 15,
PriceOffset = 3,
UseQuoting = this.UseQuoting
};
var stopLoss = new StopLossStrategy(trade, this.StopLossUnit)
{
Name = "StopLossStrategy",
PriceOffset = 3
};
s.ChildStrategies.Add(takeProfit);
s.ChildStrategies.Add(stopLoss);
basket.ChildStrategies.Add(s);
}
base.ChildStrategies.Add(basket);
}
Лог работы при использовании RealTimeEmulationTrader<QuikTrader>:
MQS | 05.01.2012 12:30:05.081 | | Заканчиваем котирование. MQS | 05.01.2012 12:30:05.097 | | Стратегия остановлена. MQS | 05.01.2012 12:30:05.081 | | Стратегия останавливается. MQS | 05.01.2012 12:30:05.081 | | Позиция изменилась на -2. Оставшийся объем 0. StopLossStrategy | 05.01.2012 12:30:05.081 | | Котирование на Buy объема 2. StopLossStrategy | 05.01.2012 12:30:05.081 | | Защита сделки 1 заявки 43787560. StopLossStrategy | 05.01.2012 12:30:05.081 | | Стратегия запущена. TakeProfitStrategy | 05.01.2012 12:30:05.081 | | Котирование на Buy объема 2. TakeProfitStrategy | 05.01.2012 12:30:05.081 | | Защита сделки 1 заявки 43787560. TakeProfitStrategy | 05.01.2012 12:30:05.081 | | Стратегия запущена. ProtectStrategy | 05.01.2012 12:30:05.081 | | Стратегия запущена. BS | 05.01.2012 12:30:05.081 | | Стратегия запущена. MQS | 05.01.2012 12:30:05.065 | | Новая Sell сделка 1 по цене 8449 на 2 заявки 43787560. EmaEventModelStrategy | 05.01.2012 12:30:05.065 | | Новая Sell сделка 1 по цене 8449 на 2 заявки 43787560. MQS | 05.01.2012 12:30:05.065 | | Перекотирование зарегистрировано для заявки 43787561 на Sell с ценой 8450 объемом 2. MQS | 05.01.2012 12:30:05.065 | | Котирование заявки 43787560 на Sell с ценой 8449 объемом 2. MQS | 05.01.2012 12:30:05.065 | | Лучший бид 8449 и лучший аск 8450. MQS | 05.01.2012 12:30:05.065 | | Цена текущей 8449 и лучшей 8450. MQS | 05.01.2012 12:30:04.063 | | Заявка 43787560 принята биржей. MQS | 05.01.2012 12:30:04.063 | | Перекотирование зарегистрировано для заявки 43787560 на Sell с ценой 8449 объемом 2. MQS | 05.01.2012 12:30:04.063 | | Котирование заявки 43787559 на Sell с ценой 8450 объемом 2. MQS | 05.01.2012 12:30:04.063 | | Лучший бид 8448 и лучший аск 8449. MQS | 05.01.2012 12:30:04.063 | | Цена текущей 8450 и лучшей 8449. MQS | 05.01.2012 12:30:03.061 | | Заявка 43787559 принята биржей. MQS | 05.01.2012 12:30:03.061 | | Перекотирование зарегистрировано для заявки 43787559 на Sell с ценой 8450 объемом 2. MQS | 05.01.2012 12:30:03.061 | | Котирование заявки 43787558 на Sell с ценой 8454 объемом 2. MQS | 05.01.2012 12:30:03.061 | | Лучший бид 8449 и лучший аск 8450. MQS | 05.01.2012 12:30:03.061 | | Цена текущей 8454 и лучшей 8450. MQS | 05.01.2012 12:30:02.059 | | Заявка 43787558 принята биржей. MQS | 05.01.2012 12:30:02.059 | | Перекотирование зарегистрировано для заявки 43787558 на Sell с ценой 8454 объемом 2. MQS | 05.01.2012 12:30:02.059 | | Котирование заявки 43787557 на Sell с ценой 8455 объемом 2. MQS | 05.01.2012 12:30:02.059 | | Лучший бид 8451 и лучший аск 8454. MQS | 05.01.2012 12:30:02.059 | | Цена текущей 8455 и лучшей 8454. MQS | 05.01.2012 12:30:01.057 | | Заявка 43787557 принята биржей. MQS | 05.01.2012 12:30:01.057 | | Перекотирование зарегистрировано для заявки 43787557 на Sell с ценой 8455 объемом 2. MQS | 05.01.2012 12:30:01.057 | | Котирование заявки 43787556 на Sell с ценой 8456 объемом 2. MQS | 05.01.2012 12:30:01.057 | | Лучший бид 8454 и лучший аск 8455. MQS | 05.01.2012 12:30:01.057 | | Цена текущей 8456 и лучшей 8455. MQS | 05.01.2012 12:30:00.383 | | Заявка 43787556 принята биржей. MQS | 05.01.2012 12:30:00.368 | | Заявка 43787556 на Sell отправлена с ценой 8456 объемом 2. MQS | 05.01.2012 12:30:00.352 | | Регистрация новой заявки на Sell с ценой 8456 и объемом 2. MQS | 05.01.2012 12:30:00.352 | | Лучший бид 8455 и лучший аск 8456. MQS | 05.01.2012 12:30:00.352 | | Цена текущей NULL и лучшей 8456. MQS | 05.01.2012 12:30:00.321 | | Котирование на Sell объема 2. MQS | 05.01.2012 12:30:00.321 | | Стратегия запущена. EmaEventModelStrategy | 05.01.2012 12:30:00.305 | | Xing Down appeared (CandleTime: 05.01.2012 12:25:00), and filter allowed the deal. EmaEventModelStrategy | 05.01.2012 12:09:50.704 | | Стратегия запущена.
Лог работы при использовании QuikTrader:
MQS | 06.01.2012 15:10:47.107 | | Позиция изменилась на -2. Оставшийся объем 0. EmaEventModelStrategy | 06.01.2012 10:35:57.031 | | Стратегия запущена. EmaEventModelStrategy | 06.01.2012 12:15:01.821 | | Xing Up appeared (CandleTime: 06.01.2012 12:10:00), but filter blocked the deal. EmaEventModelStrategy | 06.01.2012 15:10:18.733 | | Xing Down appeared (CandleTime: 06.01.2012 15:05:00), and filter allowed the deal. MQS | 06.01.2012 15:10:18.765 | | Стратегия запущена. MQS | 06.01.2012 15:10:18.765 | | Котирование на Sell объема 2. MQS | 06.01.2012 15:10:18.796 | | Цена текущей NULL и лучшей 8332. MQS | 06.01.2012 15:10:18.796 | | Лучший бид 8330 и лучший аск 8332. MQS | 06.01.2012 15:10:18.796 | | Регистрация новой заявки на Sell с ценой 8332 и объемом 2. MQS | 06.01.2012 15:10:18.812 | | Заявка 38153494 на Sell отправлена с ценой 8332 объемом 2. MQS | 06.01.2012 15:10:18.984 | | Заявка 38153494 принята биржей. MQS | 06.01.2012 15:10:26.788 | | Цена текущей 8332 и лучшей 8331. MQS | 06.01.2012 15:10:26.788 | | Лучший бид 8330 и лучший аск 8331. MQS | 06.01.2012 15:10:26.788 | | Котирование заявки 38153494 на Sell с ценой 8332 объемом 2. MQS | 06.01.2012 15:10:26.788 | | Перекотирование зарегистрировано для заявки 38153495 на Sell с ценой 8331 объемом 2. MQS | 06.01.2012 15:10:26.977 | | Заявка 38153495 принята биржей. MQS | 06.01.2012 15:10:42.867 | | Цена текущей 8331 и лучшей 8330. MQS | 06.01.2012 15:10:42.867 | | Лучший бид 8329 и лучший аск 8330. MQS | 06.01.2012 15:10:42.867 | | Котирование заявки 38153495 на Sell с ценой 8331 объемом 2. MQS | 06.01.2012 15:10:42.867 | | Перекотирование зарегистрировано для заявки 38153496 на Sell с ценой 8330 объемом 2. MQS | 06.01.2012 15:10:43.134 | | Заявка 38153496 принята биржей. EmaEventModelStrategy | 06.01.2012 15:10:47.107 | | Новая позиция -2. MQS | 06.01.2012 15:10:47.107 | | Новая позиция -2. MQS | 06.01.2012 15:10:47.107 | | Заканчиваем котирование. MQS | 06.01.2012 15:10:47.107 | | Стратегия останавливается. MQS | 06.01.2012 15:10:47.122 | | Стратегия остановлена. EmaEventModelStrategy | 06.01.2012 15:10:47.154 | | Новая Sell сделка 485257991 по цене 8330 на 2 заявки 38153496.
Kommentare (18)
Anmelden oder Konto erstellen, Melden Sie sich an oder registrieren Sie sich, um einen Kommentar zu hinterlassen
как понимаете что не вызывается обработчик? а сделки-то у MQS проходят?
В хронологическом порядке как обнаруживал проблему:
Дело в том, что порой стратегия MQS может завершится раньше чем придёт событие о новой сделки (NewMyTrades) Что у вас и происходит.
Есть 2 выхода:
P.S. Доступ на codeplex даём тем, кто готов вносить изменения в исходный код, выложенный там.
Большое спасибо за ответ, Александр.
Сразу возникает вопрос, не видите ли вы способа внутри MQS синхронизировать генерацию события NewMyTrade и смены ProcessState стратегии (и генерации ProcessStateChanged соответственно), чтобы событие нового трейда гарантированно файрилось до того, как стратегия отрапортует о своем завершении? Сложно что-то предполагать не видя реализации, но судя по всему метод генерирующий NewMyTrade (что-нибудь вроде OnNewMyTrade) слишком долго ждет какого-то ресурса (шлюза ITrader, например, пока другие события успешно генерируются), может его можно пересмотреть? Или, например, заставить Strategy.DisposeManaged() (если именно этот метод вызывается для уничтожения родительской стратегии - дочерней) как-то подождать завершения генерации всех событий.
И еще небольшой вопрос, я не совсем понял второе решение:
Например этот анонимный метод никогда не будет вызван:
Или я неправильно вас понял?
Нет, внутрях MQS не будет ничего меняться. События из QuikTrader, да и из любого трейдера не синхронны - нам событие о новой сделке может придти до \ после события о новом ордере.
У MQS есть событие NewOrders для этих новых ордеров можно создавать любые правила которые угодны
И да, вариант с RemoveChildStrategies намного проще.
Все же не очень понятно.
Спасибо, понял. Но если событие MQS.NewMyTrades может не успеть выполниться до уничтожения объекта стратегии, где гарантия, что события на порожденные ею orders успеют выполниться? Или эти orders никак не затрагиваются при dispose стратегии?
Нет, не так. MQS останавливается следующим образом:
либо - по TimeOut.
Т.к. не так - остальное рассуждение не требует ответа.
Спасибо, теперь стало все гораздо яснее. Первичность ордеров перед сделками в принятии решения на остановку было ключевым моментом.
Гораздо, но не полностью, к сожалению.
Александр, подскажите пожалуйста, почему подобная конструкция также не работает с QuikTrader'ом:
Симптомы те же: ProtectMyNewTrades вызывается в RealTimeEmulationTrader и не вызывается в QuikTrader. Как же правильно защитить сделки после котирования?
Думаю мой вопрос примерно в эту тему. Заранее прошу сильно не ругаться т.к. только начинаю осваивать C# и S# (4.0.14.0)
Есть некая событийная стратегия FirstStrategy. По замыслу она должна торговать не более чем одним контрактом(RIH2)
В связи с тем, что this.PositionManager.Position основной стратегии запаздывает относительно Котировния, для учета позиции использую this.CurrentPosition. При тестировании SampleHistoryTesting поля CurrentPosition и this.PositionManager.Position ведут себя изменяются в диапазоне -1,0,1, что и требуется. А при тестировании SampleRealTimeTesting this.PositionManager.Position вылетает далеко за рамки одного контракта. В связи с этим вопрос - как правильно учитывать позицию основной стратегии в тестах и в бою?
Ни разу не вызывается?
Подпишитесь на Trader.NewMyTrades и посмотрите приходят ли там сделки, равные qOrder.
Прошу игнорировать последний мой вопрос, приведенная выше конструкция работает стабильно (насколько мне удалось потестировать) с QuikTrader'ом (при RemoveChildStrategies == true). Проблема, мешавшая вызываться обработчику, заключалась в том, что поток прерывался Exception'ом в другом обработчике (в логи, к сожалению, ничего не попадало):
t.Trade.OrderDirection есть Nullable enum и в нем регулярно был null вместо значения, чего я не ожидал (хотя должен был). Александр, подскажите, почему в сформированном trade OrderDirection может быть null (все остальные поля объекта были заполнены верными значениями)? И самое интересное TradeGrid подобные трейды отображал нормально, с верным направлением - что необходимо вызвать дополнительно чтобы OrderDirection заполнился верным значением?
Поставьте бряку в начало функции, посмотрите - есть ли там OrderDirection у сделок в пришедшем массиве
Вот как интересно:
((StockSharp.BusinessEntities.MyTrade[])(trades))[0].Trade.OrderDirection = null ((StockSharp.BusinessEntities.MyTrade[])(trades))[0].Order.Direction = Buy
OK, спасибо!
Это очевидно, когда знаешь и видишь как заполняется объект, тут же, когда не видишь исходного кода, - просто ожидаешь наиболее очевидного варианта. Здесь я думал, что значение, в случае не передачи шлюзом, просто копируется из породившего сделку order'а.
Спасибо за ваше время, ответы и ваш труд над S#.
Нет, документация как раз тоже не говорит о том что что-то куда-то копируется. У нас для ордера на Sell легко могут проходить как Buy, так и Sell сделки.
Хотя, наверное, можно было понять двояко.