public MtBackendResponse <bool> ChangeOrderLimits([FromBody] ChangeOrderLimitsBackendRequest request) { var order = _ordersCache.GetOrderById(request.OrderId); if (_assetDayOffService.IsDayOff(order.Instrument)) { return(new MtBackendResponse <bool> { Message = "Trades for instrument are not available" }); } try { _tradingEngine.ChangeOrderLimits(request.OrderId, request.StopLoss, request.TakeProfit, request.ExpectedOpenPrice); } catch (ValidateOrderException ex) { return(new MtBackendResponse <bool> { Result = false, Message = ex.Message }); } var result = new MtBackendResponse <bool> { Result = true }; _consoleWriter.WriteLine($"action order.changeLimits for clientId = {request.ClientId}, orderId = {request.OrderId}"); _operationsLogService.AddLog("action order.changeLimits", request.ClientId, order.AccountId, request.ToJson(), result.ToJson()); return(result); }
public async Task UpdateRelatedOrderAsync(string positionId, [FromBody] UpdateRelatedOrderRequest request) { if (!_ordersCache.Positions.TryGetPositionById(positionId, out var position)) { throw new InvalidOperationException($"Position {positionId} not found"); } ValidationHelper.ValidateAccountId(position, request.AccountId); var takeProfit = position.RelatedOrders?.FirstOrDefault(x => x.Type == OrderType.TakeProfit); var stopLoss = position.RelatedOrders?.FirstOrDefault(x => x.Type == OrderType.StopLoss || x.Type == OrderType.TrailingStop); var relatedOrderShouldBeRemoved = request.NewPrice == default; var relatedOrderId = request.OrderType == RelatedOrderTypeContract.TakeProfit ? takeProfit?.Id : stopLoss?.Id; var relatedOrderExists = !string.IsNullOrWhiteSpace(relatedOrderId); if (!relatedOrderShouldBeRemoved) { if (request.OrderType == RelatedOrderTypeContract.StopLoss && relatedOrderExists) { var order = _ordersCache.GetOrderById(relatedOrderId); if ((order.OrderType == OrderType.TrailingStop) != request.HasTrailingStop) { await CancelAsync(relatedOrderId, new OrderCancelRequest { Originator = request.Originator, AdditionalInfo = request.AdditionalInfoJson }, request.AccountId); relatedOrderExists = false; } } if (!relatedOrderExists) { var orderPlaceRequest = new OrderPlaceRequest { AccountId = request.AccountId, InstrumentId = position.AssetPairId, Direction = position.Direction == PositionDirection.Long ? OrderDirectionContract.Buy : OrderDirectionContract.Sell, Price = request.NewPrice, Volume = position.Volume, Type = request.OrderType == RelatedOrderTypeContract.TakeProfit ? OrderTypeContract.TakeProfit : OrderTypeContract.StopLoss, Originator = request.Originator, ForceOpen = false, PositionId = position.Id, AdditionalInfo = request.AdditionalInfoJson, UseTrailingStop = request.HasTrailingStop ?? false }; if (orderPlaceRequest.UseTrailingStop && orderPlaceRequest.Type == OrderTypeContract.StopLoss && (!string.IsNullOrWhiteSpace(orderPlaceRequest.ParentOrderId) || !string.IsNullOrWhiteSpace(orderPlaceRequest.PositionId))) { orderPlaceRequest.Type = OrderTypeContract.TrailingStop; orderPlaceRequest.UseTrailingStop = false; } await PlaceAsync(orderPlaceRequest); } else { await ChangeAsync(relatedOrderId, new OrderChangeRequest { Price = request.NewPrice, Originator = request.Originator, AdditionalInfo = request.AdditionalInfoJson, AccountId = request.AccountId, }); } } else if (relatedOrderExists) { await CancelAsync(relatedOrderId, new OrderCancelRequest { Originator = request.Originator, AdditionalInfo = request.AdditionalInfoJson }, request.AccountId); } else { throw new Exception($"Couldn't update related order for position {positionId}"); } }