예제 #1
0
 private void RemoveSubscription(long id)
 {
     if (_subscriptionIds.TryGetAndRemove(id, out var tuple))
     {
         this.AddInfoLog("OL->{0} unsubscribed {1}/{2}.", tuple.Second ? "MD" : "TICK", tuple.First, id);
     }
 }
예제 #2
0
        /// <summary>
        /// Remove series tracking.
        /// </summary>
        /// <param name="transactionId">Request identifier.</param>
        /// <returns>Candles series.</returns>
        public CandleSeries RemoveCandleSeries(long transactionId)
        {
            CandlesSeriesHolder info;

            lock (_holders.SyncRoot)
                info = _holders.TryGetAndRemove(transactionId);

            return(info?.Series);
        }
예제 #3
0
        private bool TryRemoveSubscription(long id, out SubscriptionInfo info)
        {
            if (!_subscriptionIds.TryGetAndRemove(id, out info))
            {
                return(false);
            }

            this.AddInfoLog("OL->{0} unsubscribed {1}/{2}.", info.IsTicks ? "MD" : "TICK", info.Origin.SecurityId, info.Origin.TransactionId);
            return(true);
        }
예제 #4
0
        /// <summary>
        /// Start storage auto-save thread.
        /// </summary>
        private void StartStorageTimer()
        {
            if (_timer != null || !Buffer.Enabled || Buffer.DisableStorageTimer)
            {
                return;
            }

            var isProcessing = false;
            var sync         = new SyncObject();

            _timer = ThreadingHelper.Timer(() =>
            {
                lock (sync)
                {
                    if (isProcessing)
                    {
                        return;
                    }

                    isProcessing = true;
                }

                try
                {
                    var incremental = Settings.IsMode(StorageModes.Incremental);
                    var snapshot    = Settings.IsMode(StorageModes.Snapshot);

                    foreach (var pair in Buffer.GetTicks())
                    {
                        if (incremental)
                        {
                            Settings.GetStorage <ExecutionMessage>(pair.Key, ExecutionTypes.Tick).Save(pair.Value);
                        }
                    }

                    foreach (var pair in Buffer.GetOrderLog())
                    {
                        if (incremental)
                        {
                            Settings.GetStorage <ExecutionMessage>(pair.Key, ExecutionTypes.OrderLog).Save(pair.Value);
                        }
                    }

                    foreach (var pair in Buffer.GetTransactions())
                    {
                        var secId = pair.Key;

                        if (incremental)
                        {
                            Settings.GetStorage <ExecutionMessage>(secId, ExecutionTypes.Transaction).Save(pair.Value);
                        }

                        if (snapshot)
                        {
                            var snapshotStorage = GetSnapshotStorage(DataType.Transactions);

                            foreach (var message in pair.Value)
                            {
                                // do not store cancellation commands into snapshot
                                if (message.IsCancellation)
                                {
                                    this.AddWarningLog("Cancellation transaction: {0}", message);
                                    continue;
                                }

                                var originTransId = message.OriginalTransactionId;

                                if (originTransId == 0)
                                {
                                    continue;
                                }

                                if (_cancellationTransactions.TryGetValue(originTransId, out var cancelledId))
                                {
                                    // do not store cancellation errors
                                    if (message.Error != null)
                                    {
                                        continue;
                                    }

                                    // override cancel trans id by original order's registration trans id
                                    originTransId = cancelledId;
                                }
                                else if (_orderStatusIds.Contains(originTransId))
                                {
                                    // override status request trans id by original order's registration trans id
                                    originTransId = message.TransactionId;
                                }
                                else if (_replaceTransactions.TryGetAndRemove(originTransId, out var replacedId))
                                {
                                    if (message.Error == null)
                                    {
                                        var replaced = (ExecutionMessage)snapshotStorage.Get(replacedId);

                                        if (replaced == null)
                                        {
                                            this.AddWarningLog("Replaced order {0} not found.", replacedId);
                                        }
                                        else
                                        {
                                            if (replaced.OrderState != OrderStates.Done)
                                            {
                                                replaced.OrderState = OrderStates.Done;
                                            }
                                        }
                                    }
                                }

                                message.SecurityId = secId;

                                if (message.TransactionId == 0)
                                {
                                    message.TransactionId = originTransId;
                                }

                                message.OriginalTransactionId = 0;

                                SaveTransaction(snapshotStorage, message);
                            }
                        }
                    }

                    foreach (var pair in Buffer.GetOrderBooks())
                    {
                        if (incremental)
                        {
                            Settings.GetStorage <QuoteChangeMessage>(pair.Key, null).Save(pair.Value);
                        }

                        if (snapshot)
                        {
                            var snapshotStorage = GetSnapshotStorage(DataType.MarketDepth);

                            foreach (var message in pair.Value)
                            {
                                snapshotStorage.Update(message);
                            }
                        }
                    }

                    foreach (var pair in Buffer.GetLevel1())
                    {
                        var messages = pair.Value.Where(m => m.Changes.Count > 0).ToArray();

                        if (incremental)
                        {
                            Settings.GetStorage <Level1ChangeMessage>(pair.Key, null).Save(messages);
                        }

                        if (Settings.IsMode(StorageModes.Snapshot))
                        {
                            var snapshotStorage = GetSnapshotStorage(DataType.Level1);

                            foreach (var message in messages)
                            {
                                snapshotStorage.Update(message);
                            }
                        }
                    }

                    foreach (var pair in Buffer.GetCandles())
                    {
                        Settings.GetStorage(pair.Key.Item1, pair.Key.Item2, pair.Key.Item3).Save(pair.Value);
                    }

                    foreach (var pair in Buffer.GetPositionChanges())
                    {
                        var messages = pair.Value.Where(m => m.Changes.Count > 0).ToArray();

                        if (incremental)
                        {
                            Settings.GetStorage <PositionChangeMessage>(pair.Key, null).Save(messages);
                        }

                        if (snapshot)
                        {
                            var snapshotStorage = GetSnapshotStorage(DataType.PositionChanges);

                            foreach (var message in messages)
                            {
                                snapshotStorage.Update(message);
                            }
                        }
                    }

                    var news = Buffer.GetNews().ToArray();

                    if (news.Length > 0)
                    {
                        Settings.GetStorage <NewsMessage>(default, null).Save(news);
예제 #5
0
        private MarketDataMessage ProcessMarketDataRequest(MarketDataMessage message)
        {
            if (message.IsSubscribe)
            {
                if (!InnerAdapter.IsMarketDataTypeSupported(MarketDataTypes.OrderLog))
                {
                    return(message);
                }

                var isBuild = message.BuildMode == MarketDataBuildModes.Build && message.BuildFrom == MarketDataTypes.OrderLog;

                switch (message.DataType)
                {
                case MarketDataTypes.MarketDepth:
                {
                    if (isBuild || !InnerAdapter.IsMarketDataTypeSupported(message.DataType))
                    {
                        var secId = GetSecurityId(message.SecurityId);

                        IOrderLogMarketDepthBuilder builder = null;

                        if (InnerAdapter.IsSecurityRequired(DataType.OrderLog))
                        {
                            builder = InnerAdapter.CreateOrderLogMarketDepthBuilder(secId);
                        }

                        _subscriptionIds.Add(message.TransactionId, RefTuple.Create(secId, true, builder));

                        message          = (MarketDataMessage)message.Clone();
                        message.DataType = MarketDataTypes.OrderLog;

                        this.AddInfoLog("OL->MD subscribed {0}/{1}.", secId, message.TransactionId);
                    }

                    break;
                }

                case MarketDataTypes.Trades:
                {
                    if (isBuild || !InnerAdapter.IsMarketDataTypeSupported(message.DataType))
                    {
                        var secId = GetSecurityId(message.SecurityId);

                        _subscriptionIds.Add(message.TransactionId, RefTuple.Create(secId, false, (IOrderLogMarketDepthBuilder)null));

                        message          = (MarketDataMessage)message.Clone();
                        message.DataType = MarketDataTypes.OrderLog;

                        this.AddInfoLog("OL->TICK subscribed {0}/{1}.", secId, message.TransactionId);
                    }

                    break;
                }
                }
            }
            else
            {
                var tuple = _subscriptionIds.TryGetAndRemove(message.OriginalTransactionId);

                if (tuple != null)
                {
                    this.AddInfoLog("OL->{0} unsubscribed {1}/{2}.", tuple.Second ? "MD" : "TICK", tuple.First, message.OriginalTransactionId);
                }
            }

            return(message);
        }
예제 #6
0
        /// <inheritdoc />
        protected override void OnInnerAdapterNewOutMessage(Message message)
        {
            var processSuspended = false;

            switch (message.Type)
            {
            case MessageTypes.SubscriptionResponse:
            {
                var responseMsg = (SubscriptionResponseMessage)message;

                if (responseMsg.Error != null)
                {
                    _transactionLogSubscriptions.Remove(responseMsg.OriginalTransactionId);
                }

                break;
            }

            case MessageTypes.SubscriptionFinished:
            case MessageTypes.SubscriptionOnline:
            {
                var originMsg = (IOriginalTransactionIdMessage)message;

                if (!_transactionLogSubscriptions.TryGetAndRemove(originMsg.OriginalTransactionId, out var subscription))
                {
                    break;
                }

                Tuple <ExecutionMessage, List <ExecutionMessage> >[] tuples;

                lock (subscription.Sync)
                    tuples = subscription.Transactions.Values.ToArray();

                var canProcessFailed = subscription.Original.States.Contains(OrderStates.Failed);

                foreach (var tuple in tuples)
                {
                    var order = tuple.Item1;

                    if (order.OrderState == OrderStates.Failed && !canProcessFailed)
                    {
                        if (tuple.Item2.Count > 0)
                        {
                            this.AddWarningLog("Order {0} has failed state but contains {1} trades.", order.TransactionId, tuple.Item2.Count);
                        }

                        continue;
                    }

                    base.OnInnerAdapterNewOutMessage(order);

                    ProcessSuspended(order);

                    foreach (var trade in tuple.Item2)
                    {
                        base.OnInnerAdapterNewOutMessage(trade);
                    }
                }

                break;
            }

            case MessageTypes.Execution:
            {
                var execMsg = (ExecutionMessage)message;

                if (execMsg.IsMarketData())
                {
                    break;
                }

                // skip cancellation cause they are reply on action and no have transaction state
                if (execMsg.IsCancellation)
                {
                    break;
                }

                var transId = execMsg.TransactionId;

                if (transId != 0)
                {
                    _secIds.TryAdd(transId, execMsg.SecurityId);
                }
                else
                {
                    if (execMsg.SecurityId == default && _secIds.TryGetValue(execMsg.OriginalTransactionId, out var secId))
                    {
                        execMsg.SecurityId = secId;
                    }
                }

                if (transId != 0 || execMsg.OriginalTransactionId != 0)
                {
                    if (transId == 0)
                    {
                        transId = execMsg.OriginalTransactionId;
                    }

                    if (execMsg.OrderId != null)
                    {
                        _orderIds.TryAdd(execMsg.OrderId.Value, transId);
                    }
                    else if (!execMsg.OrderStringId.IsEmpty())
                    {
                        _orderStringIds.TryAdd(execMsg.OrderStringId, transId);
                    }
                }

                if (execMsg.TransactionId == 0 && execMsg.HasTradeInfo && _orderStatusIds.Contains(execMsg.OriginalTransactionId))
                {
                    // below the code will try find order's transaction
                    execMsg.OriginalTransactionId = 0;
                }

                if (/*execMsg.TransactionId == 0 && */ execMsg.OriginalTransactionId == 0)
                {
                    if (!execMsg.HasTradeInfo)
                    {
                        this.AddWarningLog("Order doesn't have origin trans id: {0}", execMsg);
                        break;
                    }

                    if (execMsg.OrderId != null)
                    {
                        if (_orderIds.TryGetValue(execMsg.OrderId.Value, out var originId))
                        {
                            execMsg.OriginalTransactionId = originId;
                        }
                        else
                        {
                            this.AddWarningLog("Trade doesn't have origin trans id: {0}", execMsg);
                            break;
                        }
                    }
                    else if (!execMsg.OrderStringId.IsEmpty())
                    {
                        if (_orderStringIds.TryGetValue(execMsg.OrderStringId, out var originId))
                        {
                            execMsg.OriginalTransactionId = originId;
                        }
                        else
                        {
                            this.AddWarningLog("Trade doesn't have origin trans id: {0}", execMsg);
                            break;
                        }
                    }
                }

                if (execMsg.HasTradeInfo && !execMsg.HasOrderInfo)
                {
                    if (execMsg.OrderId != null && !_orderIds.ContainsKey(execMsg.OrderId.Value) && (execMsg.OriginalTransactionId == 0 || !_secIds.ContainsKey(execMsg.OriginalTransactionId)))
                    {
                        this.AddInfoLog("{0} suspended.", execMsg);

                        lock (_nonAssociatedLock)
                            _nonAssociatedOrderIds.SafeAdd(execMsg.OrderId.Value).Add(execMsg.TypedClone());

                        return;
                    }
                    else if (!execMsg.OrderStringId.IsEmpty() && !_orderStringIds.ContainsKey(execMsg.OrderStringId) && (execMsg.OriginalTransactionId == 0 || !_secIds.ContainsKey(execMsg.OriginalTransactionId)))
                    {
                        this.AddInfoLog("{0} suspended.", execMsg);

                        lock (_nonAssociatedLock)
                            _nonAssociatedStringOrderIds.SafeAdd(execMsg.OrderStringId).Add(execMsg.TypedClone());

                        return;
                    }
                }

                if (_transactionLogSubscriptions.Count == 0)
                {
                    processSuspended = true;
                    break;
                }

                if (!_transactionLogSubscriptions.TryGetValue(execMsg.OriginalTransactionId, out var subscription))
                {
                    if (!_orders.TryGetValue(execMsg.OriginalTransactionId, out var orderTransId))
                    {
                        break;
                    }

                    if (!_transactionLogSubscriptions.TryGetValue(orderTransId, out subscription))
                    {
                        break;
                    }
                }

                if (transId == 0)
                {
                    if (execMsg.HasTradeInfo)
                    {
                        transId = execMsg.OriginalTransactionId;
                    }

                    if (transId == 0)
                    {
                        this.AddWarningLog("Message {0} do not contains transaction id.", execMsg);
                        break;
                    }
                }

                lock (subscription.Sync)
                {
                    if (subscription.Transactions.TryGetValue(transId, out var tuple))
                    {
                        var snapshot = tuple.Item1;

                        if (execMsg.HasOrderInfo)
                        {
                            if (execMsg.Balance != null)
                            {
                                snapshot.Balance = snapshot.Balance.ApplyNewBalance(execMsg.Balance.Value, transId, this);
                            }

                            if (execMsg.OrderState != null)
                            {
                                snapshot.OrderState = snapshot.OrderState.ApplyNewState(execMsg.OrderState.Value, transId, this);
                            }

                            if (execMsg.OrderStatus != null)
                            {
                                snapshot.OrderStatus = execMsg.OrderStatus;
                            }

                            if (execMsg.OrderId != null)
                            {
                                snapshot.OrderId = execMsg.OrderId;
                            }

                            if (!execMsg.OrderStringId.IsEmpty())
                            {
                                snapshot.OrderStringId = execMsg.OrderStringId;
                            }

                            if (execMsg.OrderBoardId != null)
                            {
                                snapshot.OrderBoardId = execMsg.OrderBoardId;
                            }

                            if (execMsg.PnL != null)
                            {
                                snapshot.PnL = execMsg.PnL;
                            }

                            if (execMsg.Position != null)
                            {
                                snapshot.Position = execMsg.Position;
                            }

                            if (execMsg.Commission != null)
                            {
                                snapshot.Commission = execMsg.Commission;
                            }

                            if (execMsg.CommissionCurrency != null)
                            {
                                snapshot.CommissionCurrency = execMsg.CommissionCurrency;
                            }

                            if (execMsg.AveragePrice != null)
                            {
                                snapshot.AveragePrice = execMsg.AveragePrice;
                            }

                            if (execMsg.Latency != null)
                            {
                                snapshot.Latency = execMsg.Latency;
                            }
                        }

                        if (execMsg.HasTradeInfo)
                        {
                            var clone = execMsg.TypedClone();

                            // all order's info in snapshot
                            execMsg.HasTradeInfo = false;
                            clone.HasOrderInfo   = false;

                            tuple.Item2.Add(clone);
                        }
                    }
                    else
                    {
                        _orders.Add(transId, execMsg.OriginalTransactionId);
                        subscription.Transactions.Add(transId, Tuple.Create(execMsg.TypedClone(), new List <ExecutionMessage>()));
                    }
                }

                return;
            }
            }

            base.OnInnerAdapterNewOutMessage(message);

            if (processSuspended)
            {
                ProcessSuspended((ExecutionMessage)message);
            }
        }
        /// <inheritdoc />
        protected override void OnInnerAdapterNewOutMessage(Message message)
        {
            switch (message.Type)
            {
            case MessageTypes.SubscriptionResponse:
            {
                var responseMsg = (SubscriptionResponseMessage)message;

                if (responseMsg.Error != null)
                {
                    _transactionLogSubscriptions.Remove(responseMsg.OriginalTransactionId);
                }

                break;
            }

            case MessageTypes.SubscriptionFinished:
            case MessageTypes.SubscriptionOnline:
            {
                var originMsg = (IOriginalTransactionIdMessage)message;

                if (!_transactionLogSubscriptions.TryGetAndRemove(originMsg.OriginalTransactionId, out var subscription))
                {
                    break;
                }

                foreach (var pair in subscription.Transactions)
                {
                    base.OnInnerAdapterNewOutMessage(pair.Value.Item1);

                    foreach (var trade in pair.Value.Item2)
                    {
                        base.OnInnerAdapterNewOutMessage(trade);
                    }
                }

                break;
            }

            case MessageTypes.Execution:
            {
                var execMsg = (ExecutionMessage)message;

                if (execMsg.IsMarketData())
                {
                    break;
                }

                // skip cancellation cause they are reply on action and no have transaction state
                if (execMsg.IsCancellation)
                {
                    break;
                }

                var transId = execMsg.TransactionId;

                if (transId != 0)
                {
                    _secIds.TryAdd(transId, execMsg.SecurityId);
                }
                else
                {
                    if (execMsg.SecurityId == default && _secIds.TryGetValue(execMsg.OriginalTransactionId, out var secId))
                    {
                        execMsg.SecurityId = secId;
                    }
                }

                if (transId != 0 || execMsg.OriginalTransactionId != 0)
                {
                    if (transId == 0)
                    {
                        transId = execMsg.OriginalTransactionId;
                    }

                    if (execMsg.OrderId != null)
                    {
                        _orderIds.TryAdd(execMsg.OrderId.Value, transId);
                    }
                    else if (!execMsg.OrderStringId.IsEmpty())
                    {
                        _orderStringIds.TryAdd(execMsg.OrderStringId, transId);
                    }
                }

                if (execMsg.TransactionId == 0 && execMsg.HasTradeInfo && _orderStatusIds.Contains(execMsg.OriginalTransactionId))
                {
                    // below the code will try find order's transaction
                    execMsg.OriginalTransactionId = 0;
                }

                if (/*execMsg.TransactionId == 0 && */ execMsg.OriginalTransactionId == 0)
                {
                    if (!execMsg.HasTradeInfo)
                    {
                        this.AddWarningLog("Order doesn't have origin trans id: {0}", execMsg);
                        break;
                    }

                    if (execMsg.OrderId != null)
                    {
                        if (_orderIds.TryGetValue(execMsg.OrderId.Value, out var originId))
                        {
                            execMsg.OriginalTransactionId = originId;
                        }
                        else
                        {
                            this.AddWarningLog("Trade doesn't have origin trans id: {0}", execMsg);
                            break;
                        }
                    }
                    else if (!execMsg.OrderStringId.IsEmpty())
                    {
                        if (_orderStringIds.TryGetValue(execMsg.OrderStringId, out var originId))
                        {
                            execMsg.OriginalTransactionId = originId;
                        }
                        else
                        {
                            this.AddWarningLog("Trade doesn't have origin trans id: {0}", execMsg);
                            break;
                        }
                    }
                }

                if (_transactionLogSubscriptions.Count == 0)
                {
                    break;
                }

                if (!_transactionLogSubscriptions.TryGetValue(execMsg.OriginalTransactionId, out var subscription))
                {
                    if (!_orders.TryGetValue(execMsg.OriginalTransactionId, out var orderTransId))
                    {
                        break;
                    }

                    if (!_transactionLogSubscriptions.TryGetValue(orderTransId, out subscription))
                    {
                        break;
                    }
                }

                if (transId == 0)
                {
                    if (execMsg.HasTradeInfo)
                    {
                        transId = execMsg.OriginalTransactionId;
                    }

                    if (transId == 0)
                    {
                        this.AddWarningLog("Message {0} do not contains transaction id.", execMsg);
                        break;
                    }
                }

                lock (subscription.Sync)
                {
                    if (subscription.Transactions.TryGetValue(transId, out var tuple))
                    {
                        var snapshot = tuple.Item1;

                        if (execMsg.HasOrderInfo)
                        {
                            if (execMsg.Balance != null)
                            {
                                snapshot.Balance = snapshot.Balance.ApplyNewBalance(execMsg.Balance.Value, transId, this);
                            }

                            if (execMsg.OrderState != null)
                            {
                                snapshot.OrderState = snapshot.OrderState.ApplyNewState(execMsg.OrderState.Value, transId, this);
                            }

                            if (execMsg.OrderStatus != null)
                            {
                                snapshot.OrderStatus = execMsg.OrderStatus;
                            }

                            if (execMsg.OrderId != null)
                            {
                                snapshot.OrderId = execMsg.OrderId;
                            }

                            if (execMsg.OrderStringId != null)
                            {
                                snapshot.OrderStringId = execMsg.OrderStringId;
                            }

                            if (execMsg.OrderBoardId != null)
                            {
                                snapshot.OrderBoardId = execMsg.OrderBoardId;
                            }

                            if (execMsg.PnL != null)
                            {
                                snapshot.PnL = execMsg.PnL;
                            }

                            if (execMsg.Position != null)
                            {
                                snapshot.Position = execMsg.Position;
                            }

                            if (execMsg.Commission != null)
                            {
                                snapshot.Commission = execMsg.Commission;
                            }

                            if (execMsg.CommissionCurrency != null)
                            {
                                snapshot.CommissionCurrency = execMsg.CommissionCurrency;
                            }

                            if (execMsg.AveragePrice != null)
                            {
                                snapshot.AveragePrice = execMsg.AveragePrice;
                            }

                            if (execMsg.Latency != null)
                            {
                                snapshot.Latency = execMsg.Latency;
                            }
                        }

                        if (execMsg.HasTradeInfo)
                        {
                            var clone = execMsg.TypedClone();

                            // all order's info in snapshot
                            execMsg.HasTradeInfo = false;
                            clone.HasOrderInfo   = false;

                            tuple.Item2.Add(clone);
                        }
                    }
                    else
                    {
                        _orders.Add(transId, execMsg.OriginalTransactionId);
                        subscription.Transactions.Add(transId, Tuple.Create(execMsg.TypedClone(), new List <ExecutionMessage>()));
                    }
                }

                return;
            }
            }

            base.OnInnerAdapterNewOutMessage(message);
        }
        /// <inheritdoc />
        protected override bool OnSendInMessage(Message message)
        {
            switch (message.Type)
            {
            case MessageTypes.Reset:
            {
                _subscriptions.Clear();
                _strategyIdMap.Clear();
                _strategySubscriptions.Clear();

                lock (_sync)
                    _positionManager.ProcessMessage(message);

                break;
            }

            case MessageTypes.PortfolioLookup:
            {
                var lookupMsg = (PortfolioLookupMessage)message;

                if (lookupMsg.IsSubscribe)
                {
                    if (!lookupMsg.StrategyId.IsEmpty())
                    {
                        this.AddDebugLog("Subscription (strategy='{1}') {0} added.", lookupMsg.TransactionId, lookupMsg.StrategyId);
                        _strategyIdMap.Add(lookupMsg.TransactionId, lookupMsg.StrategyId);
                        _strategySubscriptions.SafeAdd(lookupMsg.StrategyId).Add(lookupMsg.TransactionId);
                        RaiseNewOutMessage(lookupMsg.CreateResult());
                        return(true);
                    }

                    if (lookupMsg.To == null)
                    {
                        this.AddDebugLog("Subscription {0} added.", lookupMsg.TransactionId);
                        _subscriptions.Add(lookupMsg.TransactionId);

                        lock (_sync)
                            _positionManager.ProcessMessage(message);
                    }

                    if (IsEmulate)
                    {
                        RaiseNewOutMessage(lookupMsg.CreateResult());
                        return(true);
                    }
                }
                else
                {
                    if (_subscriptions.Remove(lookupMsg.OriginalTransactionId))
                    {
                        this.AddDebugLog("Subscription {0} removed.", lookupMsg.OriginalTransactionId);

                        lock (_sync)
                            _positionManager.ProcessMessage(message);
                    }
                    else if (_strategyIdMap.TryGetAndRemove(lookupMsg.OriginalTransactionId, out var strategyId))
                    {
                        _strategySubscriptions.TryGetValue(strategyId)?.Remove(lookupMsg.OriginalTransactionId);
                        this.AddDebugLog("Subscription (strategy='{1}') {0} removed.", lookupMsg.OriginalTransactionId, strategyId);
                        return(true);
                    }

                    if (IsEmulate)
                    {
                        //RaiseNewOutMessage(lookupMsg.CreateResponse());
                        return(true);
                    }
                }

                break;
            }

            default:
            {
                lock (_sync)
                    _positionManager.ProcessMessage(message);

                break;
            }
            }

            return(base.OnSendInMessage(message));
        }
        /// <inheritdoc />
        protected override void OnInnerAdapterNewOutMessage(Message message)
        {
            base.OnInnerAdapterNewOutMessage(message);

            switch (message.Type)
            {
            case MessageTypes.SubscriptionResponse:
            {
                var response = (SubscriptionResponseMessage)message;

                if (!response.IsOk())
                {
                    lock (_sync)
                        _pending.Remove(response.OriginalTransactionId);
                }

                break;
            }

            case MessageTypes.SubscriptionFinished:
            {
                var finished = (SubscriptionFinishedMessage)message;

                lock (_sync)
                    _pending.Remove(finished.OriginalTransactionId);

                break;
            }

            case MessageTypes.SubscriptionOnline:
            {
                var online = (SubscriptionOnlineMessage)message;

                ISubscriptionMessage subscrMsg;

                lock (_sync)
                {
                    if (!_pending.TryGetAndRemove(online.OriginalTransactionId, out subscrMsg))
                    {
                        break;
                    }
                }

                foreach (var snapshot in _holder.GetSnapshot(subscrMsg))
                {
                    if (snapshot is ISubscriptionIdMessage subscrIdMsg)
                    {
                        subscrIdMsg.OriginalTransactionId = online.OriginalTransactionId;
                        subscrIdMsg.SetSubscriptionIds(subscriptionId: online.OriginalTransactionId);
                    }

                    base.OnInnerAdapterNewOutMessage(snapshot);
                }

                break;
            }

            default:
            {
                lock (_sync)
                {
                    if (_pending.Count > 0 && message is ISubscriptionIdMessage subscrMsg)
                    {
                        foreach (var id in subscrMsg.GetSubscriptionIds())
                        {
                            _pending.Remove(id);
                        }
                    }
                }

                break;
            }
            }
        }
예제 #10
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));
        }