Exemplo n.º 1
0
        /// <summary>
        /// Parse from a fill type order, locks the assets.
        /// </summary>
        /// <param name="order">OrderUpdate.</param>
        private static TradeExecution FromFillOrder(OrderUpdate order)
        {
            // Some market orders are declared filled right away, redirect their parsing
            if (order.OrderType == Market)
            {
                return(FromNewMarketOrder(order));
            }

            var from = order.Side == OrderSide.Buy ? order.Pair.Right : order.Pair.Left;
            var to   = order.Side == OrderSide.Buy ? order.Pair.Left : order.Pair.Right;

            var commission = GetConvertedCommission(order, to);

            if (order.Side == OrderSide.Buy)
            {
                return(new TradeExecution(
                           new Balance(from, 0.0M, order.LastFillIncrement * order.SetPrice),
                           new Balance(to, order.LastFillIncrement - commission, 0.0M)));
            }
            else
            {
                return(new TradeExecution(
                           new Balance(from, 0, order.LastFillIncrement),
                           new Balance(to, (order.LastFillIncrement * order.LastFillPrice) - commission, 0)));
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Parse from a new, non-market order.
        /// </summary>
        /// <param name="order">OrderUpdate.</param>
        private static TradeExecution FromNewNonMarketOrder(OrderUpdate order)
        {
            var currency = order.Side == OrderSide.Buy ? order.Pair.Right : order.Pair.Left;
            var quantity = order.SetQuantity - order.FilledQuantity;

            quantity = order.Side == OrderSide.Buy ? quantity * order.SetPrice : quantity;

            // For market orders, fees are incorporated in the quantity.
            var free   = new Balance(currency, quantity, 0M);
            var locked = new Balance(currency, 0M, quantity);

            return(new TradeExecution(free, locked));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Parse from cancelled orders, frees the assets.
        /// </summary>
        /// <param name="order">OrderUpdate.</param>
        private static TradeExecution FromCancelledOrder(OrderUpdate order)
        {
            Guard.Argument(order.OrderType).Require(
                x => x != Market,
                x => $"{x} orders cannot be cancelled");

            var currency = order.Side == OrderSide.Buy ? order.Pair.Right : order.Pair.Left;
            var quantity = order.SetQuantity - order.FilledQuantity;

            quantity = order.Side == OrderSide.Buy ? quantity * order.SetPrice : quantity;
            var free   = new Balance(currency, quantity, 0M);
            var locked = new Balance(currency, 0M, quantity);

            return(new TradeExecution(locked, free));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Parse from a new, market order.
        /// This method assumes the order is filled by definition.
        /// </summary>
        /// <param name="order">OrderUpdate.</param>
        private static TradeExecution FromNewMarketOrder(OrderUpdate order)
        {
            var currencyFrom = order.Side == OrderSide.Buy ? order.Pair.Right : order.Pair.Left;
            var currencyTo   = order.Side == OrderSide.Buy ? order.Pair.Left : order.Pair.Right;
            var quantityFrom = order.FilledQuantity * (order.Side == OrderSide.Buy ? order.AverageFilledPrice : 1M);
            var quantityTo   = order.FilledQuantity * (order.Side == OrderSide.Sell ? order.AverageFilledPrice : 1M);

            decimal commission = GetConvertedCommission(order, currencyTo);

            // Only subtract commission for buy orders
            var from = new Balance(currencyFrom, quantityFrom, 0M);
            var to   = new Balance(currencyTo, quantityTo - commission, 0M);

            return(new TradeExecution(from, to));
        }
Exemplo n.º 5
0
        private static decimal GetConvertedCommission(OrderUpdate order, Currency to)
        {
            var commission = order.Commission;
            var asset      = order.CommissionAsset;

            return
                (asset is null
                    ? 0M                                  // There is no commission asset at all
                    : asset != order.Pair.Right && asset != order.Pair.Left
                        ? 0M                              // Fee is paid in neither currency (e.g. bnb for fees)
                        : asset == to
                            ? commission                  // Commission is already in the correct currency.
                            : order.Side == OrderSide.Buy // Correct commission to other asset
                                ? HelperMethods.SafeDiv(commission, order.AverageFilledPrice)
                                : commission * order.AverageFilledPrice);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Parse a trade execution from a <see cref="OrderUpdate"/>.
        /// </summary>
        /// <param name="order">OrderUpdate to derive an execution from.</param>
        /// <returns>TradeExecution order derived from the provided OrderUpdate.</returns>
        public static TradeExecution FromOrder(OrderUpdate order)
        {
            switch (order.Status)
            {
            case OrderUpdate.OrderStatus.New:
                return(FromNewOrder(order));

            case OrderUpdate.OrderStatus.PartiallyFilled:
            case OrderUpdate.OrderStatus.Filled:
                return(FromFillOrder(order));

            case OrderUpdate.OrderStatus.Cancelled:
                return(FromCancelledOrder(order));

            default:
                throw new ArgumentOutOfRangeException(nameof(order), $"{order.Status} cannot be parsed to a TradeExection");
            }
        }
Exemplo n.º 7
0
 /// <summary>
 /// Parse from a new order, redirects either to <see cref="FromNewMarketOrder"/>  or <see cref="FromNewNonMarketOrder"/>.
 /// </summary>
 /// <param name="order">OrderUpdate.</param>
 /// <returns>Parsed trade execution.</returns>
 private static TradeExecution FromNewOrder(OrderUpdate order) =>
 order.OrderType == Market
         ? FromNewMarketOrder(order)
         : FromNewNonMarketOrder(order);