public async Task <CommandHandlingResult> Handle(ProcessLimitOrderCommand command, IEventPublisher eventPublisher) { var clientId = command.LimitOrder.Order.ClientId; if (!_trusted.ContainsKey(clientId)) { _trusted[clientId] = (await _clientAccountClient.IsTrustedAsync(clientId)).Value; } var isTrustedClient = _trusted[clientId]; var limitOrderExecutedEvent = new LimitOrderExecutedEvent { IsTrustedClient = isTrustedClient, LimitOrder = command.LimitOrder }; var tradesWerePerformed = command.LimitOrder.Trades != null && command.LimitOrder.Trades.Any(); if (!isTrustedClient) { // need previous order state for not trusted clients var prevOrderState = await _limitOrdersRepository.GetOrderAsync(command.LimitOrder.Order.ClientId, command.LimitOrder.Order.Id); var isImmediateTrade = tradesWerePerformed && command.LimitOrder.Trades.First().Timestamp == command.LimitOrder.Order.Registered; limitOrderExecutedEvent.HasPrevOrderState = prevOrderState != null && !isImmediateTrade; limitOrderExecutedEvent.PrevRemainingVolume = prevOrderState?.RemainingVolume; limitOrderExecutedEvent.Aggregated = AggregateSwaps(limitOrderExecutedEvent.LimitOrder.Trades); } await _limitOrdersRepository.CreateOrUpdateAsync(command.LimitOrder.Order); var status = (OrderStatus)Enum.Parse(typeof(OrderStatus), command.LimitOrder.Order.Status); // workaround: ME sends wrong status if (status == OrderStatus.Processing && !tradesWerePerformed) { status = OrderStatus.InOrderBook; } else if (status == OrderStatus.PartiallyMatched && !tradesWerePerformed) { status = OrderStatus.Placed; } if (status == OrderStatus.Processing || status == OrderStatus.PartiallyMatched || // new version of Processing status == OrderStatus.Matched || status == OrderStatus.Cancelled) { limitOrderExecutedEvent.Trades = await CreateTrades(command.LimitOrder); } eventPublisher.PublishEvent(limitOrderExecutedEvent); return(CommandHandlingResult.Ok()); }
public async Task <CommandHandlingResult> Handle(ProcessLimitOrderCommand command, IEventPublisher eventPublisher) { var sw = new Stopwatch(); sw.Start(); var stepWatch = new Stopwatch(); stepWatch.Start(); try { var clientId = command.LimitOrder.Order.ClientId; if (!_trusted.ContainsKey(clientId)) { _trusted[clientId] = (await _clientAccountClient.IsTrustedAsync(clientId)).Value; } _log.Info("LimitOrderProcessing", new { TxHandler = new { Step = "01. Check client account is trusted", Time = stepWatch.ElapsedMilliseconds } }); stepWatch.Restart(); var isTrustedClient = _trusted[clientId]; var limitOrderExecutedEvent = new LimitOrderExecutedEvent { IsTrustedClient = isTrustedClient, LimitOrder = command.LimitOrder }; var tradesWerePerformed = command.LimitOrder.Trades != null && command.LimitOrder.Trades.Any(); if (!isTrustedClient) { // need previous order state for not trusted clients var prevOrderState = await _limitOrdersRepository.GetOrderAsync(command.LimitOrder.Order.ClientId, command.LimitOrder.Order.Id); var isImmediateTrade = tradesWerePerformed && command.LimitOrder.Trades.First().Timestamp == command.LimitOrder.Order.Registered; limitOrderExecutedEvent.HasPrevOrderState = prevOrderState != null && !isImmediateTrade; limitOrderExecutedEvent.PrevRemainingVolume = prevOrderState?.RemainingVolume; limitOrderExecutedEvent.Aggregated = AggregateSwaps(limitOrderExecutedEvent.LimitOrder.Trades); _log.Info("LimitOrderProcessing", new { TxHandler = new { Step = "02. Get Previous order state for not trusted client", Time = stepWatch.ElapsedMilliseconds } }); stepWatch.Restart(); } if (!isTrustedClient) { await _limitOrdersRepository.CreateOrUpdateAsync(command.LimitOrder.Order); _log.Info("LimitOrderProcessing", new { TxHandler = new { Step = "03. Upsert limit order for not trusted client", Time = stepWatch.ElapsedMilliseconds } }); stepWatch.Restart(); } var status = (OrderStatus)Enum.Parse(typeof(OrderStatus), command.LimitOrder.Order.Status); // workaround: ME sends wrong status if (status == OrderStatus.Processing && !tradesWerePerformed) { status = OrderStatus.InOrderBook; } else if (status == OrderStatus.PartiallyMatched && !tradesWerePerformed) { status = OrderStatus.Placed; } if (status == OrderStatus.Processing || status == OrderStatus.PartiallyMatched || // new version of Processing status == OrderStatus.Matched || status == OrderStatus.Cancelled) { limitOrderExecutedEvent.Trades = await CreateTrades(command.LimitOrder); } _log.Info("LimitOrderProcessing", new { TxHandler = new { Step = "04. Create trades", Time = stepWatch.ElapsedMilliseconds } }); stepWatch.Restart(); eventPublisher.PublishEvent(limitOrderExecutedEvent); return(CommandHandlingResult.Ok()); } finally { sw.Stop(); _log.Info("Command execution time", context: new { TxHandler = new { Handler = nameof(LimitOrderCommandHandler), Command = nameof(ProcessLimitOrderCommand), Time = sw.ElapsedMilliseconds } }); } }