public static void ValidateAccountId(PositionsCloseData positionData, string accountId) { if (string.IsNullOrEmpty(accountId)) { // TODO: Ensures backwards compatibility with Donut. Remove when Donut is updated return; } if (positionData.AccountId != accountId) { throw new InvalidOperationException( $"Position group {positionData.AssetPairId} was created by {positionData.AccountId}, but is being modified by {accountId}"); } }
public async Task <Order> ClosePositionsAsync(PositionsCloseData closeData) { var me = closeData.MatchingEngine ?? _meRouter.GetMatchingEngineForClose(closeData.OpenMatchingEngineId); var initialParameters = await _validateOrderService.GetOrderInitialParameters(closeData.AssetPairId, closeData.AccountId); var account = _accountsCacheService.Get(closeData.AccountId); var positionIds = closeData.Positions.Select(p => p.Id).ToList(); var order = new Order(initialParameters.Id, initialParameters.Code, closeData.AssetPairId, -closeData.Volume, initialParameters.Now, initialParameters.Now, null, account.Id, account.TradingConditionId, account.BaseAssetId, null, closeData.EquivalentAsset, OrderFillType.FillOrKill, $"Close positions: {string.Join(",", positionIds)}. {closeData.Comment}", account.LegalEntity, false, OrderType.Market, null, null, closeData.Originator, initialParameters.EquivalentPrice, initialParameters.FxPrice, initialParameters.FxAssetPairId, initialParameters.FxToAssetPairDirection, OrderStatus.Placed, closeData.AdditionalInfo, closeData.CorrelationId, positionIds, closeData.ExternalProviderId); _orderPlacedEventChannel.SendEvent(this, new OrderPlacedEventArgs(order)); order = await ExecuteOrderByMatchingEngineAsync(order, me, true, closeData.Modality); if (order.Status != OrderStatus.Executed && order.Status != OrderStatus.ExecutionStarted) { foreach (var position in closeData.Positions) { if (position.Status == PositionStatus.Closing) { position.CancelClosing(_dateService.Now()); } } _log.WriteWarning(nameof(ClosePositionsAsync), order, $"Order {order.Id} was not executed. Closing of positions canceled"); } return(order); }