public void ProcessRequest(Security security, MarketDataMessage message, bool tryAdd)
            {
                if (security == null)
                {
                    throw new ArgumentNullException(nameof(security));
                }

                if (message == null)
                {
                    throw new ArgumentNullException(nameof(message));
                }

                if (message.TransactionId == 0)
                {
                    message.TransactionId = _connector.TransactionIdGenerator.GetNextId();
                }

                message.FillSecurityInfo(_connector, security);

                var value = Tuple.Create((MarketDataMessage)message.Clone(), security);

                if (tryAdd)
                {
                    // if the message was looped back via IsBack=true
                    _pendingSubscriptions.TryAdd(message.TransactionId, value);
                }
                else
                {
                    _pendingSubscriptions.Add(message.TransactionId, value);
                }

                _connector.SendInMessage(message);
            }
示例#2
0
        private SubscriptionInfo ProcessSubscription <T>(Dictionary <T, SubscriptionInfo> subscriptions, T key, MarketDataMessage message, ref bool sendIn, ref MarketDataMessage sendOutMsg)
        {
            MarketDataMessage clone = null;
            var info             = subscriptions.TryGetValue(key) ?? new SubscriptionInfo(clone = (MarketDataMessage)message.Clone());
            var subscribersCount = info.Subscribers;
            var isSubscribe      = message.IsSubscribe;

            if (isSubscribe)
            {
                subscribersCount++;
                sendIn = subscribersCount == 1;
            }
            else
            {
                if (subscribersCount > 0)
                {
                    subscribersCount--;
                    sendIn = subscribersCount == 0;
                }
                else
                {
                    sendOutMsg = NonExist(message);
                }
            }

            if (sendOutMsg != null)
            {
                return(info);
            }

            //if (isSubscribe)
            info.Subscriptions.Add(clone ?? (MarketDataMessage)message.Clone());

            _subscribersById.Add(message.TransactionId, info);

            if (!sendIn && info.IsSubscribed)
            {
                sendOutMsg = new MarketDataMessage
                {
                    DataType              = message.DataType,
                    IsSubscribe           = isSubscribe,
                    SecurityId            = message.SecurityId,
                    Arg                   = message.Arg,
                    OriginalTransactionId = message.TransactionId,
                };
            }

            if (subscribersCount > 0)
            {
                info.Subscribers   = subscribersCount;
                subscriptions[key] = info;
            }
            else
            {
                subscriptions.Remove(key);
            }

            return(info);
        }
        private void RaiseMarketDataMessage(MarketDataMessage message, Exception error)
        {
            var reply = (MarketDataMessage)message.Clone();

            reply.OriginalTransactionId = message.TransactionId;
            reply.Error = error;
            SendOutMessage(reply);
        }
        private void ProcessMarketData(MarketDataMessage mdMsg)
        {
            switch (mdMsg.DataType)
            {
            case MarketDataTypes.Level1:
            {
                if (mdMsg.IsSubscribe)
                {
                    _subscribedLevel1.Add(mdMsg.SecurityId);
                }
                else
                {
                    _subscribedLevel1.Remove(mdMsg.SecurityId);
                }

                break;
            }

            case MarketDataTypes.MarketDepth:
            {
                if (mdMsg.IsSubscribe)
                {
                    _subscribedDepths.Add(mdMsg.SecurityId, mdMsg.MaxDepth ?? MarketDataMessage.DefaultMaxDepth);
                }
                else
                {
                    _subscribedDepths.Remove(mdMsg.SecurityId);
                }

                break;
            }

            case MarketDataTypes.Trades:
            {
                if (mdMsg.IsSubscribe)
                {
                    _subscribedTicks.Add(mdMsg.SecurityId);
                }
                else
                {
                    _subscribedTicks.Remove(mdMsg.SecurityId);
                }

                break;
            }

            default:
            {
                SendOutMarketDataNotSupported(mdMsg.TransactionId);
                return;
            }
            }

            var reply = (MarketDataMessage)mdMsg.Clone();

            reply.OriginalTransactionId = mdMsg.OriginalTransactionId;
            SendOutMessage(reply);
        }
示例#5
0
        /// <summary>
        /// Update filter with new subscription.
        /// </summary>
        /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param>
        public void Subscribe(MarketDataMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            var origin = (MarketDataMessage)message.Clone();

            lock (_subscriptionsLock)
            {
                DataType dataType;

                if (message.DataType == MarketDataTypes.CandleTimeFrame)
                {
                    if (message.IsCalcVolumeProfile)
                    {
                        switch (message.BuildFrom)
                        {
                        case MarketDataTypes.Trades:
                            dataType = TicksAsLevel1 ? DataType.Level1 : DataType.Ticks;
                            break;

                        case MarketDataTypes.MarketDepth:
                            dataType = DataType.MarketDepth;
                            break;

                        default:
                            dataType = DataType.Level1;
                            break;
                        }
                    }
                    else if (message.AllowBuildFromSmallerTimeFrame)
                    {
                        // null arg means do not use DataType.Arg as a filter
                        dataType = DataType.Create(typeof(TimeFrameCandleMessage), null);
                    }
                    else
                    {
                        dataType = DataType.Create(typeof(TimeFrameCandleMessage), message.Arg);
                    }
                }
                else
                {
                    dataType = CreateDataType(message);

                    if (dataType == null)
                    {
                        return;
                    }
                }

                var subscription = Tuple.Create(message.SecurityId, dataType);

                _subscriptionsById.Add(message.TransactionId, Tuple.Create(origin, subscription));
                Subscribe(subscription);
            }
        }
        private void ProcessMarketData(MarketDataMessage mdMsg)
        {
            switch (mdMsg.DataType)
            {
            case MarketDataTypes.Level1:
            {
                if (mdMsg.IsSubscribe)
                {
                    _subscribedLevel1.Add(mdMsg.SecurityId);
                }
                else
                {
                    _subscribedLevel1.Remove(mdMsg.SecurityId);
                }

                break;
            }

            case MarketDataTypes.MarketDepth:
            {
                if (mdMsg.IsSubscribe)
                {
                    _subscribedDepths.Add(mdMsg.SecurityId, mdMsg.MaxDepth);
                }
                else
                {
                    _subscribedDepths.Remove(mdMsg.SecurityId);
                }

                break;
            }

            case MarketDataTypes.Trades:
            {
                if (mdMsg.IsSubscribe)
                {
                    _subscribedTicks.Add(mdMsg.SecurityId);
                }
                else
                {
                    _subscribedTicks.Remove(mdMsg.SecurityId);
                }

                break;
            }

            default:
                throw new ArgumentOutOfRangeException("mdMsg", mdMsg.DataType, LocalizedStrings.Str1618);
            }

            var reply = (MarketDataMessage)mdMsg.Clone();

            reply.OriginalTransactionId = mdMsg.OriginalTransactionId;
            SendOutMessage(reply);
        }
