Esempio n. 1
0
        private void ValidateRelatedOrderPriceAgainstBase(Order relatedOrder, Order baseOrder = null, decimal?newPrice = null)
        {
            if (newPrice == null)
            {
                newPrice = relatedOrder.Price;
            }

            decimal basePrice;

            if ((baseOrder != null ||
                 string.IsNullOrEmpty(relatedOrder.ParentPositionId) &&
                 !string.IsNullOrEmpty(relatedOrder.ParentOrderId) &&
                 _ordersCache.TryGetOrderById(relatedOrder.ParentOrderId, out baseOrder)) &&
                baseOrder.Price.HasValue)
            {
                basePrice = baseOrder.Price.Value;
            }
            else
            {
                if (!_quoteCashService.TryGetQuoteById(relatedOrder.AssetPairId, out var quote))
                {
                    throw new ValidateOrderException(OrderRejectReason.NoLiquidity, "Quote not found");
                }

                basePrice = quote.GetPriceForOrderDirection(relatedOrder.Direction);
            }

            switch (relatedOrder.OrderType)
            {
            case OrderType.StopLoss:
            case OrderType.TrailingStop:
                ValidateStopLossOrderPrice(relatedOrder.Direction, newPrice, basePrice);
                break;

            case OrderType.TakeProfit:
                ValidateTakeProfitOrderPrice(relatedOrder.Direction, newPrice, basePrice);
                break;
            }
        }
Esempio n. 2
0
        private async Task PlacePendingOrder(Order order)
        {
            if (order.IsBasicPendingOrder() || !string.IsNullOrEmpty(order.ParentPositionId))
            {
                Position parentPosition = null;

                if (!string.IsNullOrEmpty(order.ParentPositionId))
                {
                    parentPosition = _ordersCache.Positions.GetPositionById(order.ParentPositionId);
                    parentPosition.AddRelatedOrder(order);
                }

                order.Activate(_dateService.Now(), false, parentPosition?.ClosePrice);
                _ordersCache.Active.Add(order);
                _orderActivatedEventChannel.SendEvent(this, new OrderActivatedEventArgs(order));
            }
            else if (!string.IsNullOrEmpty(order.ParentOrderId))
            {
                if (_ordersCache.TryGetOrderById(order.ParentOrderId, out var parentOrder))
                {
                    parentOrder.AddRelatedOrder(order);
                    order.MakeInactive(_dateService.Now());
                    _ordersCache.Inactive.Add(order);
                    return;
                }

                //may be it was market and now it is position
                if (_ordersCache.Positions.TryGetPositionById(order.ParentOrderId, out var parentPosition))
                {
                    parentPosition.AddRelatedOrder(order);
                    if (parentPosition.Volume != -order.Volume)
                    {
                        order.ChangeVolume(-parentPosition.Volume, _dateService.Now(), OriginatorType.System);
                    }

                    order.Activate(_dateService.Now(), true, parentPosition.ClosePrice);
                    _ordersCache.Active.Add(order);
                    _orderActivatedEventChannel.SendEvent(this, new OrderActivatedEventArgs(order));
                }
                else
                {
                    order.MakeInactive(_dateService.Now());
                    _ordersCache.Inactive.Add(order);
                    CancelPendingOrder(order.Id, order.AdditionalInfo,
                                       _identityGenerator.GenerateAlphanumericId(),
                                       $"Parent order closed the position, so {order.OrderType.ToString()} order is cancelled");
                }
            }
            else
            {
                throw new ValidateOrderException(OrderRejectReason.InvalidParent, "Order parent is not valid");
            }

            if (order.Status == OrderStatus.Active &&
                _quoteCacheService.TryGetQuoteById(order.AssetPairId, out var pair))
            {
                var price = pair.GetPriceForOrderDirection(order.Direction);

                if (!_assetPairDayOffService.IsDayOff(order.AssetPairId) && //!_assetPairDayOffService.ArePendingOrdersDisabled(order.AssetPairId))
                    order.IsSuitablePriceForPendingOrder(price))
                {
                    _ordersCache.Active.Remove(order);
                    await PlaceOrderByMarketPrice(order);
                }
            }
        }