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); }
public void Is_Order_ExpectedOpenPrice_Validated_Correctly(OrderDirectionContract direction, OrderTypeContract orderType, decimal?price, bool isValid) { const string instrument = "EURUSD"; var quote = new InstrumentBidAskPair { Instrument = instrument, Bid = 1.55M, Ask = 1.57M }; _bestPriceConsumer.SendEvent(this, new BestPriceChangeEventArgs(quote)); var request = new OrderPlaceRequest { AccountId = Accounts[0].Id, CorrelationId = Guid.NewGuid().ToString(), Direction = direction, InstrumentId = instrument, Type = orderType, Price = price, Volume = 1 }; if (isValid) { Assert.DoesNotThrowAsync(async() => await _validateOrderService.ValidateRequestAndCreateOrders(request)); } else { var ex = Assert.ThrowsAsync <ValidateOrderException>(() => _validateOrderService.ValidateRequestAndCreateOrders(request)); Assert.That(ex.RejectReason == OrderRejectReason.InvalidExpectedOpenPrice); StringAssert.Contains($"{quote.Bid}/{quote.Ask}", ex.Comment); } }