示例#7
0
 private void ProcessSubscriptionAction(IEnumerator <IMessageAdapter> enumerator, MarketDataMessage message)
 {
     if (enumerator.MoveNext())
     {
         enumerator.Current.SendInMessage(message.Clone());
     }
     else
     {
         RaiseSubscriptionFailed(message, new ArgumentException(LocalizedStrings.Str629Params.Put(message.SecurityId), "message"));
     }
 }
示例#8
0
        private void ProcessMarketDataMessage(MarketDataMessage msg)
        {
            if (msg.IsSubscribe)
            {
                if (msg.IsBack)
                {
                    if (_seriesInfosByTransactions.ContainsKey(msg.TransactionId))
                    {
                        base.SendInMessage(msg);
                        return;
                    }
                }

                var info = new SeriesInfo
                {
                    MarketDataMessage = (MarketDataMessage)msg.Clone(),
                    LastTime          = msg.From,
                    Board             = !msg.SecurityId.BoardCode.IsEmpty() ? _exchangeInfoProvider.GetOrCreateBoard(msg.SecurityId.BoardCode) : ExchangeBoard.Test
                };

                _seriesInfos
                .SafeAdd(msg.SecurityId)
                .Add(info);

                _seriesInfosByDates
                .Add(new KeyValuePair <DateTimeOffset, SeriesInfo>(msg.To ?? DateTimeOffset.MaxValue, info));

                _series
                .SafeAdd(Tuple.Create(msg.SecurityId, msg.DataType, msg.Arg))
                .Add(info);

                Subscribe(info, false);
            }
            else
            {
                var subscriptions = _seriesInfos.TryGetValue(msg.SecurityId);

                if (subscriptions == null)
                {
                    return;
                }

                var removed = subscriptions.RemoveWhere(s => s.MarketDataMessage.TransactionId == msg.OriginalTransactionId);

                foreach (var info in removed)
                {
                    UnSubscribe(info, false);
                }
            }
        }
示例#9
0
        private void ProcessMarketDataMessage(MarketDataMessage msg)
        {
            if (msg.IsBack || DaysLoad == TimeSpan.Zero)
            {
                base.SendInMessage(msg);
                return;
            }

            if (msg.IsSubscribe)
            {
                var from          = msg.From ?? DateTime.UtcNow.Date - DaysLoad;
                var to            = msg.To ?? DateTimeOffset.Now;
                var transactionId = msg.TransactionId;

                RaiseStorageMessage(new MarketDataMessage {
                    OriginalTransactionId = transactionId, IsHistory = true
                });

                var lastTime = LoadMessages(msg, from, to, transactionId);

                RaiseStorageMessage(new MarketDataFinishedMessage {
                    OriginalTransactionId = transactionId, IsHistory = true
                });

                if (msg.IsHistory)
                {
                    return;
                }

                Subscribe(msg.SecurityId, CreateDataType(msg));

                var clone = (MarketDataMessage)msg.Clone();
                clone.From = lastTime;

                base.SendInMessage(clone);
            }
            else
            {
                if (msg.IsHistory)
                {
                    return;
                }

                UnSubscribe(msg.SecurityId, CreateDataType(msg));
                base.SendInMessage(msg);
            }
        }
示例#10
0
        private void ProcessInnerAdapterMarketDataMessage(IMessageAdapter adapter, MarketDataMessage message)
        {
            var key = Tuple.Create(message.SecurityId, message.DataType);

            var tuple  = _subscriptionQueue.TryGetValue(key);
            var cancel = tuple != null && tuple.Second;

            if (message.Error == null)
            {
                SessionHolder.AddDebugLog(LocalizedStrings.Str630Params, message.SecurityId, adapter);

                _subscriptionQueue.Remove(key);

                RaiseMarketDataMessage(message, null);

                if (!cancel)
                {
                    return;
                }

                //в процессе подписки пользователь отменил ее - надо отписаться от получения данных
                var cancelMessage = (MarketDataMessage)message.Clone();
                cancelMessage.IsSubscribe = false;
                SendInMessage(cancelMessage);
            }
            else
            {
                SessionHolder.AddDebugLog(LocalizedStrings.Str631Params, adapter, message.SecurityId, message.DataType, message.Error);

                if (cancel)
                {
                    RaiseSubscriptionFailed(message, new InvalidOperationException(LocalizedStrings.SubscriptionProcessCancelled));
                }
                else if (tuple != null)
                {
                    ProcessSubscriptionAction(tuple.First, message);
                }
                else
                {
                    RaiseSubscriptionFailed(message, new InvalidOperationException(LocalizedStrings.Str633Params.Put(message.SecurityId, message.DataType)));
                }
            }
        }
示例#11
0
        private void ProcessUnSubscribeAction(MarketDataMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            lock (_subscriptionQueue.SyncRoot)
            {
                var tuple = _subscriptionQueue.TryGetValue(Tuple.Create(message.SecurityId, message.DataType));
                if (tuple != null)
                {
                    tuple.Second = true;
                    return;
                }
            }

            GetSortedAdapters().ForEach(a => a.SendInMessage(message.Clone()));
        }
示例#12
0
        private void ProcessMarketDataMessage(MarketDataMessage message)
        {
            _requests.Enqueue(new LuaRequest
            {
                MessageType = message.Type,
                DataType    = message.DataType,
                SecurityId  = new SecurityId
                {
                    SecurityCode = message.SecurityId.SecurityCode,
                    BoardCode    = _securityClassInfo.GetSecurityClass(message.SecurityId)
                },
                IsSubscribe   = message.IsSubscribe,
                TransactionId = message.TransactionId
            });

            var result = (MarketDataMessage)message.Clone();

            result.OriginalTransactionId = message.TransactionId;
            _fixServer.SendInMessage(result);
        }
