Проблема в RealTimeEmulationTrader
Atom
05.03.2013
AASorokovoy


Наблюдаю на 4.1.8

Проявляет себя как не вызывание события NewMyTrades у объекта EmulationTrader as ITrader (существует и такой по мимо RealTimeEmulationTrader).

Схема такая: ( прошу не задавать вопросы зачем это нужно :) )

1) создаем объект EmulationTrader, нацеленный на некоторую базу гидры.
2) создаем объект new RealTimeEmulationTrader<ITrader> (EmulationTrader as ITrader)
3) Создаем стратегию new MyStrategy(EmulationTrader as ITrader) с примерно следующим конструктором.

Код

MyStrategy(ITrader iDataSource)
{
iDataSource.NewMyTrades += (obj) => { MessageBox.Show("Приехали сделки"); };
}

запускаем и наблюдаем, что сделки то не приезжают.

Дальше веселее. Если поменять пункт 2 и 3 по порядку то есть сделать так:
1) создаем объект EmulationTrader, нацеленный на некоторую базу гидры.
3) Создаем стратегию new MyStrategy(EmulationTrader as ITrader)
2) создаем объект new RealTimeEmulationTrader<ITrader> (EmulationTrader as ITrader).
Сделки приедут.

В логах можно обнаружить следующее.

Цитата:

2012/02/24 10:06:10.000|Error |EmulationTrader|System.InvalidOperationException: Ордер с transactionId=101 не найден
at StockSharp.Algo.Testing.RealTimeEmulationTrader`1.#=qoYen7SIGXXIHC5yDoBmtakvI8ajVk$YMRTG2hIXiflw=(Int64 #=qO9iU2Mv29dcXgUc$4EMffw==)
at StockSharp.Algo.Testing.RealTimeEmulationTrader`1.#=qW_NOGPO8hUy5l8I2xNZCL$oRPjjivnoDpJ2KizA3TPo=(IEnumerable`1 #=qA0Q6xXtG5Oyta7t6dDl7yg==)
at System.Action`1.Invoke(T obj)
at Ecng.Common.DelegateHelper.SafeInvoke[T](Action`1 handler, T arg)
at Ecng.ComponentModel.EventsContainer`1.Raise(IEnumerable`1 items)
2012/02/24 10:06:10.000| |EmulationTrader|New order: 102/2 Покупка Цена=7025,00000 Объем=1 Сост=Active Бал=1
2012/02/24 10:06:10.000|Error |EmulationTrader|System.InvalidOperationException: Ордер с transactionId=102 не найден
at StockSharp.Algo.Testing.RealTimeEmulationTrader`1.#=qoYen7SIGXXIHC5yDoBmtakvI8ajVk$YMRTG2hIXiflw=(Int64 #=qO9iU2Mv29dcXgUc$4EMffw==)
at StockSharp.Algo.Testing.RealTimeEmulationTrader`1.#=qW_NOGPO8hUy5l8I2xNZCL$oRPjjivnoDpJ2KizA3TPo=(IEnumerable`1 #=qA0Q6xXtG5Oyta7t6dDl7yg==)
at System.Action`1.Invoke(T obj)
at Ecng.Common.DelegateHelper.SafeInvoke[T](Action`1 handler, T arg)
at Ecng.ComponentModel.EventsContainer`1.Raise(IEnumerable`1 items)


Что наводит нас на мысли о том, что мы отправляем заявки через EmulationTrader он их обрабатывает и генерирует MyTrade которые выдает ее через событие NewMyTrades. Данные MyTrades перехватываются RealTimeEmulationTrader и обрабатываются в методе.

Код

		private void NewMyTradesHandler(IEnumerable<MyTrade> trades)
		{
			foreach(var trade in trades)
			{
				trade.Order = GetOrderByTransaction(trade.Order.TransactionId);
			}
			NewMyTrades.SafeInvoke(trades);
		}

и далее 
		private Order GetOrderByTransaction(long transactionId)
		{
			var order = _byTransactionOrders.TryGetValue(transactionId);

			if(order == null)
				throw new InvalidOperationException("Ордер с transactionId="+transactionId+" не найден");

			return order;
		}


Который выбрасывает исключение (потому что заявка подавалась не через эмулятор).

На событие NewMyTrades есть два подписчика. Подписчики лежат в чем то типо List<Action<IEnumerable<MyTrade>>> и при NewMyTrades.Invoke начинают вызываться в порядке в котором на событие были подписаны (ITrader.NewMyTrades += ... ) и соответственно при порядке исполнения 1),3),2) вначале вызывается обработчик стратегии а потом обработчик RealTimeEmulationTrader и вроде все хорошо. При порядке 1), 2), 3) выброшенное, необработанное исключение RealTimeEmulationTrader'ом прерывает перечисление обработчиков в List<Action<IEnumerable<MyTrade>>> и соответственно до обработчика стратегии действие не доходит и он не вызывается и получаем то, что имеем. (По крайней мере так я вижу проблему)

Как вариант, возможно есть смысл, немного подправить обработчик NewOrderHandler RealTimeEmulationTrader

Код

		private void NewOrderHandler(Order state)
		{
			var order = GetOrderByTransaction(state.TransactionId); // (здесь кстати происходит точно такая же ситуация, только с событием NewOrder. Со всеми вытекающими.) 
			using (order.BeginUpdate())
			{
				order.Id = state.Id;
				order.LastChangeTime = state.LastChangeTime;
				order.Time = state.Time;
				order.Balance = state.Balance;
				order.State = state.State;
			}

			if (order.Type == OrderTypes.Conditional)
				NewStopOrdersHandler(new[] { order });
			else
				NewOrdersHandler(new[] { order });
		}


