示例#1
0
        /// <summary>
        /// Cancels a pending order
        /// </summary>
        /// <param name="symbol">The symbol the order is for</param>
        /// <param name="orderId">The order id of the order</param>
        /// <param name="origClientOrderId">The client order id of the order</param>
        /// <param name="newClientOrderId">Unique identifier for this cancel</param>
        /// <param name="recvWindow">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>
        /// <returns>Id's for canceled order</returns>
        public async Task <BinanceApiResult <BinanceCanceledOrder> > CancelOrderAsync(string symbol, long?orderId = null, string origClientOrderId = null, string newClientOrderId = null, long?recvWindow = null)
        {
            if (key == null || encryptor == null)
            {
                return(ThrowErrorMessage <BinanceCanceledOrder>(BinanceErrors.GetError(BinanceErrorKey.NoApiCredentialsProvided)));
            }

            if (AutoTimestamp && !timeSynced)
            {
                await GetServerTimeAsync();
            }

            var parameters = new Dictionary <string, string>()
            {
                { "symbol", symbol },
                { "timestamp", GetTimestamp() }
            };

            AddOptionalParameter(parameters, "orderId", orderId?.ToString());
            AddOptionalParameter(parameters, "origClientOrderId", origClientOrderId);
            AddOptionalParameter(parameters, "newClientOrderId", newClientOrderId);
            AddOptionalParameter(parameters, "recvWindow", recvWindow?.ToString());

            return(await ExecuteRequest <BinanceCanceledOrder>(GetUrl(CancelOrderEndpoint, Api, SignedVersion, parameters), true, DeleteMethod));
        }
示例#2
0
        /// <summary>
        /// Places a new test order. Test orders are not actually being executed and just test the functionality.
        /// </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 (limit/market)</param>
        /// <param name="timeInForce">Lifetime of the order (GoodTillCancel/ImmediateOrCancel)</param>
        /// <param name="quantity">The amount of the symbol</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="icebergQty">User for iceberg orders</param>
        /// <returns>Id's for the placed test order</returns>
        public async Task <BinanceApiResult <BinancePlacedOrder> > PlaceTestOrderAsync(string symbol, OrderSide side, OrderType type, TimeInForce timeInForce, decimal quantity, decimal price, string newClientOrderId = null, decimal?stopPrice = null, decimal?icebergQty = null)
        {
            if (key == null || encryptor == null)
            {
                return(ThrowErrorMessage <BinancePlacedOrder>(BinanceErrors.GetError(BinanceErrorKey.NoApiCredentialsProvided)));
            }

            if (AutoTimestamp && !timeSynced)
            {
                await GetServerTimeAsync();
            }

            var parameters = new Dictionary <string, string>()
            {
                { "symbol", symbol },
                { "side", JsonConvert.SerializeObject(side, new OrderSideConverter(false)) },
                { "type", JsonConvert.SerializeObject(type, new OrderTypeConverter(false)) },
                { "timeInForce", JsonConvert.SerializeObject(timeInForce, new TimeInForceConverter(false)) },
                { "quantity", quantity.ToString(CultureInfo.InvariantCulture) },
                { "price", price.ToString(CultureInfo.InvariantCulture) },
                { "timestamp", GetTimestamp() }
            };

            AddOptionalParameter(parameters, "newClientOrderId", newClientOrderId);
            AddOptionalParameter(parameters, "stopPrice", stopPrice?.ToString());
            AddOptionalParameter(parameters, "icebergQty", icebergQty?.ToString());

            return(await ExecuteRequest <BinancePlacedOrder>(GetUrl(NewTestOrderEndpoint, Api, SignedVersion, parameters), true, PostMethod));
        }