示例#13
0
            public void UnSubscribe(Security security, MarketDataMessage message)
            {
                if (security == null)
                {
                    throw new ArgumentNullException(nameof(security));
                }

                //var indexSecurity = security as IndexSecurity;

                //if (indexSecurity != null)
                //	indexSecurity.InnerSecurities.ForEach(s => _connector.UnSubscribeMarketData(s, message));
                //else if (security is ContinuousSecurity)
                //	UnSubscribeContinuous((ContinuousSecurity)security, message);
                //else
                //{
                //TryUnSubscribe(security, message);
                var tuple = Tuple.Create((MarketDataMessage)message.Clone(), security);

                // we can cancel by subscription id (message maybe by unfilled) or send fully filled unsubscription message
                _pendingSubscriptions.Add(message.OriginalTransactionId == 0 ? message.TransactionId : message.OriginalTransactionId, tuple);

                _connector.SendInMessage(message);
                //}
            }
        private void ProcessMarketDataMessage(MarketDataMessage mdMsg)
        {
            switch (mdMsg.DataType)
            {
            case MarketDataTypes.Level1:
            {
                SendCommand(mdMsg.IsSubscribe
                                                                        ? new SubscribeMessage {
                        Quotations = { mdMsg.SecurityId }
                    }
                                                                        : new UnsubscribeMessage {
                        Quotations = { mdMsg.SecurityId }
                    });

                break;
            }

            case MarketDataTypes.MarketDepth:
            {
                SendCommand(mdMsg.IsSubscribe
                                                                        ? new SubscribeMessage {
                        Quotes = { mdMsg.SecurityId }
                    }
                                                                        : new UnsubscribeMessage {
                        Quotes = { mdMsg.SecurityId }
                    });

                break;
            }

            case MarketDataTypes.Trades:
            {
                if (mdMsg.IsSubscribe)
                {
                    //Подписаться/отписаться на тики можно двумя способами:
                    //SubscribeMessage/UnsubscribeMessage - тики приходят с момента подписки
                    //SubscribeTicksMessage - Тики приходят с момента подиски(TradeNo = 0), или с любого номера. При повторном запросе отписка получения тиков по предыдущему запросу.


                    //var command = new SubscribeMessage();
                    //command.AllTrades.Add(security.GetTransaqId());

                    //ApiClient.Send(new Tuple<BaseCommandMessage, Action<BaseResponse>>(command, ProcessResult));

                    //---

                    _registeredSecurityIds.Add(mdMsg.SecurityId);

                    var command = new SubscribeTicksMessage {
                        Filter = true
                    };                                                                                     //Filter только сделки нормально периода торгов

                    foreach (var id in _registeredSecurityIds)
                    {
                        command.Items.Add(new SubscribeTicksSecurity
                            {
                                SecId   = (int)id.Native,
                                TradeNo = id.Equals(mdMsg.SecurityId) ? 1 : 0,
                            });
                    }

                    SendCommand(command);
                }
                else
                {
                    //var command = new UnsubscribeMessage();
                    //command.AllTrades.Add(security.GetTransaqId());

                    //ApiClient.Send(new Tuple<BaseCommandMessage, Action<BaseResponse>>(command, ProcessResult));

                    //---

                    _registeredSecurityIds.Remove(mdMsg.SecurityId);

                    var command = new SubscribeTicksMessage {
                        Filter = true
                    };                                                                                     //Filter только сделки нормально периода торгов

                    foreach (var id in _registeredSecurityIds)
                    {
                        command.Items.Add(new SubscribeTicksSecurity
                            {
                                SecId   = (int)id.Native,
                                TradeNo = 0,
                            });
                    }

                    SendCommand(command);
                }

                break;
            }

            case MarketDataTypes.News:
            {
                if (mdMsg.IsSubscribe)
                {
                    if (mdMsg.NewsId.IsEmpty())
                    {
                        var count = (int)mdMsg.Count;

                        if (count <= 0)
                        {
                            throw new InvalidOperationException(LocalizedStrings.Str3511Params.Put(count));
                        }

                        if (count > MaxNewsHeaderCount)
                        {
                            throw new InvalidOperationException(LocalizedStrings.Str3512Params.Put(count, MaxNewsHeaderCount));
                        }

                        SendCommand(new RequestOldNewsMessage {
                                Count = count
                            });
                    }
                    else
                    {
                        SendCommand(new RequestNewsBodyMessage {
                                NewsId = mdMsg.NewsId.To <int>()
                            });
                    }
                }

                break;
            }

            case MarketDataTypes.CandleTimeFrame:
            {
                if (mdMsg.IsSubscribe)
                {
                    var periodId = _candlePeriods.GetKeys((TimeSpan)mdMsg.Arg).First();

                    _candleTransactions.Add(Tuple.Create((int)mdMsg.SecurityId.Native, periodId), mdMsg.TransactionId);

                    var command = new RequestHistoryDataMessage
                    {
                        SecId  = (int)mdMsg.SecurityId.Native,
                        Period = periodId,
                        Count  = mdMsg.Count,
                        Reset  = mdMsg.To == DateTimeOffset.MaxValue,
                    };

                    SendCommand(command);
                }

                break;
            }

            default:
                throw new ArgumentOutOfRangeException("mdMsg", mdMsg.DataType, LocalizedStrings.Str1618);
            }

            var reply = (MarketDataMessage)mdMsg.Clone();

            reply.OriginalTransactionId = mdMsg.TransactionId;
            SendOutMessage(reply);
        }
        private void ProcessMarketDataMessage(MarketDataMessage message)
        {
            switch (message.DataType)
            {
            case MarketDataTypes.Level1:
            {
                if (message.SecurityId.Native is int)
                {
                    if (message.IsSubscribe)
                    {
                        Wrapper.RegisterLevel1((int)message.SecurityId.Native);
                    }
                    else
                    {
                        Wrapper.UnRegisterLevel1((int)message.SecurityId.Native);
                    }
                }
                else
                {
                    throw new InvalidOperationException(LocalizedStrings.Str2253Params.Put(message.SecurityId));
                }

                break;
            }

            case MarketDataTypes.MarketDepth:
            {
                if (message.SecurityId.Native is int)
                {
                    if (message.IsSubscribe)
                    {
                        Wrapper.RegisterMarketDepth((int)message.SecurityId.Native);
                    }
                    else
                    {
                        Wrapper.UnRegisterMarketDepth((int)message.SecurityId.Native);
                    }
                }
                else
                {
                    throw new InvalidOperationException(LocalizedStrings.Str2253Params.Put(message.SecurityId));
                }

                break;
            }

            case MarketDataTypes.Trades:
            {
                if (message.SecurityId.Native is int)
                {
                    if (message.IsSubscribe)
                    {
                        Wrapper.RegisterTrades((int)message.SecurityId.Native);
                    }
                    else
                    {
                        Wrapper.UnRegisterTrades((int)message.SecurityId.Native);
                    }
                }
                else
                {
                    throw new InvalidOperationException(LocalizedStrings.Str2253Params.Put(message.SecurityId));
                }

                break;
            }

            case MarketDataTypes.News:
            {
                if (!message.NewsId.IsEmpty())
                {
                    throw new NotSupportedException(LocalizedStrings.Str1617);
                }

                if (message.IsSubscribe)
                {
                    Wrapper.StartExportNews();
                }
                else
                {
                    Wrapper.StopExportNews();
                }

                break;
            }

            case MarketDataTypes.CandleTimeFrame:
            {
                if (message.IsSubscribe)
                {
                    Wrapper.LookupCandles(message);
                }

                break;
            }

            default:
            {
                SendOutMarketDataNotSupported(message.TransactionId);
                return;
            }
            }

            var reply = (MarketDataMessage)message.Clone();

            reply.OriginalTransactionId = message.TransactionId;
            SendOutMessage(reply);
        }
