/// <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;
				}
			}
		}
Пример #2
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;
            }
            }
        }