← Zurück

EmulationTrader: не приходит ответ на выставление заявки

Привет. Продолжаю мучать эмулятор. Столкнулся с тем что иногда эмулятор никак не реагирует на выставление заявки. Обработчики стоят следующие:

			this.When(newOrder.Registered())
				.Do(() => {
				    		log("заявка принята, id="+newOrder.TransactionId.ToString() + " vol="+newOrder.Volume);
				    });
			this.When(newOrder.Failed())
				.Do(() => {
				    	log("failed");
				    });
			this.When(newOrder.NewTrades())
					.Do(() => { log("ордер исполнен"); });

На всякий случай ещё подписывался на Strategy.NewOrder и Strategy.OrderFailed - там тоже реакции не видно. Заявку отправляю с помощью Strategy.RegisterOrder. Повторюсь, что этот баг плавающий - т.е. он то есть, то его нет.

Upd: this - стратегия, унаследованная от Strategy

War dieses Thema hilfreich?

Thema teilen

Kommentare (17)

Anmelden oder Konto erstellen, Melden Sie sich an oder registrieren Sie sich, um einen Kommentar zu hinterlassen

Alexander
Alexander

Посмотрите, создаётся ли событие NewOrder у Trader, который инициализирован в стратегии, в том моменте, когда у Strategy ничего не поднимается.

romanick
romanick Autor

Alexander: Посмотрите, создаётся ли событие NewOrder у Trader, который инициализирован в стратегии, в том моменте, когда у Strategy ничего не поднимается.

Не совсем понял вопрос. Я писал, что Strategy.NewOrder тоже не вызывается в этом моменте, хотя до этого момента всё отрабатывает.

Т.е. до определённого момента этот код отлично работает:

			this.NewOrder += (Order obj) => {
				log("newOrder="+obj.TransactionId);
			};
			
			this.OrderFailed += (OrderFail obj) => {
				log("fail="+obj.Order.TransactionId);
			};

А потом перестаёт.

P.S. Никаких циклов которые могут бесконечно зациклить поток, у меня нет. Эмулятор продолжает работать, в OnNewTrade сделки приходят:

			this.When(tradeData.security.SecurityNewTrades())
				.Do(OnNewTrade);
Alexander
Alexander

Я понял. Подпишитесь на событие NewOrder у Strategy.Trader, посмотрите - поднимается ли событие там.

И да, что выдаёт ProcessDataError?

romanick
romanick Autor

Alexander: Я понял. Подпишитесь на событие NewOrder у Strategy.Trader, посмотрите - поднимается ли событие там.

И да, что выдаёт ProcessDataError?

			this.Trader.ProcessDataError += (Exception obj) => {
				log("[ProcessDataError] "+obj.Message);
			};
			
			this.Trader.NewOrders += (IEnumerable<Order> obj) => {
				log("[NewOrders] "+obj.First().TransactionId);
			};

ProcessDataError - ни разу не вызывается NewOrders - ведёт себя точно также как и this.When(newOrder.Registered()) - т.е. работает до определённого момента, затем просто перестаёт. Вообще, по субъективным ощущениям эмулятор просто пропускает вызов Strategy.RegisterOrder.

Привожу на всякий случай весь код отправки заявки:

		void SendOrder(OrderDirections dir, Order order = null)
		{
			Order newOrder;
			if(order == null){
				newOrder = new Order{
					Portfolio = tradeData.portfolio,
					Price = dir== OrderDirections.Buy?bBandsBottom:bBandsTop,
					Security = tradeData.security,
					Volume = current_params.MPLimit,
					Direction = dir,
					Type = OrderTypes.Limit
				};
			} else
				newOrder = order;
			
			this.When(newOrder.Failed())
				.Do(() => {
				    	SendedOrderFailed(newOrder);
				    	if (dir==OrderDirections.Buy)
				    		buyOrder = null;
				    	else
				    		sellOrder = null;
				    });

			this.When(newOrder.Registered())
				.Do(() => {
				    	try{
				    		log(dir+"-заявка принята, id="+newOrder.TransactionId.ToString() + " vol="+newOrder.Volume);
				    		if (dir==OrderDirections.Buy && order == null && sellOrder == null && !wasMoved){
				    			SendOrder(OrderDirections.Sell); // отправляем противозаявку
				    		}
				    	}catch(Exception ex){
				    		log("ex1:"+ex.Message);
				    	}
				    });
			if (order == null)
				this.When(newOrder.NewTrades())
					.Do(() => { OnMyOpenTrade(newOrder); });
			else
				this.When(newOrder.NewTrades())
					.Do(() => {
					    	try{
					    		OnMyClosingTrade(newOrder);
					    	}catch(Exception ex){
					    		log("ex2:"+ex.Message);
					    	}
					    });
			if (dir == OrderDirections.Buy)
				buyOrder = newOrder;
			else
				sellOrder = newOrder;
			RegisterOrder(newOrder);
			log(dir+"-заявка отправлена "+newOrder.Price+" "+newOrder.Volume, true);
		}

Примечания: Лог о том что заявка отправлена вижу, но реакции на это нет. Параметр order - это заявка созданная при помощи вызова Order.Clone(), с изменёнными Price и Volume. Неадекваное поведение случается только если order != null, но и то не всегда, - примерно 50 сделок отлично проходят.

PavelAd
PavelAd