示例#16
0
        private void ProcessMarketData(MarketDataMessage mdMsg)
        {
            switch (mdMsg.DataType)
            {
            case MarketDataTypes.Level1:
            {
                //if (mdMsg.IsSubscribe)
                //	_subscribedLevel1.Add(secCode);
                //else
                //	_subscribedLevel1.Remove(secCode);

                break;
            }

            case MarketDataTypes.MarketDepth:
            {
                if (mdMsg.IsSubscribe)
                {
                    _subscribedDepths.Add(mdMsg.SecurityId);

                    if (_subscribedDepths.Count == 1)
                    {
                        _pusherClient.SubscribeDepths();
                    }
                }
                else
                {
                    _subscribedDepths.Remove(mdMsg.SecurityId);

                    if (_subscribedDepths.Count == 0)
                    {
                        _pusherClient.UnSubscribeDepths();
                    }
                }

                break;
            }

            case MarketDataTypes.Trades:
            {
                if (mdMsg.IsSubscribe)
                {
                    if (mdMsg.From != null && mdMsg.From.Value.DateTime == DateTime.Today)
                    {
                        _httpClient.RequestTransactions().Select(t => new ExecutionMessage
                            {
                                ExecutionType = ExecutionTypes.Tick,
                                SecurityId    = _btcUsd,
                                TradeId       = t.Id,
                                TradePrice    = (decimal)t.Price,
                                TradeVolume   = (decimal)t.Amount,
                                ServerTime    = t.Time.ApplyTimeZone(TimeZoneInfo.Utc)
                            }).ForEach(SendOutMessage);
                    }

                    _subscribedTicks.Add(mdMsg.SecurityId);

                    if (_subscribedTicks.Count == 1)
                    {
                        _pusherClient.SubscribeTrades();
                    }
                }
                else
                {
                    _subscribedTicks.Remove(mdMsg.SecurityId);

                    if (_subscribedTicks.Count == 0)
                    {
                        _pusherClient.UnSubscribeTrades();
                    }
                }

                break;
            }

            default:
            {
                SendOutMarketDataNotSupported(mdMsg.TransactionId);
                return;
            }
            }

            var reply = (MarketDataMessage)mdMsg.Clone();

            reply.OriginalTransactionId = mdMsg.OriginalTransactionId;
            SendOutMessage(reply);
        }
示例#17
0
            public void ProcessRequest(Security security, MarketDataMessage message, bool tryAdd)
            {
                if (message == null)
                {
                    throw new ArgumentNullException(nameof(message));
                }

                if (!tryAdd)
                {
                    var msg = (message.IsSubscribe ? LocalizedStrings.SubscriptionSent : LocalizedStrings.UnSubscriptionSent)
                              .Put(security?.Id, message.ToDataTypeString());

                    if (message.From != null && message.To != null)
                    {
                        msg += LocalizedStrings.Str691Params.Put(message.From.Value, message.To.Value);
                    }

                    _connector.AddDebugLog(msg + ".");
                }

                if (security == null)
                {
                    if (!message.IsSubscribe)
                    {
                        if (message.OriginalTransactionId != 0)
                        {
                            security = TryGetSecurity(message.OriginalTransactionId);
                        }
                    }
                }

                if (security == null)
                {
                    if (message.DataType != MarketDataTypes.News)
                    {
                        if (message.SecurityId.IsDefault())
                        {
                            throw new ArgumentNullException(nameof(security));
                        }

                        security = _connector.LookupById(message.SecurityId);

                        if (security == null)
                        {
                            throw new ArgumentException(LocalizedStrings.Str704Params.Put(message.SecurityId));
                        }
                    }
                }

                if (message.TransactionId == 0)
                {
                    message.TransactionId = _connector.TransactionIdGenerator.GetNextId();
                }

                if (security != null)
                {
                    message.FillSecurityInfo(_connector, security);
                }

                var value = Tuple.Create((MarketDataMessage)message.Clone(), security);

                if (tryAdd)
                {
                    // if the message was looped back via IsBack=true
                    _requests.TryAdd(message.TransactionId, value);
                }
                else
                {
                    _requests.Add(message.TransactionId, value);
                }

                _connector.SendInMessage(message);
            }
示例#18
0
            private void TrySubscribe(Security subscriber, MarketDataMessage message)
            {
                //Если уже выполняется поиск данного инструмента, то нет необходимости в повторном вызове OnRegisterXXX.
                //Если на инструмент была подписка ранее, то просто вызываем событие SubscriptionSucceed.
                var subscribersCount = GetSubscribers(message.DataType).ChangeSubscribers(subscriber, true);

                //var securityId = _connector.GetSecurityId(subscriber);

                if (subscribersCount == 1)
                {
                    var lookupMessage = new SecurityLookupMessage
                    {
                        SecurityId    = message.SecurityId,
                        SecurityType  = message.SecurityType,
                        TransactionId = _connector.TransactionIdGenerator.GetNextId()
                    };

                    _lookupMessages.Add(lookupMessage.TransactionId, Tuple.Create(lookupMessage, (MarketDataMessage)message.Clone()));
                    _connector.LookupSecurities(lookupMessage);
                }
                else                // if (subscribed == true)
                {
                    var reply = new MarketDataMessage
                    {
                        OriginalTransactionId = message.TransactionId,
                        IsSubscribe           = true,
                    };
                    _connector.SendOutMessage(reply);
                }
            }
