Beispiel #1
0
        /// <summary>
        /// Отправить сообщение.
        /// </summary>
        /// <param name="message">Сообщение.</param>
        protected override void OnSendInMessage(Message message)
        {
            switch (message.Type)
            {
            case MessageTypes.Reset:
            {
                _requestsType.Clear();
                _secIds.Clear();
                _candleParsers.Clear();
                _newsIds.Clear();

                _lookupResult.Clear();

                _currSystemType = null;

                if (_lookupFeed != null)
                {
                    SafeDisconnectFeed(ref _lookupFeed);
                }

                if (_level1Feed != null)
                {
                    SafeDisconnectFeed(ref _level1Feed);
                }

                if (_level2Feed != null)
                {
                    SafeDisconnectFeed(ref _level2Feed);
                }

                if (_derivativeFeed != null)
                {
                    SafeDisconnectFeed(ref _derivativeFeed);
                }

                SendOutMessage(new ResetMessage());

                break;
            }

            case MessageTypes.Connect:
            {
                _isDownloadSecurityFromSite = IsDownloadSecurityFromSite;

                _lookupFeed     = CreateFeed(LookupAddress, "LookupFeed");
                _level1Feed     = CreateFeed(Level1Address, "Level1Feed");
                _level2Feed     = CreateFeed(Level2Address, "Level2Feed");
                _derivativeFeed = CreateFeed(DerivativeAddress, "DerivativeFeed");

                _level1Feed.SetLevel1FieldSet(new[]
                    {
                        Level1ColumnRegistry.Symbol,
                        Level1ColumnRegistry.ExchangeId,
                        Level1ColumnRegistry.LastTradeMarket,
                        Level1ColumnRegistry.BidMarket,
                        Level1ColumnRegistry.AskMarket
                    }
                                              .Concat(Level1Columns)
                                              .Select(c => c.Name)
                                              .ToArray());

                break;
            }

            case MessageTypes.Disconnect:
            {
                SafeDisconnectFeed(ref _lookupFeed);
                SafeDisconnectFeed(ref _level1Feed);
                SafeDisconnectFeed(ref _level2Feed);
                SafeDisconnectFeed(ref _derivativeFeed);

                //_isCommonLookupDone = null;

                SendOutMessage(new DisconnectMessage());
                break;
            }

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

                var from = mdMsg.From.ToLocalTime(TimeHelper.Est);
                var to   = mdMsg.To.ToLocalTime(TimeHelper.Est);

                switch (mdMsg.DataType)
                {
                case MarketDataTypes.Level1:
                {
                    if (mdMsg.To == DateTimeOffset.MaxValue)
                    {
                        if (mdMsg.IsSubscribe)
                        {
                            _level1Feed.SubscribeSymbol(mdMsg.SecurityId.SecurityCode);
                        }
                        else
                        {
                            _level1Feed.UnSubscribeSymbol(mdMsg.SecurityId.SecurityCode);
                        }
                    }
                    else
                    {
                        if (mdMsg.IsSubscribe)
                        {
                            _requestsType.Add(mdMsg.TransactionId, MessageTypes.Execution);
                            _secIds.Add(mdMsg.TransactionId, mdMsg.SecurityId);

                            if (mdMsg.Count != 0)
                            {
                                _lookupFeed.RequestTicks(mdMsg.TransactionId, mdMsg.SecurityId.SecurityCode, mdMsg.Count);
                            }
                            else
                            {
                                _lookupFeed.RequestTicks(mdMsg.TransactionId, mdMsg.SecurityId.SecurityCode, from, to);
                            }
                        }
                    }

                    break;
                }

                case MarketDataTypes.MarketDepth:
                {
                    if (mdMsg.IsSubscribe)
                    {
                        _level2Feed.SubscribeSymbol(mdMsg.SecurityId.SecurityCode);
                    }
                    else
                    {
                        _level2Feed.UnSubscribeSymbol(mdMsg.SecurityId.SecurityCode);
                    }

                    break;
                }
                //case MarketDataTypes.Trades:
                //{
                //	if (mdMsg.To == DateTime.MaxValue)
                //	{
                //		if (mdMsg.IsSubscribe)
                //			_level1Feed.SubscribeSymbol(mdMsg.SecurityId.SecurityCode);
                //		else
                //			_level1Feed.UnSubscribeSymbol(mdMsg.SecurityId.SecurityCode);
                //	}
                //	else
                //	{
                //		if (mdMsg.IsSubscribe)
                //		{
                //			_requestsType.Add(mdMsg.TransactionId, MessageTypes.Execution);
                //			_lookupFeed.RequestTrades(mdMsg.TransactionId, mdMsg.SecurityId.SecurityCode, mdMsg.From, mdMsg.To);
                //		}
                //	}

                //	break;
                //}
                case MarketDataTypes.News:
                {
                    if (mdMsg.IsSubscribe)
                    {
                        if (mdMsg.NewsId.IsEmpty())
                        {
                            if (mdMsg.From.IsDefault())
                            {
                                _level1Feed.SubscribeNews();
                            }
                            else
                            {
                                _requestsType.Add(mdMsg.TransactionId, MessageTypes.News);
                                _lookupFeed.RequestNewsHeadlines(mdMsg.TransactionId, from);
                            }
                        }
                        else
                        {
                            var newsId = mdMsg.NewsId;
                            _newsIds.Add(mdMsg.TransactionId, newsId);
                            _requestsType.Add(mdMsg.TransactionId, ExtendedMessageTypes.NewsStory);
                            _lookupFeed.RequestNewsStory(mdMsg.TransactionId, newsId);
                        }
                    }
                    else
                    {
                        _level1Feed.UnSubscribeNews();
                    }

                    break;
                }

                case MarketDataTypes.CandleTimeFrame:
                case MarketDataTypes.CandleTick:
                case MarketDataTypes.CandleVolume:
                case MarketDataTypes.CandleRange:
                case MarketDataTypes.CandlePnF:
                case MarketDataTypes.CandleRenko:
                {
                    if (mdMsg.IsSubscribe)
                    {
                        // streaming
                        if (from == DateTimeOffset.MaxValue && mdMsg.Count == 0)
                        {
                            string strArg, intervalType;
                            GetCandleParams(mdMsg.DataType, mdMsg.Arg, out strArg, out intervalType);

                            _requestsType.Add(mdMsg.TransactionId, mdMsg.DataType.ToCandleMessageType());
                            _secIds.Add(mdMsg.TransactionId, mdMsg.SecurityId);
                            _candleParsers.Add(mdMsg.TransactionId, Tuple.Create(_candleStreamingParser, mdMsg.Arg));

                            _derivativeFeed.SubscribeCandles(mdMsg.SecurityId.SecurityCode, intervalType, strArg, from, mdMsg.TransactionId);
                            break;
                        }

                        if (mdMsg.Arg is TimeSpan)
                        {
                            var tf = (TimeSpan)mdMsg.Arg;

                            if (tf.Ticks == TimeHelper.TicksPerMonth)
                            {
                                _requestsType.Add(mdMsg.TransactionId, ExtendedMessageTypes.HistoryExtraDayCandle);
                                _secIds.Add(mdMsg.TransactionId, mdMsg.SecurityId);
                                _candleParsers.Add(mdMsg.TransactionId, Tuple.Create(_candleParser, mdMsg.Arg));

                                var count = mdMsg.Count;

                                if (count == 0)
                                {
                                    count = ExchangeBoard.Associated.GetTimeFrameCount(new Range <DateTimeOffset>(mdMsg.From, mdMsg.To), tf);
                                }

                                _lookupFeed.RequestMonthlyCandles(mdMsg.TransactionId, mdMsg.SecurityId.SecurityCode, count);
                            }
                            else if (tf == TimeSpan.FromDays(7))
                            {
                                _requestsType.Add(mdMsg.TransactionId, ExtendedMessageTypes.HistoryExtraDayCandle);
                                _secIds.Add(mdMsg.TransactionId, mdMsg.SecurityId);
                                _candleParsers.Add(mdMsg.TransactionId, Tuple.Create(_candleParser, mdMsg.Arg));

                                var count = mdMsg.Count;

                                if (count == 0)
                                {
                                    count = ExchangeBoard.Associated.GetTimeFrameCount(new Range <DateTimeOffset>(mdMsg.From, mdMsg.To), tf);
                                }

                                _lookupFeed.RequestWeeklyCandles(mdMsg.TransactionId, mdMsg.SecurityId.SecurityCode, count);
                            }
                            else if (tf == TimeSpan.FromDays(1))
                            {
                                _requestsType.Add(mdMsg.TransactionId, ExtendedMessageTypes.HistoryExtraDayCandle);
                                _secIds.Add(mdMsg.TransactionId, mdMsg.SecurityId);
                                _candleParsers.Add(mdMsg.TransactionId, Tuple.Create(_candleParser, mdMsg.Arg));

                                if (mdMsg.Count != 0)
                                {
                                    _lookupFeed.RequestDailyCandles(mdMsg.TransactionId, mdMsg.SecurityId.SecurityCode, mdMsg.Count);
                                }
                                else
                                {
                                    _lookupFeed.RequestDailyCandles(mdMsg.TransactionId, mdMsg.SecurityId.SecurityCode, from, to);
                                }
                            }
                            else if (tf < TimeSpan.FromDays(1))
                            {
                                string strArg, intervalType;
                                GetCandleParams(mdMsg.DataType, mdMsg.Arg, out strArg, out intervalType);

                                _requestsType.Add(mdMsg.TransactionId, mdMsg.DataType.ToCandleMessageType());
                                _secIds.Add(mdMsg.TransactionId, mdMsg.SecurityId);
                                _candleParsers.Add(mdMsg.TransactionId, Tuple.Create(_candleIntradayParser, mdMsg.Arg));

                                //var interval = tf.TotalSeconds.To<int>();

                                if (mdMsg.Count != 0)
                                {
                                    _lookupFeed.RequestCandles(mdMsg.TransactionId, mdMsg.SecurityId.SecurityCode, intervalType, strArg, mdMsg.Count);
                                }
                                else
                                {
                                    _lookupFeed.RequestCandles(mdMsg.TransactionId, mdMsg.SecurityId.SecurityCode, intervalType, strArg, from, to);
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException(LocalizedStrings.Str2139Params.Put(tf));
                            }
                        }
                        else
                        {
                            string strArg, intervalType;
                            GetCandleParams(mdMsg.DataType, mdMsg.Arg, out strArg, out intervalType);

                            if (mdMsg.Count != 0)
                            {
                                _lookupFeed.RequestCandles(mdMsg.TransactionId, mdMsg.SecurityId.SecurityCode, intervalType, strArg, mdMsg.Count);
                            }
                            else
                            {
                                _lookupFeed.RequestCandles(mdMsg.TransactionId, mdMsg.SecurityId.SecurityCode, intervalType, strArg, from, to);
                            }
                        }
                    }
                    else
                    {
                        _derivativeFeed.UnSubscribeCandles(mdMsg.SecurityId.SecurityCode, mdMsg.OriginalTransactionId);
                    }

                    break;
                }

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

                var reply = (MarketDataMessage)message.Clone();
                reply.OriginalTransactionId = mdMsg.TransactionId;
                SendOutMessage(reply);

                break;
            }

            case MessageTypes.SecurityLookup:
            {
                var lookupMsg = (SecurityLookupMessage)message;

                var securityTypes = new HashSet <SecurityTypes>();

                if (lookupMsg.SecurityTypes != null)
                {
                    securityTypes.AddRange(lookupMsg.SecurityTypes);
                }
                else if (lookupMsg.SecurityType != null)
                {
                    securityTypes.Add(lookupMsg.SecurityType.Value);
                }

                if (_isDownloadSecurityFromSite)
                {
                    _isDownloadSecurityFromSite = false;

                    using (var zip = new ZipArchive(
                               SecuritiesFile.IsEmpty()
                                                                ? IQFeedHelper.DownloadSymbols().To <Stream>()
                                                                : File.OpenRead(SecuritiesFile)))
                    {
                        var entry = zip.GetEntry("mktsymbols_v2.txt");

                        using (var reader = entry.Open())
                        {
                            reader
                            .ReadLines()
                            .Skip(1)
                            .Select(line => line.Split('\t'))
                            .ForEach(parts =>
                                {
                                    if (parts.Length == 9)
                                    {
                                        // mika 2014.09.16
                                        // below line has incorrect tabulation
                                        // CS.17.CB	CREDIT SUISSE NEW YORK 1.375% 05/26/17		NYSE	NYSE	BONDS

                                        var list = parts.ToList();
                                        list.RemoveAt(2);

                                        parts = list.ToArray();
                                    }

                                    var secType = parts[4].ToSecurityType();

                                    if (secType == null)
                                    {
                                        this.AddWarningLog(LocalizedStrings.Str2140Params.Put(parts[4]));
                                    }

                                    if (secType != null && !securityTypes.Contains(secType.Value))
                                    {
                                        return;
                                    }

                                    var secCode   = parts[0];
                                    var secName   = parts[0];
                                    var boardCode = parts[2];

                                    SendOutMessage(new BoardMessage
                                    {
                                        Code         = boardCode,
                                        ExchangeCode = boardCode
                                    });

                                    SendOutMessage(new SecurityMessage
                                    {
                                        SecurityId = new SecurityId
                                        {
                                            SecurityCode = secCode,
                                            BoardCode    = boardCode
                                        },
                                        Name                  = secName,
                                        SecurityType          = secType,
                                        OriginalTransactionId = lookupMsg.TransactionId
                                    });
                                });
                        }
                    }

                    break;
                }

                var requestedTypes = _securityTypes
                                     .Where(t => t.Value != null && securityTypes.Contains(t.Value.Value))
                                     .Select(i => i.Key.To <string>())
                                     .ToArray();

                _requestsType.Add(lookupMsg.TransactionId, MessageTypes.Security);
                _lookupResult.Add(lookupMsg.TransactionId, lookupMsg);

                var code = lookupMsg.SecurityId.SecurityCode;

                if (code.IsEmpty())
                {
                    code = "*";
                }

                _lookupFeed.RequestSecurities(lookupMsg.TransactionId, IQFeedSearchField.Symbol, code, IQFeedFilterType.SecurityType, requestedTypes);
                break;
            }
            }
        }