private void ProcessQuotesMessage(Security security, QuoteChangeMessage message, bool fromLevel1)
		{
			if (MarketDepthChanged != null || MarketDepthsChanged != null)
			{
				var marketDepth = GetMarketDepth(security);

				message.ToMarketDepth(marketDepth, GetSecurity);

				if (_subscriptionManager.IsFilteredMarketDepthRegistered(security))
					GetFilteredMarketDepthInfo(security).Process(message);

				RaiseMarketDepthChanged(marketDepth);
			}
			else
			{
				lock (_marketDepths.SyncRoot)
				{
					var info = _marketDepths.SafeAdd(security, key => new MarketDepthInfo(EntityFactory.CreateMarketDepth(security)));

					info.First.LocalTime = message.LocalTime;
					info.First.LastChangeTime = message.ServerTime;

					info.Second = message.Bids;
					info.Third = message.Asks;
				}
			}

			var bestBid = message.GetBestBid();
			var bestAsk = message.GetBestAsk();

			if (!fromLevel1 && (bestBid != null || bestAsk != null))
			{
				var values = GetSecurityValues(security);
				var changes = new List<KeyValuePair<Level1Fields, object>>(4);

				lock (values.SyncRoot)
				{
					if (bestBid != null)
					{
						values[(int)Level1Fields.BestBidPrice] = bestBid.Price;
						changes.Add(new KeyValuePair<Level1Fields, object>(Level1Fields.BestBidPrice, bestBid.Price));

						if (bestBid.Volume != 0)
						{
							values[(int)Level1Fields.BestBidVolume] = bestBid.Volume;
							changes.Add(new KeyValuePair<Level1Fields, object>(Level1Fields.BestBidVolume, bestBid.Volume));
						}
					}

					if (bestAsk != null)
					{
						values[(int)Level1Fields.BestAskPrice] = bestAsk.Price;
						changes.Add(new KeyValuePair<Level1Fields, object>(Level1Fields.BestAskPrice, bestAsk.Price));

						if (bestAsk.Volume != 0)
						{
							values[(int)Level1Fields.BestAskVolume] = bestAsk.Volume;
							changes.Add(new KeyValuePair<Level1Fields, object>(Level1Fields.BestAskVolume, bestAsk.Volume));
						}
					}
				}

				RaiseValuesChanged(security, changes, message.ServerTime, message.LocalTime);
			}

			if (UpdateSecurityLastQuotes)
			{
				var updated = false;

				if (!fromLevel1 || bestBid != null)
				{
					updated = true;
					security.BestBid = bestBid == null ? null : new Quote(security, bestBid.Price, bestBid.Volume, Sides.Buy);
				}

				if (!fromLevel1 || bestAsk != null)
				{
					updated = true;
					security.BestAsk = bestAsk == null ? null : new Quote(security, bestAsk.Price, bestAsk.Volume, Sides.Sell);
				}

				if (updated)
				{
					security.LocalTime = message.LocalTime;
					security.LastChangeTime = message.ServerTime;

					RaiseSecurityChanged(security);

					// стаканы по ALL обновляют BestXXX по конкретным инструментам
					if (security.Board.Code == AssociatedBoardCode)
					{
						var changedSecurities = new Dictionary<Security, RefPair<bool, bool>>();

						foreach (var bid in message.Bids)
						{
							if (bid.BoardCode.IsEmpty())
								continue;

							var innerSecurity = GetSecurity(new SecurityId
							{
								SecurityCode = security.Code,
								BoardCode = bid.BoardCode
							});

							var info = changedSecurities.SafeAdd(innerSecurity);

							if (info.First)
								continue;

							info.First = true;

							innerSecurity.BestBid = new Quote(innerSecurity, bid.Price, bid.Volume, Sides.Buy);
							innerSecurity.LocalTime = message.LocalTime;
							innerSecurity.LastChangeTime = message.ServerTime;
						}

						foreach (var ask in message.Asks)
						{
							if (ask.BoardCode.IsEmpty())
								continue;

							var innerSecurity = GetSecurity(new SecurityId
							{
								SecurityCode = security.Code,
								BoardCode = ask.BoardCode
							});

							var info = changedSecurities.SafeAdd(innerSecurity);

							if (info.Second)
								continue;

							info.Second = true;

							innerSecurity.BestAsk = new Quote(innerSecurity, ask.Price, ask.Volume, Sides.Sell);
							innerSecurity.LocalTime = message.LocalTime;
							innerSecurity.LastChangeTime = message.ServerTime;
						}

						RaiseSecuritiesChanged(changedSecurities.Keys.ToArray());
					}
				}
			}

			if (CreateDepthFromLevel1)
				GetBuilder(message.SecurityId).HasDepth = true;

			CreateAssociatedSecurityQuotes(message);
		}
Example #2
0
        private void UpdateIfDepthDirty()
        {
            IEnumerable <MarketDepthPair> top = null;

            lock (_lastDepthSync)
            {
                if (_needToClear)
                {
                    _needToClear = false;
                    top          = Enumerable.Empty <MarketDepthPair>();
                }
                else if (_lastDepth != null)
                {
                    top = _lastDepth.GetTopPairs(MaxDepth);
                }
                else if (_lastQuoteMsg != null)
                {
                    top = _lastQuoteMsg.ToMarketDepth(_prevSecurity).GetTopPairs(MaxDepth);
                }

                _lastDepth = null;
            }

            if (top == null)
            {
                return;
            }

            var index = 0;

            foreach (var pair in top)
            {
                var bid = _quotes[GetQuoteIndex(Sides.Buy, index)];
                if (pair.Bid != null)
                {
                    bid.Init(pair.Bid, _ordersRegistry.GetContainer(pair.Bid.Price), _stopOrdersRegistry.GetContainer(pair.Bid.Price) /*, trades.TryGetValue(pair.Bid.Price), myTrades.TryGetValue(pair.Bid.Price)*/);
                    bid.IsBest = index == 0;
                }
                else
                {
                    bid.Init();
                }

                var ask = _quotes[GetQuoteIndex(Sides.Sell, index)];
                if (pair.Ask != null)
                {
                    ask.Init(pair.Ask, _ordersRegistry.GetContainer(pair.Ask.Price), _stopOrdersRegistry.GetContainer(pair.Ask.Price) /*, trades.TryGetValue(pair.Ask.Price), myTrades.TryGetValue(pair.Ask.Price)*/);
                    ask.IsBest = index == 0;
                }
                else
                {
                    ask.Init();
                }

                index++;
            }

            for (var i = 0; i < (MaxDepth - index); i++)
            {
                _quotes[GetQuoteIndex(Sides.Buy, index + i)].Init();
                _quotes[GetQuoteIndex(Sides.Sell, index + i)].Init();
            }
        }