示例#19
0
            public void Subscribe(Security security, MarketDataMessage message)
            {
                if (security == null)
                {
                    throw new ArgumentNullException(nameof(security));
                }

                //var indexSecurity = security as IndexSecurity;

                //if (indexSecurity != null)
                //	indexSecurity.InnerSecurities.ForEach(s => _connector.SubscribeMarketData(s, message));
                //else if (security is ContinuousSecurity)
                //	SubscribeContinuous((ContinuousSecurity)security, message);
                //else
                //{
                //TrySubscribe(security, message);
                _pendingSubscriptions.Add(message.TransactionId, Tuple.Create((MarketDataMessage)message.Clone(), security));
                _connector.SendInMessage(message);
                //}
            }
        private void ProcessMarketDataMessage(MarketDataMessage mdMsg)
        {
            switch (mdMsg.DataType)
            {
            case MarketDataTypes.Level1:
            {
                SendCommand(mdMsg.IsSubscribe
                                                                        ? new SubscribeMessage {
                        Quotations = { mdMsg.SecurityId }
                    }
                                                                        : new UnsubscribeMessage {
                        Quotations = { mdMsg.SecurityId }
                    });

                break;
            }

            case MarketDataTypes.MarketDepth:
            {
                SendCommand(mdMsg.IsSubscribe
                                                                        ? new SubscribeMessage {
                        Quotes = { mdMsg.SecurityId }
                    }
                                                                        : new UnsubscribeMessage {
                        Quotes = { mdMsg.SecurityId }
                    });

                break;
            }

            case MarketDataTypes.Trades:
            {
                if (mdMsg.IsSubscribe)
                {
                    //Подписаться/отписаться на тики можно двумя способами:
                    //SubscribeMessage/UnsubscribeMessage - тики приходят с момента подписки
                    //SubscribeTicksMessage - Тики приходят с момента подиски(TradeNo = 0), или с любого номера. При повторном запросе отписка получения тиков по предыдущему запросу.


                    //var command = new SubscribeMessage();
                    //command.AllTrades.Add(security.GetTransaqId());

                    //ApiClient.Send(new Tuple<BaseCommandMessage, Action<BaseResponse>>(command, ProcessResult));

                    //---

                    _registeredSecurityIds.Add(mdMsg.SecurityId);

                    var command = new SubscribeTicksMessage {
                        Filter = true
                    };                                                                                     //Filter только сделки нормально периода торгов

                    foreach (var id in _registeredSecurityIds)
                    {
                        command.Items.Add(new SubscribeTicksSecurity
                            {
                                SecId = (int)id.Native,
                                // http://stocksharp.com/forum/yaf_postsm35978_Obnovlieniie-Tranzak-do-viersii-2-16-1.aspx#post35978
                                //TradeNo = id.Equals(mdMsg.SecurityId) ? 1 : 0,
                                TradeNo = 1,
                            });
                    }

                    SendCommand(command);
                }
                else
                {
                    //var command = new UnsubscribeMessage();
                    //command.AllTrades.Add(security.GetTransaqId());

                    //ApiClient.Send(new Tuple<BaseCommandMessage, Action<BaseResponse>>(command, ProcessResult));

                    //---

                    _registeredSecurityIds.Remove(mdMsg.SecurityId);

                    var command = new SubscribeTicksMessage {
                        Filter = true
                    };                                                                                     //Filter только сделки нормально периода торгов

                    foreach (var id in _registeredSecurityIds)
                    {
                        command.Items.Add(new SubscribeTicksSecurity
                            {
                                SecId   = (int)id.Native,
                                TradeNo = 0,
                            });
                    }

                    SendCommand(command);
                }

                break;
            }

            case MarketDataTypes.News:
            {
                if (mdMsg.IsSubscribe)
                {
                    if (mdMsg.NewsId.IsEmpty())
                    {
                        var count = mdMsg.Count;

                        if (count == null)
                        {
                            count = MaxNewsHeaderCount;
                        }
                        else
                        {
                            if (count < 0)
                            {
                                throw new InvalidOperationException(LocalizedStrings.Str3511Params.Put(count));
                            }

                            if (count > MaxNewsHeaderCount)
                            {
                                throw new InvalidOperationException(LocalizedStrings.Str3512Params.Put(count, MaxNewsHeaderCount));
                            }
                        }

                        SendCommand(new RequestOldNewsMessage {
                                Count = (int)count.Value
                            });
                    }
                    else
                    {
                        SendCommand(new RequestNewsBodyMessage {
                                NewsId = mdMsg.NewsId.To <int>()
                            });
                    }
                }

                break;
            }

            case MarketDataTypes.CandleTimeFrame:
            {
                if (mdMsg.IsSubscribe)
                {
                    var periodId = _candlePeriods.GetKeys((TimeSpan)mdMsg.Arg).First();
                    var secId    = (int)mdMsg.SecurityId.Native;
                    var key      = Tuple.Create(secId, periodId);

                    _candleTransactions.Add(key, mdMsg.TransactionId);

                    var command = new RequestHistoryDataMessage
                    {
                        SecId  = secId,
                        Period = periodId,
                        Count  = mdMsg.Count ?? 0,
                        Reset  = mdMsg.To == null,
                    };

                    try
                    {
                        SendCommand(command);
                    }
                    catch (Exception)
                    {
                        _candleTransactions.Remove(key);
                        throw;
                    }
                }

                break;
            }

            default:
            {
                SendOutMarketDataNotSupported(mdMsg.TransactionId);
                return;
            }
            }

            var reply = (MarketDataMessage)mdMsg.Clone();

            reply.OriginalTransactionId = mdMsg.TransactionId;
            SendOutMessage(reply);
        }
        private void ProcessInMarketDataMessage(MarketDataMessage message)
        {
            var sendIn = false;
            MarketDataMessage sendOutMsg = null;
            RefPair <MarketDataMessage, int> pair;
            var secIdKey = InnerAdapter.IsSupportSubscriptionBySecurity ? message.SecurityId : default(SecurityId);

            lock (_sync)
            {
                var isSubscribe = message.IsSubscribe;

                switch (message.DataType)
                {
                case MarketDataTypes.News:
                {
                    var subscriber = message.NewsId ?? string.Empty;

                    pair = _newsSubscribers.TryGetValue(subscriber) ?? RefTuple.Create((MarketDataMessage)message.Clone(), 0);
                    var subscribersCount = pair.Second;

                    if (isSubscribe)
                    {
                        subscribersCount++;
                        sendIn = subscribersCount == 1;
                    }
                    else
                    {
                        if (subscribersCount > 0)
                        {
                            subscribersCount--;
                            sendIn = subscribersCount == 0;
                        }
                        else
                        {
                            sendOutMsg = NonExist(message);
                        }
                    }

                    if (sendOutMsg == null)
                    {
                        if (!sendIn)
                        {
                            sendOutMsg = new MarketDataMessage
                            {
                                DataType              = message.DataType,
                                IsSubscribe           = isSubscribe,
                                OriginalTransactionId = message.TransactionId,
                            };
                        }

                        if (subscribersCount > 0)
                        {
                            pair.Second = subscribersCount;
                            _newsSubscribers[subscriber] = pair;
                        }
                        else
                        {
                            _newsSubscribers.Remove(subscriber);
                        }
                    }

                    break;
                }

                case MarketDataTypes.CandleTimeFrame:
                case MarketDataTypes.CandleRange:
                case MarketDataTypes.CandlePnF:
                case MarketDataTypes.CandleRenko:
                case MarketDataTypes.CandleTick:
                case MarketDataTypes.CandleVolume:
                {
                    var key = Tuple.Create(message.DataType, secIdKey, message.Arg);

                    pair = _candleSubscribers.TryGetValue(key) ?? RefTuple.Create((MarketDataMessage)message.Clone(), 0);
                    var subscribersCount = pair.Second;

                    if (isSubscribe)
                    {
                        subscribersCount++;
                        sendIn = subscribersCount == 1;
                    }
                    else
                    {
                        if (subscribersCount > 0)
                        {
                            subscribersCount--;
                            sendIn = subscribersCount == 0;
                        }
                        else
                        {
                            sendOutMsg = NonExist(message);
                        }
                    }

                    if (sendOutMsg == null)
                    {
                        if (!sendIn)
                        {
                            sendOutMsg = new MarketDataMessage
                            {
                                DataType              = message.DataType,
                                IsSubscribe           = isSubscribe,
                                SecurityId            = message.SecurityId,
                                Arg                   = message.Arg,
                                OriginalTransactionId = message.TransactionId,
                            };
                        }

                        if (subscribersCount > 0)
                        {
                            pair.Second             = subscribersCount;
                            _candleSubscribers[key] = pair;
                        }
                        else
                        {
                            _candleSubscribers.Remove(key);
                        }
                    }

                    break;
                }

                default:
                {
                    var key = message.CreateKey(secIdKey);

                    pair = _subscribers.TryGetValue(key) ?? RefTuple.Create((MarketDataMessage)message.Clone(), 0);
                    var subscribersCount = pair.Second;

                    if (isSubscribe)
                    {
                        subscribersCount++;
                        sendIn = subscribersCount == 1;
                    }
                    else
                    {
                        if (subscribersCount > 0)
                        {
                            subscribersCount--;
                            sendIn = subscribersCount == 0;
                        }
                        else
                        {
                            sendOutMsg = NonExist(message);
                        }
                    }

                    if (sendOutMsg == null)
                    {
                        if (!sendIn)
                        {
                            sendOutMsg = new MarketDataMessage
                            {
                                DataType              = message.DataType,
                                IsSubscribe           = isSubscribe,
                                SecurityId            = message.SecurityId,
                                OriginalTransactionId = message.TransactionId,
                            };
                        }

                        if (subscribersCount > 0)
                        {
                            pair.Second       = subscribersCount;
                            _subscribers[key] = pair;
                        }
                        else
                        {
                            _subscribers.Remove(key);
                        }
                    }

                    break;
                }
                }
            }

            if (sendIn)
            {
                if (!message.IsSubscribe && message.OriginalTransactionId == 0)
                {
                    message.OriginalTransactionId = pair.First.TransactionId;
                }

                base.SendInMessage(message);
            }

            if (sendOutMsg != null)
            {
                RaiseNewOutMessage(sendOutMsg);
            }
        }
        private void ProcessMarketDataMessage(MarketDataMessage mdMsg)
        {
            var secCode   = mdMsg.SecurityId.SecurityCode;
            var boardCode = mdMsg.SecurityId.BoardCode;

            switch (mdMsg.DataType)
            {
            case MarketDataTypes.Level1:
            {
                if (mdMsg.IsSubscribe)
                {
                    _client.Session.subscribe(boardCode, secCode, SubscriptionFlags.All & ~(SubscriptionFlags.Prints | SubscriptionFlags.PrintsCond | SubscriptionFlags.Quotes), mdMsg.TransactionId);
                }
                else
                {
                    _client.Session.unsubscribe(boardCode, secCode);
                }

                break;
            }

            case MarketDataTypes.MarketDepth:
            {
                if (mdMsg.IsSubscribe)
                {
                    _client.Session.rebuildBook(boardCode, secCode, mdMsg.TransactionId);
                    _client.Session.subscribe(boardCode, secCode, SubscriptionFlags.Quotes, mdMsg.TransactionId);
                }
                else
                {
                    _client.Session.unsubscribe(boardCode, secCode);
                }

                break;
            }

            case MarketDataTypes.Trades:
            {
                if (mdMsg.From == null || mdMsg.To == null)
                {
                    if (mdMsg.IsSubscribe)
                    {
                        _client.Session.subscribe(boardCode, secCode, SubscriptionFlags.Prints | SubscriptionFlags.PrintsCond, mdMsg.TransactionId);
                    }
                    else
                    {
                        _client.Session.unsubscribe(boardCode, secCode);
                    }
                }
                else
                {
                    _client.Session.replayTrades(boardCode, secCode, mdMsg.From.Value.ToSsboe(), mdMsg.To.Value.ToSsboe(), mdMsg.TransactionId);
                }

                break;
            }

            //case MarketDataTypes.OrderLog:
            //	break;
            //case MarketDataTypes.News:
            //	break;
            case MarketDataTypes.CandleTimeFrame:
            {
                if (mdMsg.From == null || mdMsg.To == null)
                {
                    if (mdMsg.IsSubscribe)
                    {
                        _client.Session.subscribeTimeBar(boardCode, secCode, mdMsg.TransactionId);
                    }
                    else
                    {
                        _client.Session.unsubscribeTimeBar(boardCode, secCode);
                    }
                }
                else
                {
                    _client.Session.replayTimeBars(boardCode, secCode, mdMsg.From.Value.ToSsboe(), mdMsg.To.Value.ToSsboe(), mdMsg.TransactionId);
                }

                break;
            }

            default:
            {
                SendOutMarketDataNotSupported(mdMsg.TransactionId);
                return;
            }
            }

            var reply = (MarketDataMessage)mdMsg.Clone();

            reply.OriginalTransactionId = mdMsg.TransactionId;
            SendOutMessage(reply);
        }
