Не правильное значение лучшей цены в стакане

Не правильное значение лучшей цены в стакане
Atom
23.03.2015
RomSunZ


АПИ 4.2.72, коннектор Quik lua. Периодически получаю неверное значение лучшей цены в стакане, которая находится в середине противоположных котировок:

[code=csharp] var md = this.Connector.GetFilteredMarketDepth(this.Security); Sides? badside = null; //проверим, есть ли "плохая" лучшая цена if (md.Asks.Count() > 1 && md.Bids.Count() > 1) { if (md.Asks[0].Price<md.Bids[0].Price) { //есть попандос if (md.Asks[0].Price < md.Bids[1].Price) badside = Sides.Sell; else if (md.Bids[0].Price > md.Asks[1].Price) badside = Sides.Buy; } } if (badside != null) this.AddErrorLog("В стакане не верная лучшая цена по направлению {0}", badside); [/code]

Вместо Asks и Bids можно использовать GetQuotes, GetFilteredQuotes, вместо GetFilteredMarketDepth использовать GetMarketDepth - результат одинаковый. Закономерность появления "плохой" лучшей цены выявить не удалось. Может выскочить с утра, может к вечеру, а может и вообще несколько дней не появляться.


Теги:


Спасибо:


< 1 2 3 
RomSunZ

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


Добавил такую проверку:

[code=csharp] case MessageTypes.QuoteChange: { var quoteMsg = (QuoteChangeMessage)message; _sessionHolder.ReplaceSecurityId(quoteMsg.SecurityId, id => quoteMsg.SecurityId = id); quoteMsg.ServerTime = _sessionHolder.CurrentTime.Convert(TimeHelper.Moscow); var ask = quoteMsg.GetBestAsk().Price; var bid = quoteMsg.GetBestBid().Price; if (ask <= bid) { LogReceiver.AddErrorLog("Не верные значения лучших цен! best ask={0} best bid={1} sec={2}", ask, bid, quoteMsg.SecurityId); } break; } [/code] В момент получения ошибки по стакану в роботе в логе луа ошибок нет, т.е. ошибка появляется где-то дальше. Где еще посмотреть можно?

P.S. Периодически в трейдере получаю такую ошибку на сборке, указанной выше: [quote] 13:54:23.464| |Quik |From server: MarketDataSnapshotFullRefresh 13:54:23.464|Error |QuikTrader|System.InvalidOperationException: Tags should be BodyLength but received BeginString. в #=qJublOOhstNGuOqciA4pO0IxEbqusgq8AzTUZ$z4_I7QdDamhxix_6xIpo0q08gJs.#=qFSkNH1E6ksrvdnmrGezbbA==(IFixReader #=qyHB14XScGdVE06FHEgMxZQ==, FixTags #=qHKHjSlBEl8dJccjTaFV94Q==) в #=qJublOOhstNGuOqciA4pO0IxEbqusgq8AzTUZ$z4_I7QdDamhxix_6xIpo0q08gJs.#=qYxLyRp9D4RLNmE615p0bhg==(IFixReader #=qjMUDTw7SUe_0KRt5Hr3OIw==, Boolean #=qeHLVtncL2jAcnczVF92hWEFOYnbsI6LNDKA14vzcvxE=, String #=qnp5_Jgq80L$XMFuCxSTvbuW9g7dT2OzNoyyy4yKpxiY=, ILogReceiver #=qLy6FlbS2B0nlLuQVBJrlLA==, String #=qqHxlCuzlbwviGaQ3NdXv5Q==, Func3 #=qByjHri7T4qfIYiyMbykVjQ==, Action1 #=qIoFIKYpJwlJ6XnjSBMM1Mg==) 13:54:23.464|Error |QuikTrader|System.InvalidOperationException: Tags should be BodyLength but received BeginString. в #=qJublOOhstNGuOqciA4pO0IxEbqusgq8AzTUZ$z4_I7QdDamhxix_6xIpo0q08gJs.#=qFSkNH1E6ksrvdnmrGezbbA==(IFixReader #=qyHB14XScGdVE06FHEgMxZQ==, FixTags #=qHKHjSlBEl8dJccjTaFV94Q==) в #=qJublOOhstNGuOqciA4pO0IxEbqusgq8AzTUZ$z4_I7QdDamhxix_6xIpo0q08gJs.#=qYxLyRp9D4RLNmE615p0bhg==(IFixReader #=qjMUDTw7SUe_0KRt5Hr3OIw==, Boolean #=qeHLVtncL2jAcnczVF92hWEFOYnbsI6LNDKA14vzcvxE=, String #=qnp5_Jgq80L$XMFuCxSTvbuW9g7dT2OzNoyyy4yKpxiY=, ILogReceiver #=qLy6FlbS2B0nlLuQVBJrlLA==, String #=qqHxlCuzlbwviGaQ3NdXv5Q==, Func3 #=qByjHri7T4qfIYiyMbykVjQ==, Action1 #=qIoFIKYpJwlJ6XnjSBMM1Mg==) 13:54:23.464| |QuikTrader|StartExport

[/quote]

Спасибо:

