/// <summary> /// Initializes a new instance of the <see cref="StrategyNameGenerator"/>. /// </summary> /// <param name="strategy">Strategy.</param> public StrategyNameGenerator(Strategy strategy) { _strategy = strategy ?? throw new ArgumentNullException(nameof(strategy)); _strategy.SecurityChanged += () => { if (_selectors.Contains("Security")) { Refresh(); } }; _strategy.PortfolioChanged += () => { if (_selectors.Contains("Portfolio")) { Refresh(); } }; ShortName = new string(_strategy.GetType().Name.Where(char.IsUpper).ToArray()); _formatter = Smart.CreateDefaultSmartFormat(); _formatter.SourceExtensions.Add(new Source(_formatter, new Dictionary <string, string> { { "FullName", _strategy.GetType().Name }, { "ShortName", ShortName }, })); _selectors = new SynchronizedSet <string>(); AutoGenerateStrategyName = true; Pattern = "{ShortName}{Security:_{0.Security}|}{Portfolio:_{0.Portfolio}|}"; }
/// <summary> /// The method is called when a new order added. /// </summary> /// <param name="order">Order.</param> protected override void OnOrderAdded(Order order) { if (order.Type != OrderTypes.Conditional) { return; } Type conditionType; lock (_conditionTypes.SyncRoot) { var condition = order.Condition; if (condition == null) { return; } conditionType = condition.GetType(); if (_conditionTypes.Contains(conditionType)) { return; } _conditionTypes.Add(conditionType); } GuiDispatcher.GlobalDispatcher.AddAction(() => AddColumns(conditionType)); }
private void OnConnectorProcessingCandle(CandleSeries series, Candle candle) { if (_candleSeries.Contains(series)) { Processing?.Invoke(series, candle); } }
protected override string TryGetRequestId(long transactionId) { if (_transactionIds.Contains(transactionId)) { return(transactionId.To <string>()); } return(base.TryGetRequestId(transactionId)); }
private bool CanStore(SecurityId securityId, Type messageType, object arg) { if (!Enabled) { return(false); } return(!FilterSubscription || _subscriptions.Contains(Tuple.Create(securityId, DataType.Create(messageType, arg)))); }
private void TrySendToEmulator(ISubscriptionIdMessage message) { foreach (var id in message.GetSubscriptionIds()) { if (_subscriptionIds.Contains(id)) { SendToEmulator((Message)message); break; } } }
private void ProcessOrderMessage(long transId, Message message) { if (_isEmulationOnly || _emuOrderIds.Contains(transId)) { SendToEmulator(message); } else { base.OnSendInMessage(message); } }
private void ProcessCandle(CandleSeries series, Candle candle) { // возможно была задержка в получении данных и обработаны еще не все данные if (!_isStarted) { this.GuiAsync(() => IsStarted = true); } _timer.Reset(); _candlesCount++; // ограничиваем кол-во передаваемых свечек, чтобы не фризился интерфейс if (_candlesCount % 100 == 0) { System.Threading.Thread.Sleep(200); } var candleSeries = (CandleSeries)_bufferedChart.GetSource(_candleElement); if (series == candleSeries) { var values = new Dictionary <IChartElement, object>(); lock (_syncRoot) { foreach (var element in _bufferedChart.Elements.Where(e => _bufferedChart.GetSource(e) == series)) { if (_skipElements.Contains(element)) { continue; } element.DoIf <IChartElement, ChartCandleElement>(e => values.Add(e, candle)); element.DoIf <IChartElement, ChartIndicatorElement>(e => values.Add(e, CreateIndicatorValue(e, candle))); } } _bufferedChart.Draw(candle.OpenTime, values); if (series.Security is ContinuousSecurity) { // для непрерывных инструментов всегда приходят данные по одной серии // но инструмент у свечки будет равен текущему инструменту ProcessContinuousSourceElements(candle); } } else { // для индексов будут приходить отдельные свечки для каждого инструмента ProcessIndexSourceElements(candle); } }
private void SecurityPicker_OnSecuritySelected(Security security) { Level1.IsEnabled = Reports.IsEnabled = NewOrder.IsEnabled = Depth.IsEnabled = HistoryCandles.IsEnabled = RealTimeCandles.IsEnabled = security != null; if (security == null) { return; } Level1.IsChecked = Trader.RegisteredSecurities.Contains(SelectedSecurity); Reports.IsChecked = _reportSecurities.Contains(SelectedSecurity); RealTimeCandles.IsChecked = _сandles.Keys.Any(s => s.Security == SelectedSecurity); Depth.IsChecked = _quotesWindows.ContainsKey(SelectedSecurity); }
private void AddTrades(IEnumerable <Trade> trades) { if (!_securityIds.IsEmpty()) { trades = trades.Where(t => _securityIds.Contains(t.Security.Id)); } if (_volumeFilter != null && _volumeFilter > 0) { trades = trades.Where(t => t.Volume >= _volumeFilter); } TradesGrid.Trades.AddRange(trades); AlertBtn.Process(trades.Select(t => t.ToMessage())); }
private void OnPortfolios(IEnumerable <Portfolio> portfolios) { //foreach (var portfolio in portfolios) //{ // _parent.AddInfoLog("Изменение портфеля {0}.", portfolio.Name); //} lock (_notSavedPortfolios.SyncRoot) { if (_notSavedPortfolios.Count == 0) { return; } foreach (var p in portfolios) { var portfolio = p; if (!_notSavedPortfolios.Contains(portfolio)) { continue; } //если площадка у портфеля пустая, то необходимо дождаться ее заполнения //пустой площадка может быть когда в начале придет информация о заявке //с портфелем или о позиции, и только потом придет сам портфель // mika: портфели могут быть универсальными и не принадлежать площадке //var board = portfolio.Board; //if (board == null) // continue; _parent.AddInfoLog(LocalizedStrings.Str3619Params, portfolio.Name); //if (board != null) // _entityRegistry.SaveExchangeBoard(board); _entityRegistry.Portfolios.Save(portfolio); _notSavedPortfolios.Remove(portfolio); } } }
private void OnNews(News news) { lock (_notSavedNews.SyncRoot) { if (_notSavedNews.Count == 0) { return; } if (!_notSavedNews.Contains(news)) { return; } _parent.AddInfoLog(LocalizedStrings.Str3620Params, news.Headline); _entityRegistry.News.Add(news); _notSavedNews.Remove(news); } }
private void OnSecurities(IEnumerable <Security> securities) { lock (_notSavedSecurities.SyncRoot) { if (_notSavedSecurities.Count == 0) { return; } foreach (var s in securities) { var security = s; if (!_notSavedSecurities.Contains(security)) { continue; } // NOTE Когда из Квика пришел инструмент, созданный по сделке if (security.Code.IsEmpty()) { continue; } _parent.AddInfoLog(LocalizedStrings.Str3618Params, security.Id); var securityToSave = security.Clone(); securityToSave.ExtensionInfo = new Dictionary <object, object>(); _entityRegistry.Securities.Save(securityToSave); _notSavedSecurities.Remove(security); } } new NewSecuritiesCommand().Process(this); }
/// <summary> /// Start storage auto-save thread. /// </summary> private void StartStorageTimer() { if (_timer != null || !Buffer.Enabled || Buffer.DisableStorageTimer) { return; } var isProcessing = false; var sync = new SyncObject(); _timer = ThreadingHelper.Timer(() => { lock (sync) { if (isProcessing) { return; } isProcessing = true; } try { var incremental = Settings.IsMode(StorageModes.Incremental); var snapshot = Settings.IsMode(StorageModes.Snapshot); foreach (var pair in Buffer.GetTicks()) { if (incremental) { Settings.GetStorage <ExecutionMessage>(pair.Key, ExecutionTypes.Tick).Save(pair.Value); } } foreach (var pair in Buffer.GetOrderLog()) { if (incremental) { Settings.GetStorage <ExecutionMessage>(pair.Key, ExecutionTypes.OrderLog).Save(pair.Value); } } foreach (var pair in Buffer.GetTransactions()) { var secId = pair.Key; if (incremental) { Settings.GetStorage <ExecutionMessage>(secId, ExecutionTypes.Transaction).Save(pair.Value); } if (snapshot) { var snapshotStorage = GetSnapshotStorage(DataType.Transactions); foreach (var message in pair.Value) { // do not store cancellation commands into snapshot if (message.IsCancellation) { this.AddWarningLog("Cancellation transaction: {0}", message); continue; } var originTransId = message.OriginalTransactionId; if (originTransId == 0) { continue; } if (_cancellationTransactions.TryGetValue(originTransId, out var cancelledId)) { // do not store cancellation errors if (message.Error != null) { continue; } // override cancel trans id by original order's registration trans id originTransId = cancelledId; } else if (_orderStatusIds.Contains(originTransId)) { // override status request trans id by original order's registration trans id originTransId = message.TransactionId; } else if (_replaceTransactions.TryGetAndRemove(originTransId, out var replacedId)) { if (message.Error == null) { var replaced = (ExecutionMessage)snapshotStorage.Get(replacedId); if (replaced == null) { this.AddWarningLog("Replaced order {0} not found.", replacedId); } else { if (replaced.OrderState != OrderStates.Done) { replaced.OrderState = OrderStates.Done; } } } } message.SecurityId = secId; if (message.TransactionId == 0) { message.TransactionId = originTransId; } message.OriginalTransactionId = 0; SaveTransaction(snapshotStorage, message); } } } foreach (var pair in Buffer.GetOrderBooks()) { if (incremental) { Settings.GetStorage <QuoteChangeMessage>(pair.Key, null).Save(pair.Value); } if (snapshot) { var snapshotStorage = GetSnapshotStorage(DataType.MarketDepth); foreach (var message in pair.Value) { snapshotStorage.Update(message); } } } foreach (var pair in Buffer.GetLevel1()) { var messages = pair.Value.Where(m => m.Changes.Count > 0).ToArray(); if (incremental) { Settings.GetStorage <Level1ChangeMessage>(pair.Key, null).Save(messages); } if (Settings.IsMode(StorageModes.Snapshot)) { var snapshotStorage = GetSnapshotStorage(DataType.Level1); foreach (var message in messages) { snapshotStorage.Update(message); } } } foreach (var pair in Buffer.GetCandles()) { Settings.GetStorage(pair.Key.Item1, pair.Key.Item2, pair.Key.Item3).Save(pair.Value); } foreach (var pair in Buffer.GetPositionChanges()) { var messages = pair.Value.Where(m => m.Changes.Count > 0).ToArray(); if (incremental) { Settings.GetStorage <PositionChangeMessage>(pair.Key, null).Save(messages); } if (snapshot) { var snapshotStorage = GetSnapshotStorage(DataType.PositionChanges); foreach (var message in messages) { snapshotStorage.Update(message); } } } var news = Buffer.GetNews().ToArray(); if (news.Length > 0) { Settings.GetStorage <NewsMessage>(default, null).Save(news);
/// <inheritdoc /> protected override void OnInnerAdapterNewOutMessage(Message message) { if (OwnInnerAdapter) { base.OnInnerAdapterNewOutMessage(message); } if (message.IsBack) { return; } switch (message.Type) { case MessageTypes.SubscriptionResponse: case MessageTypes.SubscriptionFinished: case MessageTypes.SubscriptionOnline: { if (!OwnInnerAdapter) { var originId = (IOriginalTransactionIdMessage)message; if (_realSubscribeIds.Contains(originId.OriginalTransactionId)) { base.OnInnerAdapterNewOutMessage(message); } } break; } case MessageTypes.Connect: case MessageTypes.Disconnect: case MessageTypes.Reset: //case MessageTypes.BoardState: case MessageTypes.Portfolio: case MessageTypes.PositionChange: { break; } case MessageTypes.Execution: { var execMsg = (ExecutionMessage)message; if (execMsg.IsMarketData()) { TrySendToEmulator((ISubscriptionIdMessage)message); } break; } default: { if (message is ISubscriptionIdMessage || message is SecurityMessage) { TrySendToEmulator((ISubscriptionIdMessage)message); } break; } } }
/// <inheritdoc /> protected override void OnInnerAdapterNewOutMessage(Message message) { if (message.IsBack()) { if (OwnInnerAdapter) { base.OnInnerAdapterNewOutMessage(message); } return; } switch (message.Type) { case MessageTypes.Connect: case MessageTypes.Disconnect: case MessageTypes.Reset: break; case MessageTypes.SubscriptionResponse: case MessageTypes.SubscriptionFinished: case MessageTypes.SubscriptionOnline: { if (_subscriptionIds.Contains(((IOriginalTransactionIdMessage)message).OriginalTransactionId)) { SendToEmulator(message); } break; } //case MessageTypes.BoardState: case MessageTypes.Portfolio: case MessageTypes.PositionChange: { if (OwnInnerAdapter) { base.OnInnerAdapterNewOutMessage(message); } break; } case MessageTypes.Execution: { var execMsg = (ExecutionMessage)message; if (execMsg.IsMarketData()) { TrySendToEmulator((ISubscriptionIdMessage)message); } else { if (OwnInnerAdapter) { base.OnInnerAdapterNewOutMessage(message); } } break; } case MessageTypes.Security: case MessageTypes.Board: { if (OwnInnerAdapter) { base.OnInnerAdapterNewOutMessage(message); } SendToEmulator(message); //TrySendToEmulator((ISubscriptionIdMessage)message); break; } case ExtendedMessageTypes.EmulationState: SendToEmulator(message); break; case MessageTypes.Time: { if (OwnInnerAdapter) { if (_isEmulationOnly) { SendToEmulator(message); } else { base.OnInnerAdapterNewOutMessage(message); } } break; } default: { if (message is ISubscriptionIdMessage subscrMsg) { TrySendToEmulator(subscrMsg); } else { if (OwnInnerAdapter) { base.OnInnerAdapterNewOutMessage(message); } } break; } } }
/// <inheritdoc /> protected override void OnInnerAdapterNewOutMessage(Message message) { var processSuspended = false; switch (message.Type) { case MessageTypes.SubscriptionResponse: { var responseMsg = (SubscriptionResponseMessage)message; if (responseMsg.Error != null) { _transactionLogSubscriptions.Remove(responseMsg.OriginalTransactionId); } break; } case MessageTypes.SubscriptionFinished: case MessageTypes.SubscriptionOnline: { var originMsg = (IOriginalTransactionIdMessage)message; if (!_transactionLogSubscriptions.TryGetAndRemove(originMsg.OriginalTransactionId, out var subscription)) { break; } Tuple <ExecutionMessage, List <ExecutionMessage> >[] tuples; lock (subscription.Sync) tuples = subscription.Transactions.Values.ToArray(); var canProcessFailed = subscription.Original.States.Contains(OrderStates.Failed); foreach (var tuple in tuples) { var order = tuple.Item1; if (order.OrderState == OrderStates.Failed && !canProcessFailed) { if (tuple.Item2.Count > 0) { this.AddWarningLog("Order {0} has failed state but contains {1} trades.", order.TransactionId, tuple.Item2.Count); } continue; } base.OnInnerAdapterNewOutMessage(order); ProcessSuspended(order); foreach (var trade in tuple.Item2) { base.OnInnerAdapterNewOutMessage(trade); } } break; } case MessageTypes.Execution: { var execMsg = (ExecutionMessage)message; if (execMsg.IsMarketData()) { break; } // skip cancellation cause they are reply on action and no have transaction state if (execMsg.IsCancellation) { break; } var transId = execMsg.TransactionId; if (transId != 0) { _secIds.TryAdd(transId, execMsg.SecurityId); } else { if (execMsg.SecurityId == default && _secIds.TryGetValue(execMsg.OriginalTransactionId, out var secId)) { execMsg.SecurityId = secId; } } if (transId != 0 || execMsg.OriginalTransactionId != 0) { if (transId == 0) { transId = execMsg.OriginalTransactionId; } if (execMsg.OrderId != null) { _orderIds.TryAdd(execMsg.OrderId.Value, transId); } else if (!execMsg.OrderStringId.IsEmpty()) { _orderStringIds.TryAdd(execMsg.OrderStringId, transId); } } if (execMsg.TransactionId == 0 && execMsg.HasTradeInfo && _orderStatusIds.Contains(execMsg.OriginalTransactionId)) { // below the code will try find order's transaction execMsg.OriginalTransactionId = 0; } if (/*execMsg.TransactionId == 0 && */ execMsg.OriginalTransactionId == 0) { if (!execMsg.HasTradeInfo) { this.AddWarningLog("Order doesn't have origin trans id: {0}", execMsg); break; } if (execMsg.OrderId != null) { if (_orderIds.TryGetValue(execMsg.OrderId.Value, out var originId)) { execMsg.OriginalTransactionId = originId; } else { this.AddWarningLog("Trade doesn't have origin trans id: {0}", execMsg); break; } } else if (!execMsg.OrderStringId.IsEmpty()) { if (_orderStringIds.TryGetValue(execMsg.OrderStringId, out var originId)) { execMsg.OriginalTransactionId = originId; } else { this.AddWarningLog("Trade doesn't have origin trans id: {0}", execMsg); break; } } } if (execMsg.HasTradeInfo && !execMsg.HasOrderInfo) { if (execMsg.OrderId != null && !_orderIds.ContainsKey(execMsg.OrderId.Value) && (execMsg.OriginalTransactionId == 0 || !_secIds.ContainsKey(execMsg.OriginalTransactionId))) { this.AddInfoLog("{0} suspended.", execMsg); lock (_nonAssociatedLock) _nonAssociatedOrderIds.SafeAdd(execMsg.OrderId.Value).Add(execMsg.TypedClone()); return; } else if (!execMsg.OrderStringId.IsEmpty() && !_orderStringIds.ContainsKey(execMsg.OrderStringId) && (execMsg.OriginalTransactionId == 0 || !_secIds.ContainsKey(execMsg.OriginalTransactionId))) { this.AddInfoLog("{0} suspended.", execMsg); lock (_nonAssociatedLock) _nonAssociatedStringOrderIds.SafeAdd(execMsg.OrderStringId).Add(execMsg.TypedClone()); return; } } if (_transactionLogSubscriptions.Count == 0) { processSuspended = true; break; } if (!_transactionLogSubscriptions.TryGetValue(execMsg.OriginalTransactionId, out var subscription)) { if (!_orders.TryGetValue(execMsg.OriginalTransactionId, out var orderTransId)) { break; } if (!_transactionLogSubscriptions.TryGetValue(orderTransId, out subscription)) { break; } } if (transId == 0) { if (execMsg.HasTradeInfo) { transId = execMsg.OriginalTransactionId; } if (transId == 0) { this.AddWarningLog("Message {0} do not contains transaction id.", execMsg); break; } } lock (subscription.Sync) { if (subscription.Transactions.TryGetValue(transId, out var tuple)) { var snapshot = tuple.Item1; if (execMsg.HasOrderInfo) { if (execMsg.Balance != null) { snapshot.Balance = snapshot.Balance.ApplyNewBalance(execMsg.Balance.Value, transId, this); } if (execMsg.OrderState != null) { snapshot.OrderState = snapshot.OrderState.ApplyNewState(execMsg.OrderState.Value, transId, this); } if (execMsg.OrderStatus != null) { snapshot.OrderStatus = execMsg.OrderStatus; } if (execMsg.OrderId != null) { snapshot.OrderId = execMsg.OrderId; } if (!execMsg.OrderStringId.IsEmpty()) { snapshot.OrderStringId = execMsg.OrderStringId; } if (execMsg.OrderBoardId != null) { snapshot.OrderBoardId = execMsg.OrderBoardId; } if (execMsg.PnL != null) { snapshot.PnL = execMsg.PnL; } if (execMsg.Position != null) { snapshot.Position = execMsg.Position; } if (execMsg.Commission != null) { snapshot.Commission = execMsg.Commission; } if (execMsg.CommissionCurrency != null) { snapshot.CommissionCurrency = execMsg.CommissionCurrency; } if (execMsg.AveragePrice != null) { snapshot.AveragePrice = execMsg.AveragePrice; } if (execMsg.Latency != null) { snapshot.Latency = execMsg.Latency; } } if (execMsg.HasTradeInfo) { var clone = execMsg.TypedClone(); // all order's info in snapshot execMsg.HasTradeInfo = false; clone.HasOrderInfo = false; tuple.Item2.Add(clone); } } else { _orders.Add(transId, execMsg.OriginalTransactionId); subscription.Transactions.Add(transId, Tuple.Create(execMsg.TypedClone(), new List <ExecutionMessage>())); } } return; } } base.OnInnerAdapterNewOutMessage(message); if (processSuspended) { ProcessSuspended((ExecutionMessage)message); } }
public bool Contains(T item) => set.Contains(item);
private bool CanStore(SecurityId securityId, Type messageType, object arg) { return(_subscriptions.Contains(Tuple.Create(securityId, DataType.Create(messageType, arg)))); }
/// <inheritdoc /> protected override void OnInnerAdapterNewOutMessage(Message message) { if (message.IsBack) { if (OwnInnerAdapter) { base.OnInnerAdapterNewOutMessage(message); } return; } switch (message.Type) { case MessageTypes.SubscriptionResponse: case MessageTypes.SubscriptionFinished: case MessageTypes.SubscriptionOnline: { if (!OwnInnerAdapter) { var originId = (IOriginalTransactionIdMessage)message; if (_realSubscribeIds.Contains(originId.OriginalTransactionId)) { base.OnInnerAdapterNewOutMessage(message); } } else { base.OnInnerAdapterNewOutMessage(message); } break; } case MessageTypes.Connect: case MessageTypes.Disconnect: case MessageTypes.Reset: //case MessageTypes.BoardState: case MessageTypes.Portfolio: case MessageTypes.PositionChange: { if (OwnInnerAdapter) { base.OnInnerAdapterNewOutMessage(message); } break; } case MessageTypes.Execution: { var execMsg = (ExecutionMessage)message; if (execMsg.IsMarketData()) { TrySendToEmulator((ISubscriptionIdMessage)message); } else { if (OwnInnerAdapter) { base.OnInnerAdapterNewOutMessage(message); } } break; } case MessageTypes.Security: case MessageTypes.Board: { if (OwnInnerAdapter) { base.OnInnerAdapterNewOutMessage(message); } SendToEmulator(message); //TrySendToEmulator((ISubscriptionIdMessage)message); break; } case ExtendedMessageTypes.Last: SendToEmulator(message); break; case ExtendedMessageTypes.EmulationState: { var stateMsg = (EmulationStateMessage)message; switch (stateMsg.State) { case EmulationStates.Suspending: case EmulationStates.Starting: case EmulationStates.Stopping: break; case EmulationStates.Suspended: _channelEmulator.InputChannel.Suspend(); break; case EmulationStates.Stopped: _channelEmulator.InputChannel.Close(); _channelEmulator.InputChannel.Resume(); break; case EmulationStates.Started: _channelEmulator.InputChannel.Resume(); break; default: throw new ArgumentOutOfRangeException(stateMsg.State.ToString()); } if (OwnInnerAdapter) { base.OnInnerAdapterNewOutMessage(message); } break; } case MessageTypes.Time: { if (OwnInnerAdapter) { if (_isEmulationOnly) { SendToEmulator(message); } else { base.OnInnerAdapterNewOutMessage(message); } } break; } default: { if (message is ISubscriptionIdMessage subscrMsg) { TrySendToEmulator(subscrMsg); } else { if (OwnInnerAdapter) { base.OnInnerAdapterNewOutMessage(message); } } break; } } }
private void StartStorageTimer() { var isProcessing = false; var sync = new SyncObject(); var unkByOrderId = new Dictionary <long, List <ExecutionMessage> >(); var unkByOrderStringId = new Dictionary <string, List <ExecutionMessage> >(StringComparer.InvariantCultureIgnoreCase); ThreadingHelper.Timer(() => { lock (sync) { if (isProcessing) { return; } isProcessing = true; } try { foreach (var pair in GetTicks()) { GetStorage <ExecutionMessage>(pair.Key, ExecutionTypes.Tick).Save(pair.Value); } foreach (var pair in GetOrderLog()) { GetStorage <ExecutionMessage>(pair.Key, ExecutionTypes.OrderLog).Save(pair.Value); } foreach (var pair in GetTransactions()) { var secId = pair.Key; if (Mode.Contains(StorageModes.Incremental)) { GetStorage <ExecutionMessage>(secId, ExecutionTypes.Transaction).Save(pair.Value); } if (Mode.Contains(StorageModes.Snapshot)) { var snapshotStorage = GetSnapshotStorage(DataType.Transactions); foreach (var message in pair.Value) { // do not store cancellation commands into snapshot if (message.IsCancellation /* && message.TransactionId != 0*/) { continue; } var originTransId = message.OriginalTransactionId; if (message.TransactionId == 0 && originTransId == 0) { if (!message.HasTradeInfo) { continue; } long transId; if (message.OrderId != null) { if (!_orderIds.TryGetValue(message.OrderId.Value, out transId)) { unkByOrderId.SafeAdd(message.OrderId.Value).Add(message); continue; } } else if (!message.OrderStringId.IsEmpty()) { if (!_orderStringIds.TryGetValue(message.OrderStringId, out transId)) { unkByOrderStringId.SafeAdd(message.OrderStringId).Add(message); continue; } } else { continue; } originTransId = transId; } else { if (originTransId != 0) { if (/*message.TransactionId == 0 && */ _cancellationTransactions.TryGetValue(originTransId, out var temp)) { // do not store cancellation errors if (message.Error != null) { continue; } // override cancel trans id by original order's registration trans id originTransId = temp; } if (_orderStatusIds.Contains(originTransId)) { // override status request trans id by original order's registration trans id originTransId = message.TransactionId; } } if (originTransId != 0) { if (message.OrderId != null) { _orderIds.TryAdd(message.OrderId.Value, originTransId); } else if (message.OrderStringId != null) { _orderStringIds.TryAdd(message.OrderStringId, originTransId); } } } message.SecurityId = secId; if (message.TransactionId == 0) { message.TransactionId = originTransId; } message.OriginalTransactionId = 0; SaveTransaction(snapshotStorage, message); if (message.OrderId != null) { if (unkByOrderId.TryGetValue(message.OrderId.Value, out var suspended)) { unkByOrderId.Remove(message.OrderId.Value); foreach (var trade in suspended) { trade.TransactionId = message.TransactionId; SaveTransaction(snapshotStorage, trade); } } } else if (!message.OrderStringId.IsEmpty()) { if (unkByOrderStringId.TryGetValue(message.OrderStringId, out var suspended)) { unkByOrderStringId.Remove(message.OrderStringId); foreach (var trade in suspended) { trade.TransactionId = message.TransactionId; SaveTransaction(snapshotStorage, trade); } } } } } } foreach (var pair in GetOrderBooks()) { if (Mode.Contains(StorageModes.Incremental)) { GetStorage <QuoteChangeMessage>(pair.Key, null).Save(pair.Value); } if (Mode.Contains(StorageModes.Snapshot)) { var snapshotStorage = GetSnapshotStorage(DataType.MarketDepth); foreach (var message in pair.Value) { snapshotStorage.Update(message); } } } foreach (var pair in GetLevel1()) { var messages = pair.Value.Where(m => m.Changes.Count > 0).ToArray(); var dt = DateTime.Today; var historical = messages.Where(m => m.ServerTime < dt).ToArray(); var today = messages.Where(m => m.ServerTime >= dt).ToArray(); GetStorage <Level1ChangeMessage>(pair.Key, null).Save(historical); if (Mode.Contains(StorageModes.Incremental)) { GetStorage <Level1ChangeMessage>(pair.Key, null).Save(today); } if (Mode.Contains(StorageModes.Snapshot)) { var snapshotStorage = GetSnapshotStorage(DataType.Level1); foreach (var message in today) { snapshotStorage.Update(message); } } } foreach (var pair in GetCandles()) { GetStorage(pair.Key.Item1, pair.Key.Item2, pair.Key.Item3).Save(pair.Value); } foreach (var pair in GetPositionChanges()) { var messages = pair.Value.Where(m => m.Changes.Count > 0).ToArray(); if (Mode.Contains(StorageModes.Incremental)) { GetStorage <PositionChangeMessage>(pair.Key, null).Save(messages); } if (Mode.Contains(StorageModes.Snapshot)) { var snapshotStorage = GetSnapshotStorage(DataType.PositionChanges); foreach (var message in messages) { snapshotStorage.Update(message); } } } var news = GetNews().ToArray(); if (news.Length > 0) { StorageRegistry.GetNewsMessageStorage(Drive, Format).Save(news); } } catch (Exception excp) { excp.LogError(); } finally { lock (sync) isProcessing = false; } }).Interval(TimeSpan.FromSeconds(10)); }
/// <inheritdoc /> protected override void OnInnerAdapterNewOutMessage(Message message) { switch (message.Type) { case MessageTypes.SubscriptionResponse: { var responseMsg = (SubscriptionResponseMessage)message; if (responseMsg.Error != null) { _transactionLogSubscriptions.Remove(responseMsg.OriginalTransactionId); } break; } case MessageTypes.SubscriptionFinished: case MessageTypes.SubscriptionOnline: { var originMsg = (IOriginalTransactionIdMessage)message; if (!_transactionLogSubscriptions.TryGetAndRemove(originMsg.OriginalTransactionId, out var subscription)) { break; } foreach (var pair in subscription.Transactions) { base.OnInnerAdapterNewOutMessage(pair.Value.Item1); foreach (var trade in pair.Value.Item2) { base.OnInnerAdapterNewOutMessage(trade); } } break; } case MessageTypes.Execution: { var execMsg = (ExecutionMessage)message; if (execMsg.IsMarketData()) { break; } // skip cancellation cause they are reply on action and no have transaction state if (execMsg.IsCancellation) { break; } var transId = execMsg.TransactionId; if (transId != 0) { _secIds.TryAdd(transId, execMsg.SecurityId); } else { if (execMsg.SecurityId == default && _secIds.TryGetValue(execMsg.OriginalTransactionId, out var secId)) { execMsg.SecurityId = secId; } } if (transId != 0 || execMsg.OriginalTransactionId != 0) { if (transId == 0) { transId = execMsg.OriginalTransactionId; } if (execMsg.OrderId != null) { _orderIds.TryAdd(execMsg.OrderId.Value, transId); } else if (!execMsg.OrderStringId.IsEmpty()) { _orderStringIds.TryAdd(execMsg.OrderStringId, transId); } } if (execMsg.TransactionId == 0 && execMsg.HasTradeInfo && _orderStatusIds.Contains(execMsg.OriginalTransactionId)) { // below the code will try find order's transaction execMsg.OriginalTransactionId = 0; } if (/*execMsg.TransactionId == 0 && */ execMsg.OriginalTransactionId == 0) { if (!execMsg.HasTradeInfo) { this.AddWarningLog("Order doesn't have origin trans id: {0}", execMsg); break; } if (execMsg.OrderId != null) { if (_orderIds.TryGetValue(execMsg.OrderId.Value, out var originId)) { execMsg.OriginalTransactionId = originId; } else { this.AddWarningLog("Trade doesn't have origin trans id: {0}", execMsg); break; } } else if (!execMsg.OrderStringId.IsEmpty()) { if (_orderStringIds.TryGetValue(execMsg.OrderStringId, out var originId)) { execMsg.OriginalTransactionId = originId; } else { this.AddWarningLog("Trade doesn't have origin trans id: {0}", execMsg); break; } } } if (_transactionLogSubscriptions.Count == 0) { break; } if (!_transactionLogSubscriptions.TryGetValue(execMsg.OriginalTransactionId, out var subscription)) { if (!_orders.TryGetValue(execMsg.OriginalTransactionId, out var orderTransId)) { break; } if (!_transactionLogSubscriptions.TryGetValue(orderTransId, out subscription)) { break; } } if (transId == 0) { if (execMsg.HasTradeInfo) { transId = execMsg.OriginalTransactionId; } if (transId == 0) { this.AddWarningLog("Message {0} do not contains transaction id.", execMsg); break; } } lock (subscription.Sync) { if (subscription.Transactions.TryGetValue(transId, out var tuple)) { var snapshot = tuple.Item1; if (execMsg.HasOrderInfo) { if (execMsg.Balance != null) { snapshot.Balance = snapshot.Balance.ApplyNewBalance(execMsg.Balance.Value, transId, this); } if (execMsg.OrderState != null) { snapshot.OrderState = snapshot.OrderState.ApplyNewState(execMsg.OrderState.Value, transId, this); } if (execMsg.OrderStatus != null) { snapshot.OrderStatus = execMsg.OrderStatus; } if (execMsg.OrderId != null) { snapshot.OrderId = execMsg.OrderId; } if (execMsg.OrderStringId != null) { snapshot.OrderStringId = execMsg.OrderStringId; } if (execMsg.OrderBoardId != null) { snapshot.OrderBoardId = execMsg.OrderBoardId; } if (execMsg.PnL != null) { snapshot.PnL = execMsg.PnL; } if (execMsg.Position != null) { snapshot.Position = execMsg.Position; } if (execMsg.Commission != null) { snapshot.Commission = execMsg.Commission; } if (execMsg.CommissionCurrency != null) { snapshot.CommissionCurrency = execMsg.CommissionCurrency; } if (execMsg.AveragePrice != null) { snapshot.AveragePrice = execMsg.AveragePrice; } if (execMsg.Latency != null) { snapshot.Latency = execMsg.Latency; } } if (execMsg.HasTradeInfo) { var clone = execMsg.TypedClone(); // all order's info in snapshot execMsg.HasTradeInfo = false; clone.HasOrderInfo = false; tuple.Item2.Add(clone); } } else { _orders.Add(transId, execMsg.OriginalTransactionId); subscription.Transactions.Add(transId, Tuple.Create(execMsg.TypedClone(), new List <ExecutionMessage>())); } } return; } } base.OnInnerAdapterNewOutMessage(message); }