Example #1
0
        private async Task Handle(SpecialLiquidationFailedEvent e, ICommandSender sender)
        {
            var executionInfo = await _operationExecutionInfoRepository.GetAsync <SpecialLiquidationOperationData>(
                operationName : OperationName,
                id : e.OperationId);

            if (executionInfo?.Data == null)
            {
                return;
            }

            if (executionInfo.Data.SwitchState(executionInfo.Data.State,//from any state
                                               SpecialLiquidationOperationState.Failed))
            {
                if (!string.IsNullOrEmpty(executionInfo.Data.CausationOperationId))
                {
                    sender.SendCommand(new ResumeLiquidationInternalCommand
                    {
                        OperationId  = executionInfo.Data.CausationOperationId,
                        CreationTime = _dateService.Now(),
                        Comment      = $"Resume after special liquidation {executionInfo.Id} failed. Reason: {e.Reason}",
                        IsCausedBySpecialLiquidation = true,
                        CausationOperationId         = executionInfo.Id
                    }, _cqrsContextNamesSettings.TradingEngine);
                }

                _chaosKitty.Meow(e.OperationId);

                await _operationExecutionInfoRepository.Save(executionInfo);
            }
        }
Example #2
0
        private async Task Handle(SpecialLiquidationFailedEvent e, ICommandSender sender)
        {
            var executionInfo = await _operationExecutionInfoRepository.GetAsync <SpecialLiquidationOperationData>(
                operationName : OperationName,
                id : e.OperationId);

            if (executionInfo?.Data == null)
            {
                return;
            }

            if (e.CanRetryPriceRequest)
            {
                if (!executionInfo.Data.RequestedFromCorporateActions)
                {
                    var positions = _ordersCache.Positions
                                    .GetPositionsByAccountIds(executionInfo.Data.AccountId)
                                    .Where(p => executionInfo.Data.PositionIds.Contains(p.Id))
                                    .ToArray();

                    if (_liquidationHelper.CheckIfNetVolumeCanBeLiquidated(executionInfo.Data.Instrument, positions, out _))
                    {
                        // there is liquidity so we can cancel the special liquidation flow.
                        sender.SendCommand(new CancelSpecialLiquidationCommand
                        {
                            OperationId = e.OperationId,
                            Reason      = "Liquidity is enough to close positions within regular flow"
                        }, _cqrsContextNamesSettings.TradingEngine);
                        return;
                    }
                }

                if (PriceRequestRetryRequired(executionInfo.Data.RequestedFromCorporateActions))
                {
                    var pauseAcknowledged = await _rfqPauseService.AcknowledgeAsync(executionInfo.Id);

                    if (pauseAcknowledged)
                    {
                        return;
                    }

                    if (executionInfo.Data.SwitchState(executionInfo.Data.State,
                                                       SpecialLiquidationOperationState.PriceRequested))
                    {
                        await InternalRetryPriceRequest(e.CreationTime, sender, executionInfo,
                                                        _marginTradingSettings.SpecialLiquidation.PriceRequestRetryTimeout.Value);

                        return;
                    }
                }
            }

            if (executionInfo.Data.SwitchState(executionInfo.Data.State,//from any state
                                               SpecialLiquidationOperationState.Failed))
            {
                if (!string.IsNullOrEmpty(executionInfo.Data.CausationOperationId))
                {
                    sender.SendCommand(new ResumeLiquidationInternalCommand
                    {
                        OperationId  = executionInfo.Data.CausationOperationId,
                        CreationTime = _dateService.Now(),
                        Comment      = $"Resume after special liquidation {executionInfo.Id} failed. Reason: {e.Reason}",
                        IsCausedBySpecialLiquidation = true,
                        CausationOperationId         = executionInfo.Id
                    }, _cqrsContextNamesSettings.TradingEngine);
                }

                _chaosKitty.Meow(e.OperationId);

                await _operationExecutionInfoRepository.Save(executionInfo);
            }
        }