private void Unsubscribe(Instrument instrument, SubscriptionFlags flags) { InstrumentSubscription subscription; using (subscriptionsLock.Lock()) { if (!subscriptionsByInstrument.TryGetValue(instrument, out subscription)) { // Подписки и не было return; } } try { subscription.AcquireFlagsLock(); // Отписываемся от инструмента с учетом флагов подписки if ((subscription.Flags & flags) == flags) { // Нужные флаги подписки проставлены, требуется отписаться var level = MarketDataSubscription.Level.NONE; switch (subscription.Flags & ~flags) { case SubscriptionFlags.InstrumentParams: level = MarketDataSubscription.Level.TRADES_BBA_VOLUMES; break; case SubscriptionFlags.OrderBook: level = MarketDataSubscription.Level.TRADES_BBA_DOM; break; case SubscriptionFlags.InstrumentParams | SubscriptionFlags.OrderBook: level = MarketDataSubscription.Level.TRADES_BBA_DOM; break; } subscription.Flags &= ~flags; RequestMarketDataSubscription(subscription, level); if (subscription.Flags == SubscriptionFlags.None) { // Полностью выкидываем подписку using (subscriptionsLock.Lock()) { subscriptionsByInstrument.Remove(subscription.Instrument); subscriptionsByContractId.Remove(subscription.ContractId); } } } } finally { subscription.ReleaseFlagsLock(); } }
void tl_newRegisterSymbols(string client, string symbols) { if (VerboseDebugging) { debug("client subscribe request received: " + symbols); } Basket rem = new BasketImpl(); // if we had something before, check if something was removed if (org.Count > 0) { rem = BasketImpl.Subtract(org, tl.AllClientBasket); } SubscriptionFlags flags = SubscriptionFlags.Prints; flags |= SubscriptionFlags.Quotes; flags |= SubscriptionFlags.Best; List <string> syms = new List <string>(); syms.AddRange(tl.AllClientBasket.ToSymArray()); List <string> orgs = new List <string>(org.ToSymArray()); // add current foreach (string sym in tl.AllClientBasket.ToSymArray()) { // subscribe what we don't have if (!orgs.Contains(sym)) { // get the security Security sec = SecurityImpl.Parse(sym); string ex = sec.hasDest ? sec.DestEx : "NYSE"; oEngine.subscribe(ex, sec.Symbol, flags, null); } } // remove old foreach (Security s in rem) { oEngine.unsubscribe(string.Empty, s.Symbol); } }
private async Task <SubscriptionResult> SubscribeAsync(Instrument instrument, SubscriptionFlags flags) { using (LogManager.Scope()) { InstrumentSubscription subscription = null; ContractMetadata metadata = null; var hasSubscriptionLock = false; try { // Получаем параметры подписки на инструмент using (subscriptionsLock.Lock()) { subscriptionsByInstrument.TryGetValue(instrument, out subscription); } if (subscription == null) { // Получаем ID инструмента var contractId = await instrumentResolver.GetContractIdAsync(instrument); if (contractId == uint.MaxValue) { return(SubscriptionResult.Error(instrument, "Symbol is not resolved in tree node for CQG")); } using (subscriptionsLock.Lock()) { if (!subscriptionsByInstrument.TryGetValue(instrument, out subscription)) { if (!subscriptionsByContractId.TryGetValue(contractId, out subscription)) { subscription = new InstrumentSubscription(instrumentResolver, instrument, contractId); // Сразу захватываем блокировку subscription.AcquireFlagsLock(); hasSubscriptionLock = true; subscriptionsByContractId.Add(contractId, subscription); contractMetadatas.TryGetValue(contractId, out metadata); } subscriptionsByInstrument.Add(instrument, subscription); } } } else { // Захватываем блокировку subscription.AcquireFlagsLock(); hasSubscriptionLock = true; } // Подписываемся на инструмент с учетом флагов подписки if ((subscription.Flags & flags) != flags) { // Нужные флаги подписки не проставлены, требуется доподписаться MarketDataSubscription.Level?level = null; switch (subscription.Flags | flags) { case SubscriptionFlags.InstrumentParams: level = MarketDataSubscription.Level.TRADES_BBA_VOLUMES; break; case SubscriptionFlags.OrderBook: level = MarketDataSubscription.Level.TRADES_BBA_DOM; break; case SubscriptionFlags.InstrumentParams | SubscriptionFlags.OrderBook: level = MarketDataSubscription.Level.TRADES_BBA_DOM; break; } if (level != null) { subscription.Flags |= flags; RequestMarketDataSubscription(subscription, level.Value); } } // При необходимости обрабатываем метаданные и выбрасываем события if (metadata != null) { Process(subscription, metadata, (s, data) => s.Handle(data)); } // Готово var result = SubscriptionResult.OK(instrument); return(result); } catch (OperationCanceledException) { _Log.Warn().Print($"Unable to subscribe to {instrument} (operation has been cancelled)"); return(SubscriptionResult.Error(instrument, "Operation has been cancelled")); } catch (Exception e) { _Log.Error().Print(e, $"Unable to subscribe to {instrument}"); return(SubscriptionResult.Error(instrument, e.Message)); } finally { if (subscription != null && hasSubscriptionLock) { subscription.ReleaseFlagsLock(); } } } }