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