示例#3
0
        private BinanceApiResult <BinanceStream> CreateSocket(string url)
        {
            try
            {
                var socket = SocketFactory.CreateWebsocket(url);

                var socketObject = new BinanceStream()
                {
                    Socket = socket, StreamId = NextStreamId()
                };
                socket.SetEnabledSslProtocols(protocols);
                socket.OnClose += (obj, args) => Socket_OnClose(socketObject, args);
                socket.OnError += (obj, args) => Socket_OnError(socketObject, args);
                socket.OnOpen  += (obj, args) => Socket_OnOpen(socketObject, args);
                socket.Connect();
                lock (sockets)
                    sockets.Add(socketObject);

                return(new BinanceApiResult <BinanceStream>()
                {
                    Data = socketObject, Success = true
                });
            }
            catch (Exception e)
            {
                var errorMessage = $"Couldn't open socket stream: {e.Message}";
                log.Write(LogVerbosity.Error, errorMessage);
                return(ThrowErrorMessage <BinanceStream>(BinanceErrors.GetError(BinanceErrorKey.CantConnectToServer), errorMessage));
            }
        }
        /// <summary>
        /// Subscribes to the account update stream. Prior to using this, the <see cref="BinanceClient.StartUserStream"/> method should be called.
        /// </summary>
        /// <param name="listenKey">Listen key retrieved by the StartUserStream method</param>
        /// <param name="onAccountInfoMessage">The event handler for whenever an account info update is received</param>
        /// <param name="OnOrderUpdateMessage">The event handler for whenever an order status update is received</param>
        /// <returns>A stream subscription. This stream subscription can be used to be notified when the socket is closed and can close this specific stream
        /// using the <see cref="UnsubscribeFromStream(BinanceStreamSubscription)"/> method</returns>
        public BinanceApiResult <BinanceStreamSubscription> SubscribeToUserStream(string listenKey, Action <BinanceStreamAccountInfo> onAccountInfoMessage, Action <BinanceStreamOrderUpdate> OnOrderUpdateMessage)
        {
            if (string.IsNullOrEmpty(listenKey))
            {
                return(ThrowErrorMessage <BinanceStreamSubscription>(BinanceErrors.GetError(BinanceErrorKey.NoListenKey)));
            }

            return(CreateUserStream(listenKey, onAccountInfoMessage, OnOrderUpdateMessage));
        }
示例#5
0
        /// <summary>
        /// Subscribes to the order update stream. Prior to using this, the <see cref="BinanceClient.StartUserStream"/> method should be called.
        /// </summary>
        /// <param name="listenKey">Listen key retrieved by the StartUserStream method</param>
        /// <param name="onMessage">The event handler for the data received</param>
        /// <returns>bool indicating success</returns>
        public BinanceApiResult <bool> SubscribeToOrderUpdateStream(string listenKey, Action <BinanceStreamOrderUpdate> onMessage)
        {
            if (string.IsNullOrEmpty(listenKey))
            {
                return(ThrowErrorMessage <bool>(BinanceErrors.GetError(BinanceErrorKey.NoListenKey)));
            }

            orderUpdateCallback = onMessage;
            return(CreateUserStream(listenKey));
        }
示例#6
0
        private static string Translate2011code(BinanceErrors error)
        {
            switch (error.msg)
            {
            case "Unknown order list sent.":
                return("Ordem Desconhecida.");

            default:
                return("Erro API Binance Contate a Administração.");
            }
        }
示例#7
0
        /// <summary>
        /// Starts a user stream by requesting a listen key. This listen key can be used in subsequent requests to <see cref="BinanceSocketClient.SubscribeToAccountUpdateStream"/> and <see cref="BinanceSocketClient.SubscribeToOrderUpdateStream"/>
        /// </summary>
        /// <returns>Listen key</returns>
        public async Task <BinanceApiResult <BinanceListenKey> > StartUserStreamAsync()
        {
            if (key == null || encryptor == null)
            {
                return(ThrowErrorMessage <BinanceListenKey>(BinanceErrors.GetError(BinanceErrorKey.NoApiCredentialsProvided)));
            }

            if (AutoTimestamp && !timeSynced)
            {
                await GetServerTimeAsync();
            }

            return(await ExecuteRequest <BinanceListenKey>(GetUrl(GetListenKeyEndpoint, Api, UserDataStreamVersion), false, PostMethod));
        }
示例#8
0
        /// <summary>
        /// Stops the current user stream
        /// </summary>
        /// <returns></returns>
        public async Task <BinanceApiResult <object> > StopUserStreamAsync(string listenKey)
        {
            if (key == null || encryptor == null)
            {
                return(ThrowErrorMessage <object>(BinanceErrors.GetError(BinanceErrorKey.NoApiCredentialsProvided)));
            }

            if (AutoTimestamp && !timeSynced)
            {
                await GetServerTimeAsync();
            }

            var parameters = new Dictionary <string, string>()
            {
                { "listenKey", listenKey },
            };

            return(await ExecuteRequest <object>(GetUrl(CloseListenKeyEndpoint, Api, UserDataStreamVersion, parameters), false, DeleteMethod));
        }
