public void ProcessRequest(Security security, MarketDataMessage message, bool tryAdd) { if (security == null) { throw new ArgumentNullException(nameof(security)); } if (message == null) { throw new ArgumentNullException(nameof(message)); } if (message.TransactionId == 0) { message.TransactionId = _connector.TransactionIdGenerator.GetNextId(); } message.FillSecurityInfo(_connector, security); var value = Tuple.Create((MarketDataMessage)message.Clone(), security); if (tryAdd) { // if the message was looped back via IsBack=true _pendingSubscriptions.TryAdd(message.TransactionId, value); } else { _pendingSubscriptions.Add(message.TransactionId, value); } _connector.SendInMessage(message); }
private SubscriptionInfo ProcessSubscription <T>(Dictionary <T, SubscriptionInfo> subscriptions, T key, MarketDataMessage message, ref bool sendIn, ref MarketDataMessage sendOutMsg) { MarketDataMessage clone = null; var info = subscriptions.TryGetValue(key) ?? new SubscriptionInfo(clone = (MarketDataMessage)message.Clone()); var subscribersCount = info.Subscribers; var isSubscribe = message.IsSubscribe; if (isSubscribe) { subscribersCount++; sendIn = subscribersCount == 1; } else { if (subscribersCount > 0) { subscribersCount--; sendIn = subscribersCount == 0; } else { sendOutMsg = NonExist(message); } } if (sendOutMsg != null) { return(info); } //if (isSubscribe) info.Subscriptions.Add(clone ?? (MarketDataMessage)message.Clone()); _subscribersById.Add(message.TransactionId, info); if (!sendIn && info.IsSubscribed) { sendOutMsg = new MarketDataMessage { DataType = message.DataType, IsSubscribe = isSubscribe, SecurityId = message.SecurityId, Arg = message.Arg, OriginalTransactionId = message.TransactionId, }; } if (subscribersCount > 0) { info.Subscribers = subscribersCount; subscriptions[key] = info; } else { subscriptions.Remove(key); } return(info); }
private void RaiseMarketDataMessage(MarketDataMessage message, Exception error) { var reply = (MarketDataMessage)message.Clone(); reply.OriginalTransactionId = message.TransactionId; reply.Error = error; SendOutMessage(reply); }
private void ProcessMarketData(MarketDataMessage mdMsg) { switch (mdMsg.DataType) { case MarketDataTypes.Level1: { if (mdMsg.IsSubscribe) { _subscribedLevel1.Add(mdMsg.SecurityId); } else { _subscribedLevel1.Remove(mdMsg.SecurityId); } break; } case MarketDataTypes.MarketDepth: { if (mdMsg.IsSubscribe) { _subscribedDepths.Add(mdMsg.SecurityId, mdMsg.MaxDepth ?? MarketDataMessage.DefaultMaxDepth); } else { _subscribedDepths.Remove(mdMsg.SecurityId); } break; } case MarketDataTypes.Trades: { if (mdMsg.IsSubscribe) { _subscribedTicks.Add(mdMsg.SecurityId); } else { _subscribedTicks.Remove(mdMsg.SecurityId); } break; } default: { SendOutMarketDataNotSupported(mdMsg.TransactionId); return; } } var reply = (MarketDataMessage)mdMsg.Clone(); reply.OriginalTransactionId = mdMsg.OriginalTransactionId; SendOutMessage(reply); }
/// <summary> /// Update filter with new subscription. /// </summary> /// <param name="message">Market-data message (uses as a subscribe/unsubscribe in outgoing case, confirmation event in incoming case).</param> public void Subscribe(MarketDataMessage message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } var origin = (MarketDataMessage)message.Clone(); lock (_subscriptionsLock) { DataType dataType; if (message.DataType == MarketDataTypes.CandleTimeFrame) { if (message.IsCalcVolumeProfile) { switch (message.BuildFrom) { case MarketDataTypes.Trades: dataType = TicksAsLevel1 ? DataType.Level1 : DataType.Ticks; break; case MarketDataTypes.MarketDepth: dataType = DataType.MarketDepth; break; default: dataType = DataType.Level1; break; } } else if (message.AllowBuildFromSmallerTimeFrame) { // null arg means do not use DataType.Arg as a filter dataType = DataType.Create(typeof(TimeFrameCandleMessage), null); } else { dataType = DataType.Create(typeof(TimeFrameCandleMessage), message.Arg); } } else { dataType = CreateDataType(message); if (dataType == null) { return; } } var subscription = Tuple.Create(message.SecurityId, dataType); _subscriptionsById.Add(message.TransactionId, Tuple.Create(origin, subscription)); Subscribe(subscription); } }
private void ProcessMarketData(MarketDataMessage mdMsg) { switch (mdMsg.DataType) { case MarketDataTypes.Level1: { if (mdMsg.IsSubscribe) { _subscribedLevel1.Add(mdMsg.SecurityId); } else { _subscribedLevel1.Remove(mdMsg.SecurityId); } break; } case MarketDataTypes.MarketDepth: { if (mdMsg.IsSubscribe) { _subscribedDepths.Add(mdMsg.SecurityId, mdMsg.MaxDepth); } else { _subscribedDepths.Remove(mdMsg.SecurityId); } break; } case MarketDataTypes.Trades: { if (mdMsg.IsSubscribe) { _subscribedTicks.Add(mdMsg.SecurityId); } else { _subscribedTicks.Remove(mdMsg.SecurityId); } break; } default: throw new ArgumentOutOfRangeException("mdMsg", mdMsg.DataType, LocalizedStrings.Str1618); } var reply = (MarketDataMessage)mdMsg.Clone(); reply.OriginalTransactionId = mdMsg.OriginalTransactionId; SendOutMessage(reply); }
private void ProcessSubscriptionAction(IEnumerator <IMessageAdapter> enumerator, MarketDataMessage message) { if (enumerator.MoveNext()) { enumerator.Current.SendInMessage(message.Clone()); } else { RaiseSubscriptionFailed(message, new ArgumentException(LocalizedStrings.Str629Params.Put(message.SecurityId), "message")); } }
private void ProcessMarketDataMessage(MarketDataMessage msg) { if (msg.IsSubscribe) { if (msg.IsBack) { if (_seriesInfosByTransactions.ContainsKey(msg.TransactionId)) { base.SendInMessage(msg); return; } } var info = new SeriesInfo { MarketDataMessage = (MarketDataMessage)msg.Clone(), LastTime = msg.From, Board = !msg.SecurityId.BoardCode.IsEmpty() ? _exchangeInfoProvider.GetOrCreateBoard(msg.SecurityId.BoardCode) : ExchangeBoard.Test }; _seriesInfos .SafeAdd(msg.SecurityId) .Add(info); _seriesInfosByDates .Add(new KeyValuePair <DateTimeOffset, SeriesInfo>(msg.To ?? DateTimeOffset.MaxValue, info)); _series .SafeAdd(Tuple.Create(msg.SecurityId, msg.DataType, msg.Arg)) .Add(info); Subscribe(info, false); } else { var subscriptions = _seriesInfos.TryGetValue(msg.SecurityId); if (subscriptions == null) { return; } var removed = subscriptions.RemoveWhere(s => s.MarketDataMessage.TransactionId == msg.OriginalTransactionId); foreach (var info in removed) { UnSubscribe(info, false); } } }
private void ProcessMarketDataMessage(MarketDataMessage msg) { if (msg.IsBack || DaysLoad == TimeSpan.Zero) { base.SendInMessage(msg); return; } if (msg.IsSubscribe) { var from = msg.From ?? DateTime.UtcNow.Date - DaysLoad; var to = msg.To ?? DateTimeOffset.Now; var transactionId = msg.TransactionId; RaiseStorageMessage(new MarketDataMessage { OriginalTransactionId = transactionId, IsHistory = true }); var lastTime = LoadMessages(msg, from, to, transactionId); RaiseStorageMessage(new MarketDataFinishedMessage { OriginalTransactionId = transactionId, IsHistory = true }); if (msg.IsHistory) { return; } Subscribe(msg.SecurityId, CreateDataType(msg)); var clone = (MarketDataMessage)msg.Clone(); clone.From = lastTime; base.SendInMessage(clone); } else { if (msg.IsHistory) { return; } UnSubscribe(msg.SecurityId, CreateDataType(msg)); base.SendInMessage(msg); } }
private void ProcessInnerAdapterMarketDataMessage(IMessageAdapter adapter, MarketDataMessage message) { var key = Tuple.Create(message.SecurityId, message.DataType); var tuple = _subscriptionQueue.TryGetValue(key); var cancel = tuple != null && tuple.Second; if (message.Error == null) { SessionHolder.AddDebugLog(LocalizedStrings.Str630Params, message.SecurityId, adapter); _subscriptionQueue.Remove(key); RaiseMarketDataMessage(message, null); if (!cancel) { return; } //в процессе подписки пользователь отменил ее - надо отписаться от получения данных var cancelMessage = (MarketDataMessage)message.Clone(); cancelMessage.IsSubscribe = false; SendInMessage(cancelMessage); } else { SessionHolder.AddDebugLog(LocalizedStrings.Str631Params, adapter, message.SecurityId, message.DataType, message.Error); if (cancel) { RaiseSubscriptionFailed(message, new InvalidOperationException(LocalizedStrings.SubscriptionProcessCancelled)); } else if (tuple != null) { ProcessSubscriptionAction(tuple.First, message); } else { RaiseSubscriptionFailed(message, new InvalidOperationException(LocalizedStrings.Str633Params.Put(message.SecurityId, message.DataType))); } } }
private void ProcessUnSubscribeAction(MarketDataMessage message) { if (message == null) { throw new ArgumentNullException("message"); } lock (_subscriptionQueue.SyncRoot) { var tuple = _subscriptionQueue.TryGetValue(Tuple.Create(message.SecurityId, message.DataType)); if (tuple != null) { tuple.Second = true; return; } } GetSortedAdapters().ForEach(a => a.SendInMessage(message.Clone())); }
private void ProcessMarketDataMessage(MarketDataMessage message) { _requests.Enqueue(new LuaRequest { MessageType = message.Type, DataType = message.DataType, SecurityId = new SecurityId { SecurityCode = message.SecurityId.SecurityCode, BoardCode = _securityClassInfo.GetSecurityClass(message.SecurityId) }, IsSubscribe = message.IsSubscribe, TransactionId = message.TransactionId }); var result = (MarketDataMessage)message.Clone(); result.OriginalTransactionId = message.TransactionId; _fixServer.SendInMessage(result); }
public void UnSubscribe(Security security, MarketDataMessage message) { if (security == null) { throw new ArgumentNullException(nameof(security)); } //var indexSecurity = security as IndexSecurity; //if (indexSecurity != null) // indexSecurity.InnerSecurities.ForEach(s => _connector.UnSubscribeMarketData(s, message)); //else if (security is ContinuousSecurity) // UnSubscribeContinuous((ContinuousSecurity)security, message); //else //{ //TryUnSubscribe(security, message); var tuple = Tuple.Create((MarketDataMessage)message.Clone(), security); // we can cancel by subscription id (message maybe by unfilled) or send fully filled unsubscription message _pendingSubscriptions.Add(message.OriginalTransactionId == 0 ? message.TransactionId : message.OriginalTransactionId, tuple); _connector.SendInMessage(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 = (int)mdMsg.Count; 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 = 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 void ProcessMarketDataMessage(MarketDataMessage message) { switch (message.DataType) { case MarketDataTypes.Level1: { if (message.SecurityId.Native is int) { if (message.IsSubscribe) { Wrapper.RegisterLevel1((int)message.SecurityId.Native); } else { Wrapper.UnRegisterLevel1((int)message.SecurityId.Native); } } else { throw new InvalidOperationException(LocalizedStrings.Str2253Params.Put(message.SecurityId)); } break; } case MarketDataTypes.MarketDepth: { if (message.SecurityId.Native is int) { if (message.IsSubscribe) { Wrapper.RegisterMarketDepth((int)message.SecurityId.Native); } else { Wrapper.UnRegisterMarketDepth((int)message.SecurityId.Native); } } else { throw new InvalidOperationException(LocalizedStrings.Str2253Params.Put(message.SecurityId)); } break; } case MarketDataTypes.Trades: { if (message.SecurityId.Native is int) { if (message.IsSubscribe) { Wrapper.RegisterTrades((int)message.SecurityId.Native); } else { Wrapper.UnRegisterTrades((int)message.SecurityId.Native); } } else { throw new InvalidOperationException(LocalizedStrings.Str2253Params.Put(message.SecurityId)); } break; } case MarketDataTypes.News: { if (!message.NewsId.IsEmpty()) { throw new NotSupportedException(LocalizedStrings.Str1617); } if (message.IsSubscribe) { Wrapper.StartExportNews(); } else { Wrapper.StopExportNews(); } break; } case MarketDataTypes.CandleTimeFrame: { if (message.IsSubscribe) { Wrapper.LookupCandles(message); } break; } default: { SendOutMarketDataNotSupported(message.TransactionId); return; } } var reply = (MarketDataMessage)message.Clone(); reply.OriginalTransactionId = message.TransactionId; SendOutMessage(reply); }
private void ProcessMarketData(MarketDataMessage mdMsg) { switch (mdMsg.DataType) { case MarketDataTypes.Level1: { //if (mdMsg.IsSubscribe) // _subscribedLevel1.Add(secCode); //else // _subscribedLevel1.Remove(secCode); break; } case MarketDataTypes.MarketDepth: { if (mdMsg.IsSubscribe) { _subscribedDepths.Add(mdMsg.SecurityId); if (_subscribedDepths.Count == 1) { _pusherClient.SubscribeDepths(); } } else { _subscribedDepths.Remove(mdMsg.SecurityId); if (_subscribedDepths.Count == 0) { _pusherClient.UnSubscribeDepths(); } } break; } case MarketDataTypes.Trades: { if (mdMsg.IsSubscribe) { if (mdMsg.From != null && mdMsg.From.Value.DateTime == DateTime.Today) { _httpClient.RequestTransactions().Select(t => new ExecutionMessage { ExecutionType = ExecutionTypes.Tick, SecurityId = _btcUsd, TradeId = t.Id, TradePrice = (decimal)t.Price, TradeVolume = (decimal)t.Amount, ServerTime = t.Time.ApplyTimeZone(TimeZoneInfo.Utc) }).ForEach(SendOutMessage); } _subscribedTicks.Add(mdMsg.SecurityId); if (_subscribedTicks.Count == 1) { _pusherClient.SubscribeTrades(); } } else { _subscribedTicks.Remove(mdMsg.SecurityId); if (_subscribedTicks.Count == 0) { _pusherClient.UnSubscribeTrades(); } } break; } default: { SendOutMarketDataNotSupported(mdMsg.TransactionId); return; } } var reply = (MarketDataMessage)mdMsg.Clone(); reply.OriginalTransactionId = mdMsg.OriginalTransactionId; SendOutMessage(reply); }
public void ProcessRequest(Security security, MarketDataMessage message, bool tryAdd) { if (message == null) { throw new ArgumentNullException(nameof(message)); } if (!tryAdd) { var msg = (message.IsSubscribe ? LocalizedStrings.SubscriptionSent : LocalizedStrings.UnSubscriptionSent) .Put(security?.Id, message.ToDataTypeString()); if (message.From != null && message.To != null) { msg += LocalizedStrings.Str691Params.Put(message.From.Value, message.To.Value); } _connector.AddDebugLog(msg + "."); } if (security == null) { if (!message.IsSubscribe) { if (message.OriginalTransactionId != 0) { security = TryGetSecurity(message.OriginalTransactionId); } } } if (security == null) { if (message.DataType != MarketDataTypes.News) { if (message.SecurityId.IsDefault()) { throw new ArgumentNullException(nameof(security)); } security = _connector.LookupById(message.SecurityId); if (security == null) { throw new ArgumentException(LocalizedStrings.Str704Params.Put(message.SecurityId)); } } } if (message.TransactionId == 0) { message.TransactionId = _connector.TransactionIdGenerator.GetNextId(); } if (security != null) { message.FillSecurityInfo(_connector, security); } var value = Tuple.Create((MarketDataMessage)message.Clone(), security); if (tryAdd) { // if the message was looped back via IsBack=true _requests.TryAdd(message.TransactionId, value); } else { _requests.Add(message.TransactionId, value); } _connector.SendInMessage(message); }
private void TrySubscribe(Security subscriber, MarketDataMessage message) { //Если уже выполняется поиск данного инструмента, то нет необходимости в повторном вызове OnRegisterXXX. //Если на инструмент была подписка ранее, то просто вызываем событие SubscriptionSucceed. var subscribersCount = GetSubscribers(message.DataType).ChangeSubscribers(subscriber, true); //var securityId = _connector.GetSecurityId(subscriber); if (subscribersCount == 1) { var lookupMessage = new SecurityLookupMessage { SecurityId = message.SecurityId, SecurityType = message.SecurityType, TransactionId = _connector.TransactionIdGenerator.GetNextId() }; _lookupMessages.Add(lookupMessage.TransactionId, Tuple.Create(lookupMessage, (MarketDataMessage)message.Clone())); _connector.LookupSecurities(lookupMessage); } else // if (subscribed == true) { var reply = new MarketDataMessage { OriginalTransactionId = message.TransactionId, IsSubscribe = true, }; _connector.SendOutMessage(reply); } }
public void Subscribe(Security security, MarketDataMessage message) { if (security == null) { throw new ArgumentNullException(nameof(security)); } //var indexSecurity = security as IndexSecurity; //if (indexSecurity != null) // indexSecurity.InnerSecurities.ForEach(s => _connector.SubscribeMarketData(s, message)); //else if (security is ContinuousSecurity) // SubscribeContinuous((ContinuousSecurity)security, message); //else //{ //TrySubscribe(security, message); _pendingSubscriptions.Add(message.TransactionId, Tuple.Create((MarketDataMessage)message.Clone(), security)); _connector.SendInMessage(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, // http://stocksharp.com/forum/yaf_postsm35978_Obnovlieniie-Tranzak-do-viersii-2-16-1.aspx#post35978 //TradeNo = id.Equals(mdMsg.SecurityId) ? 1 : 0, TradeNo = 1, }); } 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 == null) { 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.Value }); } else { SendCommand(new RequestNewsBodyMessage { NewsId = mdMsg.NewsId.To <int>() }); } } break; } case MarketDataTypes.CandleTimeFrame: { if (mdMsg.IsSubscribe) { var periodId = _candlePeriods.GetKeys((TimeSpan)mdMsg.Arg).First(); var secId = (int)mdMsg.SecurityId.Native; var key = Tuple.Create(secId, periodId); _candleTransactions.Add(key, mdMsg.TransactionId); var command = new RequestHistoryDataMessage { SecId = secId, Period = periodId, Count = mdMsg.Count ?? 0, Reset = mdMsg.To == null, }; try { SendCommand(command); } catch (Exception) { _candleTransactions.Remove(key); throw; } } break; } default: { SendOutMarketDataNotSupported(mdMsg.TransactionId); return; } } var reply = (MarketDataMessage)mdMsg.Clone(); reply.OriginalTransactionId = mdMsg.TransactionId; SendOutMessage(reply); }
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); } }
private void ProcessMarketDataMessage(MarketDataMessage mdMsg) { var secCode = mdMsg.SecurityId.SecurityCode; var boardCode = mdMsg.SecurityId.BoardCode; switch (mdMsg.DataType) { case MarketDataTypes.Level1: { if (mdMsg.IsSubscribe) { _client.Session.subscribe(boardCode, secCode, SubscriptionFlags.All & ~(SubscriptionFlags.Prints | SubscriptionFlags.PrintsCond | SubscriptionFlags.Quotes), mdMsg.TransactionId); } else { _client.Session.unsubscribe(boardCode, secCode); } break; } case MarketDataTypes.MarketDepth: { if (mdMsg.IsSubscribe) { _client.Session.rebuildBook(boardCode, secCode, mdMsg.TransactionId); _client.Session.subscribe(boardCode, secCode, SubscriptionFlags.Quotes, mdMsg.TransactionId); } else { _client.Session.unsubscribe(boardCode, secCode); } break; } case MarketDataTypes.Trades: { if (mdMsg.From == null || mdMsg.To == null) { if (mdMsg.IsSubscribe) { _client.Session.subscribe(boardCode, secCode, SubscriptionFlags.Prints | SubscriptionFlags.PrintsCond, mdMsg.TransactionId); } else { _client.Session.unsubscribe(boardCode, secCode); } } else { _client.Session.replayTrades(boardCode, secCode, mdMsg.From.Value.ToSsboe(), mdMsg.To.Value.ToSsboe(), mdMsg.TransactionId); } break; } //case MarketDataTypes.OrderLog: // break; //case MarketDataTypes.News: // break; case MarketDataTypes.CandleTimeFrame: { if (mdMsg.From == null || mdMsg.To == null) { if (mdMsg.IsSubscribe) { _client.Session.subscribeTimeBar(boardCode, secCode, mdMsg.TransactionId); } else { _client.Session.unsubscribeTimeBar(boardCode, secCode); } } else { _client.Session.replayTimeBars(boardCode, secCode, mdMsg.From.Value.ToSsboe(), mdMsg.To.Value.ToSsboe(), mdMsg.TransactionId); } break; } default: { SendOutMarketDataNotSupported(mdMsg.TransactionId); return; } } var reply = (MarketDataMessage)mdMsg.Clone(); reply.OriginalTransactionId = mdMsg.TransactionId; SendOutMessage(reply); }
private void ProcessMarketDataMessage(MarketDataMessage message) { switch (message.DataType) { case MarketDataTypes.Level1: { var instrument = message.SecurityId.ToOanda(); if (message.IsSubscribe) { _streamigClient.SubscribePricesStreaming(GetAccountId(), instrument); } else { _streamigClient.UnSubscribePricesStreaming(instrument); } break; } //case MarketDataTypes.MarketDepth: // break; case MarketDataTypes.News: { if (message.IsSubscribe) { var calendar = _restClient.GetCalendar(message.SecurityId.ToOanda(), (int)(3600 * message.Count)); foreach (var item in calendar) { SendOutMessage(new NewsMessage { //OriginalTransactionId = message.TransactionId, SecurityId = message.SecurityId, ServerTime = TimeHelper.GregorianStart.AddSeconds(item.TimeStamp), Headline = item.Title, Story = "unit={0} curr={1} market={2} forecast={3} previous={4} actual={5}" .Put(item.Unit, item.Currency, item.Market, item.Forecast, item.Previous, item.Actual), }); } } break; } case MarketDataTypes.CandleTimeFrame: { if (message.IsSubscribe) { var from = message.From; while (true) { var candles = _restClient.GetCandles(message.SecurityId.ToOanda(), ((TimeSpan)message.Arg).ToOanda(), message.Count, from.ToOanda()); var count = 0; foreach (var candle in candles) { count++; var time = candle.Time.FromOanda(); SendOutMessage(new TimeFrameCandleMessage { OriginalTransactionId = message.TransactionId, OpenTime = time, SecurityId = message.SecurityId, OpenPrice = (decimal)candle.Open, HighPrice = (decimal)candle.High, LowPrice = (decimal)candle.Low, ClosePrice = (decimal)candle.Close, TotalVolume = (decimal)candle.Volume, State = candle.Complete ? CandleStates.Finished : CandleStates.Active }); from = time; } if (message.Count == 0 && count == 500) { continue; } break; } } break; } default: { SendOutMarketDataNotSupported(message.TransactionId); return; } } var reply = (MarketDataMessage)message.Clone(); reply.OriginalTransactionId = message.TransactionId; SendOutMessage(reply); }
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 { var tuple = _subscriptionIds.TryGetAndRemove(message.OriginalTransactionId); if (tuple != null) { this.AddInfoLog("OL->{0} unsubscribed {1}/{2}.", tuple.Second ? "MD" : "TICK", tuple.First, message.OriginalTransactionId); } } return(message); }
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); }
private void ProcessMarketData(MarketDataMessage mdMsg) { var secCode = mdMsg.SecurityId.SecurityCode; var boardCode = mdMsg.SecurityId.BoardCode; switch (mdMsg.DataType) { case MarketDataTypes.Level1: { if (mdMsg.IsSubscribe) { SessionHolder.Session.SubscribeQuote(secCode, boardCode); } else { SessionHolder.Session.UnsubsribeQuote(secCode, boardCode); } break; } case MarketDataTypes.MarketDepth: { if (mdMsg.IsSubscribe) { SessionHolder.Session.SubscribeLevel2(secCode, boardCode); } else { SessionHolder.Session.UnsubsribeLevel2(secCode, boardCode); } break; } case MarketDataTypes.Trades: { if (mdMsg.IsSubscribe) { _subscribedSecuritiesToTrade.Add(secCode); SessionHolder.Session.SubscribeQuote(secCode, boardCode); } else { _subscribedSecuritiesToTrade.Remove(secCode); SessionHolder.Session.UnsubsribeQuote(secCode, boardCode); } break; } case MarketDataTypes.News: { if (mdMsg.IsSubscribe) { SessionHolder.Session.SubscribeNews(); } else { SessionHolder.Session.UnsubscribeNews(); } break; } default: throw new ArgumentOutOfRangeException("message", mdMsg.DataType, LocalizedStrings.Str1618); } var reply = (MarketDataMessage)mdMsg.Clone(); reply.OriginalTransactionId = mdMsg.TransactionId; SendOutMessage(reply); }
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 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 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); if (InnerAdapter.IsSupportSubscriptionBySecurity) { _depthBuilders.Add(secId, InnerAdapter.CreateOrderLogMarketDepthBuilder(secId)); } else { _depthBuilders.TryAdd(secId, (IOrderLogMarketDepthBuilder)null); } _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); }
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); }