Example #1
0
        public IOrderDetails PlaceSellOrder(SellOptions options)
        {
            OrderDetails orderDetails = new OrderDetails();

            tradingService.StopTrailingSell(options.Pair);
            tradingService.StopTrailingBuy(options.Pair);

            try
            {
                string       normalizedPair = tradingService.NormalizePair(options.Pair);
                ITradingPair tradingPair    = tradingService.Account.GetTradingPair(normalizedPair, includeDust: true);
                options.Price  = tradingService.GetPrice(options.Pair, TradePriceType.Bid);
                options.Amount = options.Amount ?? tradingPair?.Amount ?? 0;
                options.Price  = options.Price != 1 ? tradingService.Exchange.ClampOrderPrice(options.Pair, options.Price.Value) : 1; // 1 = USDT price
                options.Amount = tradingService.Exchange.ClampOrderAmount(options.Pair, options.Amount.Value);

                if (tradingService.CanSell(options, out string message))
                {
                    IPairConfig pairConfig = tradingService.GetPairConfig(normalizedPair);
                    SellOrder   sellOrder  = new SellOrder
                    {
                        Type   = pairConfig.SellType,
                        Date   = DateTimeOffset.Now,
                        Pair   = options.Pair,
                        Price  = options.Price.Value,
                        Amount = options.Amount.Value
                    };

                    lock (tradingService.Account.SyncRoot)
                    {
                        tradingPair.SetCurrentValues(tradingService.GetPrice(normalizedPair), tradingService.Exchange.GetPriceSpread(normalizedPair));
                        string sellPairName = normalizedPair != options.Pair ? options.Pair : tradingPair.FormattedName;
                        loggingService.Info($"Place sell order for {sellPairName}. " +
                                            $"Price: {sellOrder.Price:0.00000000}, Amount: {sellOrder.Amount:0.########}, Margin: {tradingPair.CurrentMargin:0.00}");

                        if (!tradingService.Config.VirtualTrading)
                        {
                            orderDetails = tradingService.Exchange.PlaceOrder(sellOrder) as OrderDetails;
                        }
                        else
                        {
                            string pairMarket = tradingService.Exchange.GetPairMarket(options.Pair);
                            orderDetails = new OrderDetails
                            {
                                OrderId      = DateTime.Now.ToFileTimeUtc().ToString(),
                                Side         = OrderSide.Sell,
                                Result       = OrderResult.Filled,
                                Date         = sellOrder.Date,
                                Pair         = sellOrder.Pair,
                                Amount       = sellOrder.Amount,
                                AmountFilled = sellOrder.Amount,
                                Price        = sellOrder.Price,
                                AveragePrice = sellOrder.Price,
                                Fees         = sellOrder.Amount * sellOrder.Price * tradingService.Config.VirtualTradingFees,
                                FeesCurrency = pairMarket
                            };
                        }

                        NormalizeOrder(orderDetails, TradePriceType.Bid);
                        tradingPair.SetMetadata(tradingPair.Metadata.MergeWith(options.Metadata));
                        orderDetails.Metadata = tradingPair.Metadata;
                        var tradeResult = tradingService.Account.AddSellOrder(orderDetails) as TradeResult;
                        tradeResult.IsSwap      = options.Swap;
                        tradeResult.IsArbitrage = options.Arbitrage;
                        tradingService.Account.Save();
                        tradingService.LogOrder(orderDetails);

                        decimal fees      = tradingService.CalculateOrderFees(orderDetails);
                        decimal margin    = (tradeResult.Profit / (tradeResult.Cost + (tradeResult.Metadata.AdditionalCosts ?? 0)) * 100);
                        string  swapPair  = options.Metadata.SwapPair != null ? $", Swap Pair: {options.Metadata.SwapPair}" : "";
                        string  arbitrage = options.Metadata.Arbitrage != null ? $", Arbitrage: {options.Metadata.Arbitrage} ({options.Metadata.ArbitragePercentage:0.00})" : "";
                        loggingService.Info("{@Trade}", orderDetails);
                        loggingService.Info("{@Trade}", tradeResult);
                        loggingService.Info($"Sell order result for {orderDetails.OriginalPair ?? tradingPair.FormattedName}: {orderDetails.Result} ({orderDetails.Message}). " +
                                            $"Price: {orderDetails.AveragePrice:0.00000000}, Amount: {orderDetails.Amount:0.########}, Filled: {orderDetails.AmountFilled:0.########}, " +
                                            $"Cost: {orderDetails.Cost:0.00000000}, Fees: {fees:0.00000000}, Margin: {margin:0.00}, Profit: {tradeResult.Profit:0.00000000}{swapPair}{arbitrage}");
                        notificationService.Notify($"Sold {tradingPair.FormattedName}. Amount: {orderDetails.AmountFilled:0.########}, " +
                                                   $"Price: {orderDetails.AveragePrice:0.00000000}, Margin: {margin:0.00}, Profit: {tradeResult.Profit:0.00000000}{swapPair}{arbitrage}");
                    }

                    tradingService.ReapplyTradingRules();
                }
                else
                {
                    loggingService.Info(message);
                }
            }
            catch (Exception ex)
            {
                loggingService.Error($"Unable to place sell order for {options.Pair}", ex);
                notificationService.Notify($"Unable to sell {options.Pair}: {ex.Message}");
            }
            return(orderDetails);
        }