示例#9
0
        /// <summary>
        /// Withdraw assets from Binance to an address
        /// </summary>
        /// <param name="asset">The asset to withdraw</param>
        /// <param name="address">The address to send the funds to</param>
        /// <param name="amount">The amount to withdraw</param>
        /// <param name="name">Name for the transaction</param>
        /// <param name="recvWindow">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>
        /// <returns>Withdrawal confirmation</returns>
        public async Task <BinanceApiResult <BinanceWithdrawalPlaced> > WithdrawAsync(string asset, string address, decimal amount, string name = null, long?recvWindow = null)
        {
            if (key == null || encryptor == null)
            {
                return(ThrowErrorMessage <BinanceWithdrawalPlaced>(BinanceErrors.GetError(BinanceErrorKey.NoApiCredentialsProvided)));
            }

            if (AutoTimestamp && !timeSynced)
            {
                await GetServerTimeAsync();
            }

            var parameters = new Dictionary <string, string>()
            {
                { "asset", asset },
                { "address", address },
                { "amount", amount.ToString(CultureInfo.InvariantCulture) },
                { "timestamp", GetTimestamp() }
            };

            AddOptionalParameter(parameters, "name", name);
            AddOptionalParameter(parameters, "recvWindow", recvWindow?.ToString());

            var result = await ExecuteRequest <BinanceWithdrawalPlaced>(GetUrl(WithdrawEndpoint, WithdrawalApi, WithdrawalVersion, parameters), true, PostMethod);

            if (!result.Success || result.Data == null)
            {
                return(result);
            }

            result.Success = result.Data.Success;
            if (!result.Success)
            {
                result.Error = new BinanceError()
                {
                    Message = result.Data.Message
                }
            }
            ;
            return(result);
        }
示例#10
0
        /// <summary>
        /// Gets the withdrawal history
        /// </summary>
        /// <param name="asset">Filter by asset</param>
        /// <param name="status">Filter by status</param>
        /// <param name="startTime">Filter start time from</param>
        /// <param name="endTime">Filter end time till</param>
        /// <param name="recvWindow">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>
        /// <returns>List of withdrawals</returns>
        public async Task <BinanceApiResult <BinanceWithdrawalList> > GetWithdrawHistoryAsync(string asset = null, WithdrawalStatus?status = null, DateTime?startTime = null, DateTime?endTime = null, long?recvWindow = null)
        {
            if (key == null || encryptor == null)
            {
                return(ThrowErrorMessage <BinanceWithdrawalList>(BinanceErrors.GetError(BinanceErrorKey.NoApiCredentialsProvided)));
            }

            if (AutoTimestamp && !timeSynced)
            {
                await GetServerTimeAsync();
            }

            var parameters = new Dictionary <string, string>()
            {
                { "timestamp", GetTimestamp() }
            };

            AddOptionalParameter(parameters, "asset", asset);
            AddOptionalParameter(parameters, "status", status != null ? JsonConvert.SerializeObject(status, new WithdrawalStatusConverter(false)): null);
            AddOptionalParameter(parameters, "startTime", startTime != null ? ToUnixTimestamp(startTime.Value).ToString(CultureInfo.InvariantCulture) : null);
            AddOptionalParameter(parameters, "endTime", endTime != null ? ToUnixTimestamp(endTime.Value).ToString(CultureInfo.InvariantCulture) : null);
            AddOptionalParameter(parameters, "recvWindow", recvWindow?.ToString());

            var result = await ExecuteRequest <BinanceWithdrawalList>(GetUrl(WithdrawHistoryEndpoint, WithdrawalApi, WithdrawalVersion, parameters), true, PostMethod);

            if (!result.Success || result.Data == null)
            {
                return(result);
            }

            result.Success = result.Data.Success;
            if (!result.Success)
            {
                result.Error = new BinanceError()
                {
                    Message = result.Data.Message
                }
            }
            ;
            return(result);
        }
