private static int ChangeSubscribers(SynchronizedDictionary <Security, int> subscribers, Security subscriber, int delta) { if (subscribers == null) { throw new ArgumentNullException("subscribers"); } lock (subscribers.SyncRoot) { var value = subscribers.TryGetValue2(subscriber) ?? 0; value += delta; if (value > 0) { subscribers[subscriber] = value; } else { subscribers.Remove(subscriber); } return(value); } }
private void OnCandlesResponse(CandlesResponse response) { var key = Tuple.Create(response.SecId, response.Period); var transactionId = _candleTransactions.TryGetValue2(key); if (transactionId == null) { SendOutError(LocalizedStrings.Str3513Params.Put(response.SecCode, response.Board, response.Period)); return; } var isFinished = false; switch (response.Status) { case CandleResponseStatus.Finished: case CandleResponseStatus.Done: case CandleResponseStatus.NotAvailable: isFinished = true; _candleTransactions.Remove(key); break; } var index = 0; foreach (var candle in response.Candles) { var time = candle.Date.ToDto(); SendOutMessage(new TimeFrameCandleMessage { OriginalTransactionId = (long)transactionId, SecurityId = new SecurityId { Native = response.SecId }, OpenPrice = candle.Open, HighPrice = candle.High, LowPrice = candle.Low, ClosePrice = candle.Close, TotalVolume = candle.Volume, OpenTime = time, CloseTime = time + _candlePeriods[response.Period], OpenInterest = candle.Oi, IsFinished = isFinished && ++index == response.Candles.Length, State = CandleStates.Finished, }); } }
private static int ChangeSubscribers(SynchronizedDictionary<Security, int> subscribers, Security subscriber, int delta) { if (subscribers == null) throw new ArgumentNullException("subscribers"); lock (subscribers.SyncRoot) { var value = subscribers.TryGetValue2(subscriber) ?? 0; value += delta; if (value > 0) subscribers[subscriber] = value; else subscribers.Remove(subscriber); return value; } }
/// <summary> /// Send message. /// </summary> /// <param name="message">Message.</param> protected override void OnSendInMessage(Message message) { if (message.IsBack) { var adapter = message.Adapter; if (adapter == null) { throw new InvalidOperationException(); } adapter.SendInMessage(message); return; } switch (message.Type) { case MessageTypes.Reset: ProcessReset(message); break; case MessageTypes.Connect: { if (_isFirstConnect) { _isFirstConnect = false; } else { ProcessReset(new ResetMessage()); } _hearbeatAdapters.AddRange(GetSortedAdapters().Select(CreateWrappers).ToDictionary(a => a, a => { var hearbeatAdapter = new HeartbeatMessageAdapter(a); ((IMessageAdapter)hearbeatAdapter).Parent = this; hearbeatAdapter.NewOutMessage += m => OnInnerAdapterNewOutMessage(a, m); return(hearbeatAdapter); })); if (_hearbeatAdapters.Count == 0) { throw new InvalidOperationException(LocalizedStrings.Str3650); } _hearbeatAdapters.Values.ForEach(a => a.SendInMessage(message)); break; } case MessageTypes.Disconnect: { _connectedAdapters.Cache.ForEach(a => a.SendInMessage(message)); break; } case MessageTypes.Portfolio: { var pfMsg = (PortfolioMessage)message; ProcessPortfolioMessage(pfMsg.PortfolioName, pfMsg); break; } case MessageTypes.OrderRegister: case MessageTypes.OrderReplace: case MessageTypes.OrderCancel: case MessageTypes.OrderGroupCancel: { var ordMsg = (OrderMessage)message; ProcessAdapterMessage(ordMsg.PortfolioName, ordMsg); break; } case MessageTypes.OrderPairReplace: { var ordMsg = (OrderPairReplaceMessage)message; ProcessAdapterMessage(ordMsg.Message1.PortfolioName, ordMsg); break; } case MessageTypes.MarketData: { IMessageAdapter[] adapters = null; if (message.Adapter != null) { var wrapper = _hearbeatAdapters.Values.FirstOrDefault(w => GetUnderlyingAdapter(w) == message.Adapter); if (wrapper != null) { adapters = new IMessageAdapter[] { wrapper } } ; } if (adapters == null) { adapters = _messageTypeAdapters.TryGetValue(message.Type)?.Cache; } if (adapters == null) { throw new InvalidOperationException(LocalizedStrings.Str629Params.Put(message.Type)); } var mdMsg = (MarketDataMessage)message; switch (mdMsg.DataType) { case MarketDataTypes.News: adapters.ForEach(a => a.SendInMessage(mdMsg)); break; default: { var key = mdMsg.CreateKey(); var state = _subscriptionStates.TryGetValue2(key); if (mdMsg.IsSubscribe) { if (state != null) { switch (state) { case SubscriptionStates.Subscribed: { var adapter = _subscriptions.TryGetValue(key); if (adapter != null) { adapter.SendInMessage(mdMsg); } else { RaiseMarketDataMessage(null, mdMsg.OriginalTransactionId, new InvalidOperationException(state.Value.ToString()), true); } break; } case SubscriptionStates.Subscribing: //case SubscriptionStates.Unsubscribing: _suspendedSubscriptions.SafeAdd(key).Add(mdMsg); break; default: throw new ArgumentOutOfRangeException(); } break; } else { _subscriptionStates.Add(key, SubscriptionStates.Subscribing); } } else { var canProcess = false; switch (state) { case SubscriptionStates.Subscribed: canProcess = true; //_subscriptionStates[key] = SubscriptionStates.Unsubscribing; break; case SubscriptionStates.Subscribing: //case SubscriptionStates.Unsubscribing: RaiseMarketDataMessage(null, mdMsg.OriginalTransactionId, new InvalidOperationException(state.Value.ToString()), false); break; case null: RaiseMarketDataMessage(null, mdMsg.OriginalTransactionId, null, false); break; default: throw new ArgumentOutOfRangeException(); } if (!canProcess) { break; } } if (mdMsg.TransactionId != 0) { _subscriptionKeys.Add(mdMsg.TransactionId, key); } if (mdMsg.IsSubscribe) { //if (_subscriptionQueue.ContainsKey(key)) // return; var enumerator = adapters.Cast <IMessageAdapter>().GetEnumerator(); _subscriptionQueue.Add(key, enumerator); ProcessSubscriptionAction(enumerator, mdMsg, mdMsg.TransactionId); } else { var adapter = _subscriptions.TryGetValue(key); if (adapter != null) { //_subscriptions.Remove(key); adapter.SendInMessage(message); } } break; } } break; } case MessageTypes.ChangePassword: { var adapter = GetSortedAdapters().FirstOrDefault(a => a.SupportedMessages.Contains(MessageTypes.ChangePassword)); if (adapter == null) { throw new InvalidOperationException(LocalizedStrings.Str629Params.Put(message.Type)); } adapter.SendInMessage(message); break; } default: { if (message.Adapter != null) { message.Adapter.SendInMessage(message); break; } var adapters = _messageTypeAdapters.TryGetValue(message.Type)?.Cache; if (adapters == null) { throw new InvalidOperationException(LocalizedStrings.Str629Params.Put(message.Type)); } adapters.ForEach(a => a.SendInMessage(message)); break; } } }
private void ProcessIQFeedMessage(IQFeedWrapper feed, Message message) { switch (message.Type) { case ExtendedMessageTypes.System: { var systemMsg = (IQFeedSystemMessage)message; switch (systemMsg.Value) { case "SERVER DISCONNECTED": case "SERVER RECONNECT FAILED": SendOutMessage(systemMsg); break; default: { if (feed == _lookupFeed) { _currSystemType = ExtendedMessageTypes.ListedMarket; _lookupFeed.RequestListedMarkets(); } break; } } break; } case ExtendedMessageTypes.HistoryExtraDayCandle: // расширенное сообщение лучше передавать внешнему коду, чтобы ему хоть как-то получить информацию //case ExtendedMessageTypes.Data: break; case ExtendedMessageTypes.ListedMarket: { var lmMsg = (IQFeedListedMarketMessage)message; _markets[lmMsg.Id] = lmMsg.Code; break; } case ExtendedMessageTypes.SecurityType: { var stMsg = (IQFeedSecurityTypeMessage)message; try { var secType = stMsg.Code.ToSecurityType(); if (secType == null) { this.AddWarningLog(LocalizedStrings.Str2140Params.Put(stMsg.Code)); } _securityTypes[stMsg.Id] = secType; } catch (Exception ex) { this.AddErrorLog(ex); } break; } case ExtendedMessageTypes.End: { var type = feed == _lookupFeed ? _currSystemType : null; var requestId = 0L; if (_currSystemType == null) { requestId = message.GetRequestId(); type = _requestsType.TryGetValue2(requestId); if (type == null) { return; } _requestsType.Remove(requestId); _secIds.Remove(requestId); if (type == MessageTypes.CandleTimeFrame || type == MessageTypes.CandleVolume || type == MessageTypes.CandleTick || type == ExtendedMessageTypes.HistoryExtraDayCandle) { _candleParsers.Remove(requestId); } } switch (type) { case MessageTypes.Security: { var result = _lookupResult.TryGetValue(requestId); if (result == null) { return; } _lookupResult.Remove(requestId); SendOutMessage(new SecurityLookupResultMessage { OriginalTransactionId = requestId }); break; } case ExtendedMessageTypes.ListedMarket: { _currSystemType = ExtendedMessageTypes.SecurityType; _lookupFeed.RequestSecurityTypes(); break; } case ExtendedMessageTypes.SecurityType: { _currSystemType = null; SendOutMessage(new ConnectMessage()); break; } // для сделок и свечек отправляем фиктивный объект, // чтобы сообщить, что получение исторических данных завершено case MessageTypes.Execution: { SendOutMessage(new Level1ChangeMessage { ExtensionInfo = new Dictionary <object, object> { { "IsFinished", true }, } }.InitRequestId(requestId)); break; } case MessageTypes.CandleTimeFrame: case MessageTypes.CandleTick: case MessageTypes.CandleVolume: case ExtendedMessageTypes.HistoryExtraDayCandle: { SendOutMessage(new TimeFrameCandleMessage { IsFinished = true, OriginalTransactionId = requestId, }); break; } } break; } //case MessageTypes.Security: //{ // var secMsg = (SecurityMessage)message; // var exchangeRoot = message.GetValue<string>("ExchangeRoot"); // switch (secMsg.SecurityType) // { // case SecurityTypes.Future: // secMsg.ExpiryDate = message.GetValue<DateTime>("ExpiryDate"); // secMsg.UnderlyingSecurityCode = exchangeRoot; // break; // case SecurityTypes.Option: // secMsg.ExpiryDate = message.GetValue<DateTime>("ExpiryDate"); // secMsg.UnderlyingSecurityCode = exchangeRoot; // secMsg.Strike = message.GetValue<decimal>("Strike"); // break; // } // SendOutMessage(secMsg); // break; //} default: SendOutMessage(message); break; } }