python-binance Documentation

repository·master·Indexed 26 days ago

https://github.com/sammchardy/python-binance

An unofficial Python wrapper for the Binance exchange REST API v3, supporting Spot, Futures, Margin, and Vanilla Options trading. It provides both synchronous (binance.client) and asynchronous (binance.async_client) interfaces, along with WebSocket support for real-time data via binance.ws.streams and depth cache management for order book tracking.

Tokens
30.3K
Snippets
80
Records
140
Agent score
92%

What's inside python-binance

  1. Monitor API Rate Limits and usage headers

    master

    Binance returns rate limit information in the response headers. You can access these via client.response.headers.

    Common headers include:

    • X-MBX-USED-WEIGHT-(intervalNum)(intervalLetter)
    • X-MBX-ORDER-COUNT-(intervalNum)

    Example of accessing headers in an async context:

    import asyncio
    from binance import AsyncClient
    
    api_key = '<api_key>'
    api_secret = '<api_secret>'
    
    async def main():
        client = await AsyncClient.create(api_key, api_secret)
        res = await client.get_exchange_info()
        print(client.response.headers)
        await client.close_connection()
    
    if __name__ == "__main__":
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main())
  2. Understand Cross-margin vs Isolated margin trading

    master

    Binance provides two types of margin trading:

    1. Cross-margin: All margin is held in a single account.
    2. Isolated margin: Each trading pair has its own separate margin account.

    Important Interaction Rules:

    • Most trade execution endpoints use the cross-margin account by default.
    • To interact with an isolated margin account, you must use the isIsolated='TRUE' or isolatedSymbol=symbol_name parameters depending on the specific endpoint.
  3. Enable orjson for faster JSON parsing

    master

    To improve performance, especially when using websockets with large messages, you can opt-in to orjson parsing. python-binance will automatically detect and use orjson if it is installed in your environment. It is not enabled by default due to interpreter compatibility requirements.

    pip install orjson
  4. Use DepthCacheManager for asyncio depth cache updates

    master

    For asyncio based applications, use DepthCacheManager (or OptionsDepthCacheManager for vanilla options).

    Usage Pattern:

    • Pass an existing AsyncClient and a symbol to the constructor.
    • Use the async with context manager pattern to handle the lifecycle.
    • Retrieve updates using await dcm_socket.recv().

    Configuration:

    • refresh_interval: Controls how often the order book is fetched via REST to stay synced. Default is 30 minutes. Set to 0 or None to disable refreshing.
    import asyncio
    from binance import AsyncClient, DepthCacheManager
    
    async def main():
        client = await AsyncClient.create()
        dcm = DepthCacheManager(client, 'BNBBTC')
    
        async with dcm as dcm_socket:
            while True:
                depth_cache = await dcm_socket.recv()
                print("symbol {}".format(depth_cache.symbol))
                print("top 5 bids")
                print(depth_cache.get_bids()[:5])
                print("top 5 asks")
                print(depth_cache.get_asks()[:5])
                print("last update time {}".format(depth_cache.update_time))
    
    if __name__ == "__main__":
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main())
  5. Stream data with BinanceSocketManager (Asynchronous)

    master

    The BinanceSocketManager is designed for asyncio environments.

    Usage Pattern:

    1. Create an AsyncClient.
    2. Pass the client to BinanceSocketManager(client).
    3. Create a socket (e.g., bm.trade_socket('SYMBOL')).
    4. Use an async with context manager to receive messages via await tscm.recv().

    Options:

    • Timeout: You can set a custom timeout for connections using the user_timeout parameter: BinanceSocketManager(client, user_timeout=60).
    • Manual Context: You can manually enter/exit the context using await ts.__aenter__() and await ts.__aexit__(None, None, None).
    import asyncio
    from binance import AsyncClient, BinanceSocketManager
    
    
    async def main():
        client = await AsyncClient.create()
        bm = BinanceSocketManager(client)
        # start any sockets here, i.e a trade socket
        ts = bm.trade_socket('BNBBTC')
        # then start receiving messages
        async with ts as tscm:
            while True:
                res = await tscm.recv()
                print(res)
    
        await client.close_connection()
    
    if __name__ == "__main__":
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main())
  6. Stop individual or all streams in ThreadedWebsocketManager

    master

    When you start a stream with ThreadedWebsocketManager, it returns a unique name for that stream. You can use this name to stop only that specific stream.

    • Stop one stream: twm.stop_socket(stream_name)
    • Stop all streams: twm.stop() (Note: You cannot start new streams after calling stop()).
    from binance import ThreadedWebsocketManager
    
    symbol = 'BNBBTC'
    
    twm = ThreadedWebsocketManager()
    twm.start()
    
    def handle_socket_message(msg):
        print(f"message type: {msg['e']}")
        print(msg)
    
    # Capture the stream name
    depth_stream_name = twm.start_depth_socket(callback=handle_socket_message, symbol=symbol)
    
    # some time later
    twm.stop_socket(depth_stream_name)
  7. Enable Verbose Mode for REST API calls

    master

    Verbose mode provides detailed logging of all HTTP requests and responses (method, URL, headers, body, and status codes). This is recommended for quick debugging but should be disabled in production to minimize overhead.

    Using the verbose parameter (Quick Debugging)

    Pass verbose=True when initializing the Client or AsyncClient.

    For fine-grained control in production, use the standard logging module to set the level for binance.base_client specifically.

    # Method 1: Using the verbose parameter (Quick Debugging)
    from binance.client import Client
    import logging
    
    logging.basicConfig(level=logging.DEBUG)
    client = Client(api_key, api_secret, verbose=True)
    server_time = client.get_server_time()
    
    # For AsyncClient
    import asyncio
    from binance.async_client import AsyncClient
    
    async def main():
        client = await AsyncClient.create(api_key, api_secret, verbose=True)
        server_time = await client.get_server_time()
        await client.close_connection()
    
    if __name__ == "__main__":
        asyncio.run(main())
    
    # Method 2: Using Python's Logging Module (Recommended for Production)
    import logging
    from binance.client import Client
    
    logging.basicConfig(
        level=logging.INFO, 
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    # Enable debug logging for binance specifically
    logging.getLogger('binance.base_client').setLevel(logging.DEBUG)
    
    client = Client(api_key, api_secret)
  8. Stream data with ThreadedWebsocketManager

    master

    The ThreadedWebsocketManager is used for streaming data without requiring asyncio programming.

    Key Requirements:

    • Initialization: You must call .start() to initialize the internal loop before starting any sockets.
    • Callbacks: Every socket start method (e.g., start_ticker_socket) requires a callback function to handle incoming messages.
    • Authentication: For authenticated streams, provide api_key and api_secret during instantiation.
    • Persistence: Use .join() to keep the manager running in the main thread.
    • Termination: Use .stop_socket(stream_name) to stop a specific stream or .stop() to stop all streams.

    Socket Types:

    • Individual sockets: start_kline_socket, start_depth_socket, etc.
    • Multiplex sockets: start_multiplex_socket(callback=..., streams=['stream1', 'stream2']).
    import time
    from binance import ThreadedWebsocketManager
    
    api_key = '<api_key>'
    api_secret = '<api_secret>'
    
    def main():
        symbol = 'BNBBTC'
    
        twm = ThreadedWebsocketManager(api_key=api_key, api_secret=api_secret)
        # start is required to initialise its internal loop
        twm.start()
    
        def handle_socket_message(msg):
            print(f"message type: {msg['e']}")
            print(msg)
    
        twm.start_kline_socket(callback=handle_socket_message, symbol=symbol)
    
        # multiple sockets can be started
        twm.start_depth_socket(callback=handle_socket_message, symbol=symbol)
    
        # or a multiplex socket can be started like this
        # see Binance docs for stream names
        streams = ['bnbbtc@miniTicker', 'bnbbtc@bookTicker']
        twm.start_multiplex_socket(callback=handle_socket_message, streams=streams)
    
        twm.join()
    
    if __name__ == "__main__":
       main()
  9. Enable Verbose Mode for WebSockets

    master

    WebSocket connections support verbose mode to log raw received messages, connection state changes, reconnection attempts, and subscription events.

    Using the verbose parameter

    Pass verbose=True when creating the BinanceSocketManager.

    Using the Logging Module

    Set the log level for binance.ws or specific sub-components.

    Sub-components for granular logging:

    • binance.ws.websocket_api: Log only WebSocket API messages
    • binance.ws.reconnecting_websocket: Log reconnection events
    • binance.ws.streams: Log stream events
    import logging
    import asyncio
    from binance import AsyncClient, BinanceSocketManager
    
    # Method 1: Using the verbose parameter
    logging.basicConfig(level=logging.DEBUG)
    
    async def main():
        client = await AsyncClient.create()
        # Enable verbose mode for WebSocket connections
        bm = BinanceSocketManager(client, verbose=True)
    
        ts = bm.trade_socket('BTCUSDT')
        async with ts as tscm:
            msg = await tscm.recv()
            print(msg)
    
        await client.close_connection()
    
    # Method 2: Using Python's Logging Module
    logging.basicConfig(level=logging.DEBUG)
    # Enable debug logging for all WebSocket connections
    logging.getLogger('binance.ws').setLevel(logging.DEBUG)
    
    # Specific component logging examples:
    # logging.getLogger('binance.ws.websocket_api').setLevel(logging.DEBUG)
    # logging.getLogger('binance.ws.reconnecting_websocket').setLevel(logging.DEBUG)
    # logging.getLogger('binance.ws.streams').setLevel(logging.DEBUG)