public async Task OrderTypes_SelectedSymbol()
        {
            // Arrange
            var cxlToken        = new CancellationToken();
            var exchangeApi     = ExchangeServiceHelper.GetExchangeService();
            var exchangeService = new WpfExchangeService(exchangeApi);
            var tradeViewModel  = new TradePanelViewModel(exchangeService, new DebugLogger());

            var symbols = await exchangeService.GetSymbols24HourStatisticsAsync(Exchange.Test, cxlToken);

            var trx = symbols.Single(s => s.Name.Equals("TRXBTC"));

            tradeViewModel.SetSymbols(symbols.ToList());
            tradeViewModel.SelectedSymbol = trx;

            // Act
            var orderTypes = tradeViewModel.OrderTypes;

            // Assert
            Assert.AreEqual(tradeViewModel.SelectedSymbol, trx);

            var missing = OrderExtensions.OrderTypes().Except(tradeViewModel.OrderTypes).ToList();

            foreach (var orderType in missing)
            {
                if (orderType != OrderExtensions.GetOrderTypeName(Core.Model.OrderType.StopLoss) &&
                    orderType != OrderExtensions.GetOrderTypeName(Core.Model.OrderType.TakeProfit))
                {
                    Assert.Fail();
                }
            }
        }
        public async Task SellQuantity()
        {
            // Arrange
            var cxlToken        = new CancellationToken();
            var exchangeApi     = ExchangeServiceHelper.GetExchangeService();
            var exchangeService = new WpfExchangeService(exchangeApi);
            var tradeViewModel  = new TradePanelViewModel(exchangeService, new DebugLogger());

            var symbols = await exchangeService.GetSymbols24HourStatisticsAsync(Exchange.Test, cxlToken);

            var trx = symbols.Single(s => s.Name.Equals("TRXBTC"));

            var account = new Account(new Core.Model.AccountInfo {
                User = new Core.Model.User()
            })
            {
                ApiKey    = "apikey",
                ApiSecret = "apisecret"
            };

            account = await exchangeService.GetAccountInfoAsync(Exchange.Test, account.AccountInfo.User, cxlToken);

            var selectedAsset = account.Balances.Single(ab => ab.Asset.Equals("TRX"));

            tradeViewModel.SetSymbols(symbols.ToList());
            tradeViewModel.SetAccount(account);
            tradeViewModel.SetSymbol(selectedAsset);

            // Act
            tradeViewModel.SellQuantityCommand.Execute(75);

            // Assert
            Assert.IsTrue(tradeViewModel.Quantity.Equals((selectedAsset.Free * 0.75m).Trim(trx.QuantityPrecision)));
        }
        public async Task Quantity_and_Price_and_StopPrice_NoTrim()
        {
            // Arrange
            var cxlToken        = new CancellationToken();
            var exchangeApi     = ExchangeServiceHelper.GetExchangeService();
            var exchangeService = new WpfExchangeService(exchangeApi);
            var tradeViewModel  = new TradePanelViewModel(exchangeService, new DebugLogger());

            var symbols = await exchangeService.GetSymbols24HourStatisticsAsync(Exchange.Test, cxlToken);

            tradeViewModel.SetSymbols(symbols.ToList());
            var trx = tradeViewModel.Symbols.Single(s => s.Name.Equals("TRXBTC"));

            tradeViewModel.SelectedSymbol = trx;

            var quantity = 294m;
            var price    = 1.12345678m;

            // Act
            tradeViewModel.Quantity  = quantity;
            tradeViewModel.Price     = price;
            tradeViewModel.StopPrice = price;

            // Assert
            Assert.AreEqual(tradeViewModel.Quantity, quantity.Trim(trx.QuantityPrecision));
            Assert.AreEqual(tradeViewModel.Price, price.Trim(trx.PricePrecision));
            Assert.AreEqual(tradeViewModel.StopPrice, price.Trim(trx.PricePrecision));
        }
        public async Task SetAccount()
        {
            // Arrange
            var cxlToken        = new CancellationToken();
            var exchangeApi     = ExchangeServiceHelper.GetExchangeService();
            var exchangeService = new WpfExchangeService(exchangeApi);
            var tradeViewModel  = new TradePanelViewModel(exchangeService, new DebugLogger());

            var symbols = await exchangeService.GetSymbols24HourStatisticsAsync(Exchange.Test, cxlToken);

            var trx = symbols.Single(s => s.Name.Equals("TRXBTC"));

            tradeViewModel.SetSymbols(symbols.ToList());

            var account = new Account(new Core.Model.AccountInfo {
                User = new Core.Model.User()
            })
            {
                ApiKey    = "apikey",
                ApiSecret = "apisecret"
            };

            account = await exchangeService.GetAccountInfoAsync(Exchange.Test, account.AccountInfo.User, cxlToken);

            // Act
            tradeViewModel.SetAccount(account);

            // Assert
            Assert.AreEqual(tradeViewModel.Account, account);
            Assert.AreEqual(tradeViewModel.SelectedOrderType, null);
            Assert.IsNull(tradeViewModel.SelectedSymbol);
        }
        public async Task Buy_Fails_PlaceOrder()
        {
            // Arrange
            var cxlToken        = new CancellationToken();
            var exchangeApi     = ExchangeServiceHelper.GetExchangeService(ExchangeServiceType.PlaceOrderException);
            var exchangeService = new WpfExchangeService(exchangeApi);
            var tradeViewModel  = new TradePanelViewModel(exchangeService, new DebugLogger());

            var symbols = await exchangeService.GetSymbols24HourStatisticsAsync(Exchange.Test, cxlToken);

            var trx = symbols.Single(s => s.Name.Equals("TRXBTC"));

            var account = new Account(new Core.Model.AccountInfo {
                User = new Core.Model.User()
            })
            {
                ApiKey    = "apikey",
                ApiSecret = "apisecret"
            };

            account = await exchangeService.GetAccountInfoAsync(Exchange.Test, account.AccountInfo.User, cxlToken);

            var selectedAsset = account.Balances.Single(ab => ab.Asset.Equals("TRX"));

            tradeViewModel.SetSymbols(symbols.ToList());
            tradeViewModel.SetAccount(account);
            tradeViewModel.SetSymbol(selectedAsset);

            tradeViewModel.QuoteAccountBalance.Free = 0.00012693M;

            tradeViewModel.SelectedOrderType        = "Limit";
            tradeViewModel.Quantity                 = 200m;
            tradeViewModel.Price                    = 0.00000900M;
            tradeViewModel.QuoteAccountBalance.Free = 200m * 0.00000900M;

            var tradeObservable = Observable.FromEventPattern <TradeEventArgs>(
                eventHandler => tradeViewModel.OnTradeNotification += eventHandler,
                eventHandler => tradeViewModel.OnTradeNotification -= eventHandler)
                                  .Select(eventPattern => eventPattern.EventArgs);

            Exception ex = null;

            tradeObservable.Subscribe(args =>
            {
                if (args.HasException)
                {
                    ex = args.Exception;
                }
            });

            // Act
            tradeViewModel.BuyCommand.Execute(null);

            // Assert
            Assert.IsNotNull(ex);
            Assert.IsTrue(ex.Message.Contains("failed to place order"));
        }
        public void HasQuoteBaseBalance_Null()
        {
            // Arrange
            var exchangeApi     = ExchangeServiceHelper.GetExchangeService();
            var exchangeService = new WpfExchangeService(exchangeApi);
            var tradeViewModel  = new TradePanelViewModel(exchangeService, new DebugLogger());

            // Act

            // Assert
            Assert.IsFalse(tradeViewModel.HasBaseBalance);
            Assert.IsFalse(tradeViewModel.HasQuoteBalance);
        }
        public void Quantity_and_Price_and_StopPrice_NoSelectedSymbol()
        {
            // Arrange
            var exchangeApi     = ExchangeServiceHelper.GetExchangeService();
            var exchangeService = new WpfExchangeService(exchangeApi);
            var tradeViewModel  = new TradePanelViewModel(exchangeService, new DebugLogger());

            var quantity = 294.123m;
            var price    = 1.123456789m;

            // Act
            tradeViewModel.Quantity  = quantity;
            tradeViewModel.Price     = price;
            tradeViewModel.StopPrice = price;

            // Assert
            Assert.AreEqual(tradeViewModel.Quantity, quantity);
            Assert.AreEqual(tradeViewModel.Price, price);
            Assert.AreEqual(tradeViewModel.StopPrice, price);
        }
        public async Task OrderTypes_NoSelectedSymbol()
        {
            // Arrange
            var cxlToken        = new CancellationToken();
            var exchangeApi     = ExchangeServiceHelper.GetExchangeService();
            var exchangeService = new WpfExchangeService(exchangeApi);
            var tradeViewModel  = new TradePanelViewModel(exchangeService, new DebugLogger());

            var symbols = await exchangeService.GetSymbols24HourStatisticsAsync(Exchange.Test, cxlToken);

            tradeViewModel.SetSymbols(symbols.ToList());

            // Act

            // Assert
            Assert.IsNull(tradeViewModel.SelectedSymbol);

            var intersection = tradeViewModel.OrderTypes.Intersect(InterfaceExtensions.OrderExtensions.OrderTypes()).ToList();

            Assert.IsTrue(InterfaceExtensions.OrderExtensions.OrderTypes().Count().Equals(intersection.Count));
        }
        public void HasQuoteBaseBalance()
        {
            // Arrange
            var exchangeApi     = ExchangeServiceHelper.GetExchangeService();
            var exchangeService = new WpfExchangeService(exchangeApi);
            var tradeViewModel  = new TradePanelViewModel(exchangeService, new DebugLogger());

            var quoteBalance = new AccountBalance {
                Free = 299m
            };
            var baseBalance = new AccountBalance {
                Free = 0.000123m
            };

            // Act
            tradeViewModel.QuoteAccountBalance = quoteBalance;
            tradeViewModel.BaseAccountBalance  = baseBalance;

            // Assert
            Assert.IsTrue(tradeViewModel.HasBaseBalance);
            Assert.IsTrue(tradeViewModel.HasQuoteBalance);
        }
        public async Task SelectedOrderType_IsStopLoss_Not_IsLoading()
        {
            // Arrange
            var cxlToken        = new CancellationToken();
            var exchangeApi     = ExchangeServiceHelper.GetExchangeService();
            var exchangeService = new WpfExchangeService(exchangeApi);
            var tradeViewModel  = new TradePanelViewModel(exchangeService, new DebugLogger());

            var symbols = await exchangeService.GetSymbols24HourStatisticsAsync(Exchange.Test, cxlToken);

            tradeViewModel.SetSymbols(symbols.ToList());
            var trx = tradeViewModel.Symbols.Single(s => s.Name.Equals("TRXBTC"));

            tradeViewModel.SelectedSymbol = trx;

            // Act
            tradeViewModel.SelectedOrderType = "Stop Loss";

            // Assert
            Assert.IsFalse(tradeViewModel.IsPriceEditable);
            Assert.IsTrue(tradeViewModel.IsMarketPrice);
        }
        public async Task SelectedSymbol_HasAccount()
        {
            // Arrange
            var cxlToken        = new CancellationToken();
            var exchangeApi     = ExchangeServiceHelper.GetExchangeService();
            var exchangeService = new WpfExchangeService(exchangeApi);
            var tradeViewModel  = new TradePanelViewModel(exchangeService, new DebugLogger());

            var account = new Account(new Core.Model.AccountInfo {
                User = new Core.Model.User()
            })
            {
                ApiKey    = "apikey",
                ApiSecret = "apisecret"
            };

            account = await exchangeService.GetAccountInfoAsync(Exchange.Test, account.AccountInfo.User, cxlToken);

            var baseBalance = account.Balances.Single(a => a.Asset.Equals("TRX"));
            var quoteAsset  = account.Balances.Single(a => a.Asset.Equals("BTC"));

            tradeViewModel.SetAccount(account);

            var symbols = await exchangeService.GetSymbols24HourStatisticsAsync(Exchange.Test, cxlToken);

            tradeViewModel.SetSymbols(symbols.ToList());
            var trx = tradeViewModel.Symbols.Single(s => s.Name.Equals("TRXBTC"));

            // Act
            tradeViewModel.SelectedSymbol = trx;

            // Assert
            Assert.AreEqual(tradeViewModel.SelectedSymbol, trx);
            Assert.AreEqual(tradeViewModel.Quantity, 0);
            Assert.AreEqual(tradeViewModel.Price, trx.SymbolStatistics.LastPrice);
            Assert.AreEqual(tradeViewModel.StopPrice, trx.SymbolStatistics.LastPrice);
            Assert.AreEqual(tradeViewModel.BaseAccountBalance, baseBalance);
            Assert.AreEqual(tradeViewModel.QuoteAccountBalance, quoteAsset);
        }
        public async Task SelectedOrderType_SelectedSymbol()
        {
            // Arrange
            var cxlToken        = new CancellationToken();
            var exchangeApi     = ExchangeServiceHelper.GetExchangeService();
            var exchangeService = new WpfExchangeService(exchangeApi);
            var tradeViewModel  = new TradePanelViewModel(exchangeService, new DebugLogger());

            var symbols = await exchangeService.GetSymbols24HourStatisticsAsync(Exchange.Test, cxlToken);

            tradeViewModel.SetSymbols(symbols.ToList());
            var trx = tradeViewModel.Symbols.Single(s => s.Name.Equals("TRXBTC"));

            tradeViewModel.SelectedSymbol = trx;

            // Act
            tradeViewModel.SelectedOrderType = "Limit";

            // Assert
            Assert.AreEqual(tradeViewModel.SelectedOrderType, "Limit");
            Assert.AreEqual(tradeViewModel.Price, trx.SymbolStatistics.LastPrice);
            Assert.AreEqual(tradeViewModel.StopPrice, trx.SymbolStatistics.LastPrice);
        }