示例#11
0
        /// <summary>
        /// Gets account information, including balances
        /// </summary>
        /// <param name="recvWindow">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>
        /// <returns>The account information</returns>
        public async Task <BinanceApiResult <BinanceAccountInfo> > GetAccountInfoAsync(long?recvWindow = null)
        {
            if (key == null || encryptor == null)
            {
                return(ThrowErrorMessage <BinanceAccountInfo>(BinanceErrors.GetError(BinanceErrorKey.NoApiCredentialsProvided)));
            }

            if (AutoTimestamp && !timeSynced)
            {
                await GetServerTimeAsync();
            }

            var parameters = new Dictionary <string, string>()
            {
                { "timestamp", GetTimestamp() }
            };

            AddOptionalParameter(parameters, "recvWindow", recvWindow?.ToString());

            return(await ExecuteRequest <BinanceAccountInfo>(GetUrl(AccountInfoEndpoint, Api, SignedVersion, parameters), true, GetMethod));
        }
示例#12
0
        /// <summary>
        /// Gets a list of open orders for the provided symbol
        /// </summary>
        /// <param name="symbol">The symbol to get open orders for</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>
        /// <returns>List of open orders</returns>
        public async Task <BinanceApiResult <BinanceOrder[]> > GetOpenOrdersAsync(string symbol, int?receiveWindow = null)
        {
            if (key == null || encryptor == null)
            {
                return(ThrowErrorMessage <BinanceOrder[]>(BinanceErrors.GetError(BinanceErrorKey.NoApiCredentialsProvided)));
            }

            if (AutoTimestamp && !timeSynced)
            {
                await GetServerTimeAsync();
            }

            var parameters = new Dictionary <string, string>()
            {
                { "symbol", symbol },
                { "timestamp", GetTimestamp() }
            };

            AddOptionalParameter(parameters, "recvWindow", receiveWindow?.ToString());

            return(await ExecuteRequest <BinanceOrder[]>(GetUrl(OpenOrdersEndpoint, Api, SignedVersion, parameters), true));
        }
示例#13
0
        /// <summary>
        /// Gets all user trades for provided symbol
        /// </summary>
        /// <param name="symbol">Symbol to get trades for</param>
        /// <param name="limit">The max number of results</param>
        /// <param name="fromId">TradeId to fetch from. Default gets most recent trades</param>
        /// <param name="recvWindow">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>
        /// <returns>List of trades</returns>
        public async Task <BinanceApiResult <BinanceTrade[]> > GetMyTradesAsync(string symbol, int?limit = null, long?fromId = null, long?recvWindow = null)
        {
            if (key == null || encryptor == null)
            {
                return(ThrowErrorMessage <BinanceTrade[]>(BinanceErrors.GetError(BinanceErrorKey.NoApiCredentialsProvided)));
            }

            if (AutoTimestamp && !timeSynced)
            {
                await GetServerTimeAsync();
            }

            var parameters = new Dictionary <string, string>()
            {
                { "symbol", symbol },
                { "timestamp", GetTimestamp() }
            };

            AddOptionalParameter(parameters, "limit", limit?.ToString(CultureInfo.InvariantCulture));
            AddOptionalParameter(parameters, "fromId", fromId?.ToString(CultureInfo.InvariantCulture));
            AddOptionalParameter(parameters, "recvWindow", recvWindow?.ToString(CultureInfo.InvariantCulture));

            return(await ExecuteRequest <BinanceTrade[]>(GetUrl(MyTradesEndpoint, Api, SignedVersion, parameters), true, GetMethod));
        }