Та же самая проблема на версии 4.0.0.22, код:


   void SendOrder(decimal sellPrice) {
     var sellOrder = this.CreateOrder(OrderDirections.Sell, sellPrice, Volume);
     sellOrder.Registered().Do(orderRegistered);
     sellOrder.Matched().Do(orderMatched);
     sellOrder.RegisterFailed().Do(orderRegisteredFailed);
     RegisterOrder(sellOrder);
   }

   void orderRegistered(Order order) {
      this.AddInfoLog("Выставлена {0} заявка номер {1} по цене {2}.", order.Direction, order.Id, order.Price);
    }

    void orderRegisteredFailed(OrderFail orderFail) {
      this.AddWarningLog("Ошибка регистрации заявки: {0}", orderFail.Error);
    }

    void orderMatched(Order order) {
      this.AddInfoLog("Исполнена {0} заявка номер {1} по цене {2}.", order.Direction, order.Id, order.Price);
    }

Ни одно из событий не вызывается в Orders - ноль заявок. Используется RealTimeEmulationTrader<QuikTrader>. Событие this.Trader.NewOrders, так же не вызывается. Ошибок на событие ProcessDataError никаких. Ошибка в реализации S#?

pyhta4og
pyhta4og

PavelAd: Та же самая проблема на версии 4.0.0.22, код:

void SendOrder(decimal sellPrice) { var sellOrder = this.CreateOrder(OrderDirections.Sell, sellPrice, Volume); sellOrder.Registered().Do(orderRegistered); sellOrder.Matched().Do(orderMatched); sellOrder.RegisterFailed().Do(orderRegisteredFailed); RegisterOrder(sellOrder); }

void orderRegistered(Order order) { this.AddInfoLog("Выставлена {0} заявка номер {1} по цене {2}.", order.Direction, order.Id, order.Price); }

void orderRegisteredFailed(OrderFail orderFail) {
  this.AddWarningLog("Ошибка регистрации заявки: {0}", orderFail.Error);
}

void orderMatched(Order order) {
  this.AddInfoLog("Исполнена {0} заявка номер {1} по цене {2}.", order.Direction, order.Id, order.Price);
}
> 
> Ни одно из событий не вызывается в Orders - ноль заявок. Используется RealTimeEmulationTrader<QuikTrader>.
> Событие this.Trader.NewOrders, так же не вызывается. Ошибок на событие ProcessDataError никаких.
> Ошибка в реализации S#?

 When(sellOrder.Registered()).Do(orderRegistered);

Вы When не написали.
PavelAd
PavelAd

pyhta4og: Вы When не написали.

Есть два варианта вызова. Как я понял When не указывается когда правило непосредственно из заявки вызываем. из документации к S#:

В Visual Basic и C# этот метод можно вызывать как метод экземпляра для любого объекта типа Order. При вызове метода для экземпляра следует опускать первый параметр.

Но и если делать так как предложили вы, тоже не происходит вызова события.

Mikhail Sukhov
Mikhail Sukhov

Начнем с простого. Пример запускали? Работает?

PavelAd
PavelAd

Mikhail Sukhov: Начнем с простого. Пример запускали? Работает? Если имеете ввиду пример SampleRealTimeTesting то за неимением SmartCOM проверить не могу. Но изменил в примере SampleSMA создание шлюза на:

_trader = new RealTimeEmulationTrader<QuikTrader>(new QuikTrader(Path.Text));

изменил регистрацию заявок через RegisterOrder(), и добавил такие же события как писал выше. После регистрации заявки вызова событий так же не происходит.

Mikhail Sukhov
Mikhail Sukhov

PavelAd: Если имеете ввиду пример SampleRealTimeTesting

Имею ввиду тот пример, которые наиболее точно подходит к вашей ситуации.

PavelAd
PavelAd

Mikhail Sukhov:

PavelAd: Если имеете ввиду пример SampleRealTimeTesting

Имею ввиду тот пример, которые наиболее точно подходит к вашей ситуации.

не понял. Какой именно? Все примеры посмотрел, под Quik нет примера для тестирования на реальных рыночных данных.

Mikhail Sukhov
Mikhail Sukhov

PavelAd: не понял. Какой именно? Все примеры посмотрел, под Quik нет примера для тестирования на реальных рыночных данных.

Вы отписались в топик про EmulationTrader. Вы его используете или RTEmulation?

PavelAd
PavelAd

Mikhail Sukhov: Вы отписались в топик про EmulationTrader. Вы его используете или RTEmulation? Использую RealTimeEmulationTrader

Mikhail Sukhov
Mikhail Sukhov

PavelAd:

Mikhail Sukhov: Вы отписались в топик про EmulationTrader. Вы его используете или RTEmulation? Использую RealTimeEmulationTrader

Если в примере заменить только шлюз, не меняя логику, он работает?

PavelAd
PavelAd

Пробовал такой вариант подписывания на события, так же вызова нет

      
      this.When(sellOrder.Registered()).Do(orderRegistered);      
      this.When(sellOrder.Matched()).Do(orderMatched);
      this.When(sellOrder.RegisterFailed()).Do(orderRegisteredFailed);

PavelAd
PavelAd

Я нашел свою ошибку. Проблема была в том что я сначала подписывался на события NewSecurities, NewTrades для QuikTrader а после этого создавал RealTimeEmulationTrader<QuikTrader> и передавал его в стратегию.

Не думал что это влияет. Предлагаю отразить это в доке в разделе "Тестирование - На рыночных данных"

Alexander
Alexander

PavelAd: Я нашел свою ошибку. Проблема была в том что я сначала подписывался на события NewSecurities, NewTrades для QuikTrader а после этого создавал RealTimeEmulationTrader<QuikTrader> и передавал его в стратегию.

Не думал что это влияет. Предлагаю отразить это в доке в разделе "Тестирование - На рыночных данных"

Так это очевидно. Вы подписываетесь на события одного шлюза,а работаете с другим. :)