Событие MarketQuotingStrategy.NewMyTrades и QuikTrader


Событие MarketQuotingStrategy.NewMyTrades и QuikTrader
Atom
1/6/2012


ak

Avatar
Здравствуйте, коллеги.

Столкнулся с проблемой: в боевом режиме, т.е. при использовании объекта QuikTrader, не вызывается событие NewMyTrades у MarketQuotingStrategy, однако в демо режиме, т.е. при использовании new RealTimeEmulationTrader<QuikTrader>, событие вызывается как положено. В обоих случаях событие ITrader.NewMyTrades вызывается нормально.

Важный момент, проблема наблюдается в последних версиях, проверял в 13417, 12460. Однако все работает в версии 12366. К сожалению, точнее определить версию в которой начала наблюдаться ошибка не могу. Из-за неудобного способа получения новых версий (codeplex download archive) обновляюсь не часто. Пользуясь моментом, хочу попросить доступ на чтение к репозиторию (мой id на codeplex: akramarev).

Спасибо за помощь.

--

Значимые на мой взгляд детали.

Инициализация объекта типа ITrader:

Code
if (rbFightMode.IsChecked.Value)
{
    _trader = new QuikTrader(this.Path.Text);
}
else
{
    _trader = new RealTimeEmulationTrader<QuikTrader>(new QuikTrader(this.Path.Text));
}


Выставление order'а внутри стратегии:

Code
if (UseQuoting)
{
    MarketQuotingStrategy marketQuotingStrategy = new MarketQuotingStrategy(order, new Unit(), new Unit());
    marketQuotingStrategy.NewMyTrades += ProtectMyNewTrades;
    base.ChildStrategies.Add(marketQuotingStrategy);
}
else
{
    base.RegisterOrder(order);
}


Обработчик события marketQuotingStrategy.NewMyTrades (именно этот обработчик не вызвается в боевом режиме):

Code
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>:
Quote:
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:
Quote:
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.


Tags:


Thanks:


1 2  >
Alexander

Avatar
Date: 1/6/2012
Reply


как понимаете что не вызывается обработчик? а сделки-то у MQS проходят?
Thanks:

ak

Avatar
Date: 1/6/2012
Reply


Alexander Mukhanchikov Go to
как понимаете что не вызывается обработчик?


В хронологическом порядке как обнаруживал проблему:
  1. Не создаются защитные стратегии для совершенных сделок
  2. Breakpoint на первой строчке внутри цикла foreach (MyTrade trade in trades) не срабатывает при отладке
  3. Тестовое сообщение в лог, вставленное первой строчкой в метод ProtectMyNewTrades, не появляется в логе


Alexander Mukhanchikov Go to
а сделки-то у MQS проходят?

Да. Более того, событие ITrader.NewMyTrades вызывается нормально, подписавшись на него, я, например, нормально заполняю TradeGrid новыми сделками.
Thanks:

Alexander

Avatar
Date: 1/9/2012
Reply


Дело в том, что порой стратегия MQS может завершится раньше чем придёт событие о новой сделки (NewMyTrades)
Что у вас и происходит.

Есть 2 выхода:
1) Поставить флаг RemoveChildStrategies у дочерней стратегии в false - тогда стратегия MQS после завершения не будет удаляться и события должны придти;
2) Реагировать не на событие новых сделок, а на событие изменения отправленного ордера.

P.S. Доступ на codeplex даём тем, кто готов вносить изменения в исходный код, выложенный там.
Thanks:

ak

Avatar
Date: 1/10/2012
Reply


Большое спасибо за ответ, Александр.

Сразу возникает вопрос, не видите ли вы способа внутри MQS синхронизировать генерацию события NewMyTrade и смены ProcessState стратегии (и генерации ProcessStateChanged соответственно), чтобы событие нового трейда гарантированно файрилось до того, как стратегия отрапортует о своем завершении? Сложно что-то предполагать не видя реализации, но судя по всему метод генерирующий NewMyTrade (что-нибудь вроде OnNewMyTrade) слишком долго ждет какого-то ресурса (шлюза ITrader, например, пока другие события успешно генерируются), может его можно пересмотреть? Или, например, заставить Strategy.DisposeManaged() (если именно этот метод вызывается для уничтожения родительской стратегии - дочерней) как-то подождать завершения генерации всех событий.

И еще небольшой вопрос, я не совсем понял второе решение:
Quote:
Реагировать не на событие новых сделок, а на событие изменения отправленного ордера.

Вы имеете ввиду order переданный в конструктор MQS? Так ведь он не имеет ничего общего с ордером, который будет на самом деле создан и исполнен в ходе котирования.

Например этот анонимный метод никогда не будет вызван:

Code
this.
When(order.Changed())
.Do(() => {
    int i = 1;
});


Или я неправильно вас понял?


Thanks:

Alexander

Avatar
Date: 1/10/2012
Reply


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

У MQS есть событие NewOrders
для этих новых ордеров можно создавать любые правила которые угодны


И да, вариант с RemoveChildStrategies намного проще.
Thanks:

ak

Avatar
Date: 1/10/2012
Reply


Quote:
И да, вариант с RemoveChildStrategies намного проще.

Безусловно, но подобные сообщения в логе напрягают:
Quote:
SLS | 05.01.2012 20:40:30.000 | Внимание | Котирование в состоянии Stopped.


Все же не очень понятно.
Quote:
События из QuikTrader, да и из любого трейдера не синхронны - нам событие о новой сделке может придти до \ после события о новом ордере.

