private void MarketDataResolved(AdapterEventArgs <InformationReport> args) { var contractId = args.Message.symbol_resolution_report.contract_metadata.contract_id; ResolutionRequest request; using (resolutionRequestsLock.Lock()) { if (!resolutionRequestsById.TryGetValue(args.Message.id, out request)) { return; } using (cacheLock.Lock()) { cachedContractIds[request.Instrument] = contractId; cachedContracts[contractId] = request.Instrument; cachedContractPriceScales[contractId] = (decimal)args.Message.symbol_resolution_report.contract_metadata.correct_price_scale; } resolutionRequestsById.Remove(request.Id); resolutionRequestsByInstrument.Remove(request.Instrument); } request.Resolve(contractId); args.MarkHandled(); OnInstrumentResolved(contractId); _Log.Debug().Print("Instrument is resolved", LogFields.Instrument(request.Instrument), LogFields.ContractId(contractId), LogFields.RequestId(request.Id)); }
/// <summary> /// Обработка сообщения по ГО /// </summary> private void CollateralStatusReceived(AdapterEventArgs <CollateralStatus> args) { args.MarkHandled(); // Ищем счет для MP string accountCode; using (accountsLock.ReadLock()) { if (!accountCodesById.TryGetValue(args.Message.account_id, out accountCode)) { Logger.Error().Print("Unable to process collateral: account is unknown", LogFields.AccountId(args.Message.account_id)); return; } } // Собираем Money Position var moneyPosition = new MoneyPosition { Account = accountCode }; moneyPosition[MoneyPositionPropertyNames.Ote] = (decimal)args.Message.ote; moneyPosition[MoneyPositionPropertyNames.Mvo] = (decimal)args.Message.mvo; moneyPosition[MoneyPositionPropertyNames.PurchasingPower] = (decimal)args.Message.purchasing_power; moneyPosition[MoneyPositionPropertyNames.TotalMargin] = (decimal)args.Message.total_margin; moneyPosition[MoneyPositionPropertyNames.Currency].Value = args.Message.currency; OnMessageReceived(moneyPosition); }
private void OnMarketDataResolved(AdapterEventArgs <InformationReport> args) { using (resolutionRequestsLock.Lock()) { if (!resolutionRequestsById.TryGetValue(args.Message.id, out var request)) { return; } resolutionRequestsById.Remove(args.Message.id); var resolvedSymbol = args.Message.symbol_resolution_report.contract_metadata.contract_symbol; if (resolvedSymbol.EndsWith(request.Symbol)) { request.TrySetResult(SubscriptionTestResult.Passed( ContractMetadataToString(args.Message.symbol_resolution_report.contract_metadata)) ); } else { request.TrySetResult(SubscriptionTestResult.Failed( ContractMetadataToString(args.Message.symbol_resolution_report.contract_metadata)) ); } } //request.TrySetResult(Tuple.Create(true,args.Message.ToString())); args.MarkHandled(); }
private void UserMessageReceived(AdapterEventArgs <UserMessage> args) { args.MarkHandled(); var type = (UserMessage.MessageType)args.Message.message_type; switch (type) { case UserMessage.MessageType.CRITICAL_ERROR: _Log.Error().PrintFormat("CQG Error Adapter error\n{0}", FormatUserMessage(args.Message).Preformatted()); adapter.Terminate(); adapter.Start(); break; case UserMessage.MessageType.WARNING: _Log.Warn().Print(FormatUserMessage(args.Message).Preformatted()); break; case UserMessage.MessageType.INFO: _Log.Info().Print(FormatUserMessage(args.Message).Preformatted()); break; case UserMessage.MessageType.LOG: _Log.Debug().Print(FormatUserMessage(args.Message).Preformatted()); break; } }
private void TimeBarReportReceived(AdapterEventArgs <TimeBarReport> args) { ITimeBarReportHandler request; using (requestsLock.Lock()) { if (!requests.TryGetValue(args.Message.request_id, out request)) { return; } } args.MarkHandled(); bool shouldRemoveHandler; request.Process(args.Message, out shouldRemoveHandler); if (shouldRemoveHandler) { using (requestsLock.Lock()) { requests.Remove(args.Message.request_id); } } }
/// <summary> /// Обработчик события по статусу заявки /// </summary> private async void OrderStatusReceived(AdapterEventArgs <OrderStatus> args) { using (LogManager.Scope()) { try { Logger.Debug().Print( "Order status received", LogFields.ExchangeOrderId(args.Message.order_id), LogFields.ChainOrderId(args.Message.chain_order_id), LogFields.State(ConvertionHelper.GetOrderState(args.Message)), LogFields.AccountId(args.Message.account_id), LogFields.ExecOrderId(args.Message.exec_order_id) ); args.MarkHandled(); // Обрабатываем метаданные контрактов if (args.Message.contract_metadata != null) { foreach (var metadata in args.Message.contract_metadata) { await instrumentResolver.HandleMetadataAsync(metadata); } } // Пытаемся выбрать заявку из контейнера Order order; using (ordersLock.Lock()) ordersByOrderExchangeId.TryGetValue(args.Message.chain_order_id, out order); Message message; // Обрабатываем изменение статуса заявки if (order != null) { message = HandleOrderStateAsOrderStateChange(order, args.Message); } // Обрабатываем заявку как новую else { message = HandleOrderStateAsNewOrder(args.Message, out order); } // Отправляем сообщение и TransactionReply if (message != null) { OnMessageReceived(message); TryEmitTransactionReplies(args.Message); // Обрабатываем сделки TryEmitFills(args.Message, order); } } catch (Exception e) { Logger.Error().Print(e, $"Failed to process {args.Message}"); } } }
/// <summary> /// Обработчик события завершения выгрузки снапшота /// </summary> private void TradeSnapshotCompletionReceived(AdapterEventArgs <TradeSnapshotCompletion> args) { args.MarkHandled(); var scopes = args.Message.subscription_scope .Select(x => ((TradeSubscription.SubscriptionScope)x).ToString("G")); Logger.Debug().PrintFormat("Trade snapshot completed ({0})", string.Join(", ", scopes).Preformatted()); }
/// <summary> /// Обработка отказа по заявке /// </summary> private void OrderRequestRejectReceived(AdapterEventArgs <OrderRequestReject> args) { args.MarkHandled(); var message = $"[{args.Message.reject_code}] {args.Message.text_message}"; Logger.Error().Print("CQG order rejected", LogFields.Message(message)); TrySendTransactionReplyRejected(args.Message.request_id, message); }
private static void MarketDataSubscriptionStatusReceived(AdapterEventArgs <MarketDataSubscriptionStatus> args) { args.MarkHandled(); _Log.Debug().Print( $"Subscription status for contract #{args.Message.contract_id}: Level={1}, Status={2}. {3}", LogFields.Level((MarketDataSubscription.Level)args.Message.level), LogFields.Status((MarketDataSubscriptionStatus.StatusCode)args.Message.status_code), LogFields.Message(args.Message.text_message) ); }
private async void ContractMetadataReceived(AdapterEventArgs <ContractMetadata> args) { try { args.MarkHandled(); await Task.Yield(); await HandleMetadataAsync(args.Message); } catch { } }
/// <summary> /// Обработчик события изменения статуса подписки /// </summary> private void TradeSubscriptionStatusReceived(AdapterEventArgs <TradeSubscriptionStatus> args) { args.MarkHandled(); Logger.Debug().Print( "Trade subscription status received", LogFields.Id(args.Message.id), LogFields.Status((TradeSubscriptionStatus.StatusCode)args.Message.status_code), LogFields.Message(args.Message.text_message) ); }
private void MarketDataResolved(AdapterEventArgs <InformationReport> args) { var isHandled = Process( args.Message.symbol_resolution_report.contract_metadata.contract_id, args.Message, (subscription, data) => subscription.Handle(data.symbol_resolution_report.contract_metadata) ); if (isHandled) { args.MarkHandled(); } }
private void RealTimeMarketDataReceived(AdapterEventArgs <RealTimeMarketData> args) { var isHandled = Process( args.Message.contract_id, args.Message, (subscription, data) => subscription.Handle(data) ); if (isHandled) { args.MarkHandled(); } }
/// <summary> /// Обработчик события получения списка счетов /// </summary> private void AccountResolved(AdapterEventArgs <AccountsReport> args) { args.MarkHandled(); // Инициализируем счета if (args.Message.brokerage != null) { using (accountsLock.WriteLock()) { foreach ( var account in from brokerage in args.Message.brokerage from ss in brokerage.sales_series from account in ss.account select account) { Logger.Debug().PrintFormat("Account resolved: {0};{1};{2}", account.brokerage_account_id, account.account_id, account.name); AddAccount(account.name); accountCodesById[account.account_id] = account.name; accountIdsByCode[account.name] = account.account_id; } } OnMessageReceived( new InitResponseMessage { OrderRouters = new Dictionary <string, string[]> { { ServiceCode, AvailableAccounts.ToArray() } } }); } // Подписываемся на счета var subscription = new TradeSubscription { publication_type = (uint)TradeSubscription.PublicationType.ALL_AUTHORIZED, subscription_scope = { (uint)TradeSubscription.SubscriptionScope.ORDERS, (uint)TradeSubscription.SubscriptionScope.POSITIONS, (uint)TradeSubscription.SubscriptionScope.COLLATERAL }, subscribe = true, id = adapter.GetNextRequestId() }; adapter.SendMessage(subscription); }
private void OnMarketDataNotResolved(AdapterEventArgs <InformationReport> args) { ResolutionRequest request; using (resolutionRequestsLock.Lock()) { if (!resolutionRequestsById.TryGetValue(args.Message.id, out request)) { return; } resolutionRequestsById.Remove(args.Message.id); } request.TrySetResult(SubscriptionTestResult.Failed(args.Message.text_message)); args.MarkHandled(); }
private void ContractMetadataReceived(AdapterEventArgs <ContractMetadata> args) { using (subscriptionsLock.Lock()) { contractMetadatas[args.Message.contract_id] = args.Message; } var isHandled = Process( args.Message.contract_id, args.Message, (subscription, data) => subscription.Handle(data) ); if (isHandled) { args.MarkHandled(); } }
private void MarketDataNotResolved(AdapterEventArgs <InformationReport> args) { ResolutionRequest request; using (resolutionRequestsLock.Lock()) { if (!resolutionRequestsById.TryGetValue(args.Message.id, out request)) { return; } resolutionRequestsById.Remove(request.Id); resolutionRequestsByInstrument.Remove(request.Instrument); } request.Reject(); args.MarkHandled(); _Log.Error().Print("Failed to resolve instrument", LogFields.RequestId(request.Id), LogFields.Message(args.Message.text_message)); }
/// <summary> /// Обработать сообщение /// </summary> private void RaiseImpl(T message, uint requestId = 0, bool hasRequestId = true) { var h = handler; if (h != null) { try { var args = new AdapterEventArgs <T>(message); h(args); if (args.Handled) { return; } } catch (Exception e) { CQGCAdapter.Log.Error().Print(e, $"Failed to process a {messageName} message"); return; } } if (hasRequestId) { CQGCAdapter.Log.Warn().Print( $"Received a {messageName} message but there are no consumers to handle it", LogFields.RequestId(requestId) ); } else { CQGCAdapter.Log.Warn().Print($"Received a {messageName} message but there are no consumers to handle it"); } }
/// <summary> /// Обработчик события получения позиции /// </summary> private async void PositionStatusReceived(AdapterEventArgs <PositionStatus> args) { using (LogManager.Scope()) { try { args.MarkHandled(); // Ищем счет для позиции string accountCode; using (accountsLock.ReadLock()) { if (!accountCodesById.TryGetValue(args.Message.account_id, out accountCode)) { Logger.Error().PrintFormat( "Unable to process position on contract #{0}: account #{1} is unknown", args.Message.contract_id, args.Message.account_id); return; } } // Обрабатываем метаданные контрактов if (args.Message.contract_metadata != null) { await instrumentResolver.HandleMetadataAsync(args.Message.contract_metadata, $"A position in \"{accountCode}\" account"); } // Ищем инструмент для позиции var instrument = instrumentResolver.GetInstrument(args.Message.contract_id); if (instrument == null) { Logger.Warn().PrintFormat( "Received a position on contract #{0} in account {1} but no matching instrument is found", args.Message.contract_id, accountCode); return; } // Рассчитываем позицию var position = new PositionMessage { Account = accountCode, Instrument = instrument }; var message = new StringBuilder(); message.AppendFormat("Position received: {0} [ ", instrument.Code); using (openPositionsLock.Lock()) { Dictionary <uint, Dictionary <int, OpenPosition> > d1; if (!openPositions.TryGetValue(args.Message.account_id, out d1)) { d1 = new Dictionary <uint, Dictionary <int, OpenPosition> >(); openPositions.Add(args.Message.account_id, d1); } Dictionary <int, OpenPosition> d2; if (!d1.TryGetValue(args.Message.contract_id, out d2)) { d2 = new Dictionary <int, OpenPosition>(); d1.Add(args.Message.contract_id, d2); } if (args.Message.is_snapshot) { d2.Clear(); } position.Quantity = 0; foreach (var p in args.Message.open_position) { var fmt = ObjectLogFormatter.Create(PrintOption.Nested, "CQGC_POSITION"); fmt.AddField(LogFieldNames.Id, p.id); fmt.AddField(LogFieldNames.Price, p.price); fmt.AddField(LogFieldNames.Quantity, p.qty); fmt.AddField(LogFieldNames.TradeDate, p.trade_date); fmt.AddField(LogFieldNames.TradeUtcTime, p.trade_utc_time); fmt.AddField(LogFieldNames.StatementDate, p.statement_date); message.Append(fmt.Print(PrintOption.Nested)); message.Append(", "); position.Quantity = (int)p.qty; position.Price = (decimal)p.price; d2[p.id] = p; } var volume = 0d; var quantity = 0u; foreach (var pair in d2) { volume += pair.Value.price * pair.Value.qty; quantity += pair.Value.qty; } position.Quantity = (int)quantity; position.Price = quantity != 0u ? (decimal)(volume / quantity) : 0; } if (args.Message.is_short_open_position) { position.Quantity *= -1; } message.Append("]: "); message.Append(LogFields.Price(position.Price)); message.Append(LogFields.Quantity(position.Quantity)); message.Append(LogFields.IsSnapshot(args.Message.is_snapshot)); Logger.Debug().Print(message.ToString().Preformatted()); // Отправляем сообщение OnMessageReceived(position); } catch (Exception e) { Logger.Error().Print(e, $"Failed to process {args.Message}"); } } }