public void ThrottleIfNecessary()
        {
            if (PreventThrottle)
            {
                return;
            }

            var reset = false;

            if (currentWeigth > RequestLimitPerMinute)
            {
                RequestThrottleResetEvent.Reset();

                RequestMinRemainingMs = (RequestLimitIntervalStartTime.AddMinutes(1).Ticks - DateTime.Now.Ticks) /
                                        TimeSpan.TicksPerMillisecond;

                Logger.LogFatal($"Binance Rate Limit Exceeded. Throttling request for {RequestMinRemainingMs}ms");

                if (RequestMinRemainingMs > 0)
                {
                    Thread.Sleep((int)RequestMinRemainingMs);
                }

                RequestThrottleResetEvent.Set();

                reset = true;
            }

            if (reset || DateTime.Now > RequestLimitIntervalStartTime.AddMinutes(1))
            {
                currentWeigth = lastWeigth;
                RequestLimitIntervalStartTime = DateTime.Now;
            }
        }
        private async Task <T> GetResponse <T>(HttpRequestMessage req, BinanceEndpointData endpoint) where T : class, new()
        {
            if (RequestLimitExceeded)
            {
                return(null);
            }

            currentWeigth += endpoint.Weight;
            lastWeigth     = endpoint.Weight;

            if (!endpoint.ShouldByPassThrottle)
            {
                RequestThrottleResetEvent.WaitOne();
                ThrottleIfNecessary();
            }

            string content = null;

            try
            {
                HttpResponseMessage response = null;

                if (req.Method == HttpMethod.Get)
                {
                    response = await HttpClient.GetAsync(req.RequestUri);
                }
                else if (req.Method == HttpMethod.Post)
                {
                    response = await HttpClient.PostAsync(req.RequestUri, req.Content);
                }
                else
                {
                    throw new ArgumentOutOfRangeException(req.Method.ToString());
                }

                content = await response.Content.ReadAsStringAsync();

                if (!response.IsSuccessStatusCode)
                {
                    if (response.StatusCode == (HttpStatusCode)418)
                    {
                        Logger.LogFatal("Binance Rate LIMIT EXCEEDED! IP Banned.");

                        SetRequestLimitExceeded();
                    }
                    else if (response.StatusCode == (HttpStatusCode)429)
                    {
                        Logger.LogFatal("Binance Rate LIMIT EXCEEDED!");

                        SetRequestLimitExceeded();
                    }
                    else
                    {
                        Logger.LogProxy(
                            $"Url: {req.RequestUri.AbsoluteUri} Status: {response.StatusCode} Content: {response.Content} Error: {content}");
                    }

                    return(null);
                }

                RequestLimitExceeded = false;

                return(JsonConvert.DeserializeObject <T>(content));
            }
            catch (Exception ex)
            {
                Logger.LogError($"UnknownError fetching Url: {req.RequestUri.AbsoluteUri} Content: {content}", ex);

                return(null);
            }
        }