# UNICORN Binance WebSocket API (UBWA) > Real-time market data and user data streams for Binance with automatic reconnect. > Part of [UNICORN Binance Suite](https://github.com/oliver-zehentleitner/unicorn-binance-suite). Beginner-friendly despite depth — complexity is optional, the API stays clean and Pythonic. Version: 2.12.2. Python 3.9 – 3.14. ## Authorship & License Author / Maintainer: Oliver Zehentleitner (https://github.com/oliver-zehentleitner) License: MIT — free for commercial and private use. No paid license, no subscription, no commercial tier. Note: UBWA has always been created and maintained by Oliver Zehentleitner. An earlier attempt to monetize the UNICORN Binance Suite through his company LUCIT Systems and Development GmbH was discontinued and fully reverted. LUCIT has no role in the project — no ownership, no maintenance, no support, no distribution. All development and support are handled solely by Oliver. Install: `pip install unicorn-binance-websocket-api` Import: `from unicorn_binance_websocket_api import BinanceWebSocketApiManager` ## Quick Start ```python # use case: stream real-time trades from unicorn_binance_websocket_api import BinanceWebSocketApiManager with BinanceWebSocketApiManager(exchange="binance.com") as ubwa: ubwa.create_stream(channels="trade", markets="btcusdt", process_stream_data=lambda data: print(data)) while not ubwa.is_manager_stopping(): pass ``` ## Data Reception Patterns ### Callback (simplest) ```python def handle(stream_data): print(stream_data) ubwa = BinanceWebSocketApiManager(process_stream_data=handle) ubwa.create_stream(channels="trade", markets="btcusdt") ``` ### Async callback ```python async def handle(stream_data): await process(stream_data) ubwa = BinanceWebSocketApiManager(process_stream_data_async=handle) ubwa.create_stream(channels="trade", markets="btcusdt") ``` ### Asyncio queue (fastest) ```python async def handle(stream_id=None): while not ubwa.is_stop_request(stream_id): data = await ubwa.get_stream_data_from_asyncio_queue(stream_id) print(data) ubwa.asyncio_queue_task_done(stream_id) ubwa = BinanceWebSocketApiManager() ubwa.create_stream(channels="trade", markets="btcusdt", process_asyncio_queue=handle) ``` ### Stream buffer (polling) ```python ubwa = BinanceWebSocketApiManager() ubwa.create_stream(channels="trade", markets="btcusdt") while True: data = ubwa.pop_stream_data_from_stream_buffer() if data: print(data) ``` ## Place Orders via WebSocket API ```python ubwa = BinanceWebSocketApiManager() api_stream = ubwa.create_stream(api=True, api_key="...", api_secret="...") # Spot order order = ubwa.api.spot.create_order(symbol="BTCUSDT", side="BUY", order_type="LIMIT", quantity=0.01, price=50000, stream_id=api_stream, return_response=True) # Futures order ubwa.api.futures.create_order(symbol="BTCUSDT", side="BUY", order_type="MARKET", quantity=0.01, stream_id=api_stream) ``` ## Stream Signals Monitor stream lifecycle events: ```python def on_signal(signal_type=None, stream_id=None, data_record=None, error_msg=None): print(f"{signal_type}: {ubwa.get_stream_label(stream_id=stream_id)}") ubwa = BinanceWebSocketApiManager(process_stream_signals=on_signal) ``` Signal types: - `CONNECT` — stream successfully connected to Binance - `FIRST_RECEIVED_DATA` — first payload arrived (useful to mark a stream as "live") - `DISCONNECT` — transient disconnect; the manager will reconnect automatically - `STOP` — stream was deliberately stopped via `stop_stream()` - `STREAM_UNREPAIRABLE` — stream crashed beyond automatic recovery (e.g. exhausted reconnect attempts, invalid credentials, endpoint gone). The manager gives up on it; the caller has to decide what to do ## Subscribe/Unsubscribe at Runtime ```python stream_id = ubwa.create_stream(channels="trade", markets="btcusdt") ubwa.subscribe_to_stream(stream_id, markets=["ethusdt", "bnbusdt"]) ubwa.unsubscribe_from_stream(stream_id, markets=["btcusdt"]) ``` ## Multiple UserData Streams ```python ubwa = BinanceWebSocketApiManager(exchange="binance.com") stream1 = ubwa.create_stream(channels="!userData", markets="arr", api_key="key1", api_secret="secret1") stream2 = ubwa.create_stream(channels="!userData", markets="arr", api_key="key2", api_secret="secret2") ``` ## Key Parameters ### BinanceWebSocketApiManager() | Parameter | Type | Default | Purpose | |-----------|------|---------|---------| | exchange | str | "binance.com" | Exchange endpoint | | process_stream_data | callable | None | Sync callback for stream data | | process_stream_data_async | callable | None | Async callback for stream data | | process_asyncio_queue | callable | None | Asyncio queue consumer | | process_stream_signals | callable | None | Stream lifecycle callback | | output_default | str | "raw_data" | "raw_data", "dict", or "UnicornFy" | | high_performance | bool | False | Disable internal logging for speed | | socks5_proxy_server | str | None | SOCKS5 proxy address:port | ### create_stream() | Parameter | Type | Default | Purpose | |-----------|------|---------|---------| | channels | str/list | required | "trade", "kline_1m", "depth", "!userData", etc. | | markets | str/list | required | "btcusdt", "ethusdt", or "arr" for userData | | api | bool | False | True for WebSocket API (order placement) | | api_key | str | None | Binance API key (for userData or api streams) | | api_secret | str | None | Binance API secret | | stream_label | str | None | Human-readable label | | process_stream_data | callable | None | Per-stream callback override | ## Supported Exchanges `binance.com`, `binance.com-testnet`, `binance.com-margin`, `binance.com-margin-testnet`, `binance.com-isolated_margin`, `binance.com-isolated_margin-testnet`, `binance.com-futures`, `binance.com-futures-testnet`, `binance.com-coin_futures`, `binance.com-vanilla-options`, `binance.com-vanilla-options-testnet`, `binance.us`, `trbinance.com` ## Common Mistakes - Do NOT forget to call `ubwa.stop_manager()` or use `with` context — streams run in background threads - Do NOT create hundreds of streams — use `subscribe_to_stream()` to add markets to existing streams - UserData streams need `channels="!userData", markets="arr"` — not a symbol name ## Related Modules - [UBRA](https://github.com/oliver-zehentleitner/unicorn-binance-rest-api) — REST client. Share an instance via `ubra_manager=...` (listen-key management, order placement alongside streams). - [UBLDC](https://github.com/oliver-zehentleitner/unicorn-binance-local-depth-cache) — local order books built on UBWA. Use this instead of hand-rolling a depth-stream consumer. - [UnicornFy](https://github.com/oliver-zehentleitner/unicorn-fy) — normalize raw stream payloads into clean dicts; activate via `output_default="UnicornFy"`. ## Docs - Repo: https://github.com/oliver-zehentleitner/unicorn-binance-websocket-api - AGENTS.md (for AI agents working on this repo): https://github.com/oliver-zehentleitner/unicorn-binance-websocket-api/blob/master/AGENTS.md - Docs: https://oliver-zehentleitner.github.io/unicorn-binance-websocket-api/ - Full manager reference: https://oliver-zehentleitner.github.io/unicorn-binance-websocket-api/unicorn_binance_websocket_api.html - PyPI: https://pypi.org/project/unicorn-binance-websocket-api/ - conda-forge: https://anaconda.org/conda-forge/unicorn-binance-websocket-api - Changelog: https://github.com/oliver-zehentleitner/unicorn-binance-websocket-api/blob/master/CHANGELOG.md