/// <summary> /// Pings the Binance Futures API /// </summary> /// <returns>True if successful ping, false if no response</returns> public async Task <WebCallResult <long> > PingAsync(CancellationToken ct = default) { var sw = Stopwatch.StartNew(); var result = await _baseClient.SendRequestInternal <object>(_futuresClient.GetUrl(pingEndpoint, Api, publicVersion), HttpMethod.Get, ct).ConfigureAwait(false); sw.Stop(); return(new WebCallResult <long>(result.ResponseStatusCode, result.ResponseHeaders, result.Error == null ? sw.ElapsedMilliseconds : 0, result.Error)); }
/// <summary> /// Starts a user stream by requesting a listen key. This listen key can be used in subsequent requests to BinanceSocketClient.Futures.SubscribeToUserDataUpdates. The stream will close after 60 minutes unless a keep alive is send. /// </summary> /// <param name="ct">Cancellation token</param> /// <returns>Listen key</returns> public async Task <WebCallResult <string> > StartUserStreamAsync(CancellationToken ct = default) { var timestampResult = await _baseClient.CheckAutoTimestamp(ct).ConfigureAwait(false); if (!timestampResult) { return(new WebCallResult <string>(timestampResult.ResponseStatusCode, timestampResult.ResponseHeaders, null, timestampResult.Error)); } var result = await _baseClient.SendRequestInternal <BinanceListenKey>(_futuresClient.GetUrl(getFuturesListenKeyEndpoint, Api, userDataStreamVersion), HttpMethod.Post, ct).ConfigureAwait(false); return(result.As(result.Data?.ListenKey !)); }
/// <summary> /// Gets the order book for the provided symbol /// </summary> /// <param name="symbol">The symbol to get the order book for</param> /// <param name="limit">Max number of results</param> /// <param name="ct">Cancellation token</param> /// <returns>The order book for the symbol</returns> public async Task <WebCallResult <BinanceOrderBook> > GetOrderBookAsync(string symbol, int?limit = null, CancellationToken ct = default) { limit?.ValidateIntValues(nameof(limit), 5, 10, 20, 50, 100, 500, 1000); var parameters = new Dictionary <string, object> { { "symbol", symbol } }; parameters.AddOptionalParameter("limit", limit?.ToString(CultureInfo.InvariantCulture)); var result = await BaseClient.SendRequestInternal <BinanceEventOrderBook>(FuturesClient.GetUrl(orderBookEndpoint, Api, publicVersion), HttpMethod.Get, ct, parameters).ConfigureAwait(false); if (result) { result.Data.Symbol = symbol; } return(new WebCallResult <BinanceOrderBook>(result.ResponseStatusCode, result.ResponseHeaders, result.Data, result.Error)); }
/// <summary> /// Places a new order /// </summary> /// <param name="symbol">The symbol the order is for</param> /// <param name="side">The order side (buy/sell)</param> /// <param name="type">The order type</param> /// <param name="timeInForce">Lifetime of the order (GoodTillCancel/ImmediateOrCancel/FillOrKill)</param> /// <param name="quantity">The amount of the base symbol</param> /// <param name="positionSide">The position side</param> /// <param name="reduceOnly">Specify as true if the order is intended to only reduce the position</param> /// <param name="price">The price to use</param> /// <param name="newClientOrderId">Unique id for order</param> /// <param name="stopPrice">Used for stop orders</param> /// <param name="activationPrice">Used with TRAILING_STOP_MARKET orders, default as the latest price(supporting different workingType)</param> /// <param name="callbackRate">Used with TRAILING_STOP_MARKET orders</param> /// <param name="workingType">stopPrice triggered by: "MARK_PRICE", "CONTRACT_PRICE"</param> /// <param name="closePosition">Close-All,used with STOP_MARKET or TAKE_PROFIT_MARKET.</param> /// <param name="orderResponseType">The response type. Default Acknowledge</param> /// <param name="receiveWindow">The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request</param> /// <param name="ct">Cancellation token</param> /// <returns>Id's for the placed order</returns> public async Task <WebCallResult <BinanceFuturesPlacedOrder> > PlaceOrderAsync( string symbol, OrderSide side, OrderType type, decimal?quantity, PositionSide?positionSide = null, TimeInForce?timeInForce = null, bool?reduceOnly = null, decimal?price = null, string?newClientOrderId = null, decimal?stopPrice = null, decimal?activationPrice = null, decimal?callbackRate = null, WorkingType?workingType = null, bool?closePosition = null, OrderResponseType?orderResponseType = null, int?receiveWindow = null, CancellationToken ct = default) { if (closePosition == true && positionSide != null) { if (positionSide == PositionSide.Short && side == OrderSide.Sell) { throw new ArgumentException("Can't close short position with order side sell"); } if (positionSide == PositionSide.Long && side == OrderSide.Buy) { throw new ArgumentException("Can't close long position with order side buy"); } } if (orderResponseType == OrderResponseType.Full) { throw new ArgumentException("OrderResponseType.Full is not supported in Futures"); } var timestampResult = await BaseClient.CheckAutoTimestamp(ct).ConfigureAwait(false); if (!timestampResult) { return(new WebCallResult <BinanceFuturesPlacedOrder>(timestampResult.ResponseStatusCode, timestampResult.ResponseHeaders, null, timestampResult.Error)); } var rulesCheck = await FuturesClient.CheckTradeRules(symbol, quantity, price, stopPrice, type, ct).ConfigureAwait(false); if (!rulesCheck.Passed) { _log.Write(LogVerbosity.Warning, rulesCheck.ErrorMessage !); return(new WebCallResult <BinanceFuturesPlacedOrder>(null, null, null, new ArgumentError(rulesCheck.ErrorMessage !))); } quantity = rulesCheck.Quantity; price = rulesCheck.Price; stopPrice = rulesCheck.StopPrice; var parameters = new Dictionary <string, object> { { "symbol", symbol }, { "side", JsonConvert.SerializeObject(side, new OrderSideConverter(false)) }, { "type", JsonConvert.SerializeObject(type, new OrderTypeConverter(false)) }, { "timestamp", BaseClient.GetTimestamp() } }; parameters.AddOptionalParameter("quantity", quantity?.ToString(CultureInfo.InvariantCulture)); parameters.AddOptionalParameter("newClientOrderId", newClientOrderId); parameters.AddOptionalParameter("price", price?.ToString(CultureInfo.InvariantCulture)); parameters.AddOptionalParameter("timeInForce", timeInForce == null ? null : JsonConvert.SerializeObject(timeInForce, new TimeInForceConverter(false))); parameters.AddOptionalParameter("positionSide", positionSide == null ? null : JsonConvert.SerializeObject(positionSide, new PositionSideConverter(false))); parameters.AddOptionalParameter("stopPrice", stopPrice?.ToString(CultureInfo.InvariantCulture)); parameters.AddOptionalParameter("activationPrice", activationPrice?.ToString(CultureInfo.InvariantCulture)); parameters.AddOptionalParameter("callbackRate", callbackRate?.ToString(CultureInfo.InvariantCulture)); parameters.AddOptionalParameter("workingType", workingType == null ? null : JsonConvert.SerializeObject(workingType, new WorkingTypeConverter(false))); parameters.AddOptionalParameter("reduceOnly", reduceOnly?.ToString().ToLower()); parameters.AddOptionalParameter("closePosition", closePosition?.ToString().ToLower()); parameters.AddOptionalParameter("newOrderRespType", orderResponseType == null ? null : JsonConvert.SerializeObject(orderResponseType, new OrderResponseTypeConverter(false))); parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? BaseClient.DefaultReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); return(await BaseClient.SendRequestInternal <BinanceFuturesPlacedOrder>(FuturesClient.GetUrl(newOrderEndpoint, Api, SignedVersion), HttpMethod.Post, ct, parameters, true).ConfigureAwait(false)); }
/// <summary>. /// Gets account balances /// </summary> /// <param name="receiveWindow">The receive window for which this request is active. When the request takes longer than this to complete the server will reject the request</param> /// <param name="ct">Cancellation token</param> /// <returns>The account information</returns> public async Task <WebCallResult <IEnumerable <BinanceFuturesAccountBalance> > > GetBalanceAsync(long?receiveWindow = null, CancellationToken ct = default) { var timestampResult = await BaseClient.CheckAutoTimestamp(ct).ConfigureAwait(false); if (!timestampResult) { return(new WebCallResult <IEnumerable <BinanceFuturesAccountBalance> >(timestampResult.ResponseStatusCode, timestampResult.ResponseHeaders, null, timestampResult.Error)); } var parameters = new Dictionary <string, object> { { "timestamp", BaseClient.GetTimestamp() } }; parameters.AddOptionalParameter("recvWindow", receiveWindow?.ToString(CultureInfo.InvariantCulture) ?? BaseClient.DefaultReceiveWindow.TotalMilliseconds.ToString(CultureInfo.InvariantCulture)); return(await BaseClient.SendRequestInternal <IEnumerable <BinanceFuturesAccountBalance> >(FuturesClient.GetUrl(futuresAccountBalanceEndpoint, Api, Api == "dapi" ? "1": "2"), HttpMethod.Get, ct, parameters, true).ConfigureAwait(false)); }