Ejemplo n.º 1
0
        /// <summary>
        /// Place a buy market order given a non base quantity.
        /// </summary>
        /// <param name="pair">TradingPair to consider.</param>
        /// <param name="quantity">Quantity of non base currency.</param>
        /// <returns>ResponseObject containing an OrderUpdate.</returns>
        public OrderUpdate ExecuteMarketOrderBuy(TradingPair pair, decimal quantity)
        {
            _logger.LogDebug($"Executing buy market order with pair {pair}, quantity {quantity}");
            Guard.Argument(pair).NotNull(nameof(pair));
            Guard.Argument(quantity).NotZero(nameof(quantity)).NotNegative();
            var currency      = pair.Right;
            var priceEstimate = _dataProvider.GetCurrentPriceTopAsk(pair);
            var proposal      = new TradeProposal(pair, new Balance(currency, quantity * priceEstimate, 0));

            var result = _allocationManager.QueueTrade(proposal, () =>
            {
                var orderQuery = HelperMethods.RetryMethod(
                    () =>
                {
                    var attempt = Implementation.ExecuteMarketOrder(pair, OrderSide.Buy, quantity, TradeId);
                    if (attempt.Success)
                    {
                        return(attempt);
                    }

                    _logger.LogInformation($"Retrying with slightly lower quantity");
                    quantity *= 0.999M;
                    return(new ResponseObject <OrderUpdate>(ResponseCode.Error, attempt.Message));
                }, _logger);

                if (orderQuery.Success)
                {
                    _openOrders.Add(orderQuery.Data.OrderId, orderQuery.Data);
                    return(WaitForOrderStatus(orderQuery.Data.OrderId, OrderUpdate.OrderStatus.Filled));
                }

                throw new OrderFailedException(orderQuery.Message);
            });

            if (!result.Success)
            {
                throw new OrderRefusedException(result.Message);
            }

            if (Program.CommandLineArgs.Trading)
            {
                _logger.LogInformation($"Executed Market Buy: {JsonConvert.SerializeObject(result)}");
            }

            return(result.Data
                   .IsBuy()
                   .IsMarket()
                   .IsFilled());
        }