示例#14
0
        private static string ServerError(BinanceErrors error)
        {
            switch (error.code)
            {
            case -1000:
                return("Erro Desconhecido na APi.");

            case -1001:
                return("O servidor se desconectou.");

            case -1002:
                return("Autorização negada para este recurso.");

            case -1003:
                if (error.msg.Contains("banned"))
                {
                    return("Seu Ip esta banido por exeço de requisições.");
                }
                return("Exeço de requisições exedida.");

            case -1006:
                return("Uma resposta inesperada foi recebida pelo servidor.");

            case -1007:
                return("Tempo de requisição excedido.");

            case -1014:
                return("Combinação de ordem não suportada.");

            case -1015:
                return("Número de Ordem por segundo foi exedida.");

            case -1016:
                return("Este Serviço foi desativado.");

            case -1020:
                return("Operaçao nao Suportada.");

            case -1021:
                return("Horario do Servidor não esta sincronizado.");

            case -1022:
                return("Assinatura de solicitação inválida.");

            case -1010:
                return("Erro nao tratado código 1010");

            case -1100:
                return("Parametro com Caracteres Ilegais encontrados.");

            case -1101:
                return("Muitos Parâmetros Enviados.");

            case -1102:
                return("Parâmetro Nullo ou Ausente");

            case -1103:
                return("Parâmetro Desconhecido enviado.");

            case -1104:
                return("Não foi possivel Ler o parâmetro enviado.");

            case -1105:
                return("O parâmetro estava vazio.");

            case -1106:
                return("Parametro desnecessário enviado.");

            case -1111:
                return("Precisão acima do permitido para este symbol.");

            case -1112:
                return("Book de ofertas em falta.");

            case -1114:
                return("Parâmetro TimeInForce enviado quando não necessário.");

            case -1115:
                return("TimeInforce Inválido.");

            case -1116:
                return("Tipo de Ordem Inválida.");

            case -1117:
                return("Side Invalido.");

            case -1118:
                return("newClientOrderId estava vazio.");

            case -1119:
                return("origClientOrderId estava vazio.");

            case -1120:
                return("Intervalo Inválido.");

            case -1121:
                return("Symbol Inválido.");

            case -1125:
                return("Listen Key Inválida.");

            case -1127:
                return("Intervalo de Tempo Inválido.");

            case -1128:
                return("Combinação de Parâmetros Inválidos.");

            case -1130:
                return("Data Inválida.");

            case -2010:
                return("Ordem Rejeitada.");

            case -2011:
                return(Translate2011code(error));

            case -2013:
                return("Ordem Inexistente.");

            case -2014:
                return("Chave API inválida.");

            case -2015:
                return("Api Kei, Ip ou Permissão bloqueados.");

            case -2016:
                return("Nenhuma Janela encontrada para este symbol.");

            default:
                return(ErrorByMsg(error));
            }
        }
示例#15
0
        private static string ErrorByMsg(BinanceErrors error)
        {
            switch (error.msg)
            {
            case "Filter failure: PRICE_FILTER":
                return("Preço da Ordem Muito alto ou muito baixo.");

            case "Filter failure: PERCENT_PRICE":
                return("Preço muito alto ou muito baixo sobre a media nos ultimos minutos");

            case "Filter failure: LOT_SIZE":
                return("Quantidade muito alta ou muito baixa ou não acopanha o step size");

            case "Filter failure: MIN_NOTIONAL":
                return("quantidade é muito baixo.");

            case "Filter failure: ICEBERG_PARTS":
                return("Iceberg irá quebrar em muitos pedaços e a quantidade é muito pequena.");

            case "Filter failure: MARKET_LOT_SIZE":
                return("Quantidade a mercado muito alta ou muito baixa ou não acopanha o step size");

            case "Filter failure: MAX_NUM_ORDERS":
                return("Muitas Ordens Abertas para este symbol");

            case "Filter failure: MAX_ALGO_ORDERS":
                return("Muitas Ordens Stoloss e Take Profit abertas para este symbol");

            case "Filter failure: MAX_NUM_ICEBERG_ORDERS":
                return("Muitos Icebertg ordems abertas para este symbol");

            case "Filter failure: EXCHANGE_MAX_NUM_ORDERS":
                return("Muitas Ordens abertas para esta conta");

            case "Filter failure: EXCHANGE_MAX_ALGO_ORDERS":
                return("A conta possui muitas perdas em abert ou recebe ordens de lucro na bolsa");

            case "Unknown order sent.":
                return("Ordem Desconhecida. orderId, clOrdId, origClOrdId não encontrado.");

            case "Duplicate order sent.":
                return("Ordem Duplicada,clOrdId  já utilizado.");

            case "Account has insufficient balance for requested action.":
                return("Fundos Insuficientes");

            case "Market orders are not supported for this symbol.":
                return("Ordem a Mercado não permitidas para este symbol");

            case "Iceberg orders are not supported for this symbol.":
                return("icebergQty nao permitidas para este symbol");

            case "Stop loss orders are not supported for this symbol.":
                return("Stop Loss nao suportado para este symbol");

            case "Stop loss limit orders are not supported for this symbol.":
                return("Stop Loss Limit nao suportado para este symbol");

            case "Take profit orders are not supported for this symbol":
                return("Take Profit nao suportado para este symbol");

            case "Take profit limit orders are not supported for this symbol.":
                return("Take Profit Limit nao suportado para este symbol");

            case "Price * QTY is zero or less":
                return("Valor da ordem muito pequeno");

            case "IcebergQty exceeds QTY.":
                return("icebergQty  precisa ser menor que a quantidade.");

            case "This action disabled is on this account.":
                return("Ação Esta desabilitada para esta conta, contate o administrador.");

            case "Unsupported order combination.":
                return("orderType, timeInForce, stopPrice, ou icebergQty combinaçao nao permitida.");

            case "Order would trigger immediately.":
                return("Valor de Entrada Ultrapassado.");

            case "Cancel order is invalid. Check origClOrdId and orderId.":
                return("origClOrdId or orderId não enviados.");

            case "Order would immediately match and take.":
                return("Ordem do tipo de pedido LIMIT_MAKER seria negociada imediatamente.");

            case "The relationship of the prices for the orders is not correct.":
                return("Regras para envio de Ordem Oco Inválidas");

            case "OCO orders are not supported for this symbol":
                return("Ordems OCO nao liberadas para este symbol.");

            default:
                return("Erro API Binance Contate a Administração.");
            }
        }
