/// <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)); }
/// <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)); }