RomSunZ

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


Михаил, подскажите где в коде устанавливается флаг message.IsSorted для LUA?

Спасибо:

RomSunZ

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


А в ответ тишина... Использую фикс a5aee499, все, что выше работает не стабильно.

  1. Код в LuaFixServer функиця public override void SendOutMessage(Message message): [code=csharp] switch (message.Type) { ...... case MessageTypes.QuoteChange: { var quoteMsg = (QuoteChangeMessage)message; SessionHolder.ReplaceSecurityId(quoteMsg.SecurityId, id => quoteMsg.SecurityId = id); quoteMsg.ServerTime = SessionHolder.CurrentTime.Convert(TimeHelper.Moscow);

     				var bask = quoteMsg.GetBestAsk().Price;
     				var bbid = quoteMsg.GetBestBid().Price;
     				if (quoteMsg.SecurityId.SecurityCode == "SRM5")
     				{
     					if (bask <= bbid)
     					{
     						SessionHolder.AddErrorLog("(0)Не верные значения лучших цен в message! best ask={0} best bid={1} sec={2}", bask, bbid, quoteMsg.SecurityId.SecurityCode);
     					}
     					else
     					{
     						SessionHolder.AddErrorLog("(1)Значения лучших цен в message: best ask={0} best bid={1} sec={2}", bask, bbid, quoteMsg.SecurityId.SecurityCode);
     					}
     				}
     				break;
     			}
    

..... }

[/code] Лог: [quote] 2015/04/28 14:21:59.828|Error |Quik |(1)Значения лучших цен в message: best ask=7503 best bid=7502 sec=SRM5 2015/04/28 14:22:00.107|Error |Quik |(1)Значения лучших цен в message: best ask=7504 best bid=7502 sec=SRM5 2015/04/28 14:22:00.401|Error |Quik |(1)Значения лучших цен в message: best ask=7504 best bid=7502 sec=SRM5 2015/04/28 14:22:00.402|Error |Quik |(1)Значения лучших цен в message: best ask=7504 best bid=7502 sec=SRM5 2015/04/28 14:22:00.685|Error |Quik |(1)Значения лучших цен в message: best ask=7504 best bid=7502 sec=SRM5 [/quote] Ошибок нет.

2. Connector_ProcessMessage.cs функция private void ProcessQuotesMessage(Security security, QuoteChangeMessage message) [code=csharp] var md = GetMarketDepth(security); var bask = message.GetBestAsk().Price; var bbid = message.GetBestBid().Price; if (bask <= bbid) { this.AddErrorLog("(0)Не верные значения лучших цен в message! best ask={0} best bid={1} sec={2}", bask, bbid, security.Id); } if (md != null && md.BestAsk != null && md.BestBid != null) { if (md.BestAsk.Price <= md.BestBid.Price || bask <= bbid) { this.AddErrorLog("(1)Не верные значения лучших цен! best ask={0} best bid={1} sec={2} md ask={3} md bid={4}", bask, bbid, security.Id, md.BestAsk.Price, md.BestBid.Price); } } ...... [/code] Лог: [quote] 14:21:59.541|Error |QuikTrader|(0)Не верные значения лучших цен в message! best ask=7503 best bid=7538 sec=SRM5@FORTS 14:21:59.541|Error |QuikTrader|(1)Не верные значения лучших цен! best ask=7503 best bid=7538 sec=SRM5@FORTS md ask=7503 md bid=7538 14:22:00.121|Error |QuikTrader|(0)Не верные значения лучших цен в message! best ask=7504 best bid=7538 sec=SRM5@FORTS 14:22:00.121|Error |QuikTrader|(1)Не верные значения лучших цен! best ask=7504 best bid=7538 sec=SRM5@FORTS md ask=7503 md bid=7538 14:22:00.411|Error |QuikTrader|(0)Не верные значения лучших цен в message! best ask=7504 best bid=7538 sec=SRM5@FORTS 14:22:00.411|Error |QuikTrader|(1)Не верные значения лучших цен! best ask=7504 best bid=7538 sec=SRM5@FORTS md ask=7504 md bid=7538 14:22:00.695|Error |QuikTrader|(0)Не верные значения лучших цен в message! best ask=7504 best bid=7538 sec=SRM5@FORTS 14:22:00.695|Error |QuikTrader|(1)Не верные значения лучших цен! best ask=7504 best bid=7538 sec=SRM5@FORTS md ask=7504 md bid=7538 [/quote] Ошибка есть. От куда вызывается ProcessQuotesMessage и что происходит с message между luaserver и коннектором пока не выяснил. Вызывается из private void MarketDataAdapterOnNewOutMessage(Message message), там message тоже с ошибкой. MarketDataAdapterOnNewOutMessage вызывается по подписке в _marketDataAdapter.NewOutMessage...

Спасибо:

Mikhail Sukhov

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


[quote=RomSunZ;33180] В момент получения ошибки по стакану в роботе в логе луа ошибок нет, т.е. ошибка появляется где-то дальше.[/quote]

