Ejemplo n.º 1
0
        private async Task <CommandHandlingResult> Handle(UnsuspendAssetPairCommand command,
                                                          IEventPublisher publisher)
        {
            //idempotency handling not required
            var updateResult = await _productsDiscontinueService.ChangeSuspendStatusAsync(command.AssetPairId,
                                                                                          false,
                                                                                          username,
                                                                                          command.OperationId);

            if (!updateResult.IsSuccess)
            {
                return(CommandHandlingResult.Fail(_delay));
            }

            _chaosKitty.Meow(command.OperationId);

            var assetPair =
                AssetPair.CreateFromProduct(updateResult.NewValue, _defaultLegalEntitySettings.DefaultLegalEntity);

            publisher.PublishEvent(new AssetPairChangedEvent
            {
                OperationId = command.OperationId,
                AssetPair   = _convertService.Convert <IAssetPair, AssetPairContract>(assetPair),
            });

            publisher.PublishEvent(CreateProductChangedEvent(updateResult.OldValue,
                                                             updateResult.NewValue,
                                                             username,
                                                             command.OperationId));

            return(CommandHandlingResult.Ok());
        }
        public async Task <IReadOnlyList <IAssetPair> > GetAllIncludingFxParisWithFilterAsync(IEnumerable <string>
                                                                                              assetPairIds = null, bool onlyStarted = true)
        {
            var settlementCurrency = await _settlementCurrencyService.GetSettlementCurrencyAsync();

            var products = await _productsRepository.GetByProductsIdsAsync(assetPairIds);

            var currencies = await _currenciesRepository.GetAllAsync();

            var assetPairs = products
                             .Where(x => !onlyStarted || x.IsStarted)
                             .Select(x => AssetPair.CreateFromProduct(x, _defaultLegalEntitySettings.DefaultLegalEntity)).ToList();

            assetPairs.AddRange(currencies.Value
                                .Where(x => !x.Id.Equals(settlementCurrency,
                                                         StringComparison.InvariantCultureIgnoreCase)).Select(x =>
                                                                                                              AssetPair.CreateFromCurrency(x, _defaultLegalEntitySettings.DefaultLegalEntity, settlementCurrency)));

            return(assetPairs);
        }
        public async Task <IAssetPair> GetByIdAsync(string assetPairId)
        {
            var result = await _productsRepository.GetByIdAsync(assetPairId);

            return(result.IsSuccess ? AssetPair.CreateFromProduct(result.Value, _defaultLegalEntitySettings.DefaultLegalEntity) : null);
        }
Ejemplo n.º 4
0
        public async Task Handle(ProductChangedEvent @event)
        {
            switch (@event.ChangeType)
            {
            case ChangeType.Creation:
            case ChangeType.Edition:
                if ([email protected])
                {
                    _log.WriteInfo(nameof(ProductChangedProjection),
                                   nameof(Handle),
                                   $"ProductChangedEvent received for productId: {@event.NewValue.ProductId}, but it was ignored because it has not been started yet.");
                    return;
                }

                break;

            case ChangeType.Deletion:
                if ([email protected])
                {
                    _log.WriteInfo(nameof(ProductChangedProjection),
                                   nameof(Handle),
                                   $"ProductChangedEvent received for productId: {@event.OldValue.ProductId}, but it was ignored because it has not been started yet.");
                    return;
                }

                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (@event.ChangeType == ChangeType.Deletion)
            {
                CloseAllOrders();

                ValidatePositions(@event.OldValue.ProductId);

                _assetPairsCache.Remove(@event.OldValue.ProductId);
            }
            else
            {
                if (@event.NewValue.IsDiscontinued)
                {
                    CloseAllOrders();
                    RemoveQuoteFromCache();
                }

                await _tradingInstrumentsManager.UpdateTradingInstrumentsCacheAsync();

                var isAdded = _assetPairsCache.AddOrUpdate(AssetPair.CreateFromProduct(@event.NewValue,
                                                                                       _mtSettings.DefaultLegalEntitySettings.DefaultLegalEntity));

                if (@event.NewValue.TradingCurrency != AssetPairConstants.BaseCurrencyId)
                {
                    _assetPairsCache.AddOrUpdate(AssetPair.CreateFromCurrency(@event.NewValue.TradingCurrency,
                                                                              _mtSettings.DefaultLegalEntitySettings.DefaultLegalEntity));
                }

                //only for product
                if (isAdded)
                {
                    await _scheduleSettingsCacheService.UpdateScheduleSettingsAsync();
                }

                if (@event.ChangeType == ChangeType.Edition &&
                    @event.OldValue.IsTradingDisabled != @event.NewValue.IsTradingDisabled)
                {
                    await HandleTradingDisabled(@event.NewValue, @event.Username);
                }
            }

            void RemoveQuoteFromCache()
            {
                var result = _quoteCache.RemoveQuote(@event.OldValue.ProductId);

                if (result != RemoveQuoteErrorCode.None)
                {
                    _log.WriteWarning(nameof(ProductChangedProjection), nameof(RemoveQuoteFromCache), result.Message);
                }
            }

            void CloseAllOrders()
            {
                try
                {
                    foreach (var order in _orderReader.GetPending()
                             .Where(x => x.AssetPairId == @event.OldValue.ProductId))
                    {
                        _tradingEngine.CancelPendingOrder(order.Id, null,
                                                          null, OrderCancellationReason.InstrumentInvalidated);
                    }
                }
                catch (Exception exception)
                {
                    _log.WriteError(nameof(ProductChangedProjection), nameof(CloseAllOrders), exception);
                    throw;
                }
            }

            void ValidatePositions(string assetPairId)
            {
                var positions = _orderReader.GetPositions(assetPairId);

                if (positions.Any())
                {
                    _log.WriteFatalError(nameof(ProductChangedProjection), nameof(ValidatePositions),
                                         new Exception(
                                             $"{positions.Length} positions are opened for [{assetPairId}], first: [{positions.First().Id}]."));
                }
            }
        }