private void SubscribeMarketData(SecurityId securityId, MarketDataTypes type) { var message = new MarketDataMessage { DataType = type, IsSubscribe = true, SecurityId = securityId, From = DateTimeOffset.MinValue, To = DateTimeOffset.MaxValue, TransactionId = _messAdapter.TransactionIdGenerator.GetNextId() }; switch (type) { case MarketDataTypes.MarketDepth: message.MaxDepth = MarketDataMessage.DefaultMaxDepth; break; case MarketDataTypes.Trades: message.Arg = ExecutionTypes.Tick; break; case MarketDataTypes.OrderLog: message.Arg = ExecutionTypes.OrderLog; break; } _messAdapter.SendInMessage(message); }
private void ProcessSubscriptionAction(IEnumerator <IMessageAdapter> enumerator, MarketDataMessage message, long originalTransactionId) { if (enumerator.MoveNext()) { enumerator.Current.SendInMessage(message); } else { _subscriptionQueue.RemoveByValue(enumerator); var key = _subscriptionKeys.TryGetValue(message.OriginalTransactionId); if (key == null) { key = message.CreateKey(); } else { _subscriptionKeys.Remove(originalTransactionId); } _subscriptionStates.Remove(key); RaiseMarketDataMessage(null, originalTransactionId, new ArgumentException(LocalizedStrings.Str629Params.Put(key.Item1 + " " + key.Item2), nameof(message)), true); } }
private void ProcessInMarketDataMessage(MarketDataMessage message) { var sendIn = false; MarketDataMessage sendOutMsg = null; RefPair <MarketDataMessage, int> pair; var secIdKey = InnerAdapter.IsSupportSubscriptionBySecurity ? message.SecurityId : default(SecurityId); lock (_sync) { var isSubscribe = message.IsSubscribe; switch (message.DataType) { case MarketDataTypes.News: { var subscriber = message.NewsId ?? string.Empty; pair = _newsSubscribers.TryGetValue(subscriber) ?? RefTuple.Create((MarketDataMessage)message.Clone(), 0); var subscribersCount = pair.Second; if (isSubscribe) { subscribersCount++; sendIn = subscribersCount == 1; } else { if (subscribersCount > 0) { subscribersCount--; sendIn = subscribersCount == 0; } else { sendOutMsg = NonExist(message); } } if (sendOutMsg == null) { if (!sendIn) { sendOutMsg = new MarketDataMessage { DataType = message.DataType, IsSubscribe = isSubscribe, OriginalTransactionId = message.TransactionId, }; } if (subscribersCount > 0) { pair.Second = subscribersCount; _newsSubscribers[subscriber] = pair; } else { _newsSubscribers.Remove(subscriber); } } break; } case MarketDataTypes.CandleTimeFrame: case MarketDataTypes.CandleRange: case MarketDataTypes.CandlePnF: case MarketDataTypes.CandleRenko: case MarketDataTypes.CandleTick: case MarketDataTypes.CandleVolume: { var key = Tuple.Create(message.DataType, secIdKey, message.Arg); pair = _candleSubscribers.TryGetValue(key) ?? RefTuple.Create((MarketDataMessage)message.Clone(), 0); var subscribersCount = pair.Second; if (isSubscribe) { subscribersCount++; sendIn = subscribersCount == 1; } else { if (subscribersCount > 0) { subscribersCount--; sendIn = subscribersCount == 0; } else { sendOutMsg = NonExist(message); } } if (sendOutMsg == null) { if (!sendIn) { sendOutMsg = new MarketDataMessage { DataType = message.DataType, IsSubscribe = isSubscribe, SecurityId = message.SecurityId, Arg = message.Arg, OriginalTransactionId = message.TransactionId, }; } if (subscribersCount > 0) { pair.Second = subscribersCount; _candleSubscribers[key] = pair; } else { _candleSubscribers.Remove(key); } } break; } default: { var key = message.CreateKey(secIdKey); pair = _subscribers.TryGetValue(key) ?? RefTuple.Create((MarketDataMessage)message.Clone(), 0); var subscribersCount = pair.Second; if (isSubscribe) { subscribersCount++; sendIn = subscribersCount == 1; } else { if (subscribersCount > 0) { subscribersCount--; sendIn = subscribersCount == 0; } else { sendOutMsg = NonExist(message); } } if (sendOutMsg == null) { if (!sendIn) { sendOutMsg = new MarketDataMessage { DataType = message.DataType, IsSubscribe = isSubscribe, SecurityId = message.SecurityId, OriginalTransactionId = message.TransactionId, }; } if (subscribersCount > 0) { pair.Second = subscribersCount; _subscribers[key] = pair; } else { _subscribers.Remove(key); } } break; } } } if (sendIn) { if (!message.IsSubscribe && message.OriginalTransactionId == 0) { message.OriginalTransactionId = pair.First.TransactionId; } base.SendInMessage(message); } if (sendOutMsg != null) { RaiseNewOutMessage(sendOutMsg); } }
public Subscription ProcessResponse(MarketDataMessage response, out MarketDataMessage originalMsg, out bool unexpectedCancelled) { originalMsg = null; try { lock (_syncObject) { unexpectedCancelled = false; if (!_requests.TryGetValue(response.OriginalTransactionId, out var tuple)) { originalMsg = null; return(null); } _requests.Remove(response.OriginalTransactionId); originalMsg = (MarketDataMessage)tuple.Item1; var info = originalMsg.IsSubscribe ? TryGetInfo(originalMsg.TransactionId, false, addLog: false) : TryGetInfo(originalMsg.OriginalTransactionId, true, addLog: false); if (info == null) { originalMsg = null; return(null); } var subscription = info.Subscription; if (originalMsg.IsSubscribe) { if (response.IsOk()) { ChangeState(subscription, SubscriptionStates.Active); } else { ChangeState(subscription, SubscriptionStates.Error); _subscriptions.Remove(subscription.TransactionId); unexpectedCancelled = subscription.State == SubscriptionStates.Active; } } else { ChangeState(subscription, SubscriptionStates.Stopped); _subscriptions.Remove(subscription.TransactionId); } return(subscription); } } finally { if (originalMsg == null) { TryWriteLog(response.OriginalTransactionId); } } }
private bool ProcessMarketDataRequest(MarketDataMessage message) { if (message.IsSubscribe) { if (!InnerAdapter.IsMarketDataTypeSupported(MarketDataTypes.OrderLog)) { return(false); } var isBuild = message.BuildMode == MarketDataBuildModes.Build && message.BuildFrom == MarketDataTypes.OrderLog; switch (message.DataType) { case MarketDataTypes.MarketDepth: { if (isBuild || !InnerAdapter.IsMarketDataTypeSupported(message.DataType)) { var secId = GetSecurityId(message.SecurityId); _depthBuilders.Add(secId, InnerAdapter.CreateOrderLogMarketDepthBuilder(secId)); _subscriptionIds.Add(message.TransactionId, Tuple.Create(secId, message.DataType)); var clone = (MarketDataMessage)message.Clone(); clone.DataType = MarketDataTypes.OrderLog; base.SendInMessage(clone); this.AddInfoLog("OL->MD subscribed {0}.", secId); return(true); } break; } case MarketDataTypes.Trades: { if (isBuild || !InnerAdapter.IsMarketDataTypeSupported(message.DataType)) { var secId = GetSecurityId(message.SecurityId); _tickBuilders.Add(secId); _subscriptionIds.Add(message.TransactionId, Tuple.Create(secId, message.DataType)); var clone = (MarketDataMessage)message.Clone(); clone.DataType = MarketDataTypes.OrderLog; base.SendInMessage(clone); this.AddInfoLog("OL->TICK subscribed {0}.", secId); return(true); } break; } } } else { if (!_subscriptionIds.TryGetValue(message.OriginalTransactionId, out var tuple)) { return(false); } var secId = tuple.Item1; if (tuple.Item2 == MarketDataTypes.MarketDepth) { _depthBuilders.Remove(secId); this.AddInfoLog("OL->MD unsubscribed {0}.", secId); } else { _tickBuilders.Remove(secId); this.AddInfoLog("OL->TICK unsubscribed {0}.", secId); } } return(false); }
public SeriesInfo(MarketDataMessage original, MarketDataMessage current) { Original = original ?? throw new ArgumentNullException(nameof(original)); Current = current; }
private void ProcessMarketDataMessage(MarketDataMessage message) { var securityId = message.SecurityId; var security = SecurityProvider.LookupById(securityId.ToStringId()); if (security == null) { RaiseMarketDataMessage(message, new InvalidOperationException(LocalizedStrings.Str704Params.Put(securityId))); return; } if (StorageRegistry == null) { RaiseMarketDataMessage(message, new InvalidOperationException(LocalizedStrings.Str1117Params.Put(message.DataType, securityId))); return; } var history = message as HistorySourceMessage; Exception error = null; switch (message.DataType) { case MarketDataTypes.Level1: { if (message.IsSubscribe) { if (history == null) { BasketStorage.AddStorage(StorageRegistry.GetLevel1MessageStorage(security, Drive, StorageFormat)); BasketStorage.AddStorage(new InMemoryMarketDataStorage <ClearingMessage>(security, null, date => new[] { new ClearingMessage { LocalTime = date.Date + security.Board.ExpiryTime, SecurityId = securityId, ClearMarketDepth = true } })); } else { BasketStorage.AddStorage(new InMemoryMarketDataStorage <Level1ChangeMessage>(security, null, history.GetMessages)); } } else { BasketStorage.RemoveStorage <IMarketDataStorage <Level1ChangeMessage> >(security, MessageTypes.Level1Change, null); BasketStorage.RemoveStorage <InMemoryMarketDataStorage <ClearingMessage> >(security, ExtendedMessageTypes.Clearing, null); } break; } case MarketDataTypes.MarketDepth: { if (message.IsSubscribe) { BasketStorage.AddStorage(history == null ? StorageRegistry.GetQuoteMessageStorage(security, Drive, StorageFormat) : new InMemoryMarketDataStorage <QuoteChangeMessage>(security, null, history.GetMessages)); } else { BasketStorage.RemoveStorage <IMarketDataStorage <QuoteChangeMessage> >(security, MessageTypes.QuoteChange, null); } break; } case MarketDataTypes.Trades: { if (message.IsSubscribe) { BasketStorage.AddStorage(history == null ? StorageRegistry.GetTickMessageStorage(security, Drive, StorageFormat) : new InMemoryMarketDataStorage <ExecutionMessage>(security, null, history.GetMessages)); } else { BasketStorage.RemoveStorage <IMarketDataStorage <ExecutionMessage> >(security, MessageTypes.Execution, ExecutionTypes.Tick); } break; } case MarketDataTypes.OrderLog: { if (message.IsSubscribe) { BasketStorage.AddStorage(history == null ? StorageRegistry.GetOrderLogMessageStorage(security, Drive, StorageFormat) : new InMemoryMarketDataStorage <ExecutionMessage>(security, null, history.GetMessages)); } else { BasketStorage.RemoveStorage <IMarketDataStorage <ExecutionMessage> >(security, MessageTypes.Execution, ExecutionTypes.OrderLog); } break; } case MarketDataTypes.CandleTimeFrame: case MarketDataTypes.CandleTick: case MarketDataTypes.CandleVolume: case MarketDataTypes.CandleRange: case MarketDataTypes.CandlePnF: case MarketDataTypes.CandleRenko: { var msgType = message.DataType.ToCandleMessageType(); if (message.IsSubscribe) { var candleType = message.DataType.ToCandleMessage(); BasketStorage.AddStorage(history == null ? StorageRegistry.GetCandleMessageStorage(candleType, security, message.Arg, Drive, StorageFormat) : new InMemoryMarketDataStorage <CandleMessage>(security, message.Arg, history.GetMessages, candleType)); } else { BasketStorage.RemoveStorage <IMarketDataStorage <CandleMessage> >(security, msgType, message.Arg); } break; } default: error = new InvalidOperationException(LocalizedStrings.Str1118Params.Put(message.DataType)); break; } RaiseMarketDataMessage(message, error); }
private MarketDataMessage ProcessMarketDataRequest(MarketDataMessage message) { if (message.IsSubscribe) { if (!InnerAdapter.IsMarketDataTypeSupported(MarketDataTypes.OrderLog)) { return(message); } var isBuild = message.BuildMode == MarketDataBuildModes.Build && message.BuildFrom == MarketDataTypes.OrderLog; switch (message.DataType) { case MarketDataTypes.MarketDepth: { if (isBuild || !InnerAdapter.IsMarketDataTypeSupported(message.DataType)) { var secId = GetSecurityId(message.SecurityId); IOrderLogMarketDepthBuilder builder = null; if (InnerAdapter.IsSecurityRequired(DataType.OrderLog)) { builder = InnerAdapter.CreateOrderLogMarketDepthBuilder(secId); } _subscriptionIds.Add(message.TransactionId, RefTuple.Create(secId, true, builder)); message = (MarketDataMessage)message.Clone(); message.DataType = MarketDataTypes.OrderLog; this.AddInfoLog("OL->MD subscribed {0}/{1}.", secId, message.TransactionId); } break; } case MarketDataTypes.Trades: { if (isBuild || !InnerAdapter.IsMarketDataTypeSupported(message.DataType)) { var secId = GetSecurityId(message.SecurityId); _subscriptionIds.Add(message.TransactionId, RefTuple.Create(secId, false, (IOrderLogMarketDepthBuilder)null)); message = (MarketDataMessage)message.Clone(); message.DataType = MarketDataTypes.OrderLog; this.AddInfoLog("OL->TICK subscribed {0}/{1}.", secId, message.TransactionId); } break; } } } else { if (_subscriptionIds.TryGetAndRemove(message.OriginalTransactionId, out var tuple)) { this.AddInfoLog("OL->{0} unsubscribed {1}/{2}.", tuple.Second ? "MD" : "TICK", tuple.First, message.OriginalTransactionId); } } return(message); }
private void ProcessMarketData(MarketDataMessage mdMsg) { var secCode = mdMsg.SecurityId.SecurityCode; var boardCode = mdMsg.SecurityId.BoardCode; switch (mdMsg.DataType) { case MarketDataTypes.Level1: { if (mdMsg.IsSubscribe) { _client.SubscribeQuote(secCode, boardCode); } else { _client.UnsubsribeQuote(secCode, boardCode); } break; } case MarketDataTypes.MarketDepth: { if (mdMsg.IsSubscribe) { _client.SubscribeLevel2(secCode, boardCode); } else { _client.UnsubsribeLevel2(secCode, boardCode); } break; } case MarketDataTypes.Trades: { if (mdMsg.IsSubscribe) { _subscribedSecuritiesToTrade.Add(secCode); _client.SubscribeQuote(secCode, boardCode); } else { _subscribedSecuritiesToTrade.Remove(secCode); _client.UnsubsribeQuote(secCode, boardCode); } break; } case MarketDataTypes.News: { if (mdMsg.IsSubscribe) { _client.SubscribeNews(); } else { _client.UnsubscribeNews(); } break; } default: { SendOutMarketDataNotSupported(mdMsg.TransactionId); return; } } var reply = (MarketDataMessage)mdMsg.Clone(); reply.OriginalTransactionId = mdMsg.TransactionId; SendOutMessage(reply); }
private IEnumerable <MarketDataMessage> ProcessSubscriptionResult <T>(Dictionary <T, SubscriptionInfo <MarketDataMessage> > subscriptions, T key, SubscriptionInfo <MarketDataMessage> info, MarketDataMessage message) { //var info = subscriptions.TryGetValue(key); if (!subscriptions.ContainsKey(key)) { return(null); } //var isSubscribe = info.Message.IsSubscribe; //var removeInfo = !isSubscribe || !message.IsOk(); info.IsSubscribed = info.Message.IsSubscribe && message.IsOk(); var replies = new List <MarketDataMessage>(); // TODO только нужная подписка foreach (var requests in info.Requests) { var reply = (MarketDataMessage)requests.Clone(); reply.OriginalTransactionId = requests.TransactionId; //reply.TransactionId = message.TransactionId; reply.Error = message.Error; reply.IsNotSupported = message.IsNotSupported; replies.Add(reply); } if (!info.IsSubscribed) { subscriptions.Remove(key); _mdSubscribersById.RemoveWhere(p => p.Value == info); } return(replies); }
public override void UpdateUI(IBMessage message) { MarketDataMessage dataMessage = (MarketDataMessage)message; //checkToAddRow(dataMessage.RequestId); DataGridView grid = (DataGridView)uiControl; if (grid.Rows.Count >= dataMessage.RequestId - TICK_ID_BASE) { if (message is TickPriceMessage) { TickPriceMessage priceMessage = (TickPriceMessage)message; switch (dataMessage.Field) { case 1: { //BID grid[BID_PRICE_INDEX, GetIndex(dataMessage.RequestId)].Value = priceMessage.Price; break; } case 2: { //ASK grid[ASK_PRICE_INDEX, GetIndex(dataMessage.RequestId)].Value = priceMessage.Price; break; } case 9: { //CLOSE grid[CLOSE_PRICE_INDEX, GetIndex(dataMessage.RequestId)].Value = priceMessage.Price; break; } } } else if (dataMessage is TickSizeMessage) { TickSizeMessage sizeMessage = (TickSizeMessage)message; switch (dataMessage.Field) { case 0: { //BID SIZE grid[BID_SIZE_INDEX, GetIndex(dataMessage.RequestId)].Value = sizeMessage.Size; break; } case 3: { //ASK SIZE grid[ASK_SIZE_INDEX, GetIndex(dataMessage.RequestId)].Value = sizeMessage.Size; break; } case 5: { //LAST SIZE grid[LAST_SIZE_INDEX, GetIndex(dataMessage.RequestId)].Value = sizeMessage.Size; break; } case 8: { //VOLUME grid[VOLUME_SIZE_INDEX, GetIndex(dataMessage.RequestId)].Value = sizeMessage.Size; break; } } } } }
private static string GetNewsBoardKey(MarketDataMessage message) => (message.DataType == MarketDataTypes.News ? message.NewsId : message.BoardCode) ?? string.Empty;
/// <inheritdoc /> public long SubscribeMarketData(MarketDataMessage message) { return(SubscribeMarketData(null, message)); }
private void ProcessMarketDataMessage(MarketDataMessage mdMsg) { if (!mdMsg.IsSubscribe) { return; } if (mdMsg.SecurityId.Native == null) { throw new InvalidOperationException(LocalizedStrings.Str3392Params.Put(mdMsg.SecurityId.SecurityCode)); } var lmaxId = (long)mdMsg.SecurityId.Native; switch (mdMsg.DataType) { case MarketDataTypes.Level1: { Session.Subscribe(new OrderBookStatusSubscriptionRequest(lmaxId), () => { }, CreateErrorHandler("OrderBookStatusSubscriptionRequest")); break; } case MarketDataTypes.MarketDepth: { Session.Subscribe(new OrderBookSubscriptionRequest(lmaxId), () => { }, CreateErrorHandler("OrderBookSubscriptionRequest")); break; } case MarketDataTypes.CandleTimeFrame: { IHistoricMarketDataRequest request; var tf = (TimeSpan)mdMsg.Arg; if (tf.Ticks == 1) { request = new TopOfBookHistoricMarketDataRequest(mdMsg.TransactionId, lmaxId, mdMsg.From.UtcDateTime, mdMsg.To.UtcDateTime, Format.Csv); } else { Resolution resolution; if (tf == TimeSpan.FromMinutes(1)) { resolution = Resolution.Minute; } else if (tf == TimeSpan.FromDays(1)) { resolution = Resolution.Day; } else { throw new InvalidOperationException(LocalizedStrings.Str3393Params.Put(tf)); } request = new AggregateHistoricMarketDataRequest(mdMsg.TransactionId, lmaxId, mdMsg.From.UtcDateTime, mdMsg.To.UtcDateTime, resolution, Format.Csv, Option.Bid, Option.Ask); } Session.RequestHistoricMarketData(request, () => { }, CreateErrorHandler("RequestHistoricMarketData")); break; } case MarketDataTypes.Trades: break; default: throw new ArgumentOutOfRangeException("mdMsg", mdMsg.DataType, LocalizedStrings.Str1618); } var result = (MarketDataMessage)mdMsg.Clone(); result.OriginalTransactionId = mdMsg.TransactionId; SendOutMessage(result); }
/// <inheritdoc /> public void SubscribeMarketData(Security security, MarketDataMessage message) { Subscribe(new Subscription(message, security)); }
protected BaseSubscription(MarketDataMessage origin) { Origin = origin ?? throw new ArgumentNullException(nameof(origin)); }
private void RaiseMarketDataUnSubscriptionFailed(Security security, MarketDataMessage message, Exception error) { this.AddErrorLog(LocalizedStrings.UnSubscribedError, security?.Id, message.DataType, message.Error); MarketDataUnSubscriptionFailed?.Invoke(security, message, error); }
public ChildSubscription(MarketDataMessage origin) : base(origin) { }
private bool ProcessMarketData(MarketDataMessage message) { message = _storageProcessor.ProcessMarketData(message, RaiseNewOutMessage); return(message == null || base.OnSendInMessage(message)); }
public ParentSubscription(MarketDataMessage origin) : base(origin) { }
private void ProcessMarketData(MarketDataMessage message) { if (message is null) { throw new ArgumentNullException(nameof(message)); } Buffer.ProcessInMessage(message); if (message.IsSubscribe && message.From == null && message.To == null && Settings.IsMode(StorageModes.Snapshot)) { void SendSnapshot <TMessage>(TMessage msg) where TMessage : Message, ISubscriptionIdMessage { msg.SetSubscriptionIds(subscriptionId: message.TransactionId); RaiseNewOutMessage(msg); } if (message.DataType2 == DataType.Level1) { var l1Storage = GetSnapshotStorage(message.DataType2); if (message.SecurityId == default) { foreach (Level1ChangeMessage msg in l1Storage.GetAll()) { SendSnapshot(msg); } } else { var level1Msg = (Level1ChangeMessage)l1Storage.Get(message.SecurityId); if (level1Msg != null) { //SendReply(); SendSnapshot(level1Msg); } } } else if (message.DataType2 == DataType.MarketDepth) { var quotesStorage = GetSnapshotStorage(message.DataType2); if (message.SecurityId == default) { foreach (QuoteChangeMessage msg in quotesStorage.GetAll()) { SendSnapshot(msg); } } else { var quotesMsg = (QuoteChangeMessage)quotesStorage.Get(message.SecurityId); if (quotesMsg != null) { //SendReply(); SendSnapshot(quotesMsg); } } } } }
/// <inheritdoc /> public Subscription SubscribeMarketData(MarketDataMessage message) { return(SubscribeMarketData(null, message)); }
private void LoadData(CandleSeries series) { var msgType = series.CandleType.ToCandleMessageType(); _holder = new CandlesSeriesHolder(series); _candleTransform.Process(new ResetMessage()); _candleBuilder = msgType.ToCandleMarketDataType().CreateCandleBuilder(); var storage = new StorageRegistry(); BusyIndicator.IsBusy = true; var path = HistoryPath.Folder; var isBuild = BuildFromTicks.IsChecked == true; var format = Format.SelectedFormat; var maxDays = (isBuild || series.CandleType != typeof(TimeFrameCandle)) ? 5 : 30 * (int)((TimeSpan)series.Arg).TotalMinutes; _mdMsg = series.ToMarketDataMessage(true); Task.Factory.StartNew(() => { var date = DateTime.MinValue; if (isBuild) { foreach (var tick in storage.GetTickMessageStorage(series.Security, new LocalMarketDataDrive(path), format).Load()) { _tradeGenerator.Process(tick); if (_candleTransform.Process(tick)) { var candles = _candleBuilder.Process(_mdMsg, _currCandle, _candleTransform); foreach (var candle in candles) { _currCandle = candle; _updatedCandles.Add((CandleMessage)candle.Clone()); } } _lastTime = tick.ServerTime; if (date != tick.ServerTime.Date) { date = tick.ServerTime.Date; var str = date.To <string>(); this.GuiAsync(() => BusyIndicator.BusyContent = str); maxDays--; if (maxDays == 0) { break; } } } } else { foreach (var candleMsg in storage.GetCandleMessageStorage(msgType, series.Security, series.Arg, new LocalMarketDataDrive(path), format).Load()) { if (candleMsg.State != CandleStates.Finished) { candleMsg.State = CandleStates.Finished; } _currCandle = candleMsg; _updatedCandles.Add(candleMsg); _lastTime = candleMsg.OpenTime; if (candleMsg is TimeFrameCandleMessage) { _lastTime += (TimeSpan)series.Arg; } _tradeGenerator.Process(new ExecutionMessage { ExecutionType = ExecutionTypes.Tick, SecurityId = series.Security.ToSecurityId(), ServerTime = _lastTime, TradePrice = candleMsg.ClosePrice, }); if (date != candleMsg.OpenTime.Date) { date = candleMsg.OpenTime.Date; var str = date.To <string>(); this.GuiAsync(() => BusyIndicator.BusyContent = str); maxDays--; if (maxDays == 0) { break; } } } } _historyLoaded = true; }) .ContinueWith(t => { if (t.Exception != null) { Error(t.Exception.Message); } BusyIndicator.IsBusy = false; Chart.IsAutoRange = false; }, TaskScheduler.FromCurrentSynchronizationContext()); }
/// <inheritdoc /> public void UnSubscribeMarketData(MarketDataMessage message) { UnSubscribeMarketData(null, message); }
private void ProcessMarketDataMessage(MarketDataMessage mdMsg) { switch (mdMsg.DataType) { case MarketDataTypes.Level1: { SendCommand(mdMsg.IsSubscribe ? new SubscribeMessage { Quotations = { mdMsg.SecurityId } } : new UnsubscribeMessage { Quotations = { mdMsg.SecurityId } }); break; } case MarketDataTypes.MarketDepth: { SendCommand(mdMsg.IsSubscribe ? new SubscribeMessage { Quotes = { mdMsg.SecurityId } } : new UnsubscribeMessage { Quotes = { mdMsg.SecurityId } }); break; } case MarketDataTypes.Trades: { if (mdMsg.IsSubscribe) { //Подписаться/отписаться на тики можно двумя способами: //SubscribeMessage/UnsubscribeMessage - тики приходят с момента подписки //SubscribeTicksMessage - Тики приходят с момента подиски(TradeNo = 0), или с любого номера. При повторном запросе отписка получения тиков по предыдущему запросу. //var command = new SubscribeMessage(); //command.AllTrades.Add(security.GetTransaqId()); //ApiClient.Send(new Tuple<BaseCommandMessage, Action<BaseResponse>>(command, ProcessResult)); //--- _registeredSecurityIds.Add(mdMsg.SecurityId); var command = new SubscribeTicksMessage { Filter = true }; //Filter только сделки нормально периода торгов foreach (var id in _registeredSecurityIds) { command.Items.Add(new SubscribeTicksSecurity { SecId = (int)id.Native, TradeNo = id.Equals(mdMsg.SecurityId) ? 1 : 0, }); } SendCommand(command); } else { //var command = new UnsubscribeMessage(); //command.AllTrades.Add(security.GetTransaqId()); //ApiClient.Send(new Tuple<BaseCommandMessage, Action<BaseResponse>>(command, ProcessResult)); //--- _registeredSecurityIds.Remove(mdMsg.SecurityId); var command = new SubscribeTicksMessage { Filter = true }; //Filter только сделки нормально периода торгов foreach (var id in _registeredSecurityIds) { command.Items.Add(new SubscribeTicksSecurity { SecId = (int)id.Native, TradeNo = 0, }); } SendCommand(command); } break; } case MarketDataTypes.News: { if (mdMsg.IsSubscribe) { if (mdMsg.NewsId.IsEmpty()) { var count = mdMsg.Count; if (count == 0) { count = MaxNewsHeaderCount; } else { if (count < 0) { throw new InvalidOperationException(LocalizedStrings.Str3511Params.Put(count)); } if (count > MaxNewsHeaderCount) { throw new InvalidOperationException(LocalizedStrings.Str3512Params.Put(count, MaxNewsHeaderCount)); } } SendCommand(new RequestOldNewsMessage { Count = (int)count }); } else { SendCommand(new RequestNewsBodyMessage { NewsId = mdMsg.NewsId.To <int>() }); } } break; } case MarketDataTypes.CandleTimeFrame: { if (mdMsg.IsSubscribe) { var periodId = _candlePeriods.GetKeys((TimeSpan)mdMsg.Arg).First(); _candleTransactions.Add(Tuple.Create((int)mdMsg.SecurityId.Native, periodId), mdMsg.TransactionId); var command = new RequestHistoryDataMessage { SecId = (int)mdMsg.SecurityId.Native, Period = periodId, Count = mdMsg.Count, Reset = mdMsg.To == DateTimeOffset.MaxValue, }; SendCommand(command); } break; } default: throw new ArgumentOutOfRangeException("mdMsg", mdMsg.DataType, LocalizedStrings.Str1618); } var reply = (MarketDataMessage)mdMsg.Clone(); reply.OriginalTransactionId = mdMsg.TransactionId; SendOutMessage(reply); }
private static SubscriptionInfo CreateKey(MarketDataMessage message) { return(Tuple.Create(message.SecurityId, message.DataType, message.From, message.To, message.Count, message.MaxDepth)); }
private void ProcessMarketDataMessage(IMessageAdapter adapter, MarketDataMessage message) { var key = _subscriptionKeys.TryGetValue(message.OriginalTransactionId) ?? message.CreateKey(); var enumerator = _subscriptionQueue.TryGetValue(key); var state = _subscriptionStates.TryGetValue2(key); var error = message.Error; var isOk = !message.IsNotSupported && error == null; var isSubscribe = message.IsSubscribe; switch (state) { case SubscriptionStates.Subscribed: break; case SubscriptionStates.Subscribing: isSubscribe = true; if (isOk) { _subscriptions.Add(key, adapter); _subscriptionStates[key] = SubscriptionStates.Subscribed; } else if (error != null) { _subscriptions.Remove(key); _subscriptionStates.Remove(key); } break; case SubscriptionStates.Unsubscribing: isSubscribe = false; _subscriptions.Remove(key); _subscriptionStates.Remove(key); break; case null: if (isOk) { if (message.IsSubscribe) { _subscriptions.Add(key, adapter); _subscriptionStates.Add(key, SubscriptionStates.Subscribed); break; } } _subscriptions.Remove(key); _subscriptionStates.Remove(key); break; default: throw new ArgumentOutOfRangeException(); } if (message.IsNotSupported) { if (enumerator != null) { ProcessSubscriptionAction(enumerator, message, message.OriginalTransactionId); } else { if (error == null) { error = new InvalidOperationException(LocalizedStrings.Str633Params.Put(message.SecurityId, message.DataType)); } } } _subscriptionQueue.Remove(key); _subscriptionKeys.Remove(message.OriginalTransactionId); RaiseMarketDataMessage(adapter, message.OriginalTransactionId, error, isSubscribe); }
private void ProcessMarketDataMessage(MarketDataMessage mdMsg) { var smartId = (string)mdMsg.SecurityId.Native; if (smartId.IsEmpty()) { throw new InvalidOperationException(LocalizedStrings.Str1853Params.Put(mdMsg.SecurityId)); } switch (mdMsg.DataType) { case MarketDataTypes.Level1: { if (mdMsg.IsSubscribe) { _wrapper.SubscribeSecurity(smartId); } else { _wrapper.UnSubscribeSecurity(smartId); } break; } case MarketDataTypes.MarketDepth: { if (mdMsg.IsSubscribe) { _wrapper.SubscribeMarketDepth(smartId); } else { _wrapper.UnSubscribeMarketDepth(smartId); } break; } case MarketDataTypes.Trades: { if (mdMsg.From == null) { if (mdMsg.IsSubscribe) { _wrapper.SubscribeTrades(smartId); } else { _wrapper.UnSubscribeTrades(smartId); } } else { const int maxTradeCount = 1000000; this.AddDebugLog("RequestHistoryTrades SecId = {0} From {1} Count = {2}", smartId, mdMsg.From, maxTradeCount); _wrapper.RequestHistoryTrades(smartId, mdMsg.From.Value.ToLocalTime(TimeHelper.Moscow), maxTradeCount); } break; } case MarketDataTypes.CandleTimeFrame: { var count = mdMsg.Count ?? 0; var direction = (SmartComHistoryDirections)mdMsg.ExtensionInfo["Direction"]; if (direction == SmartComHistoryDirections.Forward) { count = -count; } var tf = (TimeSpan)mdMsg.Arg; _candleTransactions.SafeAdd(smartId)[tf] = Tuple.Create(mdMsg.TransactionId, new List <CandleMessage>()); this.AddDebugLog("RequestHistoryBars SecId {0} TF {1} From {2} Count {3}", smartId, tf, mdMsg.From, count); _wrapper.RequestHistoryBars(smartId, tf, (mdMsg.From ?? DateTimeOffset.MinValue).ToLocalTime(TimeHelper.Moscow), (int)count); break; } default: { SendOutMarketDataNotSupported(mdMsg.TransactionId); return; } } var reply = (MarketDataMessage)mdMsg.Clone(); reply.OriginalTransactionId = mdMsg.TransactionId; SendOutMessage(reply); }
public ParentSubscription(MarketDataMessage origin) { Origin = origin ?? throw new ArgumentNullException(nameof(origin)); }
private void ProcessMarketDataMessage(MarketDataMessage mdMsg) { if (!mdMsg.IsSubscribe) { return; } if (mdMsg.SecurityId.Native == null) { throw new InvalidOperationException(LocalizedStrings.Str3392Params.Put(mdMsg.SecurityId.SecurityCode)); } var lmaxId = (long)mdMsg.SecurityId.Native; switch (mdMsg.DataType) { case MarketDataTypes.Level1: case MarketDataTypes.Trades: { _session.Subscribe(new OrderBookStatusSubscriptionRequest(lmaxId), () => { }, CreateErrorHandler("OrderBookStatusSubscriptionRequest")); break; } case MarketDataTypes.MarketDepth: { _session.Subscribe(new OrderBookSubscriptionRequest(lmaxId), () => { }, CreateErrorHandler("OrderBookSubscriptionRequest")); break; } case MarketDataTypes.CandleTimeFrame: { IHistoricMarketDataRequest request; var tf = (TimeSpan)mdMsg.Arg; var from = (mdMsg.From ?? DateTimeOffset.MinValue).UtcDateTime; var to = (mdMsg.To ?? DateTimeOffset.MaxValue).UtcDateTime; if (tf.Ticks == 1) { request = new TopOfBookHistoricMarketDataRequest(mdMsg.TransactionId, lmaxId, from, to, Format.Csv); } else { Resolution resolution; if (tf == TimeSpan.FromMinutes(1)) { resolution = Resolution.Minute; } else if (tf == TimeSpan.FromDays(1)) { resolution = Resolution.Day; } else { throw new InvalidOperationException(LocalizedStrings.Str3393Params.Put(tf)); } request = new AggregateHistoricMarketDataRequest(mdMsg.TransactionId, lmaxId, from, to, resolution, Format.Csv, Option.Bid, Option.Ask); } if (!_isHistoricalSubscribed) { _session.Subscribe(new HistoricMarketDataSubscriptionRequest(), () => { }, CreateErrorHandler("HistoricMarketDataSubscriptionRequest")); _isHistoricalSubscribed = true; } _session.RequestHistoricMarketData(request, () => { }, CreateErrorHandler("RequestHistoricMarketData")); break; } default: { SendOutMarketDataNotSupported(mdMsg.TransactionId); return; } } var result = (MarketDataMessage)mdMsg.Clone(); result.OriginalTransactionId = mdMsg.TransactionId; SendOutMessage(result); }
private void UnSubscribeMarketData(SecurityId securityId, MarketDataTypes type) { var message = new MarketDataMessage { DataType = type, SecurityId = securityId, IsSubscribe = false, TransactionId = _messAdapter.TransactionIdGenerator.GetNextId() }; switch (type) { case MarketDataTypes.Trades: message.Arg = ExecutionTypes.Tick; break; case MarketDataTypes.OrderLog: message.Arg = ExecutionTypes.OrderLog; break; } _messAdapter.SendInMessage(message); }
void IMarketDataProvider.UnSubscribeMarketData(MarketDataMessage message) { }