Получается, что из Луа приходит нормальные стакана. Видимо порча идет дальше. Выставите в скрипте IncrementalDepthUpdates=false Стакан должен слаться как есть.

Подписка на стаканы идет по одному инструменту или по нескольким?

Спасибо:

RomSunZ

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


Вообще загадка... luafixserver public override void SendOutMessage(Message message) получает message без ошибок, далее в ней вызывается base.SendOutMessage(message), который как я понимаю находится в messageadapter.cs и вызывает public virtual void SendOutMessage(Message message) для постановки message в очередь на обработку. А там уже ошибка есть... Код в messageadapter.cs: [code=csharp] public virtual void SendOutMessage(Message message) { InitMessageLocalTime(message);

		if (message.Type == MessageTypes.QuoteChange)
		{
			var quoteMsg = (QuoteChangeMessage)message;

			if (quoteMsg.SecurityId.SecurityCode == "SRM5")
			{
				var bask = quoteMsg.GetBestAsk().Price;
				var bbid = quoteMsg.GetBestBid().Price;
				if (bask <= bbid)
				{
					SessionHolder.AddErrorLog("(2)Не верные значения лучших цен в messageAdapter! best ask={0} best bid={1} sec={2}", bask, bbid, quoteMsg.SecurityId.SecurityCode);
				}
				else
				{
					SessionHolder.AddErrorLog("(3)Значения лучших цен в messageAdapter: best ask={0} best bid={1} sec={2}", bask, bbid, quoteMsg.SecurityId.SecurityCode);
				}
			}
		}

		_outMessageProcessor.EnqueueMessage(message, this, false);

.... } [/code] Лог луа-сервер: [quote] 2015/04/29 13:12:13.622|Error |Quik |(1)Значения лучших цен в message: best ask=7635 best bid=7633 sec=SRM5 2015/04/29 13:12:13.625|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7631 sec=SRM5 2015/04/29 13:12:13.628|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7631 sec=SRM5 2015/04/29 13:12:13.896|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:13.898|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:13.908|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:13.978|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:14.260|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7631 sec=SRM5 2015/04/29 13:12:14.265|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:14.745|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:15.025|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:15.305|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:16.110|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:16.509|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:17.670|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:17.767|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:18.045|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:18.050|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:18.325|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:18.606|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7631 sec=SRM5 2015/04/29 13:12:18.665|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7632 sec=SRM5 2015/04/29 13:12:18.947|Error |Quik |(1)Значения лучших цен в message: best ask=7634 best bid=7631 sec=SRM5 2015/04/29 13:12:18.956|Error |Quik |(1)Значения лучших цен в message: best ask=7632 best bid=7630 sec=SRM5 [/quote]

лог messageadapter [quote] 13:12:13.635|Error |Quik |(3)Значения лучших цен в messageAdapter: best ask=7635 best bid=7634 sec=SRM5 13:12:13.912|Error |Quik |(2)Не верные значения лучших цен в messageAdapter! best ask=7634 best bid=7634 sec=SRM5 13:12:14.278|Error |Quik |(2)Не верные значения лучших цен в messageAdapter! best ask=7634 best bid=7634 sec=SRM5 13:12:14.760|Error |Quik |(2)Не верные значения лучших цен в messageAdapter! best ask=7634 best bid=7634 sec=SRM5 13:12:15.038|Error |Quik |(2)Не верные значения лучших цен в messageAdapter! best ask=7634 best bid=7634 sec=SRM5 13:12:15.318|Error |Quik |(2)Не верные значения лучших цен в messageAdapter! best ask=7634 best bid=7634 sec=SRM5 13:12:16.122|Error |Quik |(2)Не верные значения лучших цен в messageAdapter! best ask=7634 best bid=7634 sec=SRM5 13:12:16.522|Error |Quik |(2)Не верные значения лучших цен в messageAdapter! best ask=7634 best bid=7634 sec=SRM5 13:12:17.686|Error |Quik |(2)Не верные значения лучших цен в messageAdapter! best ask=7634 best bid=7634 sec=SRM5 13:12:18.622|Error |Quik |(2)Не верные значения лучших цен в messageAdapter! best ask=7634 best bid=7634 sec=SRM5 13:12:18.960|Error |Quik |(2)Не верные значения лучших цен в messageAdapter! best ask=7634 best bid=7634 sec=SRM5 [/quote]

И еще похоже на то, что часть message теряется и не проходит в принципе судя по количеству вызовов в луа-сервере и в адаптере... Этот вариант без IncrementalDepthUpdates=false, позже попробую с ней. Подписка на несколько стаканов, просто чтобы было меньше каши в логах сделал выгрузку только по одному.

P.S. включение флага IncrementalDepthUpdates=false не помогает. P.P.S. Для luafixserver SessionHolder пишет лог в файл сервера StockSharp.QuikLua.log, а для messageadapter SessionHolder пишет лог в файл трейдера QuikTrader.txt. И как тогда поймать передачу данных от одного к другому? P.P.P.S. Михаил, может быть для лучшего быстродействия имеет смысл сделать отдельную очередь и отдельные обработчики для сообщений стакана и для прочих сообщений?

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

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

loading
clippy