public Order CancelPendingOrder(string orderId, string additionalInfo, string correlationId, string comment = null, OrderCancellationReason reason = OrderCancellationReason.None) { var order = _ordersCache.GetOrderById(orderId); if (order.Status == OrderStatus.Inactive) { _ordersCache.Inactive.Remove(order); } else if (order.Status == OrderStatus.Active) { _ordersCache.Active.Remove(order); } else { throw new InvalidOperationException($"Order in state {order.Status} can not be cancelled"); } order.Cancel(_dateService.Now(), additionalInfo, correlationId); var metadata = new OrderCancelledMetadata { Reason = reason.ToType <OrderCancellationReasonContract>() }; _orderCancelledEventChannel.SendEvent(this, new OrderCancelledEventArgs(order, metadata)); return(order); }
public void ChangeOrderLimits(string orderId, decimal?stopLoss, decimal?takeProfit, decimal?expectedOpenPrice) { using (_contextFactory.GetWriteSyncContext($"{nameof(TradingEngine)}.{nameof(ChangeOrderLimits)}")) { var order = _ordersCache.GetOrderById(orderId); if (order.Status != OrderStatus.WaitingForExecution && expectedOpenPrice > 0) { return; } var quote = _quoteCashService.GetQuote(order.Instrument); var tp = takeProfit == 0 ? null : takeProfit; var sl = stopLoss == 0 ? null : stopLoss; var expOpenPrice = expectedOpenPrice == 0 ? null : expectedOpenPrice; var accountAsset = _accountAssetsCacheService.GetAccountAsset(order.TradingConditionId, order.AccountAssetId, order.Instrument); _validateOrderService.ValidateOrderStops(order.GetOrderType(), quote, accountAsset.DeltaBid, accountAsset.DeltaAsk, tp, sl, expOpenPrice, order.AssetAccuracy); order.TakeProfit = tp.HasValue ? Math.Round(tp.Value, order.AssetAccuracy) : (decimal?)null; order.StopLoss = sl.HasValue ? Math.Round(sl.Value, order.AssetAccuracy) : (decimal?)null; order.ExpectedOpenPrice = expOpenPrice.HasValue ? Math.Round(expOpenPrice.Value, order.AssetAccuracy) : (decimal?)null; _orderLimitsChangesEventChannel.SendEvent(this, new OrderLimitsChangedEventArgs(order)); } }
private async Task <Order> ValidateAndGetSlOrTpOrder(OrderPlaceRequest request, OrderTypeContract type, decimal?price, ReportingEquivalentPricesSettings equivalentSettings, Order parentOrder) { var orderType = type.ToType <OrderType>(); Order order = null; var placedAltogether = parentOrder != null; if (parentOrder == null) { if (!string.IsNullOrEmpty(request.ParentOrderId)) { parentOrder = _ordersCache.GetOrderById(request.ParentOrderId); } } if (parentOrder != null) { ValidateRelatedOrderAlreadyExists(parentOrder.RelatedOrders, orderType); var initialParameters = await GetOrderInitialParameters(parentOrder.AssetPairId, parentOrder.LegalEntity, equivalentSettings, parentOrder.AccountAssetId); var originator = GetOriginator(request.Originator); order = new Order(initialParameters.Id, initialParameters.Code, parentOrder.AssetPairId, -parentOrder.Volume, initialParameters.Now, initialParameters.Now, placedAltogether ? null : request.Validity, parentOrder.AccountId, parentOrder.TradingConditionId, parentOrder.AccountAssetId, price, parentOrder.EquivalentAsset, OrderFillType.FillOrKill, string.Empty, parentOrder.LegalEntity, false, orderType, parentOrder.Id, null, originator, initialParameters.EquivalentPrice, initialParameters.FxPrice, initialParameters.FxAssetPairId, initialParameters.FxToAssetPairDirection, OrderStatus.Placed, request.AdditionalInfo); } else if (!string.IsNullOrEmpty(request.PositionId)) { var position = _ordersCache.Positions.GetPositionById(request.PositionId); ValidateRelatedOrderAlreadyExists(position.RelatedOrders, orderType); var initialParameters = await GetOrderInitialParameters(position.AssetPairId, position.LegalEntity, equivalentSettings, position.AccountAssetId); var originator = GetOriginator(request.Originator); order = new Order(initialParameters.Id, initialParameters.Code, position.AssetPairId, -position.Volume, initialParameters.Now, initialParameters.Now, request.Validity, position.AccountId, position.TradingConditionId, position.AccountAssetId, price, position.EquivalentAsset, OrderFillType.FillOrKill, string.Empty, position.LegalEntity, false, orderType, null, position.Id, originator, initialParameters.EquivalentPrice, initialParameters.FxPrice, initialParameters.FxAssetPairId, initialParameters.FxToAssetPairDirection, OrderStatus.Placed, request.AdditionalInfo); } if (order == null) { throw new ValidateOrderException(OrderRejectReason.InvalidParent, "Related order must have parent order or position"); } ValidateRelatedOrderPriceAgainstBase(order, parentOrder, order.Price); return(order); }