示例#23
0
        private void ProcessMarketDataMessage(MarketDataMessage message)
        {
            switch (message.DataType)
            {
            case MarketDataTypes.Level1:
            {
                var instrument = message.SecurityId.ToOanda();

                if (message.IsSubscribe)
                {
                    _streamigClient.SubscribePricesStreaming(GetAccountId(), instrument);
                }
                else
                {
                    _streamigClient.UnSubscribePricesStreaming(instrument);
                }

                break;
            }

            //case MarketDataTypes.MarketDepth:
            //	break;
            case MarketDataTypes.News:
            {
                if (message.IsSubscribe)
                {
                    var calendar = _restClient.GetCalendar(message.SecurityId.ToOanda(),
                                                           (int)(3600 * message.Count));

                    foreach (var item in calendar)
                    {
                        SendOutMessage(new NewsMessage
                            {
                                //OriginalTransactionId = message.TransactionId,
                                SecurityId = message.SecurityId,
                                ServerTime = TimeHelper.GregorianStart.AddSeconds(item.TimeStamp),
                                Headline   = item.Title,
                                Story      = "unit={0} curr={1} market={2} forecast={3} previous={4} actual={5}"
                                             .Put(item.Unit, item.Currency, item.Market, item.Forecast, item.Previous, item.Actual),
                            });
                    }
                }

                break;
            }

            case MarketDataTypes.CandleTimeFrame:
            {
                if (message.IsSubscribe)
                {
                    var from = message.From;

                    while (true)
                    {
                        var candles = _restClient.GetCandles(message.SecurityId.ToOanda(),
                                                             ((TimeSpan)message.Arg).ToOanda(), message.Count, from.ToOanda());

                        var count = 0;

                        foreach (var candle in candles)
                        {
                            count++;

                            var time = candle.Time.FromOanda();

                            SendOutMessage(new TimeFrameCandleMessage
                                {
                                    OriginalTransactionId = message.TransactionId,
                                    OpenTime    = time,
                                    SecurityId  = message.SecurityId,
                                    OpenPrice   = (decimal)candle.Open,
                                    HighPrice   = (decimal)candle.High,
                                    LowPrice    = (decimal)candle.Low,
                                    ClosePrice  = (decimal)candle.Close,
                                    TotalVolume = (decimal)candle.Volume,
                                    State       = candle.Complete ? CandleStates.Finished : CandleStates.Active
                                });

                            from = time;
                        }

                        if (message.Count == 0 && count == 500)
                        {
                            continue;
                        }

                        break;
                    }
                }

                break;
            }

            default:
            {
                SendOutMarketDataNotSupported(message.TransactionId);
                return;
            }
            }

            var reply = (MarketDataMessage)message.Clone();

            reply.OriginalTransactionId = message.TransactionId;
            SendOutMessage(reply);
        }
