示例#1
0
        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));
        }
示例#2
0
        /// <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);
        }
示例#3
0
        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();
        }
示例#4
0
        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);
                }
            }
        }
示例#6
0
        /// <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}");
                }
            }
        }
示例#7
0
        /// <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());
        }
示例#8
0
        /// <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);
        }
示例#9
0
        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)
                );
        }
示例#10
0
        private async void ContractMetadataReceived(AdapterEventArgs <ContractMetadata> args)
        {
            try
            {
                args.MarkHandled();

                await Task.Yield();
                await HandleMetadataAsync(args.Message);
            }
            catch { }
        }
示例#11
0
        /// <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)
                );
        }
示例#12
0
        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();
            }
        }
示例#13
0
        private void RealTimeMarketDataReceived(AdapterEventArgs <RealTimeMarketData> args)
        {
            var isHandled = Process(
                args.Message.contract_id,
                args.Message,
                (subscription, data) => subscription.Handle(data)
                );

            if (isHandled)
            {
                args.MarkHandled();
            }
        }
示例#14
0
        /// <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);
        }
示例#15
0
        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();
        }
示例#16
0
        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();
            }
        }
示例#17
0
        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));
        }
示例#18
0
        /// <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");
            }
        }
示例#19
0
        /// <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}");
                }
            }
        }