示例#16
0
 public static BinanceErrors GetError(BinanceErrors error)
 {
     error.motivo = ServerError(error);
     return(error);
 }
示例#17
0
        private async Task <BinanceApiResult <T> > ExecuteRequest <T>(Uri uri, bool signed = false, string method = GetMethod, int currentTry = 0)
        {
            var    apiResult    = (BinanceApiResult <T>)Activator.CreateInstance(typeof(BinanceApiResult <T>));
            string returnedData = "";

            try
            {
                var uriString = uri.ToString();
                if (signed)
                {
                    uriString +=
                        $"&signature={ByteToString(encryptor.ComputeHash(Encoding.UTF8.GetBytes(uri.Query.Replace("?", ""))))}";
                }

                var request = RequestFactory.Create(uriString);
                request.Headers.Add("X-MBX-APIKEY", key);
                request.Method = method;

                log.Write(LogVerbosity.Debug, $"Sending {method} request to {uriString}");
                var response = request.GetResponse();
                using (var reader = new StreamReader(response.GetResponseStream()))
                {
                    returnedData = await reader.ReadToEndAsync();

                    var result = JsonConvert.DeserializeObject <T>(returnedData);
                    apiResult.Success = true;
                    apiResult.Data    = result;
                    return(apiResult);
                }
            }
            catch (WebException we)
            {
                var response = (HttpWebResponse)we.Response;
                if ((int)response.StatusCode >= 400)
                {
                    try
                    {
                        using (var reader = new StreamReader(response.GetResponseStream()))
                        {
                            var error = JsonConvert.DeserializeObject <BinanceError>(await reader.ReadToEndAsync());
                            apiResult.Success = false;
                            apiResult.Error   = error;
                            log.Write(LogVerbosity.Warning,
                                      $"Request to {uri} returned an error: {apiResult.Error?.Code} - {apiResult.Error?.Message}");
                            return(apiResult);
                        }
                    }
                    catch (Exception)
                    {
                        log.Write(LogVerbosity.Warning, $"Couldn't parse error response for status code {response.StatusCode}");
                    }
                }

                if (currentTry < MaxRetries)
                {
                    return(await ExecuteRequest <T>(uri, signed, method, ++currentTry));
                }

                return(ThrowErrorMessage <T>(BinanceErrors.GetError(BinanceErrorKey.ErrorWeb), $"Status: {response.StatusCode}-{response.StatusDescription}, Message: {we.Message}"));
            }
            catch (JsonSerializationException jse)
            {
                return(ThrowErrorMessage <T>(BinanceErrors.GetError(BinanceErrorKey.ParseErrorSerialization), $"Message: {jse.Message}. Received data: {returnedData}"));
            }
            catch (JsonReaderException jre)
            {
                return(ThrowErrorMessage <T>(BinanceErrors.GetError(BinanceErrorKey.ParseErrorReader), $"Error occured at Path: {jre.Path}, LineNumber: {jre.LineNumber}, LinePosition: {jre.LinePosition}. Received data: {returnedData}"));
            }
            catch (Exception e)
            {
                return(ThrowErrorMessage <T>(BinanceErrors.GetError(BinanceErrorKey.UnknownError), $"Message: {e.Message}"));
            }
        }