bool IEnumerator.MoveNext()
                {
                    while (_itemsEnumerator.MoveNext())
                    {
                        var item = _itemsEnumerator.Current;

                        //if (_builder == null)
                        //	_builder = new OrderLogMarketDepthBuilder(new QuoteChangeMessage { SecurityId = item.SecurityId, IsSorted = true }, _maxDepth);

                        if (!_builder.Update(item))
                        {
                            continue;
                        }

                        if (Current != null && (_builder.Depth.ServerTime - Current.ServerTime) < _interval)
                        {
                            continue;
                        }

                        Current = (QuoteChangeMessage)_builder.Depth.Clone();

                        if (_maxDepth < int.MaxValue)
                        {
                            //Current.MaxDepth = _maxDepth;
                            Current.Bids = Current.Bids.Take(_maxDepth).ToArray();
                            Current.Asks = Current.Asks.Take(_maxDepth).ToArray();
                        }

                        return(true);
                    }

                    Current = null;
                    return(false);
                }
Example #2
0
		/// <summary>
		/// Build market depths from order log.
		/// </summary>
		/// <param name="items">Orders log lines.</param>
		/// <param name="builder">Order log to market depth builder.</param>
		/// <param name="interval">The interval of the order book generation. The default is <see cref="TimeSpan.Zero"/>, which means order books generation at each new item of orders log.</param>
		/// <param name="maxDepth">The maximal depth of order book. The default is <see cref="Int32.MaxValue"/>, which means endless depth.</param>
		/// <returns>Market depths.</returns>
		public static IEnumerable<QuoteChangeMessage> ToOrderBooks(this IEnumerable<ExecutionMessage> items, IOrderLogMarketDepthBuilder builder, TimeSpan interval = default, int maxDepth = int.MaxValue)
		{
			var snapshotSent = false;
			var prevTime = default(DateTimeOffset?);

			foreach (var item in items)
			{
				if (!snapshotSent)
				{
					yield return builder.Snapshot.TypedClone();
					snapshotSent = true;
				}

				var depth = builder.Update(item);
				if (depth is null)
					continue;

				if (prevTime != null && (depth.ServerTime - prevTime.Value) < interval)
					continue;

				depth = depth.TypedClone();

				if (maxDepth < int.MaxValue)
				{
					depth.Bids = depth.Bids.Take(maxDepth).ToArray();
					depth.Asks = depth.Asks.Take(maxDepth).ToArray();
				}

				yield return depth;

				prevTime = depth.ServerTime;
			}
		}
Example #3
0
        private void ProcessBuilders(ExecutionMessage execMsg)
        {
            if (execMsg.IsSystem == false)
            {
                return;
            }

            foreach (var subscriptionId in execMsg.GetSubscriptionIds())
            {
                if (!_subscriptionIds.TryGetValue(subscriptionId, out var tuple))
                {
                    // can be non OL->MB subscription
                    //this.AddDebugLog("OL processing {0}/{1} not found.", execMsg.SecurityId, subscriptionId);
                    continue;
                }

                if (tuple.First)
                {
                    var sync = tuple.Third;

                    IOrderLogMarketDepthBuilder builder = tuple.Second;

                    try
                    {
                        QuoteChangeMessage depth;

                        lock (sync)
                            depth = builder.Update(execMsg)?.TypedClone();

                        this.AddDebugLog("OL->MD processing {0}={1}.", execMsg.SecurityId, depth != null);

                        if (depth != null)
                        {
                            depth.SetSubscriptionIds(subscriptionId: subscriptionId);
                            base.OnInnerAdapterNewOutMessage(depth);
                        }
                    }
                    catch (Exception ex)
                    {
                        // если ОЛ поврежден, то не нарушаем весь цикл обработки сообщения
                        // а только выводим сообщение в лог
                        base.OnInnerAdapterNewOutMessage(ex.ToErrorMessage());
                    }
                }
                else
                {
                    this.AddDebugLog("OL->TICK processing {0}.", execMsg.SecurityId);
                    base.OnInnerAdapterNewOutMessage(execMsg.ToTick());
                }
            }
        }