/// <inheritdoc />
        protected override bool OnSendInMessage(Message message)
        {
            void AddInfo(OrderRegisterMessage regMsg)
            {
                if (regMsg is null)
                {
                    throw new ArgumentNullException(nameof(regMsg));
                }

                if (regMsg.OrderType == OrderTypes.Market || regMsg.Price == 0)
                {
                    return;
                }

                if (regMsg.TimeInForce == TimeInForce.MatchOrCancel || regMsg.TimeInForce == TimeInForce.CancelBalance)
                {
                    return;
                }

                lock (_sync)
                {
                    foreach (var info in _byId.Values)
                    {
                        if (info.BookSubscription.SecurityId == regMsg.SecurityId)
                        {
                            info.AddOrder(regMsg);
                        }
                    }
                }
            }

            switch (message.Type)
            {
            case MessageTypes.Reset:
            {
                lock (_sync)
                {
                    _byId.Clear();
                    _byBookId.Clear();
                    _byOrderStatusId.Clear();
                    _online.Clear();
                    _unsubscribeRequests.Clear();
                }

                break;
            }

            case MessageTypes.OrderRegister:
            case MessageTypes.OrderReplace:
            {
                AddInfo((OrderRegisterMessage)message);
                break;
            }

            case MessageTypes.OrderPairReplace:
            {
                var pairMsg = (OrderPairReplaceMessage)message;

                AddInfo(pairMsg.Message1);
                AddInfo(pairMsg.Message2);

                break;
            }

            case MessageTypes.MarketData:
            {
                var mdMsg = (MarketDataMessage)message;

                if (mdMsg.IsSubscribe)
                {
                    if (mdMsg.SecurityId == default)
                    {
                        break;
                    }

                    if (mdMsg.DataType2 != DataType.FilteredMarketDepth)
                    {
                        break;
                    }

                    var transId = mdMsg.TransactionId;

                    mdMsg = mdMsg.TypedClone();
                    mdMsg.TransactionId = TransactionIdGenerator.GetNextId();
                    mdMsg.DataType2     = DataType.MarketDepth;

                    var orderStatus = new OrderStatusMessage
                    {
                        TransactionId = TransactionIdGenerator.GetNextId(),
                        IsSubscribe   = true,
                        States        = new[] { OrderStates.Active },
                        SecurityId    = mdMsg.SecurityId,
                    };

                    var info = new FilteredMarketDepthInfo(transId, new Subscription(mdMsg, mdMsg), new Subscription(orderStatus, orderStatus));

                    lock (_sync)
                    {
                        _byId.Add(transId, info);
                        _byBookId.Add(mdMsg.TransactionId, info);
                        _byOrderStatusId.Add(orderStatus.TransactionId, info);
                    }

                    base.OnSendInMessage(mdMsg);
                    base.OnSendInMessage(orderStatus);

                    return(true);
                }
                else
                {
                    MarketDataMessage  bookUnsubscribe   = null;
                    OrderStatusMessage ordersUnsubscribe = null;

                    lock (_sync)
                    {
                        if (!_byId.TryGetValue(mdMsg.OriginalTransactionId, out var info))
                        {
                            break;
                        }

                        info.UnSubscribeId = mdMsg.TransactionId;

                        if (info.BookSubscription.State.IsActive())
                        {
                            bookUnsubscribe = new MarketDataMessage
                            {
                                TransactionId         = TransactionIdGenerator.GetNextId(),
                                OriginalTransactionId = info.BookSubscription.TransactionId,
                                IsSubscribe           = false,
                            };

                            _unsubscribeRequests.Add(bookUnsubscribe.TransactionId, Tuple.Create(info, true));
                        }

                        if (info.OrdersSubscription.State.IsActive())
                        {
                            ordersUnsubscribe = new OrderStatusMessage
                            {
                                TransactionId         = TransactionIdGenerator.GetNextId(),
                                OriginalTransactionId = info.OrdersSubscription.TransactionId,
                                IsSubscribe           = false,
                            };

                            _unsubscribeRequests.Add(ordersUnsubscribe.TransactionId, Tuple.Create(info, false));
                        }
                    }

                    if (bookUnsubscribe == null && ordersUnsubscribe == null)
                    {
                        RaiseNewOutMessage(new SubscriptionResponseMessage
                            {
                                OriginalTransactionId = mdMsg.TransactionId,
                                Error = new InvalidOperationException(LocalizedStrings.SubscriptionNonExist.Put(mdMsg.OriginalTransactionId)),
                            });
                    }
                    else
                    {
                        if (bookUnsubscribe != null)
                        {
                            base.OnSendInMessage(bookUnsubscribe);
                        }

                        if (ordersUnsubscribe != null)
                        {
                            base.OnSendInMessage(ordersUnsubscribe);
                        }
                    }

                    return(true);
                }
            }
            }

            return(base.OnSendInMessage(message));
        }
Ejemplo n.º 2
0
        /// <inheritdoc />
        protected override bool OnSendInMessage(Message message)
        {
            switch (message.Type)
            {
            case MessageTypes.Reset:
            {
                _infos.Clear();
                _infosBySecId.Clear();
                break;
            }

            case MessageTypes.MarketData:
            {
                var mdMsg = (MarketDataMessage)message;

                if (mdMsg.IsSubscribe)
                {
                    if (!(mdMsg is FilteredMarketDepthMessage filteredMsg))
                    {
                        break;
                    }

                    if (mdMsg.SecurityId == default)
                    {
                        break;
                    }

                    var transId = mdMsg.TransactionId;

                    var data = mdMsg.GetArg <Tuple <QuoteChangeMessage, ExecutionMessage[]> >();

                    var info = new FilteredMarketDepthInfo(filteredMsg.TypedClone(), data.Item2);
                    _infos.Add(transId, info);
                    _infosBySecId.SafeAdd(mdMsg.SecurityId).Add(transId);

                    mdMsg = new MarketDataMessage();
                    filteredMsg.CopyTo(mdMsg);
                    mdMsg.DataType2 = DataType.MarketDepth;
                    message         = mdMsg;

                    RaiseNewOutMessage(info.Process(data.Item1));
                }
                else
                {
                    if (_infos.TryGetAndRemove(mdMsg.OriginalTransactionId, out var info))
                    {
                        info.State = SubscriptionStates.Stopped;
                        _infosBySecId.TryGetValue(info.Origin.SecurityId)?.Remove(mdMsg.OriginalTransactionId);

                        var clone = new MarketDataMessage();
                        mdMsg.CopyTo(clone);
                        message = clone;
                    }
                }

                break;
            }
            }

            return(base.OnSendInMessage(message));
        }