Какое условие уничтожения дочерней стратегии/изменения MQS.ProcessState на Stopped? Приход в MQS стратегию события от ITrader о новой сделке (в самом простом случае), так? Так почему же MQS.NewMyTrade не появляется мгновенно после этого и только потом в том же потоке не происходит изменение ProcessState на Stopped и генерация ProcessStateChanged? Как тут вообще может возникнуть состояние гонок?

Thanks:

ak

Avatar
Date: 1/10/2012
Reply


Alexander Mukhanchikov Go to
У MQS есть событие NewOrders
для этих новых ордеров можно создавать любые правила которые угодны


Спасибо, понял. Но если событие MQS.NewMyTrades может не успеть выполниться до уничтожения объекта стратегии, где гарантия, что события на порожденные ею orders успеют выполниться? Или эти orders никак не затрагиваются при dispose стратегии?
Thanks:

Alexander

Avatar
Date: 1/10/2012
Reply


Quote:
Какое условие уничтожения дочерней стратегии/изменения MQS.ProcessState на Stopped? Приход в MQS стратегию события от ITrader о новой сделке (в самом простом случае), так? Так почему же MQS.NewMyTrade не появляется мгновенно после этого и только потом в том же потоке не происходит изменение ProcessState на Stopped и генерация ProcessStateChanged? Как тут вообще может возникнуть состояние гонок?


Нет, не так.
MQS останавливается следующим образом:
- у стратегии меняется позиция (по заявкам(!), не по сделкам). По умолчанию мониторим изменение позиции стратегии именно по ордерам, а не сделкам.
- проверяется условие можем ли окончить
- если да - заканчиваем


либо - по TimeOut.


Т.к. не так - остальное рассуждение не требует ответа.


Quote:
Спасибо, понял. Но если событие MQS.NewMyTrades может не успеть выполниться до уничтожения объекта стратегии, где гарантия, что события на порожденные ею orders успеют выполниться? Или эти orders никак не затрагиваются при dispose стратегии?

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

ak

Avatar
Date: 1/10/2012
Reply


Спасибо, теперь стало все гораздо яснее. Первичность ордеров перед сделками в принятии решения на остановку было ключевым моментом.
Thanks:

risty

Avatar
Date: 1/12/2012
Reply


Думаю мой вопрос примерно в эту тему.
Заранее прошу сильно не ругаться т.к. только начинаю осваивать C# и S# (4.0.14.0)

Есть некая событийная стратегия FirstStrategy. По замыслу она должна торговать не более чем одним контрактом(RIH2)
Code

private int CurrentPosition;

public FirstStrategy() 
        {
            this.RemoveChildStrategies = false;
            this.CurrentPosition = 0;
        }

protected override void OnStarting()
        {
            
            this
                .When(base.Security.SecurityNewTrades())
                .Do(base.PositionManager.Init)
                .Once();
         

            this
                 .When(base.Security.SecurityNewTrades())
                 .Do(UpOrDown);

            this
                .When(this.Stopping())
                .ClosePosition();

            base.OnStarting();
        }

private void UpOrDown()
        {
            // если наша стратегия в процессе остановки
            if (ProcessState == ProcessStates.Stopping)
            {
                // отменяем активные заявки
                CancelActiveOrders();
                return;
            }

            //свежие сделки ?
            if ((base.Security.LastTrade != null) && ((base.Trader.MarketTime - base.Security.LastTrade.Time).Duration() > new TimeSpan(0, 0, 5))) return;
            

            if ((base.Security.LastTrade.Price != 0) && (this.LevelUP != null) && (this.LevelDown != null))
            {

                //UpMoving
                if ((new Unit(base.Security.LastTrade.Price)) > this.LevelUP)
                {
                    if ((this.CurrentPosition == 0) | (this.CurrentPosition == -1))
                    {
                        _orderDirection = OrderDirections.Buy;
                        var order = this.CreateOrder(_orderDirection, Security.GetMarketPrice(_orderDirection), Volume);
                        CurrentPosition++;
                        var strategyUp = new MarketQuotingStrategy(order, new Unit(0), new Unit(0));
                        ChildStrategies.Add(strategyUp);
                        return;
                    }
                }

                //DownMoving
                if ((new Unit(base.Security.LastTrade.Price)) < this.LevelDown)
                {
                    if ((this.CurrentPosition == 0) | (this.CurrentPosition == 1))
                    {
                        _orderDirection = OrderDirections.Sell;
                        var order = this.CreateOrder(_orderDirection, Security.GetMarketPrice(_orderDirection), Volume);
                        CurrentPosition--;
                        var strategyDown = new MarketQuotingStrategy(order, new Unit(0), new Unit(0));
                        ChildStrategies.Add(strategyDown);
                        return;
                    }
                }
                        
            }
        }

В связи с тем, что this.PositionManager.Position основной стратегии запаздывает относительно Котировния, для учета позиции использую this.CurrentPosition.
При тестировании SampleHistoryTesting поля CurrentPosition и this.PositionManager.Position ведут себя изменяются в диапазоне -1,0,1, что и требуется.
А при тестировании SampleRealTimeTesting this.PositionManager.Position вылетает далеко за рамки одного контракта.
В связи с этим вопрос - как правильно учитывать позицию основной стратегии в тестах и в бою?
Thanks:
1 2  >

Attach files by dragging & dropping, , or pasting from the clipboard.

loading
clippy