Что бы при выбрасывании исключения
Код

var order = GetOrderByTransaction(state.TransactionId); 


оно обрабатывалось добавление нового ордера в коллекцию RealTimeEmulationTrader'а и что в свою очередь уберет проблему с выбрасыванием исключений при NewMyTrades (так как ордер уже будет в RealTimeEmulationTrader)









Спасибо:


< 1 2 3  >
VassilSanych

Фотография
Дата: 20.03.2013
Ответить


Творог
Мне кажется, тогда, было бы логичным сделать стандартное правило ожидания, типа:

Код
    order
        .WaitFeedback(strategy, timeout) //запрещает проводить любые действия с заявками по стратегии
        .WhenRegistered()
        .Do(() => trader.AddInfoLog("Заявка успешно зарегестрирована"))
        .Once()
        .Apply(this);

    // регистрация заявки
    trader.RegisterOrder(order);

Оk. Допустим у вас есть такое правило. Ошибка регистрации заявки. Ваши действия?

Спасибо:

Творог

Фотография
Дата: 20.03.2013
Ответить


VassilSanych
Творог
Мне кажется, тогда, было бы логичным сделать стандартное правило ожидания, типа:

Код
    order
        .WaitFeedback(strategy, timeout) //запрещает проводить любые действия с заявками по стратегии
        .WhenRegistered()
        .Do(() => trader.AddInfoLog("Заявка успешно зарегестрирована"))
        .Once()
        .Apply(this);

    // регистрация заявки
    trader.RegisterOrder(order);

Оk. Допустим у вас есть такое правило. Ошибка регистрации заявки. Ваши действия?



Если по таймауту, например 10 сек, никакого ответа, то запускается делегат
.WaitFeedback(strategy, timeout, action)
Это будет означать что косяки либо с интернетом (переход на резервный канал), либо биржей (стоп-торги) или брокером. В общем торговлю вообще надо замораживать и по возможности крыть все позиции.

Если ошибка регистрации, то это уже ответ failed, это уже другая история, например, денег на счёте не хватило.
Спасибо:

esper

Фотография
Дата: 20.03.2013
Ответить


Код
private void Process(Candle candle)
{
	if (_order != null)
		return;

	_order = this.CreateOrder(OrderDirections.Buy, candle.ClosePrice);

	_order
		.WhenRegistered()
		.Do(() => { _order = null; })
		.Apply(this);

	_order
		.WhenRegisterFailed()
		.Do(() => { _order = null; })
		.Apply(this);

	RegisterOrder(_order);
}

Почему нельзя сделать так?
Спасибо:

Творог

Фотография
Дата: 20.03.2013
Ответить


esper

Почему нельзя сделать так?


Попробую. Но в таком правиле тоже, думаю, был бы смысл
Код

    _order
        .WaitFeedback(timeout = 10)
        .Do(() => { отправить SMS и email о том, что слишком большая задержка. попытаться перейти на резервный канал. в QUIK перейти на следующий по списку сервер, если такое вообще технически возможно  })
        .Apply(this);
Спасибо:

esper

Фотография
Дата: 20.03.2013
Ответить


Творог
Но в таком правиле тоже, думаю, был бы смысл

Код
Trader.WhenIntervalElapsed

Спасибо:

Творог

Фотография
Дата: 20.03.2013
Ответить


esper
Творог
Но в таком правиле тоже, думаю, был бы смысл

Код
Trader.WhenIntervalElapsed



Но бывают же ситуации, когда просмотровая информация поступает, а с заявками проблема.
А есть ли разница приметь к заявкам null или Dispose?
Спасибо:

esper

Фотография
Дата: 20.03.2013
Ответить


Творог
Но бывают же ситуации, когда просмотровая информация поступает, а с заявками проблема.

Так и смотрите, что таймаут истек, а информация по заявке еще не пришла.
Спасибо:

AASorokovoy

Фотография
Дата: 25.04.2013
Ответить



Проявляет себя на 4.1.11
Возможно выше написанная диагностика выполнена не достаточно ясно? Может быть, что то не понятно?
Может я как то еще могу помочь?

P.S.
Прошу очистить ветку от сообщений не по теме.
Спасибо:

esper

Фотография
Дата: 25.04.2013
Ответить


AASorokovoy
Проявляет себя на 4.1.11
Возможно выше написанная диагностика выполнена не достаточно ясно? Может быть, что то не понятно?
Может я как то еще могу помочь?

Диагностика отличная, спасибо. Были другие задачи, в следующей версии будет фикс.
Спасибо:

longtrades

Фотография
Дата: 10.05.2013
Ответить


Прошу проверить:

Версия 4.1.12 , RealTimeEmulationTrader поверх QuikTrader:
_trader.CancelOrder(order) не срабатывает, заявки не удяляються и остаются висеть в _trader.Orders со статусом Active , _trader.ReRegisterOrder тоже не удаляет заявки , но при попытке повторного удаления заявок из _trader.Orders.Where(x => x.State == OrderStates.Active) выдает ошибку что заявка не была зарегистрирована или уже удалена , при чем в _trader.Orders все также остаются висеть те же заявки с OrderStates.Active. И при попытке заслать противоположную заявку с ценой ниже выдает сообщение про кросс заявку.

Спасибо.
Спасибо:
< 1 2 3  >

Добавить файлы через драг-н-дроп, , или вставить из буфера обмена.

loading
clippy