question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

binance 429 Too Many Requests - enableRateLimit: true

See original GitHub issue

I’m trying to setup async batch fetching of OHLCV values and ran into the over maxCapacity error. I have enableRateLimit set to True and was hoping that the rate limiter would dynamically queue requests rather than just throw if I spawn too many. Seems it does the later?

EDIT: It definitely does the former, just was hitting the hard coded capacity of the throttler itself

I intentionally set up the fetch to be OOB for the crypto histories (20 years of history) to see the behavior of the API when I fetched data before the exchange. Though I anticipate that as I branch out the dimensionality of the fetch with valid times I’ll encounter the same error.

System Info

  • OS: macOS Monterey (12.1)
  • Programming Language version: Python 3.9.10
  • CCXT version: 1.72.64

Code:

import ccxt.async_support as ccxt
from datetime import datetime, timedelta, timezone
import pandas as pd
import asyncio

EXCHANGES = ['binance', 'ftx', 'aax']
COIN = ['BTC', 'ETH']
LIMIT = 500

async def fetch_history_data(start_time: datetime):
    start_time = start_time.replace(second=0, microsecond=0)

    intervals = pd.date_range(start_time, datetime.now().replace(second=0, microsecond=0), freq='1min')

    reqs = {}
    exchanges = []

    # for exchange in ccxt.exchanges:
    for name in EXCHANGES:
        # Turn on rate limiting
        exchange = getattr(ccxt, name)({ 'enableRateLimit': True })
        exchanges.append(exchange)

        if not exchange.has["fetchOHLCV"]:
            print(f"Skipping {name}")
            continue
        if exchange.timeframes is None:
            print(f"Skipping {name}")
            continue
        if "1m" not in exchange.timeframes:
            print(f"Skipping {name}")
            continue

        if name not in reqs:
            reqs[name] = {}
        
        await exchange.load_markets()
        for coin in COIN:

            # Check fiat currency as well as USDT pricing
            symbol = f'{coin}/USD'
            if symbol not in exchange.symbols:
                symbol = f'{coin}/USDT'
                if symbol not in exchange.symbols:
                    continue

            data_reqs = []
            for idx in range(0, len(intervals), LIMIT):
                data_reqs.append(exchange.fetch_ohlcv(symbol, "1m", since=int(intervals[idx].replace(tzinfo=timezone.utc).timestamp() * 1000), limit=LIMIT))

            data = await asyncio.gather(*data_reqs)
            history = []
            for chunk in data:
                history += chunk
            
            reqs[name][coin] = history

    for exchange in exchanges:
        await exchange.close()
    
    columns = ['timestamp', 'open', 'high', 'low', 'close', 'volume']
    df = pd.DataFrame(columns=(['exchange', 'coin'] + columns))

    for e, cs in reqs.items():
        for c, history in cs.items():
            idf = pd.DataFrame(history, columns=columns)
            idf['exchange'] = e
            idf['coin'] = c
            df = pd.concat([df, idf])

    df = df.set_index(['timestamp', 'exchange', 'coin']).sort_index()

    return df
if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    data = loop.run_until_complete(fetch_history_data(datetime.now() - timedelta(weeks=1040)))
    print(data)

Output from python script.py

Traceback (most recent call last):
  File "/Users/jshcrowthe/Sandbox/script.py", line 76, in <module>
    data = loop.run_until_complete(fetch_history_data(datetime.now() - timedelta(weeks=1040)))
  File "/opt/homebrew/Caskroom/miniforge/base/envs/ml/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
  File "/Users/jshcrowthe/Sandbox/script.py", line 51, in fetch_history_data
    data = await asyncio.gather(*data_reqs)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/ml/lib/python3.9/site-packages/ccxt/async_support/binance.py", line 2170, in fetch_ohlcv
    response = await getattr(self, method)(self.extend(request, params))
  File "/opt/homebrew/Caskroom/miniforge/base/envs/ml/lib/python3.9/site-packages/ccxt/async_support/binance.py", line 4896, in request
    response = await self.fetch2(path, api, method, params, headers, body, config, context)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/ml/lib/python3.9/site-packages/ccxt/async_support/base/exchange.py", line 101, in fetch2
    await self.throttle(cost)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/ml/lib/python3.9/site-packages/ccxt/async_support/base/throttler.py", line 45, in __call__
    raise RuntimeError('throttle queue is over maxCapacity')
RuntimeError: throttle queue is over maxCapacity

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
ttoduacommented, Aug 1, 2022

I confirm that I’ve recently met cases of DDOS/rate-limit errors with binance . It seems some revision is needed for binance RateLimit config.

1reaction
kroitorcommented, Feb 10, 2022

@jshcrowthe i’ll paste an alternative snippet here shortly.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to Fix 429 Too Many Requests Error - Kinsta
The HTTP 429 error is returned when too many requests are made to a page within a short period of time. Find out...
Read more >
Retry-After header is 0 when receiving 429 error.
Hi, When calling the /sapi/v1/accountSnapshot endpoint more than 5 times in a minute I get a 429 response. I am using a library...
Read more >
Exchanges — ccxt 2.4.71 documentation
enableRateLimit : A boolean (true/false) value that enables the built-in rate limiter and throttles consecutive requests. This setting is true (enabled) by ...
Read more >
ccxt-dev/ccxt - Gitter
I've this message: Error: binance_cron 418 I'm a Teapot {"code":-1003,"msg":"Way too many requests; IP banned until 1525433023024. Please use the websocket for ...
Read more >
Exchange-specific Notes - Freqtrade
A exchange configuration for "binance" would look as follows: ... and which prohibit a too low stake-amount (among others) for too many orders....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found