示例#24
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);
        }
        private void ProcessMarketDataMessage(MarketDataMessage mdMsg)
        {
            var smartId = (string)mdMsg.SecurityId.Native;

            if (smartId.IsEmpty())
            {
                throw new InvalidOperationException(LocalizedStrings.Str1853Params.Put(mdMsg.SecurityId));
            }

            switch (mdMsg.DataType)
            {
            case MarketDataTypes.Level1:
            {
                if (mdMsg.IsSubscribe)
                {
                    _wrapper.SubscribeSecurity(smartId);
                }
                else
                {
                    _wrapper.UnSubscribeSecurity(smartId);
                }

                break;
            }

            case MarketDataTypes.MarketDepth:
            {
                if (mdMsg.IsSubscribe)
                {
                    _wrapper.SubscribeMarketDepth(smartId);
                }
                else
                {
                    _wrapper.UnSubscribeMarketDepth(smartId);
                }

                break;
            }

            case MarketDataTypes.Trades:
            {
                if (mdMsg.From == null)
                {
                    if (mdMsg.IsSubscribe)
                    {
                        _wrapper.SubscribeTrades(smartId);
                    }
                    else
                    {
                        _wrapper.UnSubscribeTrades(smartId);
                    }
                }
                else
                {
                    const int maxTradeCount = 1000000;
                    this.AddDebugLog("RequestHistoryTrades SecId = {0} From {1} Count = {2}", smartId, mdMsg.From, maxTradeCount);
                    _wrapper.RequestHistoryTrades(smartId, mdMsg.From.Value.ToLocalTime(TimeHelper.Moscow), maxTradeCount);
                }

                break;
            }

            case MarketDataTypes.CandleTimeFrame:
            {
                var count     = mdMsg.Count ?? 0;
                var direction = (SmartComHistoryDirections)mdMsg.ExtensionInfo["Direction"];

                if (direction == SmartComHistoryDirections.Forward)
                {
                    count = -count;
                }

                var tf = (TimeSpan)mdMsg.Arg;

                _candleTransactions.SafeAdd(smartId)[tf] = Tuple.Create(mdMsg.TransactionId, new List <CandleMessage>());

                this.AddDebugLog("RequestHistoryBars SecId {0} TF {1} From {2} Count {3}", smartId, tf, mdMsg.From, count);
                _wrapper.RequestHistoryBars(smartId, tf, (mdMsg.From ?? DateTimeOffset.MinValue).ToLocalTime(TimeHelper.Moscow), (int)count);

                break;
            }

            default:
            {
                SendOutMarketDataNotSupported(mdMsg.TransactionId);
                return;
            }
            }

            var reply = (MarketDataMessage)mdMsg.Clone();

            reply.OriginalTransactionId = mdMsg.TransactionId;
            SendOutMessage(reply);
        }
        private void ProcessMarketData(MarketDataMessage mdMsg)
        {
            var secCode   = mdMsg.SecurityId.SecurityCode;
            var boardCode = mdMsg.SecurityId.BoardCode;

            switch (mdMsg.DataType)
            {
            case MarketDataTypes.Level1:
            {
                if (mdMsg.IsSubscribe)
                {
                    SessionHolder.Session.SubscribeQuote(secCode, boardCode);
                }
                else
                {
                    SessionHolder.Session.UnsubsribeQuote(secCode, boardCode);
                }

                break;
            }

            case MarketDataTypes.MarketDepth:
            {
                if (mdMsg.IsSubscribe)
                {
                    SessionHolder.Session.SubscribeLevel2(secCode, boardCode);
                }
                else
                {
                    SessionHolder.Session.UnsubsribeLevel2(secCode, boardCode);
                }
                break;
            }

            case MarketDataTypes.Trades:
            {
                if (mdMsg.IsSubscribe)
                {
                    _subscribedSecuritiesToTrade.Add(secCode);
                    SessionHolder.Session.SubscribeQuote(secCode, boardCode);
                }
                else
                {
                    _subscribedSecuritiesToTrade.Remove(secCode);
                    SessionHolder.Session.UnsubsribeQuote(secCode, boardCode);
                }
                break;
            }

            case MarketDataTypes.News:
            {
                if (mdMsg.IsSubscribe)
                {
                    SessionHolder.Session.SubscribeNews();
                }
                else
                {
                    SessionHolder.Session.UnsubscribeNews();
                }
                break;
            }

            default:
                throw new ArgumentOutOfRangeException("message", mdMsg.DataType, LocalizedStrings.Str1618);
            }

            var reply = (MarketDataMessage)mdMsg.Clone();

            reply.OriginalTransactionId = mdMsg.TransactionId;
            SendOutMessage(reply);
        }
