public async Task GetOpenOrdersThrows() { var user = new BinanceApiUser("api-key"); var symbol = Symbol.BTC_USDT; await Assert.ThrowsAsync <ArgumentNullException>("user", () => _client.GetOpenOrdersAsync(null, symbol)); }
public void Equality() { var user = new BinanceApiUser("api-key"); var symbol = Symbol.BTC_USDT; const int id = 123456; const string clientOrderId = "test-order"; const decimal price = 4999; const decimal originalQuantity = 1; const decimal executedQuantity = 0.5m; const OrderStatus status = OrderStatus.PartiallyFilled; const TimeInForce timeInForce = TimeInForce.IOC; const OrderType orderType = OrderType.Market; const OrderSide orderSide = OrderSide.Sell; const decimal stopPrice = 5000; const decimal icebergQuantity = 0.1m; var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); var order = new Order(user, symbol, id, clientOrderId, price, originalQuantity, executedQuantity, status, timeInForce, orderType, orderSide, stopPrice, icebergQuantity, timestamp); var serializer = new OrderSerializer(); var json = serializer.Serialize(order); var other = serializer.Deserialize(json, user); Assert.True(order.Equals(other)); }
public void Equality() { var user = new BinanceApiUser("api-key"); var symbol = Symbol.BTC_USDT; const int id = 123456; const string clientOrderId = "test-order"; const decimal price = 4999; const decimal originalQuantity = 1; const decimal executedQuantity = 0.5m; const decimal cummulativeQuoteAssetQuantity = executedQuantity * price; const OrderStatus status = OrderStatus.PartiallyFilled; const TimeInForce timeInForce = TimeInForce.IOC; const OrderType orderType = OrderType.Market; const OrderSide orderSide = OrderSide.Sell; const decimal stopPrice = 5000; const decimal icebergQuantity = 0.1m; var time = DateTimeOffset.FromUnixTimeMilliseconds(DateTime.UtcNow.ToTimestamp()).UtcDateTime; const bool isWorking = true; Fill[] fills = { new Fill(price, originalQuantity, 0.001m, "BNB", 12345678990) }; var order = new Order(user, symbol, id, clientOrderId, price, originalQuantity, executedQuantity, cummulativeQuoteAssetQuantity, status, timeInForce, orderType, orderSide, stopPrice, icebergQuantity, time, time, isWorking, fills); var serializer = new OrderSerializer(); var json = serializer.Serialize(order); var other = serializer.Deserialize(json, user); Assert.True(order.Equals(other)); }
public void Properties() { var user = new BinanceApiUser("api-key"); var commissions = new AccountCommissions(10, 10, 0, 0); var status = new AccountStatus(true, true, true); long updateTime = 1234567890; var balances = new[] { new AccountBalance("BTC", 0.1m, 0.2m) }; var account = new AccountInfo(user, commissions, status, updateTime); Assert.Equal(commissions, account.Commissions); Assert.Equal(status, account.Status); Assert.Equal(updateTime, account.Timestamp); Assert.NotNull(account.Balances); Assert.Empty(account.Balances); account = new AccountInfo(user, commissions, status, updateTime, balances); Assert.Equal(commissions, account.Commissions); Assert.Equal(status, account.Status); Assert.Equal(updateTime, account.Timestamp); Assert.NotNull(account.Balances); Assert.NotEmpty(account.Balances); Assert.Equal(balances[0].Asset, account.Balances.First().Asset); }
public void Properties() { var user = new BinanceApiUser("api-key"); var commissions = new AccountCommissions(10, 10, 0, 0); var status = new AccountStatus(true, true, true); var time = DateTimeOffset.FromUnixTimeMilliseconds(DateTime.UtcNow.ToTimestamp()).UtcDateTime; var balances = new[] { new AccountBalance("BTC", 0.1m, 0.2m) }; var account = new AccountInfo(user, commissions, status, time); Assert.Equal(commissions, account.Commissions); Assert.Equal(status, account.Status); Assert.Equal(time, account.Time); Assert.NotNull(account.Balances); Assert.Empty(account.Balances); account = new AccountInfo(user, commissions, status, time, balances); Assert.Equal(commissions, account.Commissions); Assert.Equal(status, account.Status); Assert.Equal(time, account.Time); Assert.NotNull(account.Balances); Assert.NotEmpty(account.Balances); Assert.Equal(balances[0].Asset, account.Balances.First().Asset); }
public async Task SubscribeAccountInfo(Interface.Model.User user, Action <AccountInfoEventArgs> callback, Action <Exception> exception, CancellationToken cancellationToken) { var apiUser = new BinanceApiUser(user.ApiKey, user.ApiSecret); var streamControl = new UserDataWebSocketStreamControl(binanceApi); var listenKey = await streamControl.OpenStreamAsync(apiUser).ConfigureAwait(false); var accountInfoCache = new AccountInfoCache(binanceApi, new UserDataWebSocketClient()); accountInfoCache.Subscribe(listenKey, apiUser, e => { if (cancellationToken.IsCancellationRequested) { accountInfoCache.Unsubscribe(); return; } try { var accountInfo = GetAccountInfo(e.AccountInfo); accountInfo.User = user; callback.Invoke(new AccountInfoEventArgs { AccountInfo = accountInfo }); } catch (Exception ex) { accountInfoCache.Unsubscribe(); exception.Invoke(ex); return; } }); }
public async Task <List <Withdrawal> > GetNewWithdrawals() { // no api call var list = new List <Withdrawal>(); try { var binanceClient = GetApi(); using (var user = new BinanceApiUser(_config.Key, _config.Secret)) { var binanceDesposits = await binanceClient.GetWithdrawalsAsync(user, "BTC"); list = BinanceConverter.BinanceToWithdrawals(binanceDesposits); } } catch (Exception e) { _log.LogError("Error in getting withdrawals from binance: " + e.Message); } var newWithdrawals = await _databaseService.AddWithdrawals(list, Constants.Binance); await _databaseService.AddLastChecked("Binance.WithdrawalCheck", DateTime.Now); return(newWithdrawals); }
public async Task <List <Trade> > GetOrderHistory(DateTime lastChecked) { var list = new List <Trade>(); try { var binanceClient = GetApi(); using (var user = new BinanceApiUser(_config.Key, _config.Secret)) { foreach (var symbol in _symbols) { var response = await binanceClient.GetAccountTradesAsync(user, symbol); var ccy2 = symbol.Remove(symbol.Length - _generalConfig.TradingCurrency.Length); var symlist = BinanceConverter.BinanceToTrades(response, _generalConfig.TradingCurrency, ccy2, _log); list.AddRange(symlist); } } } catch (Exception e) { _log.LogError("Error in getting trades from binance: " + e.Message); } return(list); }
public void Properties() { var time = DateTimeOffset.FromUnixTimeMilliseconds(DateTime.UtcNow.ToTimestamp()).UtcDateTime; var user = new BinanceApiUser("api-key"); var symbol = Symbol.BTC_USDT; const long id = 123456; const string clientOrderId = "test-order"; const decimal price = 4999; const decimal originalQuantity = 1; const decimal executedQuantity = 0.5m; const OrderStatus status = OrderStatus.PartiallyFilled; const TimeInForce timeInForce = TimeInForce.IOC; const OrderType orderType = OrderType.Market; const OrderSide orderSide = OrderSide.Sell; const decimal stopPrice = 5000; const decimal icebergQuantity = 0.1m; const bool isWorking = true; var order = new Order(user, symbol, id, clientOrderId, price, originalQuantity, executedQuantity, status, timeInForce, orderType, orderSide, stopPrice, icebergQuantity, time, isWorking); const OrderExecutionType orderExecutionType = OrderExecutionType.New; const string orderRejectedReason = OrderRejectedReason.None; const string newClientOrderId = "new-test-order"; var args = new OrderUpdateEventArgs(time, order, orderExecutionType, orderRejectedReason, newClientOrderId); Assert.Equal(time, args.Time); Assert.Equal(order, args.Order); Assert.Equal(orderExecutionType, args.OrderExecutionType); Assert.Equal(orderRejectedReason, args.OrderRejectedReason); Assert.Equal(newClientOrderId, args.NewClientOrderId); }
public async Task <List <OpenOrder> > GetNewOpenOrders(DateTime lastChecked) { var openOrders = new List <OpenOrder>(); try { var binanceClient = GetApi(); using (var user = new BinanceApiUser(_config.Key, _config.Secret)) { foreach (var symbol in _symbols) { var response = await binanceClient.GetOpenOrdersAsync(user, symbol); var ccy2 = symbol.Remove(symbol.Length - _generalConfig.TradingCurrency.Length); var list = BinanceConverter.BinanceToOpenOrders(response, _generalConfig.TradingCurrency, ccy2); openOrders.AddRange(list); } } } catch (Exception e) { _log.LogError("Error in getting openOrders from binance: " + e.Message); } var newOrders = await _databaseService.AddOpenOrders(openOrders); return(newOrders); }
public void Throws() { var user = new BinanceApiUser("api-key"); var symbol = Symbol.BTC_USDT; const int id = 123456; const string clientOrderId = "test-order"; const decimal price = 4999; const decimal originalQuantity = 1; const decimal executedQuantity = 0.5m; const OrderStatus status = OrderStatus.PartiallyFilled; const TimeInForce timeInForce = TimeInForce.IOC; const OrderType orderType = OrderType.Market; const OrderSide orderSide = OrderSide.Sell; const decimal stopPrice = 5000; const decimal icebergQuantity = 0.1m; var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); const bool isWorking = true; Assert.Throws <ArgumentNullException>("user", () => new Order(null, symbol, id, clientOrderId, price, originalQuantity, executedQuantity, status, timeInForce, orderType, orderSide, stopPrice, icebergQuantity, timestamp, isWorking)); Assert.Throws <ArgumentNullException>("symbol", () => new Order(user, null, id, clientOrderId, price, originalQuantity, executedQuantity, status, timeInForce, orderType, orderSide, stopPrice, icebergQuantity, timestamp, isWorking)); Assert.Throws <ArgumentException>("id", () => new Order(user, symbol, -1, clientOrderId, price, originalQuantity, executedQuantity, status, timeInForce, orderType, orderSide, stopPrice, icebergQuantity, timestamp, isWorking)); Assert.Throws <ArgumentException>("price", () => new Order(user, symbol, id, clientOrderId, -1, originalQuantity, executedQuantity, status, timeInForce, orderType, orderSide, stopPrice, icebergQuantity, timestamp, isWorking)); Assert.Throws <ArgumentException>("stopPrice", () => new Order(user, symbol, id, clientOrderId, price, originalQuantity, executedQuantity, status, timeInForce, orderType, orderSide, -1, icebergQuantity, timestamp, isWorking)); Assert.Throws <ArgumentException>("originalQuantity", () => new Order(user, symbol, id, clientOrderId, price, -1, executedQuantity, status, timeInForce, orderType, orderSide, stopPrice, icebergQuantity, timestamp, isWorking)); Assert.Throws <ArgumentException>("executedQuantity", () => new Order(user, symbol, id, clientOrderId, price, originalQuantity, -1, status, timeInForce, orderType, orderSide, stopPrice, icebergQuantity, timestamp, isWorking)); Assert.Throws <ArgumentException>("icebergQuantity", () => new Order(user, symbol, id, clientOrderId, price, originalQuantity, executedQuantity, status, timeInForce, orderType, orderSide, stopPrice, -1, timestamp, isWorking)); Assert.Throws <ArgumentException>("timestamp", () => new Order(user, symbol, id, clientOrderId, price, originalQuantity, executedQuantity, status, timeInForce, orderType, orderSide, stopPrice, icebergQuantity, -1, isWorking)); Assert.Throws <ArgumentException>("timestamp", () => new Order(user, symbol, id, clientOrderId, price, originalQuantity, executedQuantity, status, timeInForce, orderType, orderSide, stopPrice, icebergQuantity, 0, isWorking)); }
public void Properties() { var user = new BinanceApiUser("api-key"); var symbol = Symbol.BTC_USDT; const int id = 123456; const string clientOrderId = "test-order"; const decimal price = 4999; const decimal originalQuantity = 1; const decimal executedQuantity = 0.5m; const OrderStatus status = OrderStatus.PartiallyFilled; const TimeInForce timeInForce = TimeInForce.IOC; const OrderType orderType = OrderType.Market; const OrderSide orderSide = OrderSide.Sell; const decimal stopPrice = 5000; const decimal icebergQuantity = 0.1m; var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); var order = new Order(user, symbol, id, clientOrderId, price, originalQuantity, executedQuantity, status, timeInForce, orderType, orderSide, stopPrice, icebergQuantity, timestamp); Assert.Equal(user, order.User); Assert.Equal(symbol, order.Symbol); Assert.Equal(id, order.Id); Assert.Equal(clientOrderId, order.ClientOrderId); Assert.Equal(price, order.Price); Assert.Equal(originalQuantity, order.OriginalQuantity); Assert.Equal(executedQuantity, order.ExecutedQuantity); Assert.Equal(status, order.Status); Assert.Equal(timeInForce, order.TimeInForce); Assert.Equal(orderType, order.Type); Assert.Equal(orderSide, order.Side); Assert.Equal(stopPrice, order.StopPrice); Assert.Equal(icebergQuantity, order.IcebergQuantity); Assert.Equal(timestamp, order.Timestamp); }
public async Task <string> CancelOrderAsync(Interface.Model.User user, string symbol, long orderId, string newClientOrderId = null, long recWindow = 0, CancellationToken cancellationToken = default(CancellationToken)) { var apiUser = new BinanceApiUser(user.ApiKey, user.ApiSecret); var result = await binanceApi.CancelOrderAsync(apiUser, symbol, orderId, newClientOrderId, recWindow, cancellationToken).ConfigureAwait(false); return(result); }
public void Throws() { var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); var user = new BinanceApiUser("api-key"); var symbol = Symbol.BTC_USDT; const long id = 123456; const string clientOrderId = "test-order"; const decimal price = 4999; const decimal originalQuantity = 1; const decimal executedQuantity = 0.5m; const OrderStatus status = OrderStatus.PartiallyFilled; const TimeInForce timeInForce = TimeInForce.IOC; const OrderType orderType = OrderType.Market; const OrderSide orderSide = OrderSide.Sell; const decimal stopPrice = 5000; const decimal icebergQuantity = 0.1m; const bool isWorking = true; var order = new Order(user, symbol, id, clientOrderId, price, originalQuantity, executedQuantity, status, timeInForce, orderType, orderSide, stopPrice, icebergQuantity, timestamp, isWorking); const OrderExecutionType orderExecutionType = OrderExecutionType.New; const OrderRejectedReason orderRejectedReason = OrderRejectedReason.None; const string newClientOrderId = "new-test-order"; using (var cts = new CancellationTokenSource()) { Assert.Throws <ArgumentException>("timestamp", () => new OrderUpdateEventArgs(-1, cts.Token, order, orderExecutionType, orderRejectedReason, newClientOrderId)); Assert.Throws <ArgumentException>("timestamp", () => new OrderUpdateEventArgs(0, cts.Token, order, orderExecutionType, orderRejectedReason, newClientOrderId)); Assert.Throws <ArgumentNullException>("order", () => new OrderUpdateEventArgs(timestamp, cts.Token, null, orderExecutionType, orderRejectedReason, newClientOrderId)); } }
public async Task <List <Withdrawal> > GetNewWithdrawals() { // no api call var list = new List <Withdrawal>(); try { var binanceClient = GetApi(); var lastChecked = _databaseService.GetLastChecked("Binance.DepositCheck"); using (var user = new BinanceApiUser(_config.Key, _config.Secret)) { var start = Helpers.Helpers.DateTimeToUnixTimestamp(lastChecked); var binanceDesposits = await binanceClient.GetWithdrawalsAsync(user, _generalConfig.TradingCurrency, null, start, 0, 10000000); list = BinanceConverter.BinanceToWithdrawals(binanceDesposits); } } catch (Exception e) { _log.LogError("Error in getting withdrawals from binance: " + e.Message); } var newWithdrawals = await _databaseService.AddWithdrawals(list, Constants.Binance); await _databaseService.AddLastChecked("Binance.WithdrawalCheck", DateTime.Now); return(newWithdrawals); }
public void Sign_Throws() { var apiKey = "api-key"; var user = new BinanceApiUser(apiKey); Assert.Throws <ArgumentNullException>("totalParams", () => user.Sign(null)); Assert.Throws <InvalidOperationException>(() => user.Sign("valid-string")); }
public async Task SubscribeThrows() { var user = new BinanceApiUser("api-key"); var client = new UserDataWebSocketClient(new Mock <IBinanceApi>().Object, new Mock <IWebSocketClient>().Object); await Assert.ThrowsAsync <ArgumentNullException>("user", () => client.SubscribeAsync(null, new CancellationToken())); await Assert.ThrowsAsync <ArgumentException>("token", () => client.SubscribeAsync(user, CancellationToken.None)); }
public async Task <IEnumerable <Interface.Model.Order> > GetOpenOrdersAsync(Interface.Model.User user, string symbol = null, long recWindow = 0, Action <Exception> exception = default(Action <Exception>), CancellationToken cancellationToken = default(CancellationToken)) { var apiUser = new BinanceApiUser(user.ApiKey, user.ApiSecret); var result = await binanceApi.GetOpenOrdersAsync(apiUser, symbol, recWindow, cancellationToken).ConfigureAwait(false); var orders = result.Select(o => NewOrder(user, o)).ToList(); return(orders); }
public async Task <IEnumerable <Interface.Model.AccountTrade> > GetAccountTradesAsync(Interface.Model.User user, string symbol, DateTime startDate, DateTime endDate, long recWindow = 0, CancellationToken cancellationToken = default(CancellationToken)) { var apiUser = new BinanceApiUser(user.ApiKey, user.ApiSecret); var result = await binanceApi.GetAccountTradesAsync(apiUser, symbol, startDate, endDate, recWindow, cancellationToken).ConfigureAwait(false); var accountTrades = result.Select(at => NewAccountTrade(at)).ToList(); return(accountTrades); }
public void Properties() { var apiKey = "api-key"; var rateLimiter = new Mock <IApiRateLimiter>().Object; var user = new BinanceApiUser(apiKey, null, rateLimiter); Assert.Equal(apiKey, user.ApiKey); Assert.Equal(rateLimiter, user.RateLimiter); }
public async Task TestPlaceThrows() { var user = new BinanceApiUser("api-key"); await Assert.ThrowsAsync <ArgumentNullException>("clientOrder", () => _api.TestPlaceAsync(null)); await Assert.ThrowsAsync <InvalidOperationException>(() => _api.TestPlaceAsync(new LimitOrder(user) { Symbol = Symbol.BTC_USDT, Quantity = 0.01m })); }
public async Task CancelOrderThrows() { var user = new BinanceApiUser("api-key"); var symbol = Symbol.BTC_USDT; await Assert.ThrowsAsync <ArgumentNullException>("user", () => _client.CancelOrderAsync(null, symbol)); await Assert.ThrowsAsync <ArgumentNullException>("symbol", () => _client.CancelOrderAsync(user, null)); await Assert.ThrowsAsync <ArgumentException>(() => _client.GetOrderAsync(user, symbol)); }
public void Throws() { var user = new BinanceApiUser("api-key"); var commissions = new AccountCommissions(10, 10, 0, 0); var time = DateTimeOffset.FromUnixTimeMilliseconds(DateTime.UtcNow.ToTimestamp()).UtcDateTime; var status = new AccountStatus(true, true, true); Assert.Throws <ArgumentNullException>("user", () => new AccountInfo(null, commissions, status, time)); Assert.Throws <ArgumentNullException>("commissions", () => new AccountInfo(user, null, status, time)); Assert.Throws <ArgumentNullException>("status", () => new AccountInfo(user, commissions, null, time)); }
private async Task <AccountInfo> InitializeAccountInfo() { using (var user = new BinanceApiUser(_config.Key, _config.Secret)) { var accountInfo = await _binanceApi.GetAccountInfoAsync(user, 10000000); _cache.SetAccountInfo(accountInfo); return(accountInfo); } }
public async Task CancelOrderThrows() { var user = new BinanceApiUser("api-key"); await Assert.ThrowsAsync <ArgumentException>("orderId", () => _api.CancelOrderAsync(user, Symbol.BTC_USDT, BinanceApi.NullId)); await Assert.ThrowsAsync <ArgumentNullException>("origClientOrderId", () => _api.CancelOrderAsync(user, Symbol.BTC_USDT, null)); await Assert.ThrowsAsync <ArgumentNullException>("origClientOrderId", () => _api.CancelOrderAsync(user, Symbol.BTC_USDT, string.Empty)); await Assert.ThrowsAsync <ArgumentNullException>("order", () => _api.CancelAsync(null)); }
public async Task StreamThrows() { var user = new BinanceApiUser("api-key"); var api = new Mock <IBinanceApi>().Object; var cache = new AccountInfoCache(api, new Mock <IUserDataWebSocketClient>().Object); using (var cts = new CancellationTokenSource()) { await Assert.ThrowsAsync <ArgumentNullException>("user", () => cache.StreamAsync(null, cts.Token)); } }
public static ClientOrder GetOrder(Interface.Model.User user, Interface.Model.ClientOrder clientOrder) { var apiUser = new BinanceApiUser(user.ApiKey, user.ApiSecret); var orderType = (OrderType)clientOrder.Type; switch (orderType) { case OrderType.Market: return(new MarketOrder(apiUser) { Symbol = clientOrder.Symbol, Side = (OrderSide)clientOrder.Side, Quantity = clientOrder.Quantity }); case OrderType.StopLoss: return(new StopLossOrder(apiUser) { Symbol = clientOrder.Symbol, Side = (OrderSide)clientOrder.Side, Quantity = clientOrder.Quantity, StopPrice = clientOrder.StopPrice }); case OrderType.TakeProfit: return(new TakeProfitOrder(apiUser) { Symbol = clientOrder.Symbol, Side = (OrderSide)clientOrder.Side, Quantity = clientOrder.Quantity, StopPrice = clientOrder.StopPrice }); case OrderType.Limit: return(new LimitOrder(apiUser) { Symbol = clientOrder.Symbol, Side = (OrderSide)clientOrder.Side, Quantity = clientOrder.Quantity, Price = clientOrder.Price }); case OrderType.LimitMaker: return(new LimitMakerOrder(apiUser) { Symbol = clientOrder.Symbol, Side = (OrderSide)clientOrder.Side, Quantity = clientOrder.Quantity, Price = clientOrder.Price }); case OrderType.StopLossLimit: return(new StopLossLimitOrder(apiUser) { Symbol = clientOrder.Symbol, Side = (OrderSide)clientOrder.Side, Quantity = clientOrder.Quantity, StopPrice = clientOrder.StopPrice, Price = clientOrder.Price }); case OrderType.TakeProfitLimit: return(new TakeProfitLimitOrder(apiUser) { Symbol = clientOrder.Symbol, Side = (OrderSide)clientOrder.Side, Quantity = clientOrder.Quantity, StopPrice = clientOrder.StopPrice, Price = clientOrder.Price }); default: throw new System.Exception("Unknown order type."); } }
public async Task <Interface.Model.AccountInfo> GetAccountInfoAsync(Interface.Model.User user, CancellationToken cancellationToken) { var apiUser = new BinanceApiUser(user.ApiKey, user.ApiSecret); var result = await binanceApi.GetAccountInfoAsync(apiUser, 0, cancellationToken).ConfigureAwait(false); var accountInfo = GetAccountInfo(result); user.RateLimiter = new Interface.Model.RateLimiter { IsEnabled = result.User.RateLimiter.IsEnabled }; accountInfo.User = user; return(accountInfo); }
private async Task <ImmutableList <AccountTrade> > InitializeAccountTrades(string symbol) { using (var user = new BinanceApiUser(_config.Key, _config.Secret)) { var accountTrades = await _binanceApi.GetAccountTradesAsync(user, symbol, -1L, 0, 10000000); var immutableAccountTrades = accountTrades.ToImmutableList(); _cache.SetAccountTrades(symbol, immutableAccountTrades); return(immutableAccountTrades); } }
public async Task UserStreamCloseThrows() { var user = new BinanceApiUser("api-key"); const string listenKey = "listen-key"; await Assert.ThrowsAsync <ArgumentNullException>("user", () => _client.UserStreamCloseAsync((IBinanceApiUser)null, listenKey)); await Assert.ThrowsAsync <ArgumentNullException>("apiKey", () => _client.UserStreamCloseAsync((string)null, listenKey)); await Assert.ThrowsAsync <ArgumentNullException>("listenKey", () => _client.UserStreamCloseAsync(user, null)); await Assert.ThrowsAsync <ArgumentNullException>("listenKey", () => _client.UserStreamCloseAsync(user, string.Empty)); }