示例#27
0
        private void ProcessMarketData(MarketDataMessage mdMsg)
        {
            var secCode   = mdMsg.SecurityId.SecurityCode;
            var boardCode = mdMsg.SecurityId.BoardCode;

            switch (mdMsg.DataType)
            {
            case MarketDataTypes.Level1:
            {
                if (mdMsg.IsSubscribe)
                {
                    _client.SubscribeQuote(secCode, boardCode);
                }
                else
                {
                    _client.UnsubsribeQuote(secCode, boardCode);
                }

                break;
            }

            case MarketDataTypes.MarketDepth:
            {
                if (mdMsg.IsSubscribe)
                {
                    _client.SubscribeLevel2(secCode, boardCode);
                }
                else
                {
                    _client.UnsubsribeLevel2(secCode, boardCode);
                }

                break;
            }

            case MarketDataTypes.Trades:
            {
                if (mdMsg.IsSubscribe)
                {
                    _subscribedSecuritiesToTrade.Add(secCode);
                    _client.SubscribeQuote(secCode, boardCode);
                }
                else
                {
                    _subscribedSecuritiesToTrade.Remove(secCode);
                    _client.UnsubsribeQuote(secCode, boardCode);
                }

                break;
            }

            case MarketDataTypes.News:
            {
                if (mdMsg.IsSubscribe)
                {
                    _client.SubscribeNews();
                }
                else
                {
                    _client.UnsubscribeNews();
                }

                break;
            }

            default:
            {
                SendOutMarketDataNotSupported(mdMsg.TransactionId);
                return;
            }
            }

            var reply = (MarketDataMessage)mdMsg.Clone();

            reply.OriginalTransactionId = mdMsg.TransactionId;
            SendOutMessage(reply);
        }
        private void ProcessMarketDataMessage(MarketDataMessage mdMsg)
        {
            if (!mdMsg.IsSubscribe)
            {
                return;
            }

            if (mdMsg.SecurityId.Native == null)
            {
                throw new InvalidOperationException(LocalizedStrings.Str3392Params.Put(mdMsg.SecurityId.SecurityCode));
            }

            var lmaxId = (long)mdMsg.SecurityId.Native;

            switch (mdMsg.DataType)
            {
            case MarketDataTypes.Level1:
            case MarketDataTypes.Trades:
            {
                _session.Subscribe(new OrderBookStatusSubscriptionRequest(lmaxId), () => { }, CreateErrorHandler("OrderBookStatusSubscriptionRequest"));
                break;
            }

            case MarketDataTypes.MarketDepth:
            {
                _session.Subscribe(new OrderBookSubscriptionRequest(lmaxId), () => { }, CreateErrorHandler("OrderBookSubscriptionRequest"));
                break;
            }

            case MarketDataTypes.CandleTimeFrame:
            {
                IHistoricMarketDataRequest request;

                var tf   = (TimeSpan)mdMsg.Arg;
                var from = (mdMsg.From ?? DateTimeOffset.MinValue).UtcDateTime;
                var to   = (mdMsg.To ?? DateTimeOffset.MaxValue).UtcDateTime;

                if (tf.Ticks == 1)
                {
                    request = new TopOfBookHistoricMarketDataRequest(mdMsg.TransactionId, lmaxId, from, to, Format.Csv);
                }
                else
                {
                    Resolution resolution;

                    if (tf == TimeSpan.FromMinutes(1))
                    {
                        resolution = Resolution.Minute;
                    }
                    else if (tf == TimeSpan.FromDays(1))
                    {
                        resolution = Resolution.Day;
                    }
                    else
                    {
                        throw new InvalidOperationException(LocalizedStrings.Str3393Params.Put(tf));
                    }

                    request = new AggregateHistoricMarketDataRequest(mdMsg.TransactionId, lmaxId, from, to, resolution, Format.Csv, Option.Bid, Option.Ask);
                }

                if (!_isHistoricalSubscribed)
                {
                    _session.Subscribe(new HistoricMarketDataSubscriptionRequest(), () => { }, CreateErrorHandler("HistoricMarketDataSubscriptionRequest"));
                    _isHistoricalSubscribed = true;
                }

                _session.RequestHistoricMarketData(request, () => { }, CreateErrorHandler("RequestHistoricMarketData"));
                break;
            }

            default:
            {
                SendOutMarketDataNotSupported(mdMsg.TransactionId);
                return;
            }
            }

            var result = (MarketDataMessage)mdMsg.Clone();

            result.OriginalTransactionId = mdMsg.TransactionId;
            SendOutMessage(result);
        }
示例#29
0
        private bool ProcessMarketDataRequest(MarketDataMessage message)
        {
            if (message.IsSubscribe)
            {
                if (!InnerAdapter.IsMarketDataTypeSupported(MarketDataTypes.OrderLog))
                {
                    return(false);
                }

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

                        if (InnerAdapter.IsSupportSubscriptionBySecurity)
                        {
                            _depthBuilders.Add(secId, InnerAdapter.CreateOrderLogMarketDepthBuilder(secId));
                        }
                        else
                        {
                            _depthBuilders.TryAdd(secId, (IOrderLogMarketDepthBuilder)null);
                        }

                        _subscriptionIds.Add(message.TransactionId, Tuple.Create(secId, message.DataType));

                        var clone = (MarketDataMessage)message.Clone();
                        clone.DataType = MarketDataTypes.OrderLog;
                        base.SendInMessage(clone);

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

                        return(true);
                    }

                    break;
                }

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

                        _tickBuilders.Add(secId);
                        _subscriptionIds.Add(message.TransactionId, Tuple.Create(secId, message.DataType));

                        var clone = (MarketDataMessage)message.Clone();
                        clone.DataType = MarketDataTypes.OrderLog;
                        base.SendInMessage(clone);

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

                        return(true);
                    }

                    break;
                }
                }
            }
            else
            {
                if (!_subscriptionIds.TryGetValue(message.OriginalTransactionId, out var tuple))
                {
                    return(false);
                }

                var secId = tuple.Item1;

                if (tuple.Item2 == MarketDataTypes.MarketDepth)
                {
                    _depthBuilders.Remove(secId);
                    this.AddInfoLog("OL->MD unsubscribed {0}.", secId);
                }
                else
                {
                    _tickBuilders.Remove(secId);
                    this.AddInfoLog("OL->TICK unsubscribed {0}.", secId);
                }
            }

            return(false);
        }
示例#30
0
        private void ProcessMarketDataMessage(MarketDataMessage mdMsg)
        {
            if (!mdMsg.IsSubscribe)
            {
                return;
            }

            if (mdMsg.SecurityId.Native == null)
            {
                throw new InvalidOperationException(LocalizedStrings.Str3392Params.Put(mdMsg.SecurityId.SecurityCode));
            }

            var lmaxId = (long)mdMsg.SecurityId.Native;

            switch (mdMsg.DataType)
            {
            case MarketDataTypes.Level1:
            {
                Session.Subscribe(new OrderBookStatusSubscriptionRequest(lmaxId), () => { }, CreateErrorHandler("OrderBookStatusSubscriptionRequest"));
                break;
            }

            case MarketDataTypes.MarketDepth:
            {
                Session.Subscribe(new OrderBookSubscriptionRequest(lmaxId), () => { }, CreateErrorHandler("OrderBookSubscriptionRequest"));
                break;
            }

            case MarketDataTypes.CandleTimeFrame:
            {
                IHistoricMarketDataRequest request;

                var tf = (TimeSpan)mdMsg.Arg;

                if (tf.Ticks == 1)
                {
                    request = new TopOfBookHistoricMarketDataRequest(mdMsg.TransactionId, lmaxId, mdMsg.From.UtcDateTime, mdMsg.To.UtcDateTime, Format.Csv);
                }
                else
                {
                    Resolution resolution;

                    if (tf == TimeSpan.FromMinutes(1))
                    {
                        resolution = Resolution.Minute;
                    }
                    else if (tf == TimeSpan.FromDays(1))
                    {
                        resolution = Resolution.Day;
                    }
                    else
                    {
                        throw new InvalidOperationException(LocalizedStrings.Str3393Params.Put(tf));
                    }

                    request = new AggregateHistoricMarketDataRequest(mdMsg.TransactionId, lmaxId, mdMsg.From.UtcDateTime, mdMsg.To.UtcDateTime, resolution, Format.Csv, Option.Bid, Option.Ask);
                }

                Session.RequestHistoricMarketData(request, () => { }, CreateErrorHandler("RequestHistoricMarketData"));
                break;
            }

            case MarketDataTypes.Trades:
                break;

            default:
                throw new ArgumentOutOfRangeException("mdMsg", mdMsg.DataType, LocalizedStrings.Str1618);
            }

            var result = (MarketDataMessage)mdMsg.Clone();

            result.OriginalTransactionId = mdMsg.TransactionId;
            SendOutMessage(result);
        }