Repository: sammchardy/python-binance Branch: master Commit: dc8d7b7d16fc Files: 109 Total size: 1.6 MB Directory structure: gitextract_kozbdaqs/ ├── .coverage ├── .github/ │ ├── CODEOWNERS │ ├── ISSUE_TEMPLATE/ │ │ └── bug_report.md │ └── workflows/ │ └── python-app.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .readthedocs.yaml ├── .travis.yml ├── Endpoints.md ├── LICENSE ├── PYPIREADME.rst ├── README.rst ├── binance/ │ ├── __init__.py │ ├── async_client.py │ ├── base_client.py │ ├── client.py │ ├── enums.py │ ├── exceptions.py │ ├── helpers.py │ └── ws/ │ ├── __init__.py │ ├── constants.py │ ├── depthcache.py │ ├── keepalive_websocket.py │ ├── reconnecting_websocket.py │ ├── streams.py │ ├── threaded_stream.py │ └── websocket_api.py ├── code-generator.py ├── docs/ │ ├── Makefile │ ├── account.rst │ ├── binance.rst │ ├── changelog.rst │ ├── conf.py │ ├── constants.rst │ ├── depth_cache.rst │ ├── exceptions.rst │ ├── faqs.rst │ ├── general.rst │ ├── helpers.rst │ ├── index.rst │ ├── margin.rst │ ├── market_data.rst │ ├── overview.rst │ ├── requirements.txt │ ├── sub_accounts.rst │ ├── websockets.rst │ └── withdraw.rst ├── examples/ │ ├── binace_socket_manager.py │ ├── create_oco_order.py │ ├── create_order.py │ ├── create_order_async.py │ ├── depth_cache_example.py │ ├── depth_cache_threaded_example.py │ ├── futures_algo_order_examples.py │ ├── save_historical_data.py │ ├── verbose_example.py │ ├── websocket.py │ ├── ws_create_order.py │ └── ws_create_order_async.py ├── pyproject.toml ├── pyrightconfig.json ├── pytest.ini ├── requirements.txt ├── setup.cfg ├── setup.py ├── test-requirements.txt ├── tests/ │ ├── __init__.py │ ├── conftest.py │ ├── test_api_request.py │ ├── test_async_client.py │ ├── test_async_client_futures.py │ ├── test_async_client_gift_card copy.py │ ├── test_async_client_margin.py │ ├── test_async_client_options.py │ ├── test_async_client_portfolio.py │ ├── test_async_client_ws_api.py │ ├── test_async_client_ws_futures_requests.py │ ├── test_client.py │ ├── test_client_futures.py │ ├── test_client_gift_card.py │ ├── test_client_margin.py │ ├── test_client_options.py │ ├── test_client_portfolio.py │ ├── test_client_ws_api.py │ ├── test_client_ws_futures_requests.py │ ├── test_cryptography.py │ ├── test_depth_cache.py │ ├── test_futures.py │ ├── test_get_order_book.py │ ├── test_headers.py │ ├── test_historical_klines.py │ ├── test_ids.py │ ├── test_init.py │ ├── test_keepalive_reconnect.py │ ├── test_order.py │ ├── test_ping.py │ ├── test_reconnecting_websocket.py │ ├── test_region_exception.py │ ├── test_socket_manager.py │ ├── test_streams.py │ ├── test_streams_options.py │ ├── test_threaded_socket_manager.py │ ├── test_threaded_stream.py │ ├── test_user_socket_integration.py │ ├── test_verbose_mode.py │ ├── test_websocket_verbose.py │ ├── test_ws_api.py │ └── utils.py └── tox.ini ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/CODEOWNERS ================================================ * @carlosmiei ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve title: '' labels: '' assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Code snippet to reproduce the behavior: **Expected behavior** A clear and concise description of what you expected to happen. **Environment (please complete the following information):** - Python version: [e.g. 3.5] - Virtual Env: [e.g. virtualenv, conda] - OS: [e.g. Mac, Ubuntu] - python-binance version **Logs** Please set logging to debug and paste any logs here, or upload `debug.log` file to the issue. ```python import logging # This will log to both console and file logging.basicConfig(level=logging.DEBUG,format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('debug.log'), logging.StreamHandler() ] ) ``` **Additional context** Add any other context about the problem here. ================================================ FILE: .github/workflows/python-app.yml ================================================ # This workflow will install Python dependencies, run tests and lint with a single version of Python # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python name: Python application on: workflow_dispatch: push: branches: [ main, master ] pull_request: branches: [ main, master ] permissions: contents: read jobs: lint: runs-on: ubuntu-latest timeout-minutes: 5 steps: - uses: actions/checkout@v5 - name: Set up Python uses: actions/setup-python@v6 with: python-version: '3.9' - name: Install Ruff run: pip install ruff - name: Lint code with Ruff run: ruff check --output-format=github --target-version=py39 . - name: Check code formatting with Ruff run: ruff format --check . continue-on-error: true test: needs: lint runs-on: ubuntu-22.04 timeout-minutes: 40 strategy: max-parallel: 2 matrix: python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] env: PROXY: "http://188.245.226.105:8911" TEST_TESTNET: "true" TEST_API_KEY: "u4L8MG2DbshTfTzkx2Xm7NfsHHigvafxeC29HrExEmah1P8JhxXkoOu6KntLICUc" TEST_API_SECRET: "hBZEqhZUUS6YZkk7AIckjJ3iLjrgEFr5CRtFPp5gjzkrHKKC9DAv4OH25PlT6yq5" TEST_FUTURES_API_KEY: "227719da8d8499e8d3461587d19f259c0b39c2b462a77c9b748a6119abd74401" TEST_FUTURES_API_SECRET: "b14b935f9cfacc5dec829008733c40da0588051f29a44625c34967b45c11d73c" steps: - uses: actions/checkout@v5 - name: Checking env run: | echo "PROXY: $PROXY" echo "Python version: ${{ matrix.python-version }}" - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip pip install pytest pytest-cov pyright tox if [ -f requirements.txt ]; then pip install -r requirements.txt; fi if [ -f test-requirements.txt ]; then pip install -r test-requirements.txt; fi - name: Type check with pyright (Python 3.12 only) if: matrix.python-version == '3.12' run: pyright - name: Test with tox run: tox -e py - name: Coveralls Parallel uses: coverallsapp/github-action@v2 with: parallel: true finish: needs: test if: ${{ always() }} runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: Coveralls Finished uses: coverallsapp/github-action@v2 with: parallel-finished: true ================================================ FILE: .gitignore ================================================ .tox .cache/v/cache docs/_build binance/__pycache__/ build/ dist/ python_binance.egg-info/ *__pycache__ *.egg-info/ .idea/ venv*/ .vscode .binance/ ================================================ FILE: .pre-commit-config.yaml ================================================ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 hooks: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.8.1 hooks: - id: ruff - id: ruff-format - repo: https://github.com/RobertCraigie/pyright-python rev: v1.1.389 hooks: - id: pyright ================================================ FILE: .readthedocs.yaml ================================================ # Read the Docs configuration file for Sphinx projects # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details # Required version: 2 # Set the OS, Python version and other tools you might need build: os: ubuntu-22.04 tools: python: "3.12" # You can also specify other tool versions: # nodejs: "20" # rust: "1.70" # golang: "1.20" # Build documentation in the "docs/" directory with Sphinx sphinx: configuration: docs/conf.py # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs # builder: "dirhtml" # Fail on all warnings to avoid broken references # fail_on_warning: true # Optionally build your docs in additional formats such as PDF and ePub # formats: # - pdf # - epub # Optional but recommended, declare the Python requirements required # to build your documentation # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html python: install: - requirements: docs/requirements.txt - requirements: requirements.txt ================================================ FILE: .travis.yml ================================================ dist: xenial language: python python: - "3.6" - "3.7" - "3.8" - "3.9" install: - pip install -r test-requirements.txt - pip install -r requirements.txt - pip install tox-travis script: - tox after_success: - coveralls ================================================ FILE: Endpoints.md ================================================ > :warning: **Disclaimer**: > * Before using the endpoints, please check the [API documentation](https://binance-docs.github.io/apidocs/#change-log) to be informed about the latest changes or possible bugs/problems. > * Not all parameters are mandatory. Some parameters are only mandatory in specific conditions/types. Check the official documentation the type of each parameter and to know if a parameter is mandatory or optional. > * This documentation only includes methods in client.py file. Websocket methods haven't (yet) been covered. ### [Spot/Margin/Saving/Mining Endpoints](https://binance-docs.github.io/apidocs/spot/en/) - *Wallet Endpoints* - **GET /sapi/v1/system/status** (Fetch system status.) ```python client.get_system_status() ``` - **GET /sapi/v1/capital/config/getall (HMAC SHA256)** (Get information of coins (available for deposit and withdraw) for user.) ```python client.get_all_coins_info() ``` - **GET /sapi/v1/accountSnapshot (HMAC SHA256)** (Daily Account Snapshot (USER_DATA).) ```python client.get_account_snapshot(type='SPOT') ``` - **POST /sapi/v1/account/disableFastWithdrawSwitch (HMAC SHA256)** (Disable Fast Withdraw Switch (USER_DATA).) ```python client.disable_fast_withdraw_switch(type='SPOT') ``` - **POST /sapi/v1/account/enableFastWithdrawSwitch (HMAC SHA256)** (Enable Fast Withdraw Switch (USER_DATA).) ```python client.enable_fast_withdraw_switch(type='SPOT') ``` - **POST /sapi/v1/capital/withdraw/apply (HMAC SHA256)** (Withdraw: Submit a withdraw request.) ```python client.withdraw(coin, withdrawOrderId, network, address, addressTag, amount, transactionFeeFlag, name, recvWindow) ``` - **GET /sapi/v1/capital/deposit/hisrec (HMAC SHA256)** (Fetch Deposit History(supporting network) (USER_DATA).) ```python client.get_deposit_history(coin, status, startTime, endTime, recvWindow) ``` - **GET /sapi/v1/capital/withdraw/history (HMAC SHA256)** (Fetch Withdraw History (supporting network) (USER_DATA).) ```python client.get_withdraw_history(coin, status, startTime, endTime, recvWindow) ``` - **GET /sapi/v1/capital/deposit/address (HMAC SHA256)** (Fetch deposit address with network.) ```python client.get_deposit_address(coin, status, recvWindow) ``` - **GET /sapi/v1/account/status** (Fetch account status detail.) ```python client.get_account_status(recvWindow) ``` - **GET /sapi/account/apiTradingStatus** (Fetch account api trading status detail.) ```python client.get_account_api_trading_status(recvWindow) ``` - **GET /sapi/v1/asset/dribblet (HMAC SHA256)** (DustLog: Fetch small amounts of assets exchanged BNB records.) ```python client.get_dust_log(recvWindow) ``` - **Post /sapi/v1/asset/dust (HMAC SHA256)** (Dust Transfer: Convert dust assets to BNB.) ```python client.transfer_dust(asset, recvWindow) ``` - **Get /sapi/v1/asset/assetDividend (HMAC SHA256)** (Query asset dividend record.) ```python client.get_asset_dividend_history(asset, startTime, endTime, limit, recvWindow) ``` - **GET /sapi/v1/asset/assetDetail (HMAC SHA256)** (Fetch details of assets supported on Binance.) ```python client.get_asset_details(recvWindow) ``` - **GET /sapi/v1/asset/tradeFee (HMAC SHA256)** (Fetch trade fee, values in percentage.) ```python client.get_trade_fee(symbol, recvWindow) ``` - *Market Data Endpoints* - **GET /api/v3/ping** (Test connectivity to the Rest API.) ```python client.ping() ``` - **GET /api/v3/time** (Test connectivity to the Rest API and get the current server time.) ```python client.get_server_time() ``` - **GET /api/v3/exchangeInfo** (Current exchange trading rules and symbol information.) ```python client.get_exchange_info() ``` - **GET /api/v3/depth** (Get the Order Book for the market.) ```python client.get_order_book(symbol, limit) ``` - **GET /api/v3/trades** (Get recent trades (up to last 500)) ```python client.get_recent_trades(symbol, limit) ``` - **GET /api/v3/historicalTrades** (Get older market trades.) ```python client.get_historical_trades(symbol, limit, fromId) ``` - **GET /api/v3/aggTrades** (Get compressed, aggregate trades. Trades that fill at the time, from the same order, with the same price will have the quantity aggregated.) ```python client.get_aggregate_trades(symbol, fromId, startTime, endTime, limit) # Wrapper function: Iterate over aggregate trade data from (start_time or last_id) the end of the history so far: client.aggregate_trade_iter(symbol, start_str, last_id) ``` - **GET /api/v3/klines** (Kline/candlestick bars for a symbol. Klines are uniquely identified by their open time.) ```python client.get_klines(symbol, interval, startTime, endTime, limit) # Wrapper function: Iterate over klines data from client.get_klines() client.get_historical_klines(symbol, interval, start_str, end_str, limit) ``` - **GET /api/v3/avgPrice** (Current average price for a symbol.) ```python client.get_avg_price(symbol) ``` - **GET /api/v3/ticker/24hr** (24 hour rolling window price change statistics. **Careful** when accessing this with no symbol.) ```python client.get_ticker(symbol) ``` - **GET /api/v3/ticker/price** (Latest price for a symbol or symbols.) ```python client.get_symbol_ticker(symbol) ``` - **GET /api/v3/ticker/bookTicker** (Best price/qty on the order book for a symbol or symbols.) ```python client.get_orderbook_ticker(symbol) ``` - *Spot Account/Trade Endpoints* - **POST /api/v3/order/test (HMAC SHA256)** (Test new order creation and signature/recvWindow long. Creates and validates a new order but does not send it into the matching engine.) ```python client.create_test_order(symbol, side, type, timeInForce, quantity, quoteOrderQty, price, newClientOrderId, stopPrice, icebergQty, newOrderRespType, recvWindow) ``` - **POST /api/v3/order (HMAC SHA256)** (Send in a new order.) ```python client.create_order(symbol, side, type, timeInForce, quantity, quoteOrderQty, price, newClientOrderId, stopPrice, icebergQty, newOrderRespType, recvWindow) ## Wrapper functions: # Send in a new limit order. # Default parameters: timeInForce=Client.TIME_IN_FORCE_GTC, type=Client.ORDER_TYPE_LIMIT client.order_limit(symbol, side, quantity, price, newClientOrderId, stopPrice, icebergQty, newOrderRespType, recvWindow) # Send in a new limit buy order. # Default parameters: timeInForce=Client.TIME_IN_FORCE_GTC, type=Client.ORDER_TYPE_LIMIT, side=Client.SIDE_BUY client.order_limit_buy(symbol, quantity, price, newClientOrderId, stopPrice, icebergQty, newOrderRespType, recvWindow) # Send in a new limit sell order. # Default parameters: timeInForce=Client.TIME_IN_FORCE_GTC, type=Client.ORDER_TYPE_LIMIT, side= Client.SIDE_SELL client.order_limit_sell(symbol, quantity, price, newClientOrderId, stopPrice, icebergQty, newOrderRespType, recvWindow) # Send in a new market order. # Default parameters: type=Client.ORDER_TYPE_MARKET client.order_market(symbol, side, quantity, quoteOrderQty, newClientOrderId, newOrderRespType, recvWindow) # Send in a new market buy order. # Default parameters: type=Client.ORDER_TYPE_MARKET, side=Client.SIDE_BUY client.order_market_buy(symbol, quantity, quoteOrderQty, newClientOrderId, newOrderRespType, recvWindow) # Send in a new market sell order. # Default parameters: type=Client.ORDER_TYPE_MARKET, side=Client.SIDE_SELL client.order_market_sell(symbol, quantity, quoteOrderQty, newClientOrderId, newOrderRespType, recvWindow) ``` - **DELETE /api/v3/order (HMAC SHA256)** (Cancel an active order.) ```python client.cancel_order(symbol, orderId, origClientOrderId, newClientOrderId, recvWindow) ``` - **DELETE api/v3/openOrders** (Cancels all active orders on a symbol. This includes OCO orders.) > :warning: Not yet implemented - **GET /api/v3/order (HMAC SHA256)** (Check an order's status.) ```python client.get_order(symbol, orderId, origClientOrderId, recvWindow) ``` - **GET /api/v3/openOrders (HMAC SHA256)** (Get all open orders on a symbol. **Careful** when accessing this with no symbol.) ```python client.get_open_orders(symbol, recvWindow) ``` - **GET /api/v3/allOrders (HMAC SHA256)** (Get all account orders; active, canceled, or filled.) ```python client.get_all_orders(symbol, orderId, startTime, endTime, limit, recvWindow) ``` - **POST /api/v3/order/oco (HMAC SHA256)** (Send in a new OCO order) ```python client.create_oco_order(symbol, listClientOrderId, side, quantity, limitClientOrderId, price, limitIcebergQty, stopClientOrderId, stopPrice, stopLimitPrice, stopIcebergQty, stopLimitTimeInForce, newOrderRespType, recvWindow) ## Wrapper Functions: # Send in a new OCO buy order. Default parameter: type=Client.SIDE_BUY client.order_oco_buy(symbol, listClientOrderId, quantity, limitClientOrderId, price, limitIcebergQty, stopClientOrderId, stopPrice, stopLimitPrice, stopIcebergQty, stopLimitTimeInForce, newOrderRespType, recvWindow) # Send in a new OCO sell order. Default parameter: type=Client.SIDE_SELL client.order_oco_sell(symbol, listClientOrderId, quantity, limitClientOrderId, price, limitIcebergQty, stopClientOrderId, stopPrice, stopLimitPrice, stopIcebergQty, stopLimitTimeInForce, newOrderRespType, recvWindow) ``` - **DELETE /api/v3/orderList (HMAC SHA256)** (Cancel OCO: Cancel an entire Order List) > :warning: Not yet implemented - **GET /api/v3/orderList (HMAC SHA256)** (Query OCO: Retrieves a specific OCO based on provided optional parameters) > :warning: Not yet implemented - **GET /api/v3/allOrderList (HMAC SHA256)** (Retrieves all OCO based on provided optional parameters) > :warning: Not yet implemented - **GET /api/v3/openOrderList (HMAC SHA256)** (Query Open OCO (USER_DATA)) > :warning: Not yet implemented - **GET /api/v3/account (HMAC SHA256)** (Get current account information.) ```python client.get_account(recvWindow) ``` - **GET /api/v3/myTrades (HMAC SHA256)** (Get trades for a specific account and symbol.) ```python client.get_my_trades(symbol, startTime, endTime, fromId, limit, recvWindow) ``` - *Margin Account/Trade* - **POST /sapi/v1/margin/transfer (HMAC SHA256)** (Execute transfer between margin account and spot account(MARGIN).) ```python client.transfer_margin_to_spot(asset, amount, recvWindow) client.transfer_spot_to_margin(asset, amount, recvWindow) ``` - **POST /sapi/v1/margin/loan (HMAC SHA256)** (Apply for a loan(MARGIN).) ```python client.create_margin_loan(asset, isIsolated, symbol, amount, recvWindow) ``` - **POST /sapi/v1/margin/repay (HMAC SHA256)** (Repay loan for margin account (MARGIN).) ```python client.repay_margin_loan(asset, isIsolated, symbol, amount, recvWindow) ``` - **GET /sapi/v1/margin/asset** (Query Margin Asset (MARKET_DATA).) ```python client.get_margin_asset(asset) ``` - **GET /sapi/v1/margin/pair** (Query Cross Margin Pair (MARKET_DATA).) ```python client.get_margin_symbol(symbol) ``` - **GET /sapi/v1/margin/allAssets** (Get All Cross Margin Assets (MARKET_DATA).) ```python client.get_margin_all_assets() ``` - **GET /sapi/v1/margin/allPairs** (Get All Cross Margin Pairs (MARKET_DATA).) ```python client.get_margin_all_pairs() ``` - **GET /sapi/v1/margin/priceIndex** (Query Margin PriceIndex (MARKET_DATA).) ```python client.get_margin_price_index(symbol) ``` - **POST /sapi/v1/margin/order (HMAC SHA256)** (Post a new order for margin account.) ```python client.create_margin_order(symbol, isIsolated, side, type, quantity, price, stopPrice, newClientOrderId, icebergQty, newOrderRespType, sideEffectType, timeInForce, recvWindow) ``` - **DELETE /sapi/v1/margin/order (HMAC SHA256)** (Cancel an active order for margin account.) ```python client.cancel_margin_order(symbol, isIsolated, orderId, origClientOrderId, newClientOrderId, recvWindow) ``` - **GET /sapi/v1/margin/transfer (HMAC SHA256)** (Get Cross Margin Transfer History (USER_DATA).) ```python client.transfer_margin_to_spot(asset, amount, recvWindow) client.transfer_spot_to_margin(asset, amount, recvWindow) ``` - **GET /sapi/v1/margin/loan (HMAC SHA256)** (Query Loan Record (USER_DATA).) ```python client.get_margin_loan_details(asset, isolatedSymbol, txId, startTime, endTime, current, size, recvWindow) ``` - **GET /sapi/v1/margin/repay (HMAC SHA256)** (Query repay record (USER_DATA).) ```python client.get_margin_repay_details(asset, isolatedSymbol, txId, startTime, endTime, current, size, recvWindow) ``` - **GET /sapi/v1/margin/interestHistory (HMAC SHA256)** (Get Interest History (USER_DATA).) ```python client.get_margin_interest_history(asset, isolatedSymbol, startTime, endTime, current, size, archived, recvWindow) ``` - **GET /sapi/v1/margin/forceLiquidationRec (HMAC SHA256)** (Get Force Liquidation Record (USER_DATA).) ```python client.get_margin_force_liquidation_rec(isolatedSymbol, startTime, endTime, current, size, recvWindow) ``` - **GET /sapi/v1/margin/account (HMAC SHA256)** (Query Cross Margin Account Details (USER_DATA).) ```python client.get_margin_account(recvWindow) ``` - **GET /sapi/v1/margin/order (HMAC SHA256)** (Query Margin Account's Order (USER_DATA).) ```python client.get_margin_order(symbol, isIsolated, orderId, origClientOrderId, recvWindow) ``` - **GET /sapi/v1/margin/openOrders (HMAC SHA256)** (Query Margin Account's Open Order (USER_DATA).) ```python client.get_open_margin_orders(symbol, isIsolated, recvWindow) ``` - **GET /sapi/v1/margin/allOrders (HMAC SHA256)** (Query Margin Account's All Order (USER_DATA).) ```python client.get_all_margin_orders(symbol, isIsolated, orderId, startTime, endTime, limit, recvWindow) ``` - **GET /sapi/v1/margin/myTrades (HMAC SHA256)** (Query Margin Account's Trade List (USER_DATA).) ```python client.get_margin_trades(symbol, isIsolated, startTime, endTime, fromId, limit, recvWindow) ``` - **GET /sapi/v1/margin/maxBorrowable (HMAC SHA256)** (Query Max Borrow amount for an asset (USER_DATA).) ```python client.get_max_margin_loan(asset, isolatedSymbol, recvWindow) ``` - **GET /sapi/v1/margin/maxTransferable (HMAC SHA256)** (Query Max Transfer-Out Amount (USER_DATA).) ```python client.get_max_margin_transfer(asset, isolatedSymbol, recvWindow) ``` - **POST /sapi/v1/margin/isolated/create (HMAC SHA256)** (Create Isolated Margin Account (MARGIN).) ```python client.create_isolated_margin_account(base, quote, recvWindow) ``` - **POST /sapi/v1/margin/isolated/transfer (HMAC SHA256)** (Isolated Margin Account Transfer (MARGIN).) ```python client.transfer_spot_to_isolated_margin(asset, symbol, amount, recvWindow) client.transfer_isolated_margin_to_spot(asset, symbol, amount, recvWindow) ``` - **GET /sapi/v1/margin/isolated/transfer (HMAC SHA256)** (Get Isolated Margin Transfer History (USER_DATA).) > :warning: Not yet implemented - **GET /sapi/v1/margin/isolated/account (HMAC SHA256)** (Query Isolated Margin Account Info (USER_DATA).) ```python client.get_isolated_margin_account(symbols, recvWindow) ``` - **GET /sapi/v1/margin/isolated/pair (HMAC SHA256)** (Query Isolated Margin Symbol (USER_DATA).) ```python client.get_isolated_margin_symbol(symbol, recvWindow) ``` - **GET /sapi/v1/margin/isolated/allPairs (HMAC SHA256)** (Get All Isolated Margin Symbol (USER_DATA).) ```python client.get_all_isolated_margin_symbols(recvWindow) ``` - **POST /sapi/v1/margin/manual-liquidation (HMAC SHA256)** (Margin manual liquidation (MARGIN).) ```python client.margin_manual_liquidation(type) ``` - *User Data Streams* - **POST /api/v3/userDataStream** (Create a ListenKey (Spot) (USER_STREAM): Start a new user data stream.) ```python client.stream_get_listen_key() ``` - **PUT /api/v3/userDataStream** (Ping/Keep-alive a ListenKey (Spot) (USER_STREAM).) ```python client.stream_keepalive(listenKey) ``` - **DELETE /api/v3/userDataStream** (Close a ListenKey (Spot) (USER_STREAM).) ```python client.stream_close(listenKey) ``` - **POST /sapi/v1/userDataStream** (Create a ListenKey (Margin).) ```python client.margin_stream_get_listen_key() ``` - **PUT /sapi/v1/userDataStream** (Ping/Keep-alive a ListenKey (Margin).) ```python client.margin_stream_keepalive(listenKey) ``` - **DELETE /sapi/v1/userDataStream** (Close a ListenKey (Margin).) ```python client.margin_stream_close(listenKey) ``` - **POST /sapi/v1/userDataStream/isolated** (Create a ListenKey (Isolated).) ```python client.isolated_margin_stream_get_listen_key(symbol) ``` - **PUT /sapi/v1/userDataStream/isolated** (Ping/Keep-alive a ListenKey (Isolated).) ```python client.isolated_margin_stream_keepalive(symbol, listenKey) ``` - **DELETE /sapi/v1/userDataStream/isolated** (Close a ListenKey (Isolated).) ```python client.isolated_margin_stream_close(symbol, listenKey) ``` - *Savings Endpoints* - **GET /sapi/v1/lending/daily/product/list (HMAC SHA256)** (Get Flexible Product List (USER_DATA).) ```python client.get_lending_product_list(status, featured, recvWindow) ``` - **GET /sapi/v1/lending/daily/userLeftQuota (HMAC SHA256)** (Get Left Daily Purchase Quota of Flexible Product (USER_DATA).) ```python client.get_lending_daily_quota_left(productId, recvWindow) ``` - **POST /sapi/v1/lending/daily/purchase (HMAC SHA256)** (Purchase Flexible Product (USER_DATA).) ```python client.purchase_lending_product(productId, amount, recvWindow) ``` - **GET /sapi/v1/lending/daily/userRedemptionQuota (HMAC SHA256)** (Get Left Daily Redemption Quota of Flexible Product (USER_DATA).) ```python client.get_lending_daily_redemption_quota(productId, type, recvWindow) ``` - **POST /sapi/v1/lending/daily/redeem (HMAC SHA256)** (Redeem Flexible Product (USER_DATA).) ```python client.redeem_lending_product(productId, amount, type, recvWindow) ``` - **GET /sapi/v1/lending/daily/token/position (HMAC SHA256)** (Get Flexible Product Position (USER_DATA).) ```python client.get_lending_position(asset, recvWindow) ``` - **GET /sapi/v1/lending/project/list (HMAC SHA256)** (Get Fixed and Activity Project List (USER_DATA).) ```python client.get_fixed_activity_project_list(asset, type, status, isSortAsc, sortBy, current, size, recvWindow) ``` - **POST /sapi/v1/lending/customizedFixed/purchase (HMAC SHA256)** (Purchase Fixed/Activity Project (USER_DATA).) > :warning: Not yet implemented - **GET /sapi/v1/lending/project/position/list (HMAC SHA256)** (Get Fixed/Activity Project Position (USER_DATA).) > :warning: Not yet implemented - **GET /sapi/v1/lending/union/account (HMAC SHA256)** (Lending Account (USER_DATA).) ```python client.get_lending_account(recvWindow) ``` - **GET /sapi/v1/lending/union/purchaseRecord (HMAC SHA256)** (Get Purchase Record (USER_DATA).) ```python client.get_lending_purchase_history(lendingType, asset, startTime, endTime, current, size, recvWindow) ``` - **GET /sapi/v1/lending/union/redemptionRecord (HMAC SHA256)** (Get Redemption Record (USER_DATA).) ```python client.get_lending_redemption_history(lendingType, asset, startTime, endTime, current, size, recvWindow) ``` - **GET /sapi/v1/lending/union/interestHistory (HMAC SHA256)** (Get Interest History (USER_DATA).) ```python client.get_lending_interest_history(lendingType, asset, startTime, endTime, current, size, recvWindow) ``` - **POST /sapi/v1/lending/positionChanged (HMAC SHA256)** (Change Fixed/Activity Position to Daily Position (USER_DATA).) ```python client.change_fixed_activity_to_daily_position(projectId, lot, positionId, recvWindow) ``` - *Mining Endpoints* > :warning: Not yet implemented - *Sub-Account Endpoints* - **GET /sapi/v1/sub-account/list (HMAC SHA256)** (Query Sub-account List (For Master Account).) ```python client.get_sub_account_list(email, isFreeze, page, limit, recvWindow) ``` - **GET /sapi/v1/sub-account/sub/transfer/history (HMAC SHA256)** (Query Sub-account Spot Asset Transfer History (For Master Account).) ```python client.get_sub_account_transfer_history(fromEmail, toEmail, startTime, endTime, page, limit, recvWindow) ``` - **GET /sapi/v1/sub-account/assets (HMAC SHA256)** (Query Sub-account Assets (For Master Account).) ```python client.get_sub_account_assets(email, recvWindow) ``` > :warning: The rest of methods for Sub-Account Endpoints are not yet implemented - *BLVT Endpoints* > :warning: Not yet implemented - *BSwap Endpoints* > :warning: Not yet implemented ### [USDT-M Futures](https://binance-docs.github.io/apidocs/futures/en/) - *Market Data Endpoints* - **GET /fapi/v1/ping** (Test connectivity to the Rest API.) ```python client.futures_ping() ``` - **GET /fapi/v1/time** (Test connectivity to the Rest API and get the current server time.) ```python client.futures_time() ``` - **GET /fapi/v1/exchangeInfo** (Current exchange trading rules and symbol information.) ```python client.futures_exchange_info() ``` - **GET /fapi/v1/depth** (Get the Order Book for the market.) ```python client.futures_order_book(symbol, limit) ``` - **GET /fapi/v1/trades** (Get recent trades.) ```python client.futures_recent_trades(symbol, limit) ``` - **GET /fapi/v1/historicalTrades** (Get older market historical trades (MARKET_DATA).) ```python client.futures_historical_trades(symbol, limit, fromId) ``` - **GET /fapi/v1/aggTrades** (Get compressed, aggregate trades. Trades that fill at the time, from the same order, with the same price will have the quantity aggregated.) ```python client.futures_aggregate_trades(symbol, fromId, startTime, endTime, limit) ``` - **GET /fapi/v1/klines** (Kline/candlestick bars for a symbol. Klines are uniquely identified by their open time.) ```python client.futures_klines(symbol, interval, startTime, endTime, limit) ``` - **GET /fapi/v1/premiumIndex** (Get Mark Price and Funding Rate.) ```python client.futures_mark_price(symbol) ``` - **GET /fapi/v1/fundingRate** (Get Funding Rate History.) ```python client.futures_funding_rate(symbol, startTime, endTime, limit) ``` - **GET /fapi/v1/ticker/24hr** (24 hour rolling window price change statistics. **Careful** when accessing this with no symbol.) ```python client.futures_ticker(symbol) ``` - **GET /fapi/v1/ticker/price** (Latest price for a symbol or symbols.) ```python client.futures_symbol_ticker(symbol) ``` - **GET /fapi/v1/ticker/bookTicker** (Best price/qty on the order book for a symbol or symbols.) ```python client.futures_orderbook_ticker(symbol) ``` - **GET /fapi/v1/allForceOrders** (Get all Liquidation Orders.) > :warning: Probably broken, python code below is implemented on v1/ticker/allForceOrders endpoint. ```python client.futures_liquidation_orders(symbol, startTime, endTime, limit) ``` - **GET /fapi/v1/openInterest** (Get present open interest of a specific symbol.) ```python client.futures_open_interest(symbol) ``` - **GET /futures/data/openInterestHist** (Open Interest Statistics.) ```python client.futures_open_interest_hist(symbol, period, limit, startTime, endTime) ``` - **GET /futures/data/topLongShortAccountRatio** (Top Trader Long/Short Ratio (Accounts) (MARKET_DATA).) ```python client.futures_top_longshort_account_ratio(symbol, period, limit, startTime, endTime) ``` - **GET /futures/data/topLongShortPositionRatio** (Top Trader Long/Short Ratio (Positions).) ```python client.futures_top_longshort_position_ratio(symbol, period, limit, startTime, endTime) ``` - **GET /futures/data/globalLongShortAccountRatio** (Long/Short Ratio.) ```python client.futures_global_longshort_ratio(symbol, period, limit, startTime, endTime) ``` - **GET /futures/data/takerlongshortRatio** (Taker Buy/Sell Volume.) ```python client.futures_taker_longshort_ratio(symbol, period, limit, startTime, endTime) ``` - **GET /fapi/v1/lvtKlines** (Historical BLVT NAV Kline/Candlestick.) > :warning: Not yet implemented - **GET /fapi/v1/indexInfo** (Composite Index Symbol Information.) > :warning: Not yet implemented - *Account/trades Endpoints* - **POST /sapi/v1/futures/transfer (HMAC SHA256)** (New Future Account Transfer (FUTURES): Execute transfer between spot account and futures account.) ```python client.futures_account_transfer(asset, amount, type, recvWindow) ``` - **GET /sapi/v1/futures/transfer (HMAC SHA256)** (Get Future Account Transaction History List (USER_DATA).) ```python client.transfer_history(asset, startTime, endTime, current, size, recvWindow) ``` - **POST /fapi/v1/positionSide/dual (HMAC SHA256)** (Change user's position mode (Hedge Mode or One-way Mode ) on _**EVERY symbol**_.) ```python client.futures_change_position_mode(dualSidePosition, recvWindow) ``` - **GET /fapi/v1/positionSide/dual (HMAC SHA256)** (Get user's position mode (Hedge Mode or One-way Mode ) on _**EVERY symbol**_.) ```python client.futures_get_position_mode(recvWindow) ``` - **POST /fapi/v1/order (HMAC SHA256)** (Send in a new order (TRADE).) ```python client.futures_create_order(symbol, side, positionSide, type, timeInForce, quantity, reduceOnly, price, newClientOrderId, stopPrice, closePosition, activationPrice, callbackRate, workingType, priceProtect, newOrderRespType, recvWindow) ``` - **POST /fapi/v1/batchOrders (HMAC SHA256)** (Place Multiple Orders (TRADE).) > :warning: Not yet implemented - **GET /fapi/v1/order (HMAC SHA256)** (Query Order (USER_DATA): Check an order's status.) ```python client.futures_get_order(symbol, orderId, origClientOrderId, recvWindow) ``` - **DELETE /fapi/v1/order (HMAC SHA256)** (Cancel an active order (TRADE).) ```python client.futures_cancel_order(symbol, orderId, origClientOrderId, recvWindow) ``` - **DELETE /fapi/v1/allOpenOrders (HMAC SHA256)** (Cancel All Open Orders (TRADE).) ```python client.futures_cancel_all_open_orders(symbol, recvWindow) ``` - **DELETE /fapi/v1/batchOrders (HMAC SHA256)** (Cancel Multiple Orders (TRADE).) ```python client.futures_cancel_orders(symbol, orderIdList, origClientOrderIdList, recvWindow) ``` - **POST /fapi/v1/countdownCancelAll (HMAC SHA256)** (Cancel all open orders of the specified symbol at the end of the specified countdown (TRADE).) > :warning: Not yet implemented - **GET /fapi/v1/openOrder (HMAC SHA256)** (Query Current Open Order (USER_DATA).) > :warning: Not yet implemented - **GET /fapi/v1/openOrders (HMAC SHA256)** (Get all open orders on a symbol. **Careful** when accessing this with no symbol (USER_DATA).) ```python client.futures_get_open_orders(symbol, recvWindow) ``` - **GET /fapi/v1/allOrders (HMAC SHA256)** (Get all account orders; active, canceled, or filled (USER_DATA).) ```python client.futures_get_all_orders(symbol, orderId, startTime, endTime, limit, recvWindow) ``` - **GET /fapi/v2/balance (HMAC SHA256)** (Futures Account Balance V2 (USER_DATA).) > :warning: Probably broken, python code below is implemented on v1 endpoint. ```python client.futures_account_balance(recvWindow) ``` - **GET /fapi/v2/account (HMAC SHA256)** (Account Information V2: Get current account information (USER_DATA).) > :warning: Probably broken, python code below is implemented on v1 endpoint. ```python client.futures_account(recvWindow) ``` - **POST /fapi/v1/leverage (HMAC SHA256)** (Change user's initial leverage of specific symbol market (TRADE).) ```python client.futures_change_leverage(symbol, leverage, recvWindow) ``` - **POST /fapi/v1/marginType (HMAC SHA256)** (Change the margin type for a symbol (TRADE).) ```python client.futures_change_margin_type(symbol, marginType, recvWindow) ``` - **POST /fapi/v1/positionMargin (HMAC SHA256)** (Modify Isolated Position Margin (TRADE).) ```python client.futures_change_position_margin(symbol, positionSide, amount, type, recvWindow) ``` - **GET /fapi/v1/positionMargin/history (HMAC SHA256)** (Get Position Margin Change History (TRADE).) ```python client.futures_position_margin_history(symbol, type, startTime, endTime, limit, recvWindow) ``` - **GET /fapi/v2/positionRisk (HMAC SHA256)** (Position Information V2: Get current position information (USER_DATA).) > :warning: Probably broken, python code below is implemented on v1 endpoint. ```python client.futures_position_information(symbol, recvWindow) ``` - **GET /fapi/v1/userTrades (HMAC SHA256)** (Account Trade List: Get trades for a specific account and symbol (USER_DATA).) ```python client.futures_account_trades(symbol, startTime, endTime, fromId, limit, recvWindow) ``` - **GET /fapi/v1/income (HMAC SHA256)** (Get Income History (USER_DATA).) ```python client.futures_income_history(symbol, incomeType, startTime, endTime, limit, recvWindow) ``` - **GET /fapi/v1/leverageBracket** (Notional and Leverage Brackets (USER_DATA).) > :warning: Probably broken, python code below is implemented on ticker/leverageBracket endpoint. ```python client.futures_leverage_bracket(symbol, recvWindow) ``` - **GET /fapi/v1/adlQuantile** (Position ADL Quantile Estimation (USER_DATA).) > :warning: Not yet implemented - **GET /fapi/v1/forceOrders** (User's Force Orders (USER_DATA).) > :warning: Not yet implemented - **GET /fapi/v1/apiTradingStatus** (User API Trading Quantitative Rules Indicators (USER_DATA).) > :warning: Not yet implemented - *User Data Streams* > :warning: Not yet implemented ### [Vanilla Options](https://binance-docs.github.io/apidocs/voptions/en/) - *Quoting interface* - **GET /vapi/v1/ping** (Test connectivity) ```python client.options_ping() ``` - **GET /vapi/v1/time** (Get server time) ```python client.options_time() ``` - **GET /vapi/v1/optionInfo** (Get current trading pair info) ```python client.options_info() ``` - **GET /vapi/v1/exchangeInfo** (Get current limit info and trading pair info) ```python client.options_exchange_info() ``` - **GET /vapi/v1/index** (Get the spot index price) ```python client.options_index_price(underlying) ``` - **GET /vapi/v1/ticker** (Get the latest price) ```python client.options_price(symbol) ``` - **GET /vapi/v1/mark** (Get the latest mark price) ```python client.options_mark_price(symbol) ``` - **GET /vapi/v1/depth** (Depth information) ```python client.options_order_book(symbol, limit) ``` - **GET /vapi/v1/klines** (Candle data) ```python client.options_klines(symbol, interval, startTime, endTime, limit) ``` - **GET /vapi/v1/trades** (Recently completed Option trades) ```python client.options_recent_trades(symbol, limit) ``` - **GET /vapi/v1/historicalTrades** (Query trade history) ```python client.options_historical_trades(symbol, fromId, limit) ``` - *Account and trading interface* - **GET /vapi/v1/account (HMAC SHA256)** (Account asset info (USER_DATA)) ```python client.options_account_info(recvWindow) ``` - **POST /vapi/v1/transfer (HMAC SHA256)** (Funds transfer (USER_DATA)) ```python client.options_funds_transfer(currency, type, amount, recvWindow) ``` - **GET /vapi/v1/position (HMAC SHA256)** (Option holdings info (USER_DATA)) ```python client.options_positions(symbol, recvWindow) ``` - **POST /vapi/v1/bill (HMAC SHA256)** (Account funding flow (USER_DATA)) ```python client.options_bill(currency, recordId, startTime, endTime, limit, recvWindow) ``` - **POST /vapi/v1/order (HMAC SHA256)** (Option order (TRADE)) ```python client.options_place_order(symbol, side, type, quantity, price, timeInForce, reduceOnly, postOnly, \ newOrderRespType, clientOrderId, recvWindow, recvWindow) ``` - **POST /vapi/v1/batchOrders (HMAC SHA256)** (Place Multiple Option orders (TRADE)) ```python client.options_place_batch_order(orders, recvWindow) ``` - **DELETE /vapi/v1/order (HMAC SHA256)** (Cancel Option order (TRADE)) ```python client.options_cancel_order(symbol, orderId, clientOrderId, recvWindow) ``` - **DELETE /vapi/v1/batchOrders (HMAC SHA256)** (Cancel Multiple Option orders (TRADE)) ```python client.options_cancel_batch_order(symbol, orderIds, clientOrderIds, recvWindow) ``` - **DELETE /vapi/v1/allOpenOrders (HMAC SHA256)** (Cancel all Option orders (TRADE)) ```python client.options_cancel_all_orders(symbol, recvWindow) ``` - **GET /vapi/v1/order (HMAC SHA256)** (Query Option order (TRADE)) ```python client.options_query_order(symbol, orderId, clientOrderId, recvWindow) ``` - **GET /vapi/v1/openOrders (HMAC SHA256)** (Query current pending Option orders (TRADE)) ```python client.options_query_pending_orders(symbol, orderId, startTime, endTime, limit, recvWindow) ``` - **GET /vapi/v1/historyOrders (HMAC SHA256)** (Query Option order history (TRADE)) ```python client.options_query_order_history(symbol, orderId, startTime, endTime, limit, recvWindow) ``` - **GET /vapi/v1/userTrades (HMAC SHA256)** (Option Trade List (USER_DATA)) ```python client.options_user_trades(symbol, fromId, startTime, endTime, limit, recvWindow) ``` ### [COIN-M Futures](https://binance-docs.github.io/apidocs/delivery/en/) > :warning: Not yet implemented ### [USDT-M Futures testnet](https://binance-docs.github.io/apidocs/testnet/en/) > :warning: Not yet implemented ### [COIN-M Futures testnet](https://binance-docs.github.io/apidocs/delivery_testnet/en/) > :warning: Not yet implemented - **GET /sapi/v1/loan/vip/ongoing/orders** ```python client.margin_v1_get_loan_vip_ongoing_orders(**params) ``` - **GET /sapi/v1/mining/payment/other** ```python client.margin_v1_get_mining_payment_other(**params) ``` - **GET /dapi/v1/income/asyn/id** ```python client.futures_coin_v1_get_income_asyn_id(**params) ``` - **GET /sapi/v1/simple-earn/flexible/history/subscriptionRecord** ```python client.margin_v1_get_simple_earn_flexible_history_subscription_record(**params) ``` - **POST /sapi/v1/lending/auto-invest/one-off** ```python client.margin_v1_post_lending_auto_invest_one_off(**params) ``` - **POST /sapi/v1/broker/subAccountApi/commission/coinFutures** ```python client.margin_v1_post_broker_sub_account_api_commission_coin_futures(**params) ``` - **POST /papi/v1/repay-futures-negative-balance** ```python client.papi_v1_post_repay_futures_negative_balance(**params) ``` - **POST /eapi/v1/block/order/execute** ```python client.options_v1_post_block_order_execute(**params) ``` - **GET /sapi/v1/margin/dust** ```python client.margin_v1_get_margin_dust(**params) ``` - **GET /dapi/v1/trades** ```python client.futures_coin_v1_get_trades(**params) ``` - **POST /api/v3/orderList/otoco** ```python client.v3_post_order_list_otoco(**params) ``` - **GET /fapi/v1/order/asyn** ```python client.futures_v1_get_order_asyn(**params) ``` - **GET /sapi/v1/asset/custody/transfer-history** ```python client.margin_v1_get_asset_custody_transfer_history(**params) ``` - **POST /fapi/v1/order/test** ```python client.futures_v1_post_order_test(**params) ``` - **POST /sapi/v1/broker/subAccount/blvt** ```python client.margin_v1_post_broker_sub_account_blvt(**params) ``` - **POST /sapi/v1/sol-staking/sol/redeem** ```python client.margin_v1_post_sol_staking_sol_redeem(**params) ``` - **GET /eapi/v1/countdownCancelAll** ```python client.options_v1_get_countdown_cancel_all(**params) ``` - **GET /sapi/v1/margin/tradeCoeff** ```python client.margin_v1_get_margin_trade_coeff(**params) ``` - **GET /sapi/v1/sub-account/futures/positionRisk** ```python client.margin_v1_get_sub_account_futures_position_risk(**params) ``` - **GET /dapi/v1/orderAmendment** ```python client.futures_coin_v1_get_order_amendment(**params) ``` - **GET /papi/v1/margin/openOrders** ```python client.papi_v1_get_margin_open_orders(**params) ``` - **GET /sapi/v1/margin/available-inventory** ```python client.margin_v1_get_margin_available_inventory(**params) ``` - **POST /sapi/v1/account/apiRestrictions/ipRestriction/ipList** ```python client.margin_v1_post_account_api_restrictions_ip_restriction_ip_list(**params) ``` - **GET /sapi/v2/eth-staking/account** ```python client.margin_v2_get_eth_staking_account(**params) ``` - **POST /papi/v1/asset-collection** ```python client.papi_v1_post_asset_collection(**params) ``` - **GET /papi/v1/um/trade/asyn/id** ```python client.papi_v1_get_um_trade_asyn_id(**params) ``` - **POST /sapi/v1/staking/redeem** ```python client.margin_v1_post_staking_redeem(**params) ``` - **GET /sapi/v1/loan/income** ```python client.margin_v1_get_loan_income(**params) ``` - **GET /eapi/v1/depth** ```python client.options_v1_get_depth(**params) ``` - **GET /dapi/v1/pmAccountInfo** ```python client.futures_coin_v1_get_pm_account_info(**params) ``` - **GET /sapi/v1/managed-subaccount/queryTransLogForInvestor** ```python client.margin_v1_get_managed_subaccount_query_trans_log_for_investor(**params) ``` - **POST /sapi/v1/dci/product/auto_compound/edit-status** ```python client.margin_v1_post_dci_product_auto_compound_edit_status(**params) ``` - **GET /fapi/v1/trade/asyn** ```python client.futures_v1_get_trade_asyn(**params) ``` - **GET /sapi/v1/loan/vip/request/interestRate** ```python client.margin_v1_get_loan_vip_request_interest_rate(**params) ``` - **GET /fapi/v1/fundingInfo** ```python client.futures_v1_get_funding_info(**params) ``` - **GET /sapi/v2/loan/flexible/repay/rate** ```python client.margin_v2_get_loan_flexible_repay_rate(**params) ``` - **GET /sapi/v1/lending/auto-invest/plan/id** ```python client.margin_v1_get_lending_auto_invest_plan_id(**params) ``` - **POST /sapi/v1/loan/adjust/ltv** ```python client.margin_v1_post_loan_adjust_ltv(**params) ``` - **GET /sapi/v1/bnbBurn** ```python client.margin_v1_get_bnb_burn(**params) ``` - **GET /papi/v1/um/order** ```python client.papi_v1_get_um_order(**params) ``` - **GET /sapi/v1/mining/statistics/user/status** ```python client.margin_v1_get_mining_statistics_user_status(**params) ``` - **POST /sapi/v1/staking/purchase** ```python client.margin_v1_post_staking_purchase(**params) ``` - **POST /sapi/v1/giftcard/redeemCode** ```python client.margin_v1_post_giftcard_redeem_code(**params) ``` - **GET /eapi/v1/userTrades** ```python client.options_v1_get_user_trades(**params) ``` - **GET /sapi/v1/broker/transfer/futures** ```python client.margin_v1_get_broker_transfer_futures(**params) ``` - **POST /sapi/v1/algo/spot/newOrderTwap** ```python client.margin_v1_post_algo_spot_new_order_twap(**params) ``` - **GET /sapi/v1/lending/auto-invest/target-asset/list** ```python client.margin_v1_get_lending_auto_invest_target_asset_list(**params) ``` - **GET /sapi/v1/capital/deposit/address/list** ```python client.margin_v1_get_capital_deposit_address_list(**params) ``` - **POST /sapi/v1/broker/subAccount/bnbBurn/marginInterest** ```python client.margin_v1_post_broker_sub_account_bnb_burn_margin_interest(**params) ``` - **POST /sapi/v2/loan/flexible/repay** ```python client.margin_v2_post_loan_flexible_repay(**params) ``` - **GET /sapi/v2/loan/flexible/loanable/data** ```python client.margin_v2_get_loan_flexible_loanable_data(**params) ``` - **POST /sapi/v1/broker/subAccountApi/permission** ```python client.margin_v1_post_broker_sub_account_api_permission(**params) ``` - **GET /sapi/v1/dci/product/positions** ```python client.margin_v1_get_dci_product_positions(**params) ``` - **POST /sapi/v1/convert/limit/cancelOrder** ```python client.margin_v1_post_convert_limit_cancel_order(**params) ``` - **GET /sapi/v1/margin/exchange-small-liability-history** ```python client.margin_v1_get_margin_exchange_small_liability_history(**params) ``` - **GET /sapi/v1/mining/hash-transfer/config/details/list** ```python client.margin_v1_get_mining_hash_transfer_config_details_list(**params) ``` - **GET /sapi/v1/mining/hash-transfer/profit/details** ```python client.margin_v1_get_mining_hash_transfer_profit_details(**params) ``` - **GET /sapi/v1/broker/subAccount** ```python client.margin_v1_get_broker_sub_account(**params) ``` - **GET /sapi/v1/portfolio/balance** ```python client.margin_v1_get_portfolio_balance(**params) ``` - **POST /sapi/v1/sub-account/eoptions/enable** ```python client.margin_v1_post_sub_account_eoptions_enable(**params) ``` - **POST /papi/v1/ping** ```python client.papi_v1_post_ping(**params) ``` - **GET /sapi/v1/loan/loanable/data** ```python client.margin_v1_get_loan_loanable_data(**params) ``` - **POST /sapi/v1/eth-staking/wbeth/unwrap** ```python client.margin_v1_post_eth_staking_wbeth_unwrap(**params) ``` - **PUT /fapi/v1/order** ```python client.futures_v1_put_order(**params) ``` - **GET /sapi/v1/eth-staking/eth/history/stakingHistory** ```python client.margin_v1_get_eth_staking_eth_history_staking_history(**params) ``` - **GET /papi/v1/um/conditional/openOrder** ```python client.papi_v1_get_um_conditional_open_order(**params) ``` - **GET /dapi/v1/openOrders** ```python client.futures_coin_v1_get_open_orders(**params) ``` - **GET /eapi/v1/order** ```python client.options_v1_get_order(**params) ``` - **POST /sapi/v1/convert/acceptQuote** ```python client.margin_v1_post_convert_accept_quote(**params) ``` - **GET /sapi/v1/staking/stakingRecord** ```python client.margin_v1_get_staking_staking_record(**params) ``` - **GET /sapi/v1/broker/rebate/recentRecord** ```python client.margin_v1_get_broker_rebate_recent_record(**params) ``` - **GET /eapi/v1/block/order/orders** ```python client.options_v1_get_block_order_orders(**params) ``` - **GET /sapi/v1/asset/transfer** ```python client.margin_v1_get_asset_transfer(**params) ``` - **GET /sapi/v1/loan/vip/collateral/account** ```python client.margin_v1_get_loan_vip_collateral_account(**params) ``` - **GET /sapi/v1/algo/spot/openOrders** ```python client.margin_v1_get_algo_spot_open_orders(**params) ``` - **POST /sapi/v1/loan/repay** ```python client.margin_v1_post_loan_repay(**params) ``` - **POST /sapi/v1/margin/isolated/account** ```python client.margin_v1_post_margin_isolated_account(**params) ``` - **GET /dapi/v1/fundingInfo** ```python client.futures_coin_v1_get_funding_info(**params) ``` - **GET /papi/v1/cm/leverageBracket** ```python client.papi_v1_get_cm_leverage_bracket(**params) ``` - **POST /sapi/v1/simple-earn/locked/subscribe** ```python client.margin_v1_post_simple_earn_locked_subscribe(**params) ``` - **GET /sapi/v1/margin/leverageBracket** ```python client.margin_v1_get_margin_leverage_bracket(**params) ``` - **GET /sapi/v2/portfolio/collateralRate** ```python client.margin_v2_get_portfolio_collateral_rate(**params) ``` - **POST /sapi/v2/loan/flexible/adjust/ltv** ```python client.margin_v2_post_loan_flexible_adjust_ltv(**params) ``` - **GET /sapi/v1/convert/orderStatus** ```python client.margin_v1_get_convert_order_status(**params) ``` - **POST /sapi/v1/margin/dust** ```python client.margin_v1_post_margin_dust(**params) ``` - **GET /sapi/v1/broker/subAccountApi/ipRestriction** ```python client.margin_v1_get_broker_sub_account_api_ip_restriction(**params) ``` - **GET /papi/v1/um/conditional/allOrders** ```python client.papi_v1_get_um_conditional_all_orders(**params) ``` - **PUT /eapi/v1/block/order/create** ```python client.options_v1_put_block_order_create(**params) ``` - **POST /sapi/v1/dci/product/subscribe** ```python client.margin_v1_post_dci_product_subscribe(**params) ``` - **GET /fapi/v1/income/asyn/id** ```python client.futures_v1_get_income_asyn_id(**params) ``` - **GET /dapi/v1/positionRisk** ```python client.futures_coin_v1_get_position_risk(**params) ``` - **POST /eapi/v1/countdownCancelAll** ```python client.options_v1_post_countdown_cancel_all(**params) ``` - **POST /papi/v1/repay-futures-switch** ```python client.papi_v1_post_repay_futures_switch(**params) ``` - **POST /sapi/v1/mining/hash-transfer/config/cancel** ```python client.margin_v1_post_mining_hash_transfer_config_cancel(**params) ``` - **GET /sapi/v1/broker/subAccount/depositHist** ```python client.margin_v1_get_broker_sub_account_deposit_hist(**params) ``` - **POST /eapi/v1/block/order/create** ```python client.options_v1_post_block_order_create(**params) ``` - **GET /sapi/v1/capital/deposit/subAddress** ```python client.margin_v1_get_capital_deposit_sub_address(**params) ``` - **GET /sapi/v1/mining/payment/list** ```python client.margin_v1_get_mining_payment_list(**params) ``` - **GET /fapi/v1/pmAccountInfo** ```python client.futures_v1_get_pm_account_info(**params) ``` - **GET /dapi/v1/adlQuantile** ```python client.futures_coin_v1_get_adl_quantile(**params) ``` - **GET /eapi/v1/income/asyn/id** ```python client.options_v1_get_income_asyn_id(**params) ``` - **POST /api/v3/cancelReplace** ```python client.v3_post_cancel_replace(**params) ``` - **PUT /papi/v1/um/order** ```python client.papi_v1_put_um_order(**params) ``` - **GET /sapi/v1/sub-account/futures/accountSummary** ```python client.margin_v1_get_sub_account_futures_account_summary(**params) ``` - **GET /papi/v1/um/symbolConfig** ```python client.papi_v1_get_um_symbol_config(**params) ``` - **GET /papi/v1/um/userTrades** ```python client.papi_v1_get_um_user_trades(**params) ``` - **GET /sapi/v1/staking/productList** ```python client.margin_v1_get_staking_product_list(**params) ``` - **POST /sapi/v1/asset/get-funding-asset** ```python client.margin_v1_post_asset_get_funding_asset(**params) ``` - **POST /sapi/v1/bnbBurn** ```python client.margin_v1_post_bnb_burn(**params) ``` - **POST /papi/v1/um/order** ```python client.papi_v1_post_um_order(**params) ``` - **GET /dapi/v1/order/asyn** ```python client.futures_coin_v1_get_order_asyn(**params) ``` - **GET /sapi/v1/c2c/orderMatch/listUserOrderHistory** ```python client.margin_v1_get_c2c_order_match_list_user_order_history(**params) ``` - **POST /sapi/v1/simple-earn/flexible/subscribe** ```python client.margin_v1_post_simple_earn_flexible_subscribe(**params) ``` - **POST /sapi/v1/broker/transfer/futures** ```python client.margin_v1_post_broker_transfer_futures(**params) ``` - **POST /api/v3/order/cancelReplace** ```python client.v3_post_order_cancel_replace(**params) ``` - **POST /sapi/v1/sol-staking/sol/stake** ```python client.margin_v1_post_sol_staking_sol_stake(**params) ``` - **POST /sapi/v1/loan/borrow** ```python client.margin_v1_post_loan_borrow(**params) ``` - **GET /sapi/v1/managed-subaccount/info** ```python client.margin_v1_get_managed_subaccount_info(**params) ``` - **POST /sapi/v1/lending/auto-invest/plan/edit-status** ```python client.margin_v1_post_lending_auto_invest_plan_edit_status(**params) ``` - **GET /fapi/v1/symbolConfig** ```python client.futures_v1_get_symbol_config(**params) ``` - **GET /sapi/v1/sol-staking/sol/history/unclaimedRewards** ```python client.margin_v1_get_sol_staking_sol_history_unclaimed_rewards(**params) ``` - **POST /sapi/v1/asset/convert-transfer/queryByPage** ```python client.margin_v1_post_asset_convert_transfer_query_by_page(**params) ``` - **GET /sapi/v1/sub-account/universalTransfer** ```python client.margin_v1_get_sub_account_universal_transfer(**params) ``` - **GET /sapi/v1/sol-staking/sol/history/boostRewardsHistory** ```python client.margin_v1_get_sol_staking_sol_history_boost_rewards_history(**params) ``` - **GET /sapi/v1/lending/auto-invest/one-off/status** ```python client.margin_v1_get_lending_auto_invest_one_off_status(**params) ``` - **GET /sapi/v1/asset/ledger-transfer/cloud-mining/queryByPage** ```python client.margin_v1_get_asset_ledger_transfer_cloud_mining_query_by_page(**params) ``` - **DELETE /sapi/v1/margin/orderList** ```python client.margin_v1_delete_margin_order_list(**params) ``` - **GET /sapi/v1/mining/pub/coinList** ```python client.margin_v1_get_mining_pub_coin_list(**params) ``` - **GET /sapi/v2/loan/flexible/repay/history** ```python client.margin_v2_get_loan_flexible_repay_history(**params) ``` - **GET /fapi/v3/account** ```python client.futures_v3_get_account(**params) ``` - **POST /api/v3/sor/order** ```python client.v3_post_sor_order(**params) ``` - **POST /sapi/v1/capital/deposit/credit-apply** ```python client.margin_v1_post_capital_deposit_credit_apply(**params) ``` - **PUT /fapi/v1/batchOrder** ```python client.futures_v1_put_batch_order(**params) ``` - **GET /sapi/v1/fiat/payments** ```python client.margin_v1_get_fiat_payments(**params) ``` - **GET /api/v3/myPreventedMatches** ```python client.v3_get_my_prevented_matches(**params) ``` - **GET /dapi/v1/forceOrders** ```python client.futures_coin_v1_get_force_orders(**params) ``` - **POST /sapi/v1/asset/transfer** ```python client.margin_v1_post_asset_transfer(**params) ``` - **GET /sapi/v1/mining/statistics/user/list** ```python client.margin_v1_get_mining_statistics_user_list(**params) ``` - **GET /api/v3/ticker/tradingDay** ```python client.v3_get_ticker_trading_day(**params) ``` - **GET /sapi/v1/mining/worker/detail** ```python client.margin_v1_get_mining_worker_detail(**params) ``` - **GET /sapi/v1/managed-subaccount/fetch-future-asset** ```python client.margin_v1_get_managed_subaccount_fetch_future_asset(**params) ``` - **GET /dapi/v1/pmExchangeInfo** ```python client.futures_coin_v1_get_pm_exchange_info(**params) ``` - **POST /sapi/v1/convert/getQuote** ```python client.margin_v1_post_convert_get_quote(**params) ``` - **GET /api/v3/uiKlines** ```python client.v3_get_ui_klines(**params) ``` - **GET /sapi/v1/margin/rateLimit/order** ```python client.margin_v1_get_margin_rate_limit_order(**params) ``` - **GET /sapi/v1/localentity/vasp** ```python client.margin_v1_get_localentity_vasp(**params) ``` - **GET /fapi/v1/commissionRate** ```python client.futures_v1_get_commission_rate(**params) ``` - **GET /sapi/v1/sol-staking/sol/history/rateHistory** ```python client.margin_v1_get_sol_staking_sol_history_rate_history(**params) ``` - **POST /sapi/v1/broker/subAccountApi/ipRestriction** ```python client.margin_v1_post_broker_sub_account_api_ip_restriction(**params) ``` - **GET /eapi/v1/block/user-trades** ```python client.options_v1_get_block_user_trades(**params) ``` - **GET /dapi/v1/order/asyn/id** ```python client.futures_coin_v1_get_order_asyn_id(**params) ``` - **GET /sapi/v1/sol-staking/account** ```python client.margin_v1_get_sol_staking_account(**params) ``` - **GET /sapi/v1/account/info** ```python client.margin_v1_get_account_info(**params) ``` - **POST /sapi/v1/sub-account/transfer/subToMaster** ```python client.margin_v1_post_sub_account_transfer_sub_to_master(**params) ``` - **POST /sapi/v1/portfolio/repay-futures-switch** ```python client.margin_v1_post_portfolio_repay_futures_switch(**params) ``` - **GET /sapi/v1/giftcard/buyCode/token-limit** ```python client.margin_v1_get_giftcard_buy_code_token_limit(**params) ``` - **GET /sapi/v1/capital/deposit/subHisrec** ```python client.margin_v1_get_capital_deposit_sub_hisrec(**params) ``` - **POST /sapi/v1/loan/vip/borrow** ```python client.margin_v1_post_loan_vip_borrow(**params) ``` - **GET /papi/v1/um/order/asyn/id** ```python client.papi_v1_get_um_order_asyn_id(**params) ``` - **GET /papi/v1/cm/account** ```python client.papi_v1_get_cm_account(**params) ``` - **DELETE /papi/v1/um/conditional/order** ```python client.papi_v1_delete_um_conditional_order(**params) ``` - **GET /sapi/v2/loan/flexible/ltv/adjustment/history** ```python client.margin_v2_get_loan_flexible_ltv_adjustment_history(**params) ``` - **DELETE /eapi/v1/allOpenOrdersByUnderlying** ```python client.options_v1_delete_all_open_orders_by_underlying(**params) ``` - **PUT /papi/v1/cm/order** ```python client.papi_v1_put_cm_order(**params) ``` - **GET /sapi/v1/broker/subAccount/futuresSummary** ```python client.margin_v1_get_broker_sub_account_futures_summary(**params) ``` - **GET /dapi/v1/continuousKlines** ```python client.futures_coin_v1_get_continuous_klines(**params) ``` - **GET /fapi/v1/accountConfig** ```python client.futures_v1_get_account_config(**params) ``` - **DELETE /dapi/v1/batchOrders** ```python client.futures_coin_v1_delete_batch_orders(**params) ``` - **GET /sapi/v1/broker/subAccount/spotSummary** ```python client.margin_v1_get_broker_sub_account_spot_summary(**params) ``` - **GET /papi/v1/margin/openOrderList** ```python client.papi_v1_get_margin_open_order_list(**params) ``` - **POST /sapi/v1/sub-account/blvt/enable** ```python client.margin_v1_post_sub_account_blvt_enable(**params) ``` - **GET /dapi/v1/trade/asyn** ```python client.futures_coin_v1_get_trade_asyn(**params) ``` - **GET /sapi/v1/algo/spot/historicalOrders** ```python client.margin_v1_get_algo_spot_historical_orders(**params) ``` - **GET /sapi/v1/loan/vip/repay/history** ```python client.margin_v1_get_loan_vip_repay_history(**params) ``` - **GET /eapi/v1/openInterest** ```python client.options_v1_get_open_interest(**params) ``` - **GET /papi/v1/um/adlQuantile** ```python client.papi_v1_get_um_adl_quantile(**params) ``` - **GET /eapi/v1/account** ```python client.options_v1_get_account(**params) ``` - **POST /sapi/v1/sub-account/universalTransfer** ```python client.margin_v1_post_sub_account_universal_transfer(**params) ``` - **GET /papi/v1/margin/allOrderList** ```python client.papi_v1_get_margin_all_order_list(**params) ``` - **GET /fapi/v2/ticker/price** ```python client.futures_v2_get_ticker_price(**params) ``` - **GET /sapi/v1/loan/borrow/history** ```python client.margin_v1_get_loan_borrow_history(**params) ``` - **GET /papi/v1/um/account** ```python client.papi_v1_get_um_account(**params) ``` - **POST /sapi/v1/lending/auto-invest/redeem** ```python client.margin_v1_post_lending_auto_invest_redeem(**params) ``` - **POST /sapi/v1/managed-subaccount/deposit** ```python client.margin_v1_post_managed_subaccount_deposit(**params) ``` - **GET /dapi/v1/fundingRate** ```python client.futures_coin_v1_get_funding_rate(**params) ``` - **GET /fapi/v1/trade/asyn/id** ```python client.futures_v1_get_trade_asyn_id(**params) ``` - **DELETE /sapi/v1/sub-account/subAccountApi/ipRestriction/ipList** ```python client.margin_v1_delete_sub_account_sub_account_api_ip_restriction_ip_list(**params) ``` - **GET /sapi/v1/copyTrading/futures/userStatus** ```python client.margin_v1_get_copy_trading_futures_user_status(**params) ``` - **GET /papi/v1/um/income** ```python client.papi_v1_get_um_income(**params) ``` - **GET /papi/v1/um/openOrders** ```python client.papi_v1_get_um_open_orders(**params) ``` - **GET /eapi/v1/marginAccount** ```python client.options_v1_get_margin_account(**params) ``` - **GET /dapi/v1/premiumIndex** ```python client.futures_coin_v1_get_premium_index(**params) ``` - **POST /sapi/v1/localentity/withdraw/apply** ```python client.margin_v1_post_localentity_withdraw_apply(**params) ``` - **GET /sapi/v1/margin/orderList** ```python client.margin_v1_get_margin_order_list(**params) ``` - **GET /papi/v1/um/feeBurn** ```python client.papi_v1_get_um_fee_burn(**params) ``` - **GET /fapi/v1/multiAssetsMargin** ```python client.futures_v1_get_multi_assets_margin(**params) ``` - **GET /sapi/v1/giftcard/verify** ```python client.margin_v1_get_giftcard_verify(**params) ``` - **GET /sapi/v1/asset/wallet/balance** ```python client.margin_v1_get_asset_wallet_balance(**params) ``` - **POST /sapi/v1/algo/futures/newOrderTwap** ```python client.margin_v1_post_algo_futures_new_order_twap(**params) ``` - **GET /sapi/v1/margin/crossMarginCollateralRatio** ```python client.margin_v1_get_margin_cross_margin_collateral_ratio(**params) ``` - **POST /sapi/v2/eth-staking/eth/stake** ```python client.margin_v2_post_eth_staking_eth_stake(**params) ``` - **POST /sapi/v1/loan/flexible/repay/history** ```python client.margin_v1_post_loan_flexible_repay_history(**params) ``` - **GET /dapi/v1/exchangeInfo** ```python client.futures_coin_v1_get_exchange_info(**params) ``` - **POST /sapi/v1/sub-account/futures/enable** ```python client.margin_v1_post_sub_account_futures_enable(**params) ``` - **GET /sapi/v1/lending/auto-invest/index/info** ```python client.margin_v1_get_lending_auto_invest_index_info(**params) ``` - **GET /sapi/v2/sub-account/futures/positionRisk** ```python client.margin_v2_get_sub_account_futures_position_risk(**params) ``` - **GET /sapi/v1/sub-account/margin/account** ```python client.margin_v1_get_sub_account_margin_account(**params) ``` - **GET /papi/v1/rateLimit/order** ```python client.papi_v1_get_rate_limit_order(**params) ``` - **GET /sapi/v1/sol-staking/sol/history/redemptionHistory** ```python client.margin_v1_get_sol_staking_sol_history_redemption_history(**params) ``` - **GET /fapi/v1/markPriceKlines** ```python client.futures_v1_get_mark_price_klines(**params) ``` - **GET /sapi/v1/broker/rebate/futures/recentRecord** ```python client.margin_v1_get_broker_rebate_futures_recent_record(**params) ``` - **GET /sapi/v3/broker/subAccount/futuresSummary** ```python client.margin_v3_get_broker_sub_account_futures_summary(**params) ``` - **GET /dapi/v1/aggTrades** ```python client.futures_coin_v1_get_agg_trades(**params) ``` - **GET /eapi/v1/exchangeInfo** ```python client.options_v1_get_exchange_info(**params) ``` - **GET /sapi/v1/lending/auto-invest/target-asset/roi/list** ```python client.margin_v1_get_lending_auto_invest_target_asset_roi_list(**params) ``` - **GET /sapi/v1/broker/universalTransfer** ```python client.margin_v1_get_broker_universal_transfer(**params) ``` - **POST /sapi/v1/sub-account/futures/transfer** ```python client.margin_v1_post_sub_account_futures_transfer(**params) ``` - **PUT /fapi/v1/batchOrders** ```python client.futures_v1_put_batch_orders(**params) ``` - **POST /eapi/v1/countdownCancelAllHeartBeat** ```python client.options_v1_post_countdown_cancel_all_heart_beat(**params) ``` - **GET /sapi/v1/loan/collateral/data** ```python client.margin_v1_get_loan_collateral_data(**params) ``` - **GET /sapi/v1/margin/borrow-repay** ```python client.margin_v1_get_margin_borrow_repay(**params) ``` - **GET /sapi/v1/loan/repay/history** ```python client.margin_v1_get_loan_repay_history(**params) ``` - **GET /dapi/v2/leverageBracket** ```python client.futures_coin_v2_get_leverage_bracket(**params) ``` - **GET /fapi/v1/indexPriceKlines** ```python client.futures_v1_get_index_price_klines(**params) ``` - **POST /sapi/v1/convert/limit/placeOrder** ```python client.margin_v1_post_convert_limit_place_order(**params) ``` - **GET /fapi/v1/convert/exchangeInfo** ```python client.futures_v1_get_convert_exchange_info(**params) ``` - **GET /dapi/v1/historicalTrades** ```python client.futures_coin_v1_get_historical_trades(**params) ``` - **DELETE /sapi/v1/broker/subAccountApi/ipRestriction/ipList** ```python client.margin_v1_delete_broker_sub_account_api_ip_restriction_ip_list(**params) ``` - **GET /sapi/v1/staking/personalLeftQuota** ```python client.margin_v1_get_staking_personal_left_quota(**params) ``` - **POST /sapi/v1/sub-account/virtualSubAccount** ```python client.margin_v1_post_sub_account_virtual_sub_account(**params) ``` - **GET /sapi/v1/staking/position** ```python client.margin_v1_get_staking_position(**params) ``` - **GET /papi/v1/um/income/asyn/id** ```python client.papi_v1_get_um_income_asyn_id(**params) ``` - **PUT /sapi/v1/localentity/deposit/provide-info** ```python client.margin_v1_put_localentity_deposit_provide_info(**params) ``` - **POST /sapi/v1/portfolio/mint** ```python client.margin_v1_post_portfolio_mint(**params) ``` - **POST /sapi/v1/sub-account/transfer/subToSub** ```python client.margin_v1_post_sub_account_transfer_sub_to_sub(**params) ``` - **GET /fapi/v1/orderAmendment** ```python client.futures_v1_get_order_amendment(**params) ``` - **POST /sapi/v1/sol-staking/sol/claim** ```python client.margin_v1_post_sol_staking_sol_claim(**params) ``` - **GET /sapi/v1/account/apiRestrictions** ```python client.margin_v1_get_account_api_restrictions(**params) ``` - **GET /papi/v1/um/allOrders** ```python client.papi_v1_get_um_all_orders(**params) ``` - **POST /sapi/v1/giftcard/createCode** ```python client.margin_v1_post_giftcard_create_code(**params) ``` - **GET /sapi/v1/lending/auto-invest/rebalance/history** ```python client.margin_v1_get_lending_auto_invest_rebalance_history(**params) ``` - **GET /sapi/v1/loan/repay/collateral/rate** ```python client.margin_v1_get_loan_repay_collateral_rate(**params) ``` - **GET /sapi/v1/mining/payment/uid** ```python client.margin_v1_get_mining_payment_uid(**params) ``` - **GET /sapi/v2/loan/flexible/borrow/history** ```python client.margin_v2_get_loan_flexible_borrow_history(**params) ``` - **POST /sapi/v1/asset/dust** ```python client.margin_v1_post_asset_dust(**params) ``` - **GET /sapi/v1/capital/contract/convertible-coins** ```python client.margin_v1_get_capital_contract_convertible_coins(**params) ``` - **POST /sapi/v1/asset/dust-btc** ```python client.margin_v1_post_asset_dust_btc(**params) ``` - **GET /papi/v1/um/conditional/openOrders** ```python client.papi_v1_get_um_conditional_open_orders(**params) ``` - **GET /sapi/v1/sub-account/spotSummary** ```python client.margin_v1_get_sub_account_spot_summary(**params) ``` - **POST /sapi/v1/broker/subAccountApi/permission/vanillaOptions** ```python client.margin_v1_post_broker_sub_account_api_permission_vanilla_options(**params) ``` - **GET /sapi/v1/lending/auto-invest/redeem/history** ```python client.margin_v1_get_lending_auto_invest_redeem_history(**params) ``` - **GET /fapi/v3/positionRisk** ```python client.futures_v3_get_position_risk(**params) ``` - **GET /dapi/v1/klines** ```python client.futures_coin_v1_get_klines(**params) ``` - **GET /sapi/v2/localentity/withdraw/history** ```python client.margin_v2_get_localentity_withdraw_history(**params) ``` - **GET /sapi/v1/eth-staking/eth/history/redemptionHistory** ```python client.margin_v1_get_eth_staking_eth_history_redemption_history(**params) ``` - **POST /eapi/v1/transfer** ```python client.options_v1_post_transfer(**params) ``` - **GET /fapi/v1/feeBurn** ```python client.futures_v1_get_fee_burn(**params) ``` - **GET /sapi/v1/lending/auto-invest/index/user-summary** ```python client.margin_v1_get_lending_auto_invest_index_user_summary(**params) ``` - **POST /sapi/v2/loan/flexible/borrow** ```python client.margin_v2_post_loan_flexible_borrow(**params) ``` - **DELETE /dapi/v1/order** ```python client.futures_coin_v1_delete_order(**params) ``` - **POST /sapi/v3/asset/getUserAsset** ```python client.margin_v3_post_asset_get_user_asset(**params) ``` - **POST /sapi/v1/loan/vip/repay** ```python client.margin_v1_post_loan_vip_repay(**params) ``` - **GET /sapi/v2/sub-account/futures/accountSummary** ```python client.margin_v2_get_sub_account_futures_account_summary(**params) ``` - **GET /dapi/v1/commissionRate** ```python client.futures_coin_v1_get_commission_rate(**params) ``` - **GET /papi/v1/um/conditional/orderHistory** ```python client.papi_v1_get_um_conditional_order_history(**params) ``` - **GET /fapi/v3/balance** ```python client.futures_v3_get_balance(**params) ``` - **GET /sapi/v1/convert/assetInfo** ```python client.margin_v1_get_convert_asset_info(**params) ``` - **POST /api/v3/sor/order/test** ```python client.v3_post_sor_order_test(**params) ``` - **GET /sapi/v1/giftcard/cryptography/rsa-public-key** ```python client.margin_v1_get_giftcard_cryptography_rsa_public_key(**params) ``` - **POST /sapi/v1/broker/universalTransfer** ```python client.margin_v1_post_broker_universal_transfer(**params) ``` - **GET /dapi/v1/allOrders** ```python client.futures_coin_v1_get_all_orders(**params) ``` - **POST /sapi/v1/margin/borrow-repay** ```python client.margin_v1_post_margin_borrow_repay(**params) ``` - **GET /fapi/v1/assetIndex** ```python client.futures_v1_get_asset_index(**params) ``` - **GET /api/v3/rateLimit/order** ```python client.v3_get_rate_limit_order(**params) ``` - **GET /papi/v1/um/orderAmendment** ```python client.papi_v1_get_um_order_amendment(**params) ``` - **GET /sapi/v1/account/apiRestrictions/ipRestriction** ```python client.margin_v1_get_account_api_restrictions_ip_restriction(**params) ``` - **POST /sapi/v1/broker/subAccount/bnbBurn/spot** ```python client.margin_v1_post_broker_sub_account_bnb_burn_spot(**params) ``` - **POST /papi/v1/um/conditional/order** ```python client.papi_v1_post_um_conditional_order(**params) ``` - **PUT /dapi/v1/batchOrders** ```python client.futures_coin_v1_put_batch_orders(**params) ``` - **DELETE /api/v3/openOrders** ```python client.v3_delete_open_orders(**params) ``` - **GET /sapi/v1/margin/delist-schedule** ```python client.margin_v1_get_margin_delist_schedule(**params) ``` - **POST /sapi/v1/broker/subAccountApi/permission/universalTransfer** ```python client.margin_v1_post_broker_sub_account_api_permission_universal_transfer(**params) ``` - **GET /papi/v1/cm/positionRisk** ```python client.papi_v1_get_cm_position_risk(**params) ``` - **GET /papi/v1/cm/income** ```python client.papi_v1_get_cm_income(**params) ``` - **POST /sapi/v1/giftcard/buyCode** ```python client.margin_v1_post_giftcard_buy_code(**params) ``` - **GET /fapi/v1/balance** ```python client.futures_v1_get_balance(**params) ``` - **GET /api/v3/myAllocations** ```python client.v3_get_my_allocations(**params) ``` - **GET /papi/v1/margin/order** ```python client.papi_v1_get_margin_order(**params) ``` - **GET /sapi/v1/loan/ltv/adjustment/history** ```python client.margin_v1_get_loan_ltv_adjustment_history(**params) ``` - **POST /dapi/v1/batchOrders** ```python client.futures_coin_v1_post_batch_orders(**params) ``` - **GET /sapi/v1/localentity/withdraw/history** ```python client.margin_v1_get_localentity_withdraw_history(**params) ``` - **GET /sapi/v1/sub-account/status** ```python client.margin_v1_get_sub_account_status(**params) ``` - **POST /sapi/v2/sub-account/subAccountApi/ipRestriction** ```python client.margin_v2_post_sub_account_sub_account_api_ip_restriction(**params) ``` - **GET /dapi/v1/trade/asyn/id** ```python client.futures_coin_v1_get_trade_asyn_id(**params) ``` - **GET /fapi/v1/rateLimit/order** ```python client.futures_v1_get_rate_limit_order(**params) ``` - **GET /sapi/v1/broker/subAccountApi/commission/futures** ```python client.margin_v1_get_broker_sub_account_api_commission_futures(**params) ``` - **GET /sapi/v1/sol-staking/sol/history/stakingHistory** ```python client.margin_v1_get_sol_staking_sol_history_staking_history(**params) ``` - **DELETE /sapi/v1/algo/spot/order** ```python client.margin_v1_delete_algo_spot_order(**params) ``` - **GET /papi/v1/repay-futures-switch** ```python client.papi_v1_get_repay_futures_switch(**params) ``` - **POST /sapi/v1/margin/max-leverage** ```python client.margin_v1_post_margin_max_leverage(**params) ``` - **DELETE /sapi/v1/account/apiRestrictions/ipRestriction/ipList** ```python client.margin_v1_delete_account_api_restrictions_ip_restriction_ip_list(**params) ``` - **POST /sapi/v1/capital/contract/convertible-coins** ```python client.margin_v1_post_capital_contract_convertible_coins(**params) ``` - **GET /sapi/v1/managed-subaccount/marginAsset** ```python client.margin_v1_get_managed_subaccount_margin_asset(**params) ``` - **GET /sapi/v3/sub-account/assets** ```python client.margin_v3_get_sub_account_assets(**params) ``` - **GET /fapi/v1/continuousKlines** ```python client.futures_v1_get_continuous_klines(**params) ``` - **GET /sapi/v1/sub-account/futures/internalTransfer** ```python client.margin_v1_get_sub_account_futures_internal_transfer(**params) ``` - **GET /sapi/v1/capital/withdraw/apply** ```python client.margin_v1_get_capital_withdraw_apply(**params) ``` - **POST /sapi/v1/sub-account/subAccountApi/ipRestriction/ipList** ```python client.margin_v1_post_sub_account_sub_account_api_ip_restriction_ip_list(**params) ``` - **POST /sapi/v1/staking/setAutoStaking** ```python client.margin_v1_post_staking_set_auto_staking(**params) ``` - **POST /fapi/v1/feeBurn** ```python client.futures_v1_post_fee_burn(**params) ``` - **POST /sapi/v1/simple-earn/flexible/redeem** ```python client.margin_v1_post_simple_earn_flexible_redeem(**params) ``` - **GET /sapi/v1/broker/subAccount/marginSummary** ```python client.margin_v1_get_broker_sub_account_margin_summary(**params) ``` - **GET /sapi/v1/lending/auto-invest/plan/list** ```python client.margin_v1_get_lending_auto_invest_plan_list(**params) ``` - **GET /sapi/v1/loan/vip/loanable/data** ```python client.margin_v1_get_loan_vip_loanable_data(**params) ``` - **POST /sapi/v1/margin/exchange-small-liability** ```python client.margin_v1_post_margin_exchange_small_liability(**params) ``` - **GET /sapi/v2/loan/flexible/collateral/data** ```python client.margin_v2_get_loan_flexible_collateral_data(**params) ``` - **POST /papi/v1/margin/repay-debt** ```python client.papi_v1_post_margin_repay_debt(**params) ``` - **GET /sapi/v1/sol-staking/sol/history/bnsolRewardsHistory** ```python client.margin_v1_get_sol_staking_sol_history_bnsol_rewards_history(**params) ``` - **GET /sapi/v1/convert/limit/queryOpenOrders** ```python client.margin_v1_get_convert_limit_query_open_orders(**params) ``` - **GET /api/v3/account/commission** ```python client.v3_get_account_commission(**params) ``` - **GET /sapi/v1/margin/interestRateHistory** ```python client.margin_v1_get_margin_interest_rate_history(**params) ``` - **POST /api/v3/orderList/oco** ```python client.v3_post_order_list_oco(**params) ``` - **GET /sapi/v1/managed-subaccount/query-trans-log** ```python client.margin_v1_get_managed_subaccount_query_trans_log(**params) ``` - **POST /sapi/v2/broker/subAccountApi/ipRestriction** ```python client.margin_v2_post_broker_sub_account_api_ip_restriction(**params) ``` - **GET /papi/v1/um/positionRisk** ```python client.papi_v1_get_um_position_risk(**params) ``` - **POST /sapi/v1/sub-account/margin/transfer** ```python client.margin_v1_post_sub_account_margin_transfer(**params) ``` - **GET /fapi/v1/positionRisk** ```python client.futures_v1_get_position_risk(**params) ``` - **GET /sapi/v1/lending/auto-invest/all/asset** ```python client.margin_v1_get_lending_auto_invest_all_asset(**params) ``` - **POST /fapi/v1/convert/acceptQuote** ```python client.futures_v1_post_convert_accept_quote(**params) ``` - **GET /sapi/v1/spot/delist-schedule** ```python client.margin_v1_get_spot_delist_schedule(**params) ``` - **GET /sapi/v1/dci/product/accounts** ```python client.margin_v1_get_dci_product_accounts(**params) ``` - **GET /sapi/v1/sub-account/subAccountApi/ipRestriction** ```python client.margin_v1_get_sub_account_sub_account_api_ip_restriction(**params) ``` - **GET /papi/v1/um/accountConfig** ```python client.papi_v1_get_um_account_config(**params) ``` - **GET /papi/v1/cm/adlQuantile** ```python client.papi_v1_get_cm_adl_quantile(**params) ``` - **GET /sapi/v1/sub-account/transaction-statistics** ```python client.margin_v1_get_sub_account_transaction_statistics(**params) ``` - **PUT /fapi/v1/listenKey** ```python client.futures_v1_put_listen_key(**params) ``` - **GET /sapi/v1/margin/openOrderList** ```python client.margin_v1_get_margin_open_order_list(**params) ``` - **GET /api/v3/acccount** ```python client.v3_get_acccount(**params) ``` - **GET /sapi/v1/fiat/orders** ```python client.margin_v1_get_fiat_orders(**params) ``` - **GET /papi/v1/margin/allOrders** ```python client.papi_v1_get_margin_all_orders(**params) ``` - **POST /sapi/v1/sub-account/margin/enable** ```python client.margin_v1_post_sub_account_margin_enable(**params) ``` - **GET /sapi/v1/managed-subaccount/deposit/address** ```python client.margin_v1_get_managed_subaccount_deposit_address(**params) ``` - **DELETE /sapi/v1/margin/isolated/account** ```python client.margin_v1_delete_margin_isolated_account(**params) ``` - **GET /sapi/v2/portfolio/account** ```python client.margin_v2_get_portfolio_account(**params) ``` - **GET /sapi/v1/simple-earn/locked/history/redemptionRecord** ```python client.margin_v1_get_simple_earn_locked_history_redemption_record(**params) ``` - **GET /fapi/v1/order/asyn/id** ```python client.futures_v1_get_order_asyn_id(**params) ``` - **POST /sapi/v1/managed-subaccount/withdraw** ```python client.margin_v1_post_managed_subaccount_withdraw(**params) ``` - **GET /sapi/v1/convert/tradeFlow** ```python client.margin_v1_get_convert_trade_flow(**params) ``` - **GET /sapi/v1/localentity/deposit/history** ```python client.margin_v1_get_localentity_deposit_history(**params) ``` - **POST /sapi/v1/eth-staking/wbeth/wrap** ```python client.margin_v1_post_eth_staking_wbeth_wrap(**params) ``` - **POST /sapi/v1/simple-earn/locked/setRedeemOption** ```python client.margin_v1_post_simple_earn_locked_set_redeem_option(**params) ``` - **POST /sapi/v1/broker/subAccountApi/ipRestriction/ipList** ```python client.margin_v1_post_broker_sub_account_api_ip_restriction_ip_list(**params) ``` - **POST /sapi/v1/broker/subAccountApi/commission/futures** ```python client.margin_v1_post_broker_sub_account_api_commission_futures(**params) ``` - **GET /papi/v1/margin/myTrades** ```python client.papi_v1_get_margin_my_trades(**params) ``` - **GET /sapi/v1/pay/transactions** ```python client.margin_v1_get_pay_transactions(**params) ``` - **GET /papi/v1/um/leverageBracket** ```python client.papi_v1_get_um_leverage_bracket(**params) ``` - **GET /papi/v1/margin/orderList** ```python client.papi_v1_get_margin_order_list(**params) ``` - **GET /dapi/v1/allForceOrders** ```python client.futures_coin_v1_get_all_force_orders(**params) ``` - **GET /sapi/v1/margin/isolated/accountLimit** ```python client.margin_v1_get_margin_isolated_account_limit(**params) ``` - **GET /sapi/v1/lending/auto-invest/history/list** ```python client.margin_v1_get_lending_auto_invest_history_list(**params) ``` - **GET /dapi/v1/account** ```python client.futures_coin_v1_get_account(**params) ``` - **GET /dapi/v1/markPriceKlines** ```python client.futures_coin_v1_get_mark_price_klines(**params) ``` - **POST /sapi/v1/loan/customize/margin_call** ```python client.margin_v1_post_loan_customize_margin_call(**params) ``` - **GET /sapi/v1/broker/subAccount/bnbBurn/status** ```python client.margin_v1_get_broker_sub_account_bnb_burn_status(**params) ``` - **DELETE /eapi/v1/block/order/create** ```python client.options_v1_delete_block_order_create(**params) ``` - **GET /sapi/v1/managed-subaccount/accountSnapshot** ```python client.margin_v1_get_managed_subaccount_account_snapshot(**params) ``` - **GET /fapi/v1/constituents** ```python client.futures_v1_get_constituents(**params) ``` - **GET /dapi/v1/indexPriceKlines** ```python client.futures_coin_v1_get_index_price_klines(**params) ``` - **GET /sapi/v1/broker/subAccountApi/commission/coinFutures** ```python client.margin_v1_get_broker_sub_account_api_commission_coin_futures(**params) ``` - **GET /sapi/v2/broker/subAccount/futuresSummary** ```python client.margin_v2_get_broker_sub_account_futures_summary(**params) ``` - **GET /sapi/v1/sub-account/transfer/subUserHistory** ```python client.margin_v1_get_sub_account_transfer_sub_user_history(**params) ``` - **POST /sapi/v1/sub-account/futures/internalTransfer** ```python client.margin_v1_post_sub_account_futures_internal_transfer(**params) ``` - **GET /sapi/v1/loan/ongoing/orders** ```python client.margin_v1_get_loan_ongoing_orders(**params) ``` - **GET /sapi/v2/loan/flexible/ongoing/orders** ```python client.margin_v2_get_loan_flexible_ongoing_orders(**params) ``` - **GET /eapi/v1/block/order/execute** ```python client.options_v1_get_block_order_execute(**params) ``` - **GET /papi/v2/um/account** ```python client.papi_v2_get_um_account(**params) ``` - **POST /sapi/v1/margin/order/oco** ```python client.margin_v1_post_margin_order_oco(**params) ``` - **GET /api/v1/portfolio/negative-balance-exchange-record** ```python client.v1_get_portfolio_negative_balance_exchange_record(**params) ``` - **POST /sapi/v1/algo/futures/newOrderVp** ```python client.margin_v1_post_algo_futures_new_order_vp(**params) ``` - **DELETE /papi/v1/um/order** ```python client.papi_v1_delete_um_order(**params) ``` - **POST /fapi/v1/convert/getQuote** ```python client.futures_v1_post_convert_get_quote(**params) ``` - **GET /sapi/v1/algo/spot/subOrders** ```python client.margin_v1_get_algo_spot_sub_orders(**params) ``` - **GET /dapi/v1/userTrades** ```python client.futures_coin_v1_get_user_trades(**params) ``` - **POST /papi/v1/um/feeBurn** ```python client.papi_v1_post_um_fee_burn(**params) ``` - **POST /sapi/v1/portfolio/redeem** ```python client.margin_v1_post_portfolio_redeem(**params) ``` - **POST /fapi/v1/multiAssetsMargin** ```python client.futures_v1_post_multi_assets_margin(**params) ``` - **POST /sapi/v1/lending/auto-invest/plan/add** ```python client.margin_v1_post_lending_auto_invest_plan_add(**params) ``` - **GET /eapi/v1/historyOrders** ```python client.options_v1_get_history_orders(**params) ``` - **GET /sapi/v1/lending/auto-invest/source-asset/list** ```python client.margin_v1_get_lending_auto_invest_source_asset_list(**params) ``` - **GET /sapi/v1/margin/allOrderList** ```python client.margin_v1_get_margin_all_order_list(**params) ``` - **POST /sapi/v1/eth-staking/eth/redeem** ```python client.margin_v1_post_eth_staking_eth_redeem(**params) ``` - **GET /sapi/v1/broker/rebate/historicalRecord** ```python client.margin_v1_get_broker_rebate_historical_record(**params) ``` - **GET /sapi/v1/simple-earn/locked/history/subscriptionRecord** ```python client.margin_v1_get_simple_earn_locked_history_subscription_record(**params) ``` - **PUT /dapi/v1/order** ```python client.futures_coin_v1_put_order(**params) ``` - **GET /sapi/v1/managed-subaccount/asset** ```python client.margin_v1_get_managed_subaccount_asset(**params) ``` - **GET /sapi/v1/sol-staking/sol/quota** ```python client.margin_v1_get_sol_staking_sol_quota(**params) ``` - **POST /sapi/v1/loan/vip/renew** ```python client.margin_v1_post_loan_vip_renew(**params) ``` - **POST /dapi/v1/order** ```python client.futures_coin_v1_post_order(**params) ``` - **GET /sapi/v1/managed-subaccount/queryTransLogForTradeParent** ```python client.margin_v1_get_managed_subaccount_query_trans_log_for_trade_parent(**params) ``` - **GET /sapi/v1/simple-earn/flexible/history/redemptionRecord** ```python client.margin_v1_get_simple_earn_flexible_history_redemption_record(**params) ``` - **GET /sapi/v1/sub-account/margin/accountSummary** ```python client.margin_v1_get_sub_account_margin_account_summary(**params) ``` - **GET /sapi/v1/margin/dribblet** ```python client.margin_v1_get_margin_dribblet(**params) ``` - **GET /eapi/v1/exerciseHistory** ```python client.options_v1_get_exercise_history(**params) ``` - **GET /sapi/v1/convert/exchangeInfo** ```python client.margin_v1_get_convert_exchange_info(**params) ``` - **GET /sapi/v1/eth-staking/eth/history/wbethRewardsHistory** ```python client.margin_v1_get_eth_staking_eth_history_wbeth_rewards_history(**params) ``` - **GET /sapi/v1/simple-earn/locked/position** ```python client.margin_v1_get_simple_earn_locked_position(**params) ``` - **GET /sapi/v1/mining/pub/algoList** ```python client.margin_v1_get_mining_pub_algo_list(**params) ``` - **GET /dapi/v1/ticker/bookTicker** ```python client.futures_coin_v1_get_ticker_book_ticker(**params) ``` - **GET /eapi/v1/blockTrades** ```python client.options_v1_get_block_trades(**params) ``` - **GET /sapi/v1/copyTrading/futures/leadSymbol** ```python client.margin_v1_get_copy_trading_futures_lead_symbol(**params) ``` - **GET /papi/v1/cm/orderAmendment** ```python client.papi_v1_get_cm_order_amendment(**params) ``` - **GET /sapi/v4/sub-account/assets** ```python client.margin_v4_get_sub_account_assets(**params) ``` - **GET /sapi/v1/mining/worker/list** ```python client.margin_v1_get_mining_worker_list(**params) ``` - **DELETE /sapi/v1/margin/openOrders** ```python client.margin_v1_delete_margin_open_orders(**params) ``` - **GET /dapi/v1/constituents** ```python client.futures_coin_v1_get_constituents(**params) ``` - **GET /sapi/v1/dci/product/list** ```python client.margin_v1_get_dci_product_list(**params) ``` - **GET /fapi/v1/convert/orderStatus** ```python client.futures_v1_get_convert_order_status(**params) ``` ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2017 sammchardy Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: PYPIREADME.rst ================================================ .. image:: https://img.shields.io/pypi/v/python-binance.svg :target: https://pypi.python.org/pypi/python-binance .. image:: https://img.shields.io/pypi/l/python-binance.svg :target: https://pypi.python.org/pypi/python-binance .. image:: https://img.shields.io/travis/sammchardy/python-binance.svg :target: https://travis-ci.org/sammchardy/python-binance .. image:: https://img.shields.io/coveralls/sammchardy/python-binance.svg :target: https://coveralls.io/github/sammchardy/python-binance .. image:: https://img.shields.io/pypi/wheel/python-binance.svg :target: https://pypi.python.org/pypi/python-binance .. image:: https://img.shields.io/pypi/pyversions/python-binance.svg :target: https://pypi.python.org/pypi/python-binance This is an unofficial Python wrapper for the `Binance exchange REST API v3 `_. I am in no way affiliated with Binance, use at your own risk. If you came here looking for the `Binance exchange `_ to purchase cryptocurrencies, then `go here `_. If you want to automate interactions with Binance stick around. If you're interested in Binance's new DEX Binance Chain see my `python-binance-chain library `_ Source code https://github.com/sammchardy/python-binance Documentation https://python-binance.readthedocs.io/en/latest/ Binance API Telegram https://t.me/binance_api_english Blog with examples including async https://sammchardy.github.io - `Async basics for Binance `_ - `Understanding Binance Order Filters `_ Make sure you update often and check the `Changelog `_ for new features and bug fixes. Features -------- - Implementation of all General, Market Data and Account endpoints. - Asyncio implementation - Testnet support for Spot, Futures and Vanilla Options - Simple handling of authentication include RSA keys - No need to generate timestamps yourself, the wrapper does it for you - Response exception handling - Websocket handling with reconnection and multiplexed connections - Symbol Depth Cache - Historical Kline/Candle fetching function - Withdraw functionality - Deposit addresses - Margin Trading - Futures Trading - Vanilla Options - Support other domains (.us, .jp, etc) Upgrading to v1.0.0+ -------------------- The breaking changes include the migration from wapi to sapi endpoints which related to the wallet endpoints detailed in the `Binance Docs `_ The other breaking change is for websocket streams and the Depth Cache Manager which have been converted to use Asynchronous Context Managers. See examples in the Async section below or view the `websockets `_ and `depth cache `_ docs. Quick Start ----------- `Register an account with Binance `_. `Generate an API Key `_ and assign relevant permissions. If you are using an exchange from the US, Japan or other TLD then make sure pass `tld='us'` when creating the client. To use the `Spot `_ or `Vanilla Options `_ Testnet, pass `testnet=True` when creating the client. .. code:: bash pip install python-binance .. code:: python from binance import Client, ThreadedWebsocketManager, ThreadedDepthCacheManager client = Client(api_key, api_secret) # get market depth depth = client.get_order_book(symbol='BNBBTC') # place a test market buy order, to place an actual order use the create_order function order = client.create_test_order( symbol='BNBBTC', side=Client.SIDE_BUY, type=Client.ORDER_TYPE_MARKET, quantity=100) # get all symbol prices prices = client.get_all_tickers() # withdraw 100 ETH # check docs for assumptions around withdrawals from binance.exceptions import BinanceAPIException try: result = client.withdraw( asset='ETH', address='', amount=100) except BinanceAPIException as e: print(e) else: print("Success") # fetch list of withdrawals withdraws = client.get_withdraw_history() # fetch list of ETH withdrawals eth_withdraws = client.get_withdraw_history(coin='ETH') # get a deposit address for BTC address = client.get_deposit_address(coin='BTC') # get historical kline data from any date range # fetch 1 minute klines for the last day up until now klines = client.get_historical_klines("BNBBTC", Client.KLINE_INTERVAL_1MINUTE, "1 day ago UTC") # fetch 30 minute klines for the last month of 2017 klines = client.get_historical_klines("ETHBTC", Client.KLINE_INTERVAL_30MINUTE, "1 Dec, 2017", "1 Jan, 2018") # fetch weekly klines since it listed klines = client.get_historical_klines("NEOBTC", Client.KLINE_INTERVAL_1WEEK, "1 Jan, 2017") # socket manager using threads twm = ThreadedWebsocketManager() twm.start() # depth cache manager using threads dcm = ThreadedDepthCacheManager() dcm.start() def handle_socket_message(msg): print(f"message type: {msg['e']}") print(msg) def handle_dcm_message(depth_cache): print(f"symbol {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)) twm.start_kline_socket(callback=handle_socket_message, symbol='BNBBTC') dcm.start_depth_cache(callback=handle_dcm_message, symbol='ETHBTC') # replace with a current options symbol options_symbol = 'BTC-210430-36000-C' dcm.start_options_depth_cache(callback=handle_dcm_message, symbol=options_symbol) For more `check out the documentation `_. Async Example ------------- Read `Async basics for Binance `_ for more information. .. code:: python import asyncio import json from binance import AsyncClient, DepthCacheManager, BinanceSocketManager async def main(): # initialise the client client = await AsyncClient.create() # run some simple requests print(json.dumps(await client.get_exchange_info(), indent=2)) print(json.dumps(await client.get_symbol_ticker(symbol="BTCUSDT"), indent=2)) # initialise websocket factory manager bsm = BinanceSocketManager(client) # create listener using async with # this will exit and close the connection after 5 messages async with bsm.trade_socket('ETHBTC') as ts: for _ in range(5): res = await ts.recv() print(f'recv {res}') # get historical kline data from any date range # fetch 1 minute klines for the last day up until now klines = client.get_historical_klines("BNBBTC", AsyncClient.KLINE_INTERVAL_1MINUTE, "1 day ago UTC") # use generator to fetch 1 minute klines for the last day up until now async for kline in await client.get_historical_klines_generator("BNBBTC", AsyncClient.KLINE_INTERVAL_1MINUTE, "1 day ago UTC"): print(kline) # fetch 30 minute klines for the last month of 2017 klines = client.get_historical_klines("ETHBTC", Client.KLINE_INTERVAL_30MINUTE, "1 Dec, 2017", "1 Jan, 2018") # fetch weekly klines since it listed klines = client.get_historical_klines("NEOBTC", Client.KLINE_INTERVAL_1WEEK, "1 Jan, 2017") # setup an async context the Depth Cache and exit after 5 messages async with DepthCacheManager(client, symbol='ETHBTC') as dcm_socket: for _ in range(5): depth_cache = await dcm_socket.recv() print(f"symbol {depth_cache.symbol} updated:{depth_cache.update_time}") print("Top 5 asks:") print(depth_cache.get_asks()[:5]) print("Top 5 bids:") print(depth_cache.get_bids()[:5]) # Vanilla options Depth Cache works the same, update the symbol to a current one options_symbol = 'BTC-210430-36000-C' async with OptionsDepthCacheManager(client, symbol=options_symbol) as dcm_socket: for _ in range(5): depth_cache = await dcm_socket.recv() count += 1 print(f"symbol {depth_cache.symbol} updated:{depth_cache.update_time}") print("Top 5 asks:") print(depth_cache.get_asks()[:5]) print("Top 5 bids:") print(depth_cache.get_bids()[:5]) await client.close_connection() if __name__ == "__main__": loop = asyncio.get_event_loop() loop.run_until_complete(main()) Donate ------ If this library helped you out feel free to donate. - ETH: 0xD7a7fDdCfA687073d7cC93E9E51829a727f9fE70 - LTC: LPC5vw9ajR1YndE1hYVeo3kJ9LdHjcRCUZ - NEO: AVJB4ZgN7VgSUtArCt94y7ZYT6d5NDfpBo - BTC: 1Dknp6L6oRZrHDECRedihPzx2sSfmvEBys Other Exchanges --------------- If you use `Binance Chain `_ check out my `python-binance-chain `_ library. If you use `Kucoin `_ check out my `python-kucoin `_ library. If you use `IDEX `_ check out my `python-idex `_ library. .. image:: https://ga-beacon.appspot.com/UA-111417213-1/github/python-binance?pixel&useReferer ================================================ FILE: README.rst ================================================ ================================= Welcome to python-binance v1.0.35 ================================= .. image:: https://img.shields.io/pypi/v/python-binance.svg :target: https://pypi.python.org/pypi/python-binance .. image:: https://img.shields.io/pypi/l/python-binance.svg :target: https://pypi.python.org/pypi/python-binance .. image:: https://img.shields.io/coveralls/sammchardy/python-binance.svg :target: https://coveralls.io/github/sammchardy/python-binance .. image:: https://img.shields.io/pypi/wheel/python-binance.svg :target: https://pypi.python.org/pypi/python-binance .. image:: https://img.shields.io/pypi/pyversions/python-binance.svg :target: https://pypi.python.org/pypi/python-binance .. image:: https://img.shields.io/badge/Telegram-Join%20Us-blue?logo=Telegram :target: https://t.me/python_binance This is an unofficial Python wrapper for the `Binance exchange REST API v3 `_. If you came here looking for the `Binance exchange `_ to purchase cryptocurrencies, then `go here `_. If you want to automate interactions with Binance stick around. .. |ico1| image:: https://avatars.githubusercontent.com/u/31901609?s=48&v=4 :target: https://github.com/ccxt/ccxt :height: 3ex :align: middle **This project is powered by** |ico1| *Please make sure your* `python-binance` *version is* **v.1.0.20** *or higher.* *The previous versions are no longer recommended because some endpoints have been deprecated.* Source code https://github.com/sammchardy/python-binance Documentation https://python-binance.readthedocs.io/en/latest/ Community Telegram Chat https://t.me/python_binance Announcements Channel https://t.me/python_binance_announcements Examples including async https://github.com/sammchardy/python-binance/tree/master/examples - `Async basics for Binance `_ - `Understanding Binance Order Filters `_ Make sure you update often and check the `Changelog `_ for new features and bug fixes. Your contributions, suggestions, and fixes are always welcome! Don't hesitate to open a GitHub issue or reach out to us on our Telegram chat Features -------- - Implementation of all General, Market Data and Account endpoints. - Asyncio implementation - Demo trading support (by providing demo=True) - Testnet support for Spot, Futures and Vanilla Options (deprecated) - Simple handling of authentication include RSA and EDDSA keys - Verbose mode for inspecting requests (verbose=True) - No need to generate timestamps yourself, the wrapper does it for you - RecvWindow sent by default - Response exception handling - Customizable HTTP headers - Websocket handling with reconnection and multiplexed connections - CRUD over websockets, create/fetch/edit through websockets for minimum latency. - Symbol Depth Cache - Historical Kline/Candle fetching function - Withdraw functionality - Deposit addresses - Margin Trading - Futures Trading - Porfolio Margin Trading - Vanilla Options - Proxy support (REST and WS) - Orjson support for faster JSON parsing - Support other domains (.us, .jp, etc) - Support for the Gift Card API Upgrading to v1.0.0+ -------------------- The breaking changes include the migration from wapi to sapi endpoints which related to the wallet endpoints detailed in the `Binance Docs `_ The other breaking change is for websocket streams and the Depth Cache Manager which have been converted to use Asynchronous Context Managers. See examples in the Async section below or view the `websockets `_ and `depth cache `_ docs. Quick Start ----------- `Register an account with Binance `_. `Generate an API Key `_ and assign relevant permissions. If you are using an exchange from the US, Japan or other TLD then make sure pass `tld='us'` when creating the client. To use the `Spot `_, `Vanilla Options `_ , or `Futures `_ Testnet pass `testnet=True` when creating the client. .. code:: bash pip install python-binance .. code:: python from binance import Client, ThreadedWebsocketManager, ThreadedDepthCacheManager client = Client(api_key, api_secret) # get market depth depth = client.get_order_book(symbol='BNBBTC') # place a test market buy order, to place an actual order use the create_order function order = client.create_test_order( symbol='BNBBTC', side=Client.SIDE_BUY, type=Client.ORDER_TYPE_MARKET, quantity=100) # get all symbol prices prices = client.get_all_tickers() # withdraw 100 ETH # check docs for assumptions around withdrawals from binance.exceptions import BinanceAPIException try: result = client.withdraw( asset='ETH', address='', amount=100) except BinanceAPIException as e: print(e) else: print("Success") # fetch list of withdrawals withdraws = client.get_withdraw_history() # fetch list of ETH withdrawals eth_withdraws = client.get_withdraw_history(coin='ETH') # get a deposit address for BTC address = client.get_deposit_address(coin='BTC') # get historical kline data from any date range # fetch 1 minute klines for the last day up until now klines = client.get_historical_klines("BNBBTC", Client.KLINE_INTERVAL_1MINUTE, "1 day ago UTC") # fetch 30 minute klines for the last month of 2017 klines = client.get_historical_klines("ETHBTC", Client.KLINE_INTERVAL_30MINUTE, "1 Dec, 2017", "1 Jan, 2018") # fetch weekly klines since it listed klines = client.get_historical_klines("NEOBTC", Client.KLINE_INTERVAL_1WEEK, "1 Jan, 2017") # create conditional order using the dedicated method algo_order = client.futures_create_algo_order(symbol="LTCUSDT", side="BUY", type="STOP_MARKET", quantity=0.1, triggerPrice = 120) # create conditional order using the create_order method (will redirect to the algoOrder as well) order2 = await client.futures_create_order(symbol="LTCUSDT", side="BUY", type="STOP_MARKET", quantity=0.1, triggerPrice = 120) # cancel algo/conditional order cancel2 = await client.futures_cancel_algo_order(orderId=order2["orderId"], symbol="LTCUSDT") # fetch open algo/conditional orders open_orders = await client.futures_get_open_algo_orders(symbol="LTCUSDT") # create order through websockets order_ws = client.ws_create_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1) # get account using custom headers account = client.get_account(headers={'MyCustomKey': 'MyCustomValue'}) # socket manager using threads twm = ThreadedWebsocketManager() twm.start() # depth cache manager using threads dcm = ThreadedDepthCacheManager() dcm.start() def handle_socket_message(msg): print(f"message type: {msg['e']}") print(msg) def handle_dcm_message(depth_cache): print(f"symbol {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)) twm.start_kline_socket(callback=handle_socket_message, symbol='BNBBTC') dcm.start_depth_cache(callback=handle_dcm_message, symbol='ETHBTC') # replace with a current options symbol options_symbol = 'BTC-241227-41000-C' dcm.start_options_depth_cache(callback=handle_dcm_message, symbol=options_symbol) # join the threaded managers to the main thread twm.join() dcm.join() For more `check out the documentation `_. Async Example ------------- Read `Async basics for Binance `_ for more information. .. code:: python import asyncio import json from binance import AsyncClient, DepthCacheManager, BinanceSocketManager async def main(): # initialise the client client = await AsyncClient.create() # run some simple requests print(json.dumps(await client.get_exchange_info(), indent=2)) print(json.dumps(await client.get_symbol_ticker(symbol="BTCUSDT"), indent=2)) # initialise websocket factory manager bsm = BinanceSocketManager(client) # create listener using async with # this will exit and close the connection after 5 messages async with bsm.trade_socket('ETHBTC') as ts: for _ in range(5): res = await ts.recv() print(f'recv {res}') # get historical kline data from any date range # fetch 1 minute klines for the last day up until now klines = client.get_historical_klines("BNBBTC", AsyncClient.KLINE_INTERVAL_1MINUTE, "1 day ago UTC") # use generator to fetch 1 minute klines for the last day up until now async for kline in await client.get_historical_klines_generator("BNBBTC", AsyncClient.KLINE_INTERVAL_1MINUTE, "1 day ago UTC"): print(kline) # fetch 30 minute klines for the last month of 2017 klines = await client.get_historical_klines("ETHBTC", Client.KLINE_INTERVAL_30MINUTE, "1 Dec, 2017", "1 Jan, 2018") # fetch weekly klines since it listed klines = await client.get_historical_klines("NEOBTC", Client.KLINE_INTERVAL_1WEEK, "1 Jan, 2017") # create order through websockets order_ws = await client.ws_create_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1) # setup an async context the Depth Cache and exit after 5 messages async with DepthCacheManager(client, symbol='ETHBTC') as dcm_socket: for _ in range(5): depth_cache = await dcm_socket.recv() print(f"symbol {depth_cache.symbol} updated:{depth_cache.update_time}") print("Top 5 asks:") print(depth_cache.get_asks()[:5]) print("Top 5 bids:") print(depth_cache.get_bids()[:5]) # Vanilla options Depth Cache works the same, update the symbol to a current one options_symbol = 'BTC-241227-41000-C' async with OptionsDepthCacheManager(client, symbol=options_symbol) as dcm_socket: for _ in range(5): depth_cache = await dcm_socket.recv() count += 1 print(f"symbol {depth_cache.symbol} updated:{depth_cache.update_time}") print("Top 5 asks:") print(depth_cache.get_asks()[:5]) print("Top 5 bids:") print(depth_cache.get_bids()[:5]) await client.close_connection() if __name__ == "__main__": loop = asyncio.get_event_loop() loop.run_until_complete(main()) The library is under `MIT license`, that means it's absolutely free for any developer to build commercial and opensource software on top of it, but use it at your own risk with no warranties, as is. Orjson support ------------------- Python-binance also supports `orjson` for parsing JSON since it is much faster than the builtin library. This is especially important when using websockets because some exchanges return big messages that need to be parsed and dispatched as quickly as possible. However, `orjson` is not enabled by default because it is not supported by every python interpreter. If you want to opt-in, you just need to install it (`pip install orjson`) on your local environment. Python-binance will detect the installion and pick it up automatically. Star history ------------ .. image:: https://api.star-history.com/svg?repos=sammchardy/python-binance&type=Date :target: https://api.star-history.com/svg?repos=sammchardy/python-binance&type=Date Contact Us ---------- For business inquiries: `info@ccxt.trade` Other Exchanges --------------- - Check out `CCXT `_ for more than 100 crypto exchanges with a unified trading API. - If you use `Kucoin `_ check out my `python-kucoin `_ library. ================================================ FILE: binance/__init__.py ================================================ """An unofficial Python wrapper for the Binance exchange API v3 .. moduleauthor:: Sam McHardy """ __version__ = "1.0.35" from binance.async_client import AsyncClient # noqa from binance.client import Client # noqa from binance.ws.depthcache import ( DepthCacheManager, # noqa OptionsDepthCacheManager, # noqa ThreadedDepthCacheManager, # noqa FuturesDepthCacheManager, # noqa ) from binance.ws.streams import ( BinanceSocketManager, # noqa ThreadedWebsocketManager, # noqa BinanceSocketType, # noqa ) from binance.ws.keepalive_websocket import KeepAliveWebsocket # noqa from binance.ws.reconnecting_websocket import ReconnectingWebsocket # noqa from binance.ws.constants import * # noqa from binance.exceptions import * # noqa from binance.enums import * # noqa ================================================ FILE: binance/async_client.py ================================================ import asyncio from pathlib import Path from typing import Any, Dict, List, Optional, Union from urllib.parse import urlencode, quote import time import warnings import aiohttp import yarl from binance.enums import HistoricalKlinesType from binance.exceptions import ( BinanceAPIException, BinanceRequestException, NotImplementedException, ) from binance.helpers import ( convert_list_to_json_array, convert_ts_str, get_loop, interval_to_milliseconds, ) from .base_client import BaseClient from .client import Client class AsyncClient(BaseClient): def __init__( self, api_key: Optional[str] = None, api_secret: Optional[str] = None, requests_params: Optional[Dict[str, Any]] = None, tld: str = "com", base_endpoint: str = BaseClient.BASE_ENDPOINT_DEFAULT, testnet: bool = False, demo: bool = False, loop=None, session_params: Optional[Dict[str, Any]] = None, private_key: Optional[Union[str, Path]] = None, private_key_pass: Optional[str] = None, https_proxy: Optional[str] = None, time_unit: Optional[str] = None, verbose: bool = False, ): self.https_proxy = https_proxy self.loop = loop or get_loop() self._session_params: Dict[str, Any] = session_params or {} # Convert https_proxy to requests_params format for BaseClient if https_proxy and requests_params is None: requests_params = {'proxies': {'http': https_proxy, 'https': https_proxy}} elif https_proxy and requests_params is not None: if 'proxies' not in requests_params: requests_params['proxies'] = {} requests_params['proxies'].update({'http': https_proxy, 'https': https_proxy}) super().__init__( api_key, api_secret, requests_params, tld, base_endpoint, testnet, demo, private_key, private_key_pass, time_unit=time_unit, verbose=verbose, ) @classmethod async def create( cls, api_key: Optional[str] = None, api_secret: Optional[str] = None, requests_params: Optional[Dict[str, Any]] = None, tld: str = "com", base_endpoint: str = BaseClient.BASE_ENDPOINT_DEFAULT, testnet: bool = False, demo: bool = False, loop=None, session_params: Optional[Dict[str, Any]] = None, private_key: Optional[Union[str, Path]] = None, private_key_pass: Optional[str] = None, https_proxy: Optional[str] = None, time_unit: Optional[str] = None, verbose: bool = False, ): self = cls( api_key, api_secret, requests_params, tld, base_endpoint, testnet, demo, loop, session_params, private_key, private_key_pass, https_proxy, time_unit, verbose ) self.https_proxy = https_proxy # move this to the constructor try: await self.ping() # calculate timestamp offset between local and binance server res = await self.get_server_time() self.timestamp_offset = res["serverTime"] - int(time.time() * 1000) return self except Exception: # If ping throw an exception, the current self must be cleaned # else, we can receive a "asyncio:Unclosed client session" await self.close_connection() raise def _init_session(self) -> aiohttp.ClientSession: session = aiohttp.ClientSession( loop=self.loop, headers=self._get_headers(), **self._session_params ) return session async def close_connection(self): if self.session: assert self.session await self.session.close() if self.ws_api: await self.ws_api.close() self._ws_api = None close_connection.__doc__ = Client.close_connection.__doc__ async def _request( self, method, uri: str, signed: bool, force_params: bool = False, **kwargs ): # this check needs to be done before __get_request_kwargs to avoid # polluting the signature headers = {} if method.upper() in ["POST", "PUT", "DELETE"]: headers.update({"Content-Type": "application/x-www-form-urlencoded"}) if "data" in kwargs: for key in kwargs["data"]: if key == "headers": headers.update(kwargs["data"][key]) del kwargs["data"][key] break kwargs = self._get_request_kwargs(method, signed, force_params, **kwargs) if method == "get": # url encode the query string if "params" in kwargs: uri = f"{uri}?{kwargs['params']}" kwargs.pop("params") data = kwargs.get("data") if data is not None: del kwargs["data"] if ( signed and self.PRIVATE_KEY and data ): # handle issues with signing using eddsa/rsa and POST requests dict_data = Client.convert_to_dict(data) signature = dict_data["signature"] if "signature" in dict_data else None if signature: del dict_data["signature"] url_encoded_data = urlencode(dict_data) data = f"{url_encoded_data}&signature={signature}" # Remove proxies from kwargs since aiohttp uses 'proxy' parameter instead kwargs.pop('proxies', None) async with getattr(self.session, method)( yarl.URL(uri, encoded=True), proxy=self.https_proxy, headers=headers, data=data, **kwargs, ) as response: self.response = response if self.verbose: response_text = await response.text() self.logger.debug( "\nRequest: %s %s\nRequestHeaders: %s\nRequestBody: %s\nResponse: %s\nResponseHeaders: %s\nResponseBody: %s", method.upper(), uri, headers, data, response.status, dict(response.headers), response_text[:1000] if response_text else None ) return await self._handle_response(response) async def _handle_response(self, response: aiohttp.ClientResponse): """Internal helper for handling API responses from the Binance server. Raises the appropriate exceptions when necessary; otherwise, returns the response. """ if not str(response.status).startswith("2"): raise BinanceAPIException(response, response.status, await response.text()) text = await response.text() if text == "": return {} try: return await response.json() except ValueError: txt = await response.text() raise BinanceRequestException(f"Invalid Response: {txt}") async def _request_api( self, method, path, signed=False, version=BaseClient.PUBLIC_API_VERSION, **kwargs, ): uri = self._create_api_uri(path, signed, version) force_params = kwargs.pop("force_params", False) return await self._request(method, uri, signed, force_params, **kwargs) async def _request_futures_api( self, method, path, signed=False, version=1, **kwargs ) -> Dict: version = self._get_version(version, **kwargs) uri = self._create_futures_api_uri(path, version=version) force_params = kwargs.pop("force_params", False) return await self._request(method, uri, signed, force_params, **kwargs) async def _request_futures_data_api( self, method, path, signed=False, **kwargs ) -> Dict: uri = self._create_futures_data_api_uri(path) force_params = kwargs.pop("force_params", True) return await self._request(method, uri, signed, force_params, **kwargs) async def _request_futures_coin_api( self, method, path, signed=False, version=1, **kwargs ) -> Dict: version = self._get_version(version, **kwargs) uri = self._create_futures_coin_api_url(path, version=version) force_params = kwargs.pop("force_params", False) return await self._request(method, uri, signed, force_params, **kwargs) async def _request_futures_coin_data_api( self, method, path, signed=False, version=1, **kwargs ) -> Dict: version = self._get_version(version, **kwargs) uri = self._create_futures_coin_data_api_url(path, version=version) force_params = kwargs.pop("force_params", True) return await self._request(method, uri, signed, force_params, **kwargs) async def _request_options_api(self, method, path, signed=False, **kwargs) -> Dict: uri = self._create_options_api_uri(path) force_params = kwargs.pop("force_params", True) return await self._request(method, uri, signed, force_params, **kwargs) async def _request_margin_api( self, method, path, signed=False, version=1, **kwargs ) -> Dict: version = self._get_version(version, **kwargs) uri = self._create_margin_api_uri(path, version) force_params = kwargs.pop("force_params", False) return await self._request(method, uri, signed, force_params, **kwargs) async def _request_papi_api( self, method, path, signed=False, version=1, **kwargs ) -> Dict: version = self._get_version(version, **kwargs) uri = self._create_papi_api_uri(path, version) force_params = kwargs.pop("force_params", False) return await self._request(method, uri, signed, force_params, **kwargs) async def _request_website(self, method, path, signed=False, **kwargs) -> Dict: uri = self._create_website_uri(path) return await self._request(method, uri, signed, **kwargs) async def _get( self, path, signed=False, version=BaseClient.PUBLIC_API_VERSION, **kwargs ): return await self._request_api("get", path, signed, version, **kwargs) async def _post( self, path, signed=False, version=BaseClient.PUBLIC_API_VERSION, **kwargs ) -> Dict: return await self._request_api("post", path, signed, version, **kwargs) async def _put( self, path, signed=False, version=BaseClient.PUBLIC_API_VERSION, **kwargs ) -> Dict: return await self._request_api("put", path, signed, version, **kwargs) async def _delete( self, path, signed=False, version=BaseClient.PUBLIC_API_VERSION, **kwargs ) -> Dict: return await self._request_api("delete", path, signed, version, **kwargs) # Exchange Endpoints async def get_products(self) -> Dict: products = await self._request_website( "get", "bapi/asset/v2/public/asset-service/product/get-products?includeEtf=true", ) return products get_products.__doc__ = Client.get_products.__doc__ async def get_exchange_info(self) -> Dict: return await self._get("exchangeInfo") get_exchange_info.__doc__ = Client.get_exchange_info.__doc__ async def get_symbol_info(self, symbol) -> Optional[Dict]: res = await self.get_exchange_info() for item in res["symbols"]: if item["symbol"] == symbol.upper(): return item return None get_symbol_info.__doc__ = Client.get_symbol_info.__doc__ # General Endpoints async def ping(self) -> Dict: return await self._get("ping") ping.__doc__ = Client.ping.__doc__ async def get_server_time(self) -> Dict: return await self._get("time") get_server_time.__doc__ = Client.get_server_time.__doc__ # Market Data Endpoints async def get_all_tickers( self, symbol: Optional[str] = None ) -> List[Dict[str, str]]: params = {} if symbol: params["symbol"] = symbol response = await self._get( "ticker/price", data=params ) if isinstance(response, list) and all(isinstance(item, dict) for item in response): return response raise TypeError("Expected a list of dictionaries") get_all_tickers.__doc__ = Client.get_all_tickers.__doc__ async def get_orderbook_tickers(self, **params) -> Dict: data = {} if "symbol" in params: data["symbol"] = params["symbol"] elif "symbols" in params: data["symbols"] = params["symbols"] return await self._get( "ticker/bookTicker", data=data ) get_orderbook_tickers.__doc__ = Client.get_orderbook_tickers.__doc__ async def get_order_book(self, **params) -> Dict: return await self._get("depth", data=params) get_order_book.__doc__ = Client.get_order_book.__doc__ async def get_recent_trades(self, **params) -> Dict: return await self._get("trades", data=params) get_recent_trades.__doc__ = Client.get_recent_trades.__doc__ async def get_historical_trades(self, **params) -> Dict: return await self._get( "historicalTrades", data=params ) get_historical_trades.__doc__ = Client.get_historical_trades.__doc__ async def get_aggregate_trades(self, **params) -> Dict: return await self._get( "aggTrades", data=params ) get_aggregate_trades.__doc__ = Client.get_aggregate_trades.__doc__ async def aggregate_trade_iter(self, symbol, start_str=None, last_id=None): if start_str is not None and last_id is not None: raise ValueError( "start_time and last_id may not be simultaneously specified." ) # If there's no last_id, get one. if last_id is None: # Without a last_id, we actually need the first trade. Normally, # we'd get rid of it. See the next loop. if start_str is None: trades = await self.get_aggregate_trades(symbol=symbol, fromId=0) else: # The difference between startTime and endTime should be less # or equal than an hour and the result set should contain at # least one trade. start_ts = convert_ts_str(start_str) # If the resulting set is empty (i.e. no trades in that interval) # then we just move forward hour by hour until we find at least one # trade or reach present moment while True: end_ts = start_ts + (60 * 60 * 1000) trades = await self.get_aggregate_trades( symbol=symbol, startTime=start_ts, endTime=end_ts ) if len(trades) > 0: break # If we reach present moment and find no trades then there is # nothing to iterate, so we're done if end_ts > int(time.time() * 1000): return start_ts = end_ts for t in trades: yield t last_id = trades[-1][self.AGG_ID] while True: # There is no need to wait between queries, to avoid hitting the # rate limit. We're using blocking IO, and as long as we're the # only thread running calls like this, Binance will automatically # add the right delay time on their end, forcing us to wait for # data. That really simplifies this function's job. Binance is # fucking awesome. trades = await self.get_aggregate_trades(symbol=symbol, fromId=last_id) # fromId=n returns a set starting with id n, but we already have # that one. So get rid of the first item in the result set. trades = trades[1:] if len(trades) == 0: return for t in trades: yield t last_id = trades[-1][self.AGG_ID] aggregate_trade_iter.__doc__ = Client.aggregate_trade_iter.__doc__ async def get_ui_klines(self, **params) -> Dict: return await self._get("uiKlines", data=params) get_ui_klines.__doc__ = Client.get_ui_klines.__doc__ async def get_klines(self, **params) -> Dict: return await self._get("klines", data=params) get_klines.__doc__ = Client.get_klines.__doc__ async def _klines( self, klines_type: HistoricalKlinesType = HistoricalKlinesType.SPOT, **params ) -> Dict: if "endTime" in params and not params["endTime"]: del params["endTime"] if HistoricalKlinesType.SPOT == klines_type: return await self.get_klines(**params) elif HistoricalKlinesType.FUTURES == klines_type: return await self.futures_klines(**params) elif HistoricalKlinesType.FUTURES_COIN == klines_type: return await self.futures_coin_klines(**params) elif HistoricalKlinesType.FUTURES_MARK_PRICE == klines_type: return await self.futures_mark_price_klines(**params) elif HistoricalKlinesType.FUTURES_INDEX_PRICE == klines_type: return await self.futures_index_price_klines(**params) elif HistoricalKlinesType.FUTURES_COIN_MARK_PRICE == klines_type: return await self.futures_coin_mark_price_klines(**params) elif HistoricalKlinesType.FUTURES_COIN_INDEX_PRICE == klines_type: return await self.futures_coin_index_price_klines(**params) else: raise NotImplementedException(klines_type) _klines.__doc__ = Client._klines.__doc__ async def _get_earliest_valid_timestamp( self, symbol, interval, klines_type: HistoricalKlinesType = HistoricalKlinesType.SPOT, ): kline = await self._klines( klines_type=klines_type, symbol=symbol, interval=interval, limit=1, startTime=0, endTime=int(time.time() * 1000), ) return kline[0][0] _get_earliest_valid_timestamp.__doc__ = Client._get_earliest_valid_timestamp.__doc__ async def get_historical_klines( self, symbol, interval, start_str=None, end_str=None, limit=None, klines_type: HistoricalKlinesType = HistoricalKlinesType.SPOT, ): return await self._historical_klines( symbol, interval, start_str, end_str=end_str, limit=limit, klines_type=klines_type, ) get_historical_klines.__doc__ = Client.get_historical_klines.__doc__ async def _historical_klines( self, symbol, interval, start_str=None, end_str=None, limit=None, klines_type: HistoricalKlinesType = HistoricalKlinesType.SPOT, ): initial_limit_set = True if limit is None: limit = 1000 initial_limit_set = False # init our list output_data = [] # convert interval to useful value in seconds timeframe = interval_to_milliseconds(interval) # establish first available start timestamp start_ts = convert_ts_str(start_str) if start_ts is not None: first_valid_ts = await self._get_earliest_valid_timestamp( symbol, interval, klines_type ) start_ts = max(start_ts, first_valid_ts) # if an end time was passed convert it end_ts = convert_ts_str(end_str) if end_ts and start_ts and end_ts <= start_ts: return output_data idx = 0 while True: # fetch the klines from start_ts up to max 500 entries or the end_ts if set temp_data = await self._klines( klines_type=klines_type, symbol=symbol, interval=interval, limit=limit, startTime=start_ts, endTime=end_ts, ) # append this loops data to our output data if temp_data: output_data += temp_data # check if output_data is greater than limit and truncate if needed and break loop if initial_limit_set and len(output_data) > limit: output_data = output_data[:limit] break # handle the case where exactly the limit amount of data was returned last loop # or check if we received less than the required limit and exit the loop if not len(temp_data) or len(temp_data) < limit: # exit the while loop break # set our start timestamp using the last value in the array # and increment next call by our timeframe start_ts = temp_data[-1][0] + timeframe # exit loop if we reached end_ts before reaching klines if end_ts and start_ts >= end_ts: break # sleep after every 3rd call to be kind to the API idx += 1 if idx % 3 == 0: await asyncio.sleep(1) return output_data _historical_klines.__doc__ = Client._historical_klines.__doc__ async def get_historical_klines_generator( self, symbol, interval, start_str=None, end_str=None, limit=1000, klines_type: HistoricalKlinesType = HistoricalKlinesType.SPOT, ): return self._historical_klines_generator( symbol, interval, start_str, end_str=end_str, limit=limit, klines_type=klines_type, ) get_historical_klines_generator.__doc__ = ( Client.get_historical_klines_generator.__doc__ ) async def _historical_klines_generator( self, symbol, interval, start_str=None, end_str=None, limit=1000, klines_type: HistoricalKlinesType = HistoricalKlinesType.SPOT, ): # convert interval to useful value in seconds timeframe = interval_to_milliseconds(interval) # if a start time was passed convert it start_ts = convert_ts_str(start_str) # establish first available start timestamp if start_ts is not None: first_valid_ts = await self._get_earliest_valid_timestamp( symbol, interval, klines_type ) start_ts = max(start_ts, first_valid_ts) # if an end time was passed convert it end_ts = convert_ts_str(end_str) if end_ts and start_ts and end_ts <= start_ts: return idx = 0 while True: # fetch the klines from start_ts up to max 500 entries or the end_ts if set output_data = await self._klines( klines_type=klines_type, symbol=symbol, interval=interval, limit=limit, startTime=start_ts, endTime=end_ts, ) # yield data if output_data: for o in output_data: yield o # handle the case where exactly the limit amount of data was returned last loop # check if we received less than the required limit and exit the loop if not len(output_data) or len(output_data) < limit: # exit the while loop break # increment next call by our timeframe start_ts = output_data[-1][0] + timeframe # exit loop if we reached end_ts before reaching klines if end_ts and start_ts >= end_ts: break # sleep after every 3rd call to be kind to the API idx += 1 if idx % 3 == 0: await asyncio.sleep(1) _historical_klines_generator.__doc__ = Client._historical_klines_generator.__doc__ async def get_avg_price(self, **params): return await self._get( "avgPrice", data=params ) get_avg_price.__doc__ = Client.get_avg_price.__doc__ async def get_ticker(self, **params): return await self._get( "ticker/24hr", data=params ) get_ticker.__doc__ = Client.get_ticker.__doc__ async def get_symbol_ticker(self, **params): return await self._get( "ticker/price", data=params ) get_symbol_ticker.__doc__ = Client.get_symbol_ticker.__doc__ async def get_symbol_ticker_window(self, **params): return await self._get("ticker", data=params) get_symbol_ticker_window.__doc__ = Client.get_symbol_ticker_window.__doc__ async def get_orderbook_ticker(self, **params): return await self._get( "ticker/bookTicker", data=params ) get_orderbook_ticker.__doc__ = Client.get_orderbook_ticker.__doc__ # Account Endpoints async def create_order(self, **params): if "newClientOrderId" not in params: params["newClientOrderId"] = self.SPOT_ORDER_PREFIX + self.uuid22() return await self._post("order", True, data=params) create_order.__doc__ = Client.create_order.__doc__ async def order_limit(self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params): params.update({"type": self.ORDER_TYPE_LIMIT, "timeInForce": timeInForce}) return await self.create_order(**params) order_limit.__doc__ = Client.order_limit.__doc__ async def order_limit_buy(self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params): params.update({ "side": self.SIDE_BUY, }) return await self.order_limit(timeInForce=timeInForce, **params) order_limit_buy.__doc__ = Client.order_limit_buy.__doc__ async def order_limit_sell( self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params ): params.update({"side": self.SIDE_SELL}) return await self.order_limit(timeInForce=timeInForce, **params) order_limit_sell.__doc__ = Client.order_limit_sell.__doc__ async def order_market(self, **params): params.update({"type": self.ORDER_TYPE_MARKET}) return await self.create_order(**params) order_market.__doc__ = Client.order_market.__doc__ async def order_market_buy(self, **params): params.update({"side": self.SIDE_BUY}) return await self.order_market(**params) order_market_buy.__doc__ = Client.order_market_buy.__doc__ async def order_market_sell(self, **params): params.update({"side": self.SIDE_SELL}) return await self.order_market(**params) order_market_sell.__doc__ = Client.order_market_sell.__doc__ async def order_oco_buy(self, **params): params.update({"side": self.SIDE_BUY}) return await self.create_oco_order(**params) order_oco_buy.__doc__ = Client.order_oco_buy.__doc__ async def order_oco_sell(self, **params): params.update({"side": self.SIDE_SELL}) return await self.create_oco_order(**params) order_oco_sell.__doc__ = Client.order_oco_sell.__doc__ async def create_test_order(self, **params): return await self._post("order/test", True, data=params) create_test_order.__doc__ = Client.create_test_order.__doc__ async def get_order(self, **params): return await self._get("order", True, data=params) get_order.__doc__ = Client.get_order.__doc__ async def get_all_orders(self, **params): return await self._get("allOrders", True, data=params) get_all_orders.__doc__ = Client.get_all_orders.__doc__ async def cancel_order(self, **params): return await self._delete("order", True, data=params) cancel_order.__doc__ = Client.cancel_order.__doc__ async def get_open_orders(self, **params): return await self._get("openOrders", True, data=params) get_open_orders.__doc__ = Client.get_open_orders.__doc__ async def get_open_oco_orders(self, **params): return await self._get("openOrderList", True, data=params) get_open_oco_orders.__doc__ = Client.get_open_oco_orders.__doc__ # User Stream Endpoints async def get_account(self, **params): return await self._get("account", True, data=params) get_account.__doc__ = Client.get_account.__doc__ async def get_asset_balance(self, asset=None, **params): res = await self.get_account(**params) # find asset balance in list of balances if "balances" in res: if asset: for bal in res["balances"]: if bal["asset"].lower() == asset.lower(): return bal else: return res["balances"] return None get_asset_balance.__doc__ = Client.get_asset_balance.__doc__ async def get_my_trades(self, **params): return await self._get("myTrades", True, data=params) get_my_trades.__doc__ = Client.get_my_trades.__doc__ async def get_current_order_count(self, **params): return await self._get("rateLimit/order", True, data=params) get_current_order_count.__doc__ = Client.get_current_order_count.__doc__ async def get_prevented_matches(self, **params): return await self._get("myPreventedMatches", True, data=params) get_prevented_matches.__doc__ = Client.get_prevented_matches.__doc__ async def get_allocations(self, **params): return await self._get("myAllocations", True, data=params) get_allocations.__doc__ = Client.get_allocations.__doc__ async def get_system_status(self): return await self._request_margin_api("get", "system/status") get_system_status.__doc__ = Client.get_system_status.__doc__ async def get_account_status(self, **params): return await self._request_margin_api( "get", "account/status", True, data=params ) get_account_status.__doc__ = Client.get_account_status.__doc__ async def get_account_api_trading_status(self, **params): return await self._request_margin_api( "get", "account/apiTradingStatus", True, data=params ) get_account_api_trading_status.__doc__ = ( Client.get_account_api_trading_status.__doc__ ) async def get_account_api_permissions(self, **params): return await self._request_margin_api( "get", "account/apiRestrictions", True, data=params ) get_account_api_permissions.__doc__ = Client.get_account_api_permissions.__doc__ async def get_dust_assets(self, **params): return await self._request_margin_api( "post", "asset/dust-btc", True, data=params ) get_dust_assets.__doc__ = Client.get_dust_assets.__doc__ async def get_dust_log(self, **params): return await self._request_margin_api( "get", "asset/dribblet", True, data=params ) get_dust_log.__doc__ = Client.get_dust_log.__doc__ async def transfer_dust(self, **params): return await self._request_margin_api("post", "asset/dust", True, data=params) transfer_dust.__doc__ = Client.transfer_dust.__doc__ async def get_asset_dividend_history(self, **params): return await self._request_margin_api( "get", "asset/assetDividend", True, data=params ) get_asset_dividend_history.__doc__ = Client.get_asset_dividend_history.__doc__ async def make_universal_transfer(self, **params): return await self._request_margin_api( "post", "asset/transfer", signed=True, data=params ) make_universal_transfer.__doc__ = Client.make_universal_transfer.__doc__ async def query_universal_transfer_history(self, **params): return await self._request_margin_api( "get", "asset/transfer", signed=True, data=params ) query_universal_transfer_history.__doc__ = ( Client.query_universal_transfer_history.__doc__ ) async def get_trade_fee(self, **params): if self.tld == "us": endpoint = "asset/query/trading-fee" else: endpoint = "asset/tradeFee" return await self._request_margin_api("get", endpoint, True, data=params) get_trade_fee.__doc__ = Client.get_trade_fee.__doc__ async def get_asset_details(self, **params): return await self._request_margin_api( "get", "asset/assetDetail", True, data=params ) get_asset_details.__doc__ = Client.get_asset_details.__doc__ async def get_spot_delist_schedule(self, **params): return await self._request_margin_api( "get", "/spot/delist-schedule", signed=False, data=params ) get_spot_delist_schedule.__doc__ = Client.get_spot_delist_schedule.__doc__ # Withdraw Endpoints async def withdraw(self, **params): # force a name for the withdrawal if one not set if "coin" in params and "name" not in params: params["name"] = params["coin"] return await self._request_margin_api( "post", "capital/withdraw/apply", True, data=params ) withdraw.__doc__ = Client.withdraw.__doc__ async def get_deposit_history(self, **params): return await self._request_margin_api( "get", "capital/deposit/hisrec", True, data=params ) get_deposit_history.__doc__ = Client.get_deposit_history.__doc__ async def get_withdraw_history(self, **params): return await self._request_margin_api( "get", "capital/withdraw/history", True, data=params ) get_withdraw_history.__doc__ = Client.get_withdraw_history.__doc__ async def get_withdraw_history_id(self, withdraw_id, **params): result = await self.get_withdraw_history(**params) for entry in result: if "id" in entry and entry["id"] == withdraw_id: return entry raise Exception("There is no entry with withdraw id", result) get_withdraw_history_id.__doc__ = Client.get_withdraw_history_id.__doc__ async def get_deposit_address( self, coin: str, network: Optional[str] = None, **params ): params["coin"] = coin if network: params["network"] = network return await self._request_margin_api( "get", "capital/deposit/address", True, data=params ) get_deposit_address.__doc__ = Client.get_deposit_address.__doc__ # User Stream Endpoints async def stream_get_listen_key(self): res = await self._post("userDataStream", False, data={}) return res["listenKey"] stream_get_listen_key.__doc__ = Client.stream_get_listen_key.__doc__ async def stream_keepalive(self, listenKey): params = {"listenKey": listenKey} return await self._put("userDataStream", False, data=params) stream_keepalive.__doc__ = Client.stream_keepalive.__doc__ async def stream_close(self, listenKey): params = {"listenKey": listenKey} return await self._delete("userDataStream", False, data=params) stream_close.__doc__ = Client.stream_close.__doc__ # Margin Trading Endpoints async def get_margin_account(self, **params): return await self._request_margin_api( "get", "margin/account", True, data=params ) get_margin_account.__doc__ = Client.get_margin_account.__doc__ async def get_isolated_margin_account(self, **params): return await self._request_margin_api( "get", "margin/isolated/account", True, data=params ) get_isolated_margin_account.__doc__ = Client.get_isolated_margin_account.__doc__ async def enable_isolated_margin_account(self, **params): return await self._request_margin_api( "post", "margin/isolated/account", True, data=params ) enable_isolated_margin_account.__doc__ = ( Client.enable_isolated_margin_account.__doc__ ) async def disable_isolated_margin_account(self, **params): return await self._request_margin_api( "delete", "margin/isolated/account", True, data=params ) disable_isolated_margin_account.__doc__ = ( Client.disable_isolated_margin_account.__doc__ ) async def get_enabled_isolated_margin_account_limit(self, **params): return await self._request_margin_api( "get", "margin/isolated/accountLimit", True, data=params ) get_enabled_isolated_margin_account_limit.__doc__ = ( Client.get_enabled_isolated_margin_account_limit.__doc__ ) async def get_margin_dustlog(self, **params): return await self._request_margin_api( "get", "margin/dribblet", True, data=params ) get_margin_dustlog.__doc__ = Client.get_margin_dustlog.__doc__ async def get_margin_dust_assets(self, **params): return await self._request_margin_api("get", "margin/dust", True, data=params) get_margin_dust_assets.__doc__ = Client.get_margin_dust_assets.__doc__ async def transfer_margin_dust(self, **params): return await self._request_margin_api("post", "margin/dust", True, data=params) transfer_margin_dust.__doc__ = Client.transfer_margin_dust.__doc__ async def get_cross_margin_collateral_ratio(self, **params): return await self._request_margin_api( "get", "margin/crossMarginCollateralRatio", True, data=params ) get_cross_margin_collateral_ratio.__doc__ = ( Client.get_cross_margin_collateral_ratio.__doc__ ) async def get_small_liability_exchange_assets(self, **params): return await self._request_margin_api( "get", "margin/exchange-small-liability", True, data=params ) get_small_liability_exchange_assets.__doc__ = ( Client.get_small_liability_exchange_assets.__doc__ ) async def exchange_small_liability_assets(self, **params): return await self._request_margin_api( "post", "margin/exchange-small-liability", True, data=params ) exchange_small_liability_assets.__doc__ = ( Client.exchange_small_liability_assets.__doc__ ) async def get_small_liability_exchange_history(self, **params): return await self._request_margin_api( "get", "margin/exchange-small-liability-history", True, data=params ) get_small_liability_exchange_history.__doc__ = ( Client.get_small_liability_exchange_history.__doc__ ) async def get_future_hourly_interest_rate(self, **params): return await self._request_margin_api( "get", "margin/next-hourly-interest-rate", True, data=params ) get_future_hourly_interest_rate.__doc__ = ( Client.get_future_hourly_interest_rate.__doc__ ) async def get_margin_capital_flow(self, **params): return await self._request_margin_api( "get", "margin/capital-flow", True, data=params ) get_margin_capital_flow.__doc__ = Client.get_margin_capital_flow.__doc__ async def get_margin_delist_schedule(self, **params): return await self._request_margin_api( "get", "margin/delist-schedule", True, data=params ) get_margin_delist_schedule.__doc__ = Client.get_margin_delist_schedule.__doc__ async def get_margin_asset(self, **params): return await self._request_margin_api("get", "margin/asset", data=params) get_margin_asset.__doc__ = Client.get_margin_asset.__doc__ async def get_margin_symbol(self, **params): return await self._request_margin_api("get", "margin/pair", data=params) get_margin_symbol.__doc__ = Client.get_margin_symbol.__doc__ async def get_margin_all_assets(self, **params): return await self._request_margin_api("get", "margin/allAssets", data=params) get_margin_all_assets.__doc__ = Client.get_margin_all_assets.__doc__ async def get_margin_all_pairs(self, **params): return await self._request_margin_api("get", "margin/allPairs", data=params) get_margin_all_pairs.__doc__ = Client.get_margin_all_pairs.__doc__ async def create_isolated_margin_account(self, **params): return await self._request_margin_api( "post", "margin/isolated/create", signed=True, data=params ) create_isolated_margin_account.__doc__ = ( Client.create_isolated_margin_account.__doc__ ) async def get_isolated_margin_symbol(self, **params): return await self._request_margin_api( "get", "margin/isolated/pair", signed=True, data=params ) get_isolated_margin_symbol.__doc__ = Client.get_isolated_margin_symbol.__doc__ async def get_all_isolated_margin_symbols(self, **params): return await self._request_margin_api( "get", "margin/isolated/allPairs", signed=True, data=params ) get_all_isolated_margin_symbols.__doc__ = ( Client.get_all_isolated_margin_symbols.__doc__ ) async def get_isolated_margin_fee_data(self, **params): return await self._request_margin_api( "get", "margin/isolatedMarginData", True, data=params ) get_isolated_margin_fee_data.__doc__ = Client.get_isolated_margin_fee_data.__doc__ async def get_isolated_margin_tier_data(self, **params): return await self._request_margin_api( "get", "margin/isolatedMarginTier", True, data=params ) get_isolated_margin_tier_data.__doc__ = Client.get_isolated_margin_tier_data.__doc__ async def margin_manual_liquidation(self, **params): return await self._request_margin_api( "get", "margin/manual-liquidation", True, data=params ) margin_manual_liquidation.__doc__ = Client.margin_manual_liquidation.__doc__ async def toggle_bnb_burn_spot_margin(self, **params): return await self._request_margin_api( "post", "bnbBurn", signed=True, data=params ) toggle_bnb_burn_spot_margin.__doc__ = Client.toggle_bnb_burn_spot_margin.__doc__ async def get_bnb_burn_spot_margin(self, **params): return await self._request_margin_api( "get", "bnbBurn", signed=True, data=params ) get_bnb_burn_spot_margin.__doc__ = Client.get_bnb_burn_spot_margin.__doc__ async def get_margin_price_index(self, **params): return await self._request_margin_api("get", "margin/priceIndex", data=params) get_margin_price_index.__doc__ = Client.get_margin_price_index.__doc__ async def transfer_margin_to_spot(self, **params): params["type"] = 2 return await self._request_margin_api( "post", "margin/transfer", signed=True, data=params ) transfer_margin_to_spot.__doc__ = Client.transfer_margin_to_spot.__doc__ async def transfer_spot_to_margin(self, **params): params["type"] = 1 return await self._request_margin_api( "post", "margin/transfer", signed=True, data=params ) transfer_spot_to_margin.__doc__ = Client.transfer_spot_to_margin.__doc__ async def transfer_isolated_margin_to_spot(self, **params): params["transFrom"] = "ISOLATED_MARGIN" params["transTo"] = "SPOT" return await self._request_margin_api( "post", "margin/isolated/transfer", signed=True, data=params ) transfer_isolated_margin_to_spot.__doc__ = ( Client.transfer_isolated_margin_to_spot.__doc__ ) async def transfer_spot_to_isolated_margin(self, **params): params["transFrom"] = "SPOT" params["transTo"] = "ISOLATED_MARGIN" return await self._request_margin_api( "post", "margin/isolated/transfer", signed=True, data=params ) transfer_spot_to_isolated_margin.__doc__ = ( Client.transfer_spot_to_isolated_margin.__doc__ ) async def create_margin_loan(self, **params): return await self._request_margin_api( "post", "margin/loan", signed=True, data=params ) create_margin_loan.__doc__ = Client.create_margin_loan.__doc__ async def repay_margin_loan(self, **params): return await self._request_margin_api( "post", "margin/repay", signed=True, data=params ) repay_margin_loan.__doc__ = Client.repay_margin_loan.__doc__ async def create_margin_order(self, **params): if "newClientOrderId" not in params: params["newClientOrderId"] = self.SPOT_ORDER_PREFIX + self.uuid22() return await self._request_margin_api( "post", "margin/order", signed=True, data=params ) create_margin_order.__doc__ = Client.create_margin_order.__doc__ async def cancel_margin_order(self, **params): return await self._request_margin_api( "delete", "margin/order", signed=True, data=params ) cancel_margin_order.__doc__ = Client.cancel_margin_order.__doc__ async def cancel_all_open_margin_orders(self, **params): return await self._request_margin_api( "delete", "margin/openOrders", signed=True, data=params ) cancel_all_open_margin_orders.__doc__ = Client.cancel_all_open_margin_orders.__doc__ async def set_margin_max_leverage(self, **params): return await self._request_margin_api( "post", "margin/max-leverage", signed=True, data=params ) set_margin_max_leverage.__doc__ = Client.set_margin_max_leverage.__doc__ async def get_margin_transfer_history(self, **params): return await self._request_margin_api( "get", "margin/transfer", signed=True, data=params ) get_margin_transfer_history.__doc__ = Client.get_margin_transfer_history.__doc__ async def get_margin_loan_details(self, **params): return await self._request_margin_api( "get", "margin/loan", signed=True, data=params ) get_margin_loan_details.__doc__ = Client.get_margin_loan_details.__doc__ async def get_margin_repay_details(self, **params): return await self._request_margin_api( "get", "margin/repay", signed=True, data=params ) get_margin_repay_details.__doc__ = Client.get_margin_repay_details.__doc__ async def get_cross_margin_data(self, **params): return await self._request_margin_api( "get", "margin/crossMarginData", signed=True, data=params ) get_cross_margin_data.__doc__ = Client.get_cross_margin_data.__doc__ async def get_margin_interest_history(self, **params): return await self._request_margin_api( "get", "margin/interestHistory", signed=True, data=params ) get_margin_interest_history.__doc__ = Client.get_margin_interest_history.__doc__ async def get_margin_force_liquidation_rec(self, **params): return await self._request_margin_api( "get", "margin/forceLiquidationRec", signed=True, data=params ) get_margin_force_liquidation_rec.__doc__ = Client.get_margin_force_liquidation_rec.__doc__ async def get_margin_order(self, **params): return await self._request_margin_api( "get", "margin/order", signed=True, data=params ) get_margin_order.__doc__ = Client.get_margin_order.__doc__ async def get_open_margin_orders(self, **params): return await self._request_margin_api( "get", "margin/openOrders", signed=True, data=params ) get_open_margin_orders.__doc__ = Client.get_open_margin_orders.__doc__ async def get_all_margin_orders(self, **params): return await self._request_margin_api( "get", "margin/allOrders", signed=True, data=params ) get_all_margin_orders.__doc__ = Client.get_all_margin_orders.__doc__ async def get_margin_trades(self, **params): return await self._request_margin_api( "get", "margin/myTrades", signed=True, data=params ) get_margin_trades.__doc__ = Client.get_margin_trades.__doc__ async def get_max_margin_loan(self, **params): return await self._request_margin_api( "get", "margin/maxBorrowable", signed=True, data=params ) get_max_margin_loan.__doc__ = Client.get_max_margin_loan.__doc__ async def get_max_margin_transfer(self, **params): return await self._request_margin_api( "get", "margin/maxTransferable", signed=True, data=params ) # Margin OCO get_max_margin_transfer.__doc__ = Client.get_max_margin_transfer.__doc__ async def create_margin_oco_order(self, **params): return await self._request_margin_api( "post", "margin/order/oco", signed=True, data=params ) create_margin_oco_order.__doc__ = Client.create_margin_oco_order.__doc__ async def cancel_margin_oco_order(self, **params): return await self._request_margin_api( "delete", "margin/orderList", signed=True, data=params ) cancel_margin_oco_order.__doc__ = Client.cancel_margin_oco_order.__doc__ async def get_margin_oco_order(self, **params): return await self._request_margin_api( "get", "margin/orderList", signed=True, data=params ) get_margin_oco_order.__doc__ = Client.get_margin_oco_order.__doc__ async def get_open_margin_oco_orders(self, **params): return await self._request_margin_api( "get", "margin/openOrderList", signed=True, data=params ) # Cross-margin get_open_margin_oco_orders.__doc__ = Client.get_open_margin_oco_orders.__doc__ async def margin_stream_get_listen_key(self): warnings.warn( "POST /sapi/v1/userDataStream is deprecated and will be removed on 2026-02-20. " "Use the WebSocket API subscription method instead (create listenToken via POST /sapi/v1/userListenToken, " "then subscribe with userDataStream.subscribe.listenToken). " "The margin_socket() method now uses WebSocket API by default.", DeprecationWarning, stacklevel=2 ) res = await self._request_margin_api( "post", "userDataStream", signed=False, data={} ) return res["listenKey"] margin_stream_get_listen_key.__doc__ = Client.margin_stream_get_listen_key.__doc__ async def margin_stream_keepalive(self, listenKey): warnings.warn( "PUT /sapi/v1/userDataStream is deprecated and will be removed on 2026-02-20. " "Use the WebSocket API subscription method instead (create listenToken via POST /sapi/v1/userListenToken, " "then subscribe with userDataStream.subscribe.listenToken). " "The margin_socket() method now uses WebSocket API by default.", DeprecationWarning, stacklevel=2 ) params = {"listenKey": listenKey} return await self._request_margin_api( "put", "userDataStream", signed=False, data=params ) margin_stream_keepalive.__doc__ = Client.margin_stream_keepalive.__doc__ async def margin_stream_close(self, listenKey): warnings.warn( "DELETE /sapi/v1/userDataStream is deprecated and will be removed on 2026-02-20. " "Use the WebSocket API subscription method instead (create listenToken via POST /sapi/v1/userListenToken, " "then subscribe with userDataStream.subscribe.listenToken). " "The margin_socket() method now uses WebSocket API by default.", DeprecationWarning, stacklevel=2 ) params = {"listenKey": listenKey} return await self._request_margin_api( "delete", "userDataStream", signed=False, data=params ) async def margin_create_listen_token(self, symbol: Optional[str] = None, is_isolated: bool = False, validity: Optional[int] = None): """Create a listenToken for margin account user data stream https://developers.binance.com/docs/margin_trading/trade-data-stream/Create-Margin-Account-listenToken :param symbol: Trading pair symbol (required when is_isolated=True) :type symbol: str :param is_isolated: Whether it is isolated margin (default: False for cross-margin) :type is_isolated: bool :param validity: Validity in milliseconds (default: 24 hours, max: 24 hours) :type validity: int :returns: API response with token and expirationTime .. code-block:: python { "token": "6xXxePXwZRjVSHKhzUCCGnmN3fkvMTXru+pYJS8RwijXk9Vcyr3rkwfVOTcP2OkONqciYA", "expirationTime": 1758792204196 } """ params = {} if is_isolated: if not symbol: raise ValueError("symbol is required when is_isolated=True") params["symbol"] = symbol params["isIsolated"] = "true" if validity is not None: params["validity"] = validity return await self._request_margin_api( "post", "userListenToken", signed=True, data=params ) # Isolated margin margin_stream_close.__doc__ = Client.margin_stream_close.__doc__ async def isolated_margin_stream_get_listen_key(self, symbol): warnings.warn( "POST /sapi/v1/userDataStream/isolated is deprecated and will be removed on 2026-02-20. " "Use the WebSocket API subscription method instead (create listenToken via POST /sapi/v1/userListenToken " "with isIsolated=true, then subscribe with userDataStream.subscribe.listenToken). " "The isolated_margin_socket() method now uses WebSocket API by default.", DeprecationWarning, stacklevel=2 ) params = {"symbol": symbol} res = await self._request_margin_api( "post", "userDataStream/isolated", signed=False, data=params ) return res["listenKey"] isolated_margin_stream_get_listen_key.__doc__ = Client.isolated_margin_stream_get_listen_key.__doc__ async def isolated_margin_stream_keepalive(self, symbol, listenKey): warnings.warn( "PUT /sapi/v1/userDataStream/isolated is deprecated and will be removed on 2026-02-20. " "Use the WebSocket API subscription method instead (create listenToken via POST /sapi/v1/userListenToken " "with isIsolated=true, then subscribe with userDataStream.subscribe.listenToken). " "The isolated_margin_socket() method now uses WebSocket API by default.", DeprecationWarning, stacklevel=2 ) params = {"symbol": symbol, "listenKey": listenKey} return await self._request_margin_api( "put", "userDataStream/isolated", signed=False, data=params ) isolated_margin_stream_keepalive.__doc__ = Client.isolated_margin_stream_keepalive.__doc__ async def isolated_margin_stream_close(self, symbol, listenKey): warnings.warn( "DELETE /sapi/v1/userDataStream/isolated is deprecated and will be removed on 2026-02-20. " "Use the WebSocket API subscription method instead (create listenToken via POST /sapi/v1/userListenToken " "with isIsolated=true, then subscribe with userDataStream.subscribe.listenToken). " "The isolated_margin_socket() method now uses WebSocket API by default.", DeprecationWarning, stacklevel=2 ) params = {"symbol": symbol, "listenKey": listenKey} return await self._request_margin_api( "delete", "userDataStream/isolated", signed=False, data=params ) # Simple Earn Endpoints isolated_margin_stream_close.__doc__ = Client.isolated_margin_stream_close.__doc__ async def get_simple_earn_flexible_product_list(self, **params): return await self._request_margin_api( "get", "simple-earn/flexible/list", signed=True, data=params ) get_simple_earn_flexible_product_list.__doc__ = ( Client.get_simple_earn_flexible_product_list.__doc__ ) async def get_simple_earn_locked_product_list(self, **params): return await self._request_margin_api( "get", "simple-earn/locked/list", signed=True, data=params ) get_simple_earn_locked_product_list.__doc__ = ( Client.get_simple_earn_locked_product_list.__doc__ ) async def subscribe_simple_earn_flexible_product(self, **params): return await self._request_margin_api( "post", "simple-earn/flexible/subscribe", signed=True, data=params ) subscribe_simple_earn_flexible_product.__doc__ = ( Client.subscribe_simple_earn_flexible_product.__doc__ ) async def subscribe_simple_earn_locked_product(self, **params): return await self._request_margin_api( "post", "simple-earn/locked/subscribe", signed=True, data=params ) subscribe_simple_earn_locked_product.__doc__ = ( Client.subscribe_simple_earn_locked_product.__doc__ ) async def redeem_simple_earn_flexible_product(self, **params): return await self._request_margin_api( "post", "simple-earn/flexible/redeem", signed=True, data=params ) redeem_simple_earn_flexible_product.__doc__ = ( Client.redeem_simple_earn_flexible_product.__doc__ ) async def redeem_simple_earn_locked_product(self, **params): return await self._request_margin_api( "post", "simple-earn/locked/redeem", signed=True, data=params ) redeem_simple_earn_locked_product.__doc__ = ( Client.redeem_simple_earn_locked_product.__doc__ ) async def get_simple_earn_flexible_product_position(self, **params): return await self._request_margin_api( "get", "simple-earn/flexible/position", signed=True, data=params ) get_simple_earn_flexible_product_position.__doc__ = ( Client.get_simple_earn_flexible_product_position.__doc__ ) async def get_simple_earn_locked_product_position(self, **params): return await self._request_margin_api( "get", "simple-earn/locked/position", signed=True, data=params ) get_simple_earn_locked_product_position.__doc__ = ( Client.get_simple_earn_locked_product_position.__doc__ ) async def get_simple_earn_account(self, **params): return await self._request_margin_api( "get", "simple-earn/account", signed=True, data=params ) get_simple_earn_account.__doc__ = Client.get_simple_earn_account.__doc__ # Lending Endpoints async def get_fixed_activity_project_list(self, **params): return await self._request_margin_api( "get", "lending/project/list", signed=True, data=params ) get_fixed_activity_project_list.__doc__ = Client.get_fixed_activity_project_list.__doc__ async def change_fixed_activity_to_daily_position(self, **params): return await self._request_margin_api( "post", "lending/positionChanged", signed=True, data=params ) # Staking Endpoints change_fixed_activity_to_daily_position.__doc__ = Client.change_fixed_activity_to_daily_position.__doc__ async def get_staking_product_list(self, **params): return await self._request_margin_api( "get", "staking/productList", signed=True, data=params ) get_staking_product_list.__doc__ = Client.get_staking_product_list.__doc__ async def purchase_staking_product(self, **params): return await self._request_margin_api( "post", "staking/purchase", signed=True, data=params ) purchase_staking_product.__doc__ = Client.purchase_staking_product.__doc__ async def redeem_staking_product(self, **params): return await self._request_margin_api( "post", "staking/redeem", signed=True, data=params ) redeem_staking_product.__doc__ = Client.redeem_staking_product.__doc__ async def get_staking_position(self, **params): return await self._request_margin_api( "get", "staking/position", signed=True, data=params ) get_staking_position.__doc__ = Client.get_staking_position.__doc__ async def get_staking_purchase_history(self, **params): return await self._request_margin_api( "get", "staking/purchaseRecord", signed=True, data=params ) get_staking_purchase_history.__doc__ = Client.get_staking_purchase_history.__doc__ async def set_auto_staking(self, **params): return await self._request_margin_api( "post", "staking/setAutoStaking", signed=True, data=params ) set_auto_staking.__doc__ = Client.set_auto_staking.__doc__ async def get_personal_left_quota(self, **params): return await self._request_margin_api( "get", "staking/personalLeftQuota", signed=True, data=params ) # US Staking Endpoints get_personal_left_quota.__doc__ = Client.get_personal_left_quota.__doc__ async def get_staking_asset_us(self, **params): self._require_tld("us", "get_staking_asset_us") return await self._request_margin_api("get", "staking/asset", True, data=params) get_staking_asset_us.__doc__ = Client.get_staking_asset_us.__doc__ async def stake_asset_us(self, **params): self._require_tld("us", "stake_asset_us") return await self._request_margin_api( "post", "staking/stake", True, data=params ) stake_asset_us.__doc__ = Client.stake_asset_us.__doc__ async def unstake_asset_us(self, **params): self._require_tld("us", "unstake_asset_us") return await self._request_margin_api( "post", "staking/unstake", True, data=params ) unstake_asset_us.__doc__ = Client.unstake_asset_us.__doc__ async def get_staking_balance_us(self, **params): self._require_tld("us", "get_staking_balance_us") return await self._request_margin_api( "get", "staking/stakingBalance", True, data=params ) get_staking_balance_us.__doc__ = Client.get_staking_balance_us.__doc__ async def get_staking_history_us(self, **params): self._require_tld("us", "get_staking_history_us") return await self._request_margin_api( "get", "staking/history", True, data=params ) get_staking_history_us.__doc__ = Client.get_staking_history_us.__doc__ async def get_staking_rewards_history_us(self, **params): self._require_tld("us", "get_staking_rewards_history_us") return await self._request_margin_api( "get", "staking/stakingRewardsHistory", True, data=params ) get_staking_rewards_history_us.__doc__ = ( Client.get_staking_rewards_history_us.__doc__ ) # Sub Accounts async def get_sub_account_list(self, **params): return await self._request_margin_api( "get", "sub-account/list", True, data=params ) get_sub_account_list.__doc__ = Client.get_sub_account_list.__doc__ async def get_sub_account_transfer_history(self, **params): return await self._request_margin_api( "get", "sub-account/sub/transfer/history", True, data=params ) get_sub_account_transfer_history.__doc__ = Client.get_sub_account_transfer_history.__doc__ async def get_sub_account_futures_transfer_history(self, **params): return await self._request_margin_api( "get", "sub-account/futures/internalTransfer", True, data=params ) get_sub_account_futures_transfer_history.__doc__ = Client.get_sub_account_futures_transfer_history.__doc__ async def create_sub_account_futures_transfer(self, **params): return await self._request_margin_api( "post", "sub-account/futures/internalTransfer", True, data=params ) create_sub_account_futures_transfer.__doc__ = Client.create_sub_account_futures_transfer.__doc__ async def get_sub_account_assets(self, **params): return await self._request_margin_api( "get", "sub-account/assets", True, data=params, version=4 ) get_sub_account_assets.__doc__ = Client.get_sub_account_assets.__doc__ async def query_subaccount_spot_summary(self, **params): return await self._request_margin_api( "get", "sub-account/spotSummary", True, data=params ) query_subaccount_spot_summary.__doc__ = Client.query_subaccount_spot_summary.__doc__ async def get_subaccount_deposit_address(self, **params): return await self._request_margin_api( "get", "capital/deposit/subAddress", True, data=params ) get_subaccount_deposit_address.__doc__ = Client.get_subaccount_deposit_address.__doc__ async def get_subaccount_deposit_history(self, **params): return await self._request_margin_api( "get", "capital/deposit/subHisrec", True, data=params ) get_subaccount_deposit_history.__doc__ = Client.get_subaccount_deposit_history.__doc__ async def get_subaccount_futures_margin_status(self, **params): return await self._request_margin_api( "get", "sub-account/status", True, data=params ) get_subaccount_futures_margin_status.__doc__ = Client.get_subaccount_futures_margin_status.__doc__ async def enable_subaccount_margin(self, **params): return await self._request_margin_api( "post", "sub-account/margin/enable", True, data=params ) enable_subaccount_margin.__doc__ = Client.enable_subaccount_margin.__doc__ async def get_subaccount_margin_details(self, **params): return await self._request_margin_api( "get", "sub-account/margin/account", True, data=params ) get_subaccount_margin_details.__doc__ = Client.get_subaccount_margin_details.__doc__ async def get_subaccount_margin_summary(self, **params): return await self._request_margin_api( "get", "sub-account/margin/accountSummary", True, data=params ) get_subaccount_margin_summary.__doc__ = Client.get_subaccount_margin_summary.__doc__ async def enable_subaccount_futures(self, **params): return await self._request_margin_api( "post", "sub-account/futures/enable", True, data=params ) enable_subaccount_futures.__doc__ = Client.enable_subaccount_futures.__doc__ async def get_subaccount_futures_details(self, **params): return await self._request_margin_api( "get", "sub-account/futures/account", True, data=params, version=2 ) get_subaccount_futures_details.__doc__ = Client.get_subaccount_futures_details.__doc__ async def get_subaccount_futures_summary(self, **params): return await self._request_margin_api( "get", "sub-account/futures/accountSummary", True, data=params, version=2 ) get_subaccount_futures_summary.__doc__ = Client.get_subaccount_futures_summary.__doc__ async def get_subaccount_futures_positionrisk(self, **params): return await self._request_margin_api( "get", "sub-account/futures/positionRisk", True, data=params, version=2 ) get_subaccount_futures_positionrisk.__doc__ = Client.get_subaccount_futures_positionrisk.__doc__ async def make_subaccount_futures_transfer(self, **params): return await self._request_margin_api( "post", "sub-account/futures/transfer", True, data=params ) make_subaccount_futures_transfer.__doc__ = Client.make_subaccount_futures_transfer.__doc__ async def make_subaccount_margin_transfer(self, **params): return await self._request_margin_api( "post", "sub-account/margin/transfer", True, data=params ) make_subaccount_margin_transfer.__doc__ = Client.make_subaccount_margin_transfer.__doc__ async def make_subaccount_to_subaccount_transfer(self, **params): return await self._request_margin_api( "post", "sub-account/transfer/subToSub", True, data=params ) make_subaccount_to_subaccount_transfer.__doc__ = Client.make_subaccount_to_subaccount_transfer.__doc__ async def make_subaccount_to_master_transfer(self, **params): return await self._request_margin_api( "post", "sub-account/transfer/subToMaster", True, data=params ) make_subaccount_to_master_transfer.__doc__ = Client.make_subaccount_to_master_transfer.__doc__ async def get_subaccount_transfer_history(self, **params): return await self._request_margin_api( "get", "sub-account/transfer/subUserHistory", True, data=params ) get_subaccount_transfer_history.__doc__ = Client.get_subaccount_transfer_history.__doc__ async def make_subaccount_universal_transfer(self, **params): return await self._request_margin_api( "post", "sub-account/universalTransfer", True, data=params ) make_subaccount_universal_transfer.__doc__ = Client.make_subaccount_universal_transfer.__doc__ async def get_universal_transfer_history(self, **params): return await self._request_margin_api( "get", "sub-account/universalTransfer", True, data=params ) # Futures API get_universal_transfer_history.__doc__ = Client.get_universal_transfer_history.__doc__ async def futures_ping(self): return await self._request_futures_api("get", "ping") futures_ping.__doc__ = Client.futures_ping.__doc__ async def futures_time(self): return await self._request_futures_api("get", "time") futures_time.__doc__ = Client.futures_time.__doc__ async def futures_exchange_info(self): return await self._request_futures_api("get", "exchangeInfo") futures_exchange_info.__doc__ = Client.futures_exchange_info.__doc__ async def futures_order_book(self, **params): return await self._request_futures_api("get", "depth", data=params) futures_order_book.__doc__ = Client.futures_order_book.__doc__ async def futures_rpi_depth(self, **params): return await self._request_futures_api("get", "rpiDepth", data=params) futures_rpi_depth.__doc__ = Client.futures_rpi_depth.__doc__ async def futures_recent_trades(self, **params): return await self._request_futures_api("get", "trades", data=params) futures_recent_trades.__doc__ = Client.futures_recent_trades.__doc__ async def futures_historical_trades(self, **params): return await self._request_futures_api("get", "historicalTrades", data=params) futures_historical_trades.__doc__ = Client.futures_historical_trades.__doc__ async def futures_aggregate_trades(self, **params): return await self._request_futures_api("get", "aggTrades", data=params) futures_aggregate_trades.__doc__ = Client.futures_aggregate_trades.__doc__ async def futures_klines(self, **params): return await self._request_futures_api("get", "klines", data=params) futures_klines.__doc__ = Client.futures_klines.__doc__ async def futures_mark_price_klines(self, **params): return await self._request_futures_api("get", "markPriceKlines", data=params) futures_mark_price_klines.__doc__ = Client.futures_mark_price_klines.__doc__ async def futures_index_price_klines(self, **params): return await self._request_futures_api("get", "indexPriceKlines", data=params) futures_index_price_klines.__doc__ = Client.futures_index_price_klines.__doc__ async def futures_premium_index_klines(self, **params): return await self._request_futures_api("get", "premiumIndexKlines", data=params) futures_premium_index_klines.__doc__ = Client.futures_index_price_klines.__doc__ async def futures_continuous_klines(self, **params): return await self._request_futures_api("get", "continuousKlines", data=params) futures_continuous_klines.__doc__ = Client.futures_continuous_klines.__doc__ async def futures_historical_klines( self, symbol: str, interval: str, start_str, end_str=None, limit=None ): return await self._historical_klines( symbol, interval, start_str, end_str=end_str, limit=limit, klines_type=HistoricalKlinesType.FUTURES, ) futures_historical_klines.__doc__ = Client.futures_historical_klines.__doc__ async def futures_historical_klines_generator( self, symbol, interval, start_str, end_str=None ): return self._historical_klines_generator( symbol, interval, start_str, end_str=end_str, klines_type=HistoricalKlinesType.FUTURES, ) futures_historical_klines_generator.__doc__ = Client.futures_historical_klines_generator.__doc__ async def futures_mark_price(self, **params): return await self._request_futures_api("get", "premiumIndex", data=params) futures_mark_price.__doc__ = Client.futures_mark_price.__doc__ async def futures_funding_rate(self, **params): return await self._request_futures_api("get", "fundingRate", data=params) futures_funding_rate.__doc__ = Client.futures_funding_rate.__doc__ async def futures_top_longshort_account_ratio(self, **params): return await self._request_futures_data_api( "get", "topLongShortAccountRatio", data=params ) futures_top_longshort_account_ratio.__doc__ = Client.futures_top_longshort_account_ratio.__doc__ async def futures_top_longshort_position_ratio(self, **params): return await self._request_futures_data_api( "get", "topLongShortPositionRatio", data=params ) futures_top_longshort_position_ratio.__doc__ = Client.futures_top_longshort_position_ratio.__doc__ async def futures_global_longshort_ratio(self, **params): return await self._request_futures_data_api( "get", "globalLongShortAccountRatio", data=params ) futures_global_longshort_ratio.__doc__ = Client.futures_global_longshort_ratio.__doc__ async def futures_taker_longshort_ratio(self, **params): return await self._request_futures_data_api( "get", "takerlongshortRatio", data=params ) futures_taker_longshort_ratio.__doc__ = Client.futures_taker_longshort_ratio.__doc__ async def futures_ticker(self, **params): return await self._request_futures_api("get", "ticker/24hr", data=params) futures_ticker.__doc__ = Client.futures_ticker.__doc__ async def futures_symbol_ticker(self, **params): return await self._request_futures_api("get", "ticker/price", version=2, data=params) futures_symbol_ticker.__doc__ = Client.futures_symbol_ticker.__doc__ futures_symbol_ticker.__doc__ = Client.futures_symbol_ticker.__doc__ futures_symbol_ticker.__doc__ = Client.futures_symbol_ticker.__doc__ async def futures_orderbook_ticker(self, **params): return await self._request_futures_api("get", "ticker/bookTicker", data=params) futures_orderbook_ticker.__doc__ = Client.futures_orderbook_ticker.__doc__ async def futures_index_price_constituents(self, **params): return await self._request_futures_api("get", "constituents", data=params) futures_index_price_constituents.__doc__ = ( Client.futures_index_price_constituents.__doc__ ) async def futures_liquidation_orders(self, **params): return await self._request_futures_api( "get", "forceOrders", signed=True, data=params ) futures_liquidation_orders.__doc__ = Client.futures_liquidation_orders.__doc__ async def futures_api_trading_status(self, **params): return await self._request_futures_api( "get", "apiTradingStatus", signed=True, data=params ) futures_api_trading_status.__doc__ = Client.futures_api_trading_status.__doc__ async def futures_commission_rate(self, **params): return await self._request_futures_api( "get", "commissionRate", signed=True, data=params ) futures_commission_rate.__doc__ = Client.futures_commission_rate.__doc__ async def futures_adl_quantile_estimate(self, **params): return await self._request_futures_api( "get", "adlQuantile", signed=True, data=params ) futures_adl_quantile_estimate.__doc__ = Client.futures_adl_quantile_estimate.__doc__ async def futures_open_interest(self, **params): return await self._request_futures_api("get", "openInterest", data=params) futures_open_interest.__doc__ = Client.futures_open_interest.__doc__ async def futures_index_info(self, **params): return await self._request_futures_api("get", "indexInfo", data=params) futures_index_info.__doc__ = Client.futures_index_info.__doc__ async def futures_open_interest_hist(self, **params): return await self._request_futures_data_api( "get", "openInterestHist", data=params ) futures_open_interest_hist.__doc__ = Client.futures_open_interest_hist.__doc__ async def futures_leverage_bracket(self, **params): return await self._request_futures_api( "get", "leverageBracket", True, data=params ) futures_leverage_bracket.__doc__ = Client.futures_leverage_bracket.__doc__ async def futures_account_transfer(self, **params): return await self._request_margin_api( "post", "futures/transfer", True, data=params ) futures_account_transfer.__doc__ = Client.futures_account_transfer.__doc__ async def transfer_history(self, **params): return await self._request_margin_api( "get", "futures/transfer", True, data=params ) transfer_history.__doc__ = Client.transfer_history.__doc__ async def futures_loan_borrow_history(self, **params): return await self._request_margin_api( "get", "futures/loan/borrow/history", True, data=params ) futures_loan_borrow_history.__doc__ = Client.futures_loan_borrow_history.__doc__ async def futures_loan_repay_history(self, **params): return await self._request_margin_api( "get", "futures/loan/repay/history", True, data=params ) futures_loan_repay_history.__doc__ = Client.futures_loan_repay_history.__doc__ async def futures_loan_wallet(self, **params): return await self._request_margin_api( "get", "futures/loan/wallet", True, data=params, version=2 ) futures_loan_wallet.__doc__ = Client.futures_loan_wallet.__doc__ async def futures_cross_collateral_adjust_history(self, **params): return await self._request_margin_api( "get", "futures/loan/adjustCollateral/history", True, data=params ) futures_cross_collateral_adjust_history.__doc__ = Client.futures_cross_collateral_adjust_history.__doc__ async def futures_cross_collateral_liquidation_history(self, **params): return await self._request_margin_api( "get", "futures/loan/liquidationHistory", True, data=params ) futures_cross_collateral_liquidation_history.__doc__ = Client.futures_cross_collateral_liquidation_history.__doc__ async def futures_loan_interest_history(self, **params): return await self._request_margin_api( "get", "futures/loan/interestHistory", True, data=params ) futures_loan_interest_history.__doc__ = Client.futures_loan_interest_history.__doc__ async def futures_create_order(self, **params): # Check if this is a conditional order type that needs to use algo endpoint order_type = params.get("type", "").upper() conditional_types = [ "STOP", "STOP_MARKET", "TAKE_PROFIT", "TAKE_PROFIT_MARKET", "TRAILING_STOP_MARKET", ] if order_type in conditional_types: # Route to algo order endpoint if "clientAlgoId" not in params: params["clientAlgoId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() # Remove newClientOrderId if it was added by default params.pop("newClientOrderId", None) params["algoType"] = "CONDITIONAL" # Convert stopPrice to triggerPrice for algo orders (camelCase per API docs) if "stopPrice" in params and "triggerPrice" not in params: params["triggerPrice"] = params.pop("stopPrice") return await self._request_futures_api("post", "algoOrder", True, data=params) else: # Use regular order endpoint if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return await self._request_futures_api("post", "order", True, data=params) futures_create_order.__doc__ = Client.futures_create_order.__doc__ async def futures_limit_order(self, **params): """Send in a new futures limit order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() params["type"] = "LIMIT" return await self._request_futures_api("post", "order", True, data=params) async def futures_market_order(self, **params): """Send in a new futures market order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() params["type"] = "MARKET" return await self._request_futures_api("post", "order", True, data=params) async def futures_limit_buy_order(self, **params): """Send in a new futures limit buy order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() params["side"] = "BUY" params["type"] = "LIMIT" return await self._request_futures_api("post", "order", True, data=params) async def futures_limit_sell_order(self, **params): """Send in a new futures limit sell order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() params["side"] = "SELL" params["type"] = "LIMIT" return await self._request_futures_api("post", "order", True, data=params) async def futures_market_buy_order(self, **params): """Send in a new futures market buy order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() params["side"] = "BUY" params["type"] = "MARKET" return await self._request_futures_api("post", "order", True, data=params) async def futures_market_sell_order(self, **params): """Send in a new futures market sell order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() params["side"] = "SELL" params["type"] = "MARKET" return await self._request_futures_api("post", "order", True, data=params) async def futures_modify_order(self, **params): """Modify an existing order. Currently only LIMIT order modification is supported. https://binance-docs.github.io/apidocs/futures/en/#modify-order-trade """ return await self._request_futures_api("put", "order", True, data=params) futures_modify_order.__doc__ = Client.futures_modify_order.__doc__ async def futures_create_test_order(self, **params): return await self._request_futures_api("post", "order/test", True, data=params) futures_create_test_order.__doc__ = Client.futures_create_test_order.__doc__ async def futures_place_batch_order(self, **params): for order in params["batchOrders"]: if "newClientOrderId" not in order: order["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() order = self._order_params(order) query_string = urlencode(params).replace("%40", "@").replace("%27", "%22") params["batchOrders"] = query_string[12:] return await self._request_futures_api( "post", "batchOrders", True, data=params, force_params=True ) futures_place_batch_order.__doc__ = Client.futures_place_batch_order.__doc__ async def futures_get_order(self, **params): # Check if this is a request for a conditional/algo order is_conditional = params.pop("conditional", False) # Also check if algoId or clientAlgoId is provided if "algoId" in params or "clientAlgoId" in params: is_conditional = True if is_conditional: return await self._request_futures_api("get", "algoOrder", True, data=params) else: return await self._request_futures_api("get", "order", True, data=params) futures_get_order.__doc__ = Client.futures_get_order.__doc__ async def futures_get_open_orders(self, **params): is_conditional = params.pop("conditional", False) if is_conditional: return await self._request_futures_api("get", "openAlgoOrders", True, data=params) else: return await self._request_futures_api("get", "openOrders", True, data=params) futures_get_open_orders.__doc__ = Client.futures_get_open_orders.__doc__ async def futures_get_all_orders(self, **params): is_conditional = params.pop("conditional", False) if is_conditional: return await self._request_futures_api("get", "allAlgoOrders", True, data=params) else: return await self._request_futures_api("get", "allOrders", True, data=params) futures_get_all_orders.__doc__ = Client.futures_get_all_orders.__doc__ async def futures_cancel_order(self, **params): # Check if this is a request for a conditional/algo order is_conditional = params.pop("conditional", False) # Also check if algoId or clientAlgoId is provided if "algoId" in params or "clientAlgoId" in params: is_conditional = True if is_conditional: return await self._request_futures_api("delete", "algoOrder", True, data=params) else: return await self._request_futures_api("delete", "order", True, data=params) futures_cancel_order.__doc__ = Client.futures_cancel_order.__doc__ async def futures_cancel_all_open_orders(self, **params): is_conditional = params.pop("conditional", False) if is_conditional: return await self._request_futures_api( "delete", "algoOpenOrders", True, data=params ) else: return await self._request_futures_api( "delete", "allOpenOrders", True, data=params ) futures_cancel_all_open_orders.__doc__ = Client.futures_cancel_all_open_orders.__doc__ async def futures_cancel_orders(self, **params): if params.get("orderidlist"): params["orderidlist"] = quote( convert_list_to_json_array(params["orderidlist"]) ) if params.get("origclientorderidlist"): params["origclientorderidlist"] = quote( convert_list_to_json_array(params["origclientorderidlist"]) ) return await self._request_futures_api( "delete", "batchOrders", True, data=params, force_params=True ) futures_cancel_orders.__doc__ = Client.futures_cancel_orders.__doc__ async def futures_countdown_cancel_all(self, **params): return await self._request_futures_api( "post", "countdownCancelAll", True, data=params ) # Algo Orders (Conditional Orders) futures_countdown_cancel_all.__doc__ = Client.futures_countdown_cancel_all.__doc__ async def futures_create_algo_order(self, **params): if "clientAlgoId" not in params: params["clientAlgoId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() if "algoType" not in params: params["algoType"] = "CONDITIONAL" return await self._request_futures_api("post", "algoOrder", True, data=params) futures_create_algo_order.__doc__ = Client.futures_create_algo_order.__doc__ async def futures_cancel_algo_order(self, **params): return await self._request_futures_api("delete", "algoOrder", True, data=params) futures_cancel_algo_order.__doc__ = Client.futures_cancel_algo_order.__doc__ async def futures_cancel_all_algo_open_orders(self, **params): return await self._request_futures_api( "delete", "algoOpenOrders", True, data=params ) futures_cancel_all_algo_open_orders.__doc__ = Client.futures_cancel_all_algo_open_orders.__doc__ async def futures_get_algo_order(self, **params): return await self._request_futures_api("get", "algoOrder", True, data=params) futures_get_algo_order.__doc__ = Client.futures_get_algo_order.__doc__ async def futures_get_open_algo_orders(self, **params): return await self._request_futures_api("get", "openAlgoOrders", True, data=params) futures_get_open_algo_orders.__doc__ = Client.futures_get_open_algo_orders.__doc__ async def futures_get_all_algo_orders(self, **params): return await self._request_futures_api("get", "allAlgoOrders", True, data=params) futures_get_all_algo_orders.__doc__ = Client.futures_get_all_algo_orders.__doc__ async def futures_account_balance(self, **params): return await self._request_futures_api( "get", "balance", True, version=3, data=params ) futures_account_balance.__doc__ = Client.futures_account_balance.__doc__ async def futures_account(self, **params): return await self._request_futures_api( "get", "account", True, version=2, data=params ) futures_account.__doc__ = Client.futures_account.__doc__ async def futures_symbol_adl_risk(self, **params): return await self._request_futures_api("get", "symbolAdlRisk", True, data=params) futures_symbol_adl_risk.__doc__ = Client.futures_symbol_adl_risk.__doc__ async def futures_change_leverage(self, **params): return await self._request_futures_api("post", "leverage", True, data=params) futures_change_leverage.__doc__ = Client.futures_change_leverage.__doc__ async def futures_change_margin_type(self, **params): return await self._request_futures_api("post", "marginType", True, data=params) futures_change_margin_type.__doc__ = Client.futures_change_margin_type.__doc__ async def futures_change_position_margin(self, **params): return await self._request_futures_api( "post", "positionMargin", True, data=params ) futures_change_position_margin.__doc__ = Client.futures_change_position_margin.__doc__ async def futures_position_margin_history(self, **params): return await self._request_futures_api( "get", "positionMargin/history", True, data=params ) futures_position_margin_history.__doc__ = Client.futures_position_margin_history.__doc__ async def futures_position_information(self, **params): return await self._request_futures_api( "get", "positionRisk", True, version=3, data=params ) futures_position_information.__doc__ = Client.futures_position_information.__doc__ async def futures_account_trades(self, **params): return await self._request_futures_api("get", "userTrades", True, data=params) futures_account_trades.__doc__ = Client.futures_account_trades.__doc__ async def futures_income_history(self, **params): return await self._request_futures_api("get", "income", True, data=params) futures_income_history.__doc__ = Client.futures_income_history.__doc__ async def futures_change_position_mode(self, **params): return await self._request_futures_api( "post", "positionSide/dual", True, data=params ) futures_change_position_mode.__doc__ = Client.futures_change_position_mode.__doc__ async def futures_get_position_mode(self, **params): return await self._request_futures_api( "get", "positionSide/dual", True, data=params ) futures_get_position_mode.__doc__ = Client.futures_get_position_mode.__doc__ async def futures_change_multi_assets_mode(self, multiAssetsMargin: bool): params = {"multiAssetsMargin": "true" if multiAssetsMargin else "false"} return await self._request_futures_api( "post", "multiAssetsMargin", True, data=params ) futures_change_multi_assets_mode.__doc__ = Client.futures_change_multi_assets_mode.__doc__ async def futures_get_multi_assets_mode(self): return await self._request_futures_api( "get", "multiAssetsMargin", True, data={} ) futures_get_multi_assets_mode.__doc__ = Client.futures_get_multi_assets_mode.__doc__ async def futures_stream_get_listen_key(self): res = await self._request_futures_api( "post", "listenKey", signed=False, data={} ) return res["listenKey"] futures_stream_get_listen_key.__doc__ = Client.futures_stream_get_listen_key.__doc__ async def futures_stream_keepalive(self, listenKey): params = {"listenKey": listenKey} return await self._request_futures_api( "put", "listenKey", signed=False, data=params ) futures_stream_keepalive.__doc__ = Client.futures_stream_keepalive.__doc__ async def futures_stream_close(self, listenKey): params = {"listenKey": listenKey} return await self._request_futures_api( "delete", "listenKey", signed=False, data=params ) # new methods futures_stream_close.__doc__ = Client.futures_stream_close.__doc__ async def futures_account_config(self, **params): return await self._request_futures_api( "get", "accountConfig", signed=True, version=1, data=params ) futures_account_config.__doc__ = Client.futures_account_config.__doc__ async def futures_symbol_config(self, **params): return await self._request_futures_api( "get", "symbolConfig", signed=True, version=1, data=params ) # COIN Futures API futures_symbol_config.__doc__ = Client.futures_symbol_config.__doc__ async def futures_coin_ping(self): return await self._request_futures_coin_api("get", "ping") futures_coin_ping.__doc__ = Client.futures_coin_ping.__doc__ async def futures_coin_time(self): return await self._request_futures_coin_api("get", "time") futures_coin_time.__doc__ = Client.futures_coin_time.__doc__ async def futures_coin_exchange_info(self): return await self._request_futures_coin_api("get", "exchangeInfo") futures_coin_exchange_info.__doc__ = Client.futures_coin_exchange_info.__doc__ async def futures_coin_order_book(self, **params): return await self._request_futures_coin_api("get", "depth", data=params) futures_coin_order_book.__doc__ = Client.futures_coin_order_book.__doc__ async def futures_coin_recent_trades(self, **params): return await self._request_futures_coin_api("get", "trades", data=params) futures_coin_recent_trades.__doc__ = Client.futures_coin_recent_trades.__doc__ async def futures_coin_historical_trades(self, **params): return await self._request_futures_coin_api( "get", "historicalTrades", data=params ) futures_coin_historical_trades.__doc__ = Client.futures_coin_historical_trades.__doc__ async def futures_coin_aggregate_trades(self, **params): return await self._request_futures_coin_api("get", "aggTrades", data=params) futures_coin_aggregate_trades.__doc__ = Client.futures_coin_aggregate_trades.__doc__ async def futures_coin_klines(self, **params): return await self._request_futures_coin_api("get", "klines", data=params) futures_coin_klines.__doc__ = Client.futures_coin_klines.__doc__ async def futures_coin_continous_klines(self, **params): return await self._request_futures_coin_api( "get", "continuousKlines", data=params ) futures_coin_continous_klines.__doc__ = Client.futures_coin_continous_klines.__doc__ async def futures_coin_index_price_klines(self, **params): return await self._request_futures_coin_api( "get", "indexPriceKlines", data=params ) futures_coin_index_price_klines.__doc__ = Client.futures_coin_index_price_klines.__doc__ async def futures_coin_mark_price_klines(self, **params): return await self._request_futures_coin_api( "get", "markPriceKlines", data=params ) futures_coin_mark_price_klines.__doc__ = Client.futures_mark_price_klines.__doc__ async def futures_coin_premium_index_klines(self, **params): return await self._request_futures_coin_api( "get", "premiumIndexKlines", data=params ) futures_coin_premium_index_klines.__doc__ = ( Client.futures_premium_index_klines.__doc__ ) async def futures_coin_mark_price(self, **params): return await self._request_futures_coin_api("get", "premiumIndex", data=params) futures_coin_mark_price.__doc__ = Client.futures_coin_mark_price.__doc__ async def futures_coin_funding_rate(self, **params): return await self._request_futures_coin_api("get", "fundingRate", data=params) futures_coin_funding_rate.__doc__ = Client.futures_coin_funding_rate.__doc__ async def futures_coin_ticker(self, **params): return await self._request_futures_coin_api("get", "ticker/24hr", data=params) futures_coin_ticker.__doc__ = Client.futures_coin_ticker.__doc__ async def futures_coin_symbol_ticker(self, **params): return await self._request_futures_coin_api("get", "ticker/price", data=params) futures_coin_symbol_ticker.__doc__ = Client.futures_coin_symbol_ticker.__doc__ async def futures_coin_orderbook_ticker(self, **params): return await self._request_futures_coin_api( "get", "ticker/bookTicker", data=params ) futures_coin_orderbook_ticker.__doc__ = Client.futures_coin_orderbook_ticker.__doc__ async def futures_coin_index_price_constituents(self, **params): return await self._request_futures_coin_api("get", "constituents", data=params) futures_coin_index_price_constituents.__doc__ = ( Client.futures_coin_index_price_constituents.__doc__ ) async def futures_coin_liquidation_orders(self, **params): return await self._request_futures_coin_api( "get", "forceOrders", signed=True, data=params ) futures_coin_liquidation_orders.__doc__ = Client.futures_coin_liquidation_orders.__doc__ async def futures_coin_open_interest(self, **params): return await self._request_futures_coin_api("get", "openInterest", data=params) futures_coin_open_interest.__doc__ = Client.futures_coin_open_interest.__doc__ async def futures_coin_open_interest_hist(self, **params): return await self._request_futures_coin_data_api( "get", "openInterestHist", data=params ) futures_coin_open_interest_hist.__doc__ = Client.futures_coin_open_interest_hist.__doc__ async def futures_coin_leverage_bracket(self, **params): return await self._request_futures_coin_api( "get", "leverageBracket", version=2, signed=True, data=params ) futures_coin_leverage_bracket.__doc__ = Client.futures_coin_leverage_bracket.__doc__ async def new_transfer_history(self, **params): return await self._request_margin_api( "get", "asset/transfer", True, data=params ) new_transfer_history.__doc__ = Client.new_transfer_history.__doc__ async def funding_wallet(self, **params): return await self._request_margin_api( "post", "asset/get-funding-asset", True, data=params ) funding_wallet.__doc__ = Client.funding_wallet.__doc__ async def get_user_asset(self, **params): return await self._request_margin_api( "post", "asset/getUserAsset", True, data=params, version=3 ) get_user_asset.__doc__ = Client.get_user_asset.__doc__ async def universal_transfer(self, **params): return await self._request_margin_api( "post", "asset/transfer", signed=True, data=params ) universal_transfer.__doc__ = Client.universal_transfer.__doc__ async def futures_coin_create_order(self, **params): if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return await self._request_futures_coin_api("post", "order", True, data=params) futures_coin_create_order.__doc__ = Client.futures_coin_create_order.__doc__ async def futures_coin_place_batch_order(self, **params): for order in params["batchOrders"]: if "newClientOrderId" not in order: order["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() query_string = urlencode(params) query_string = query_string.replace("%27", "%22") params["batchOrders"] = query_string[12:] return await self._request_futures_coin_api( "post", "batchOrders", True, data=params ) futures_coin_place_batch_order.__doc__ = Client.futures_coin_place_batch_order.__doc__ async def futures_coin_get_order(self, **params): return await self._request_futures_coin_api("get", "order", True, data=params) futures_coin_get_order.__doc__ = Client.futures_coin_get_order.__doc__ async def futures_coin_get_open_orders(self, **params): return await self._request_futures_coin_api( "get", "openOrders", True, data=params ) futures_coin_get_open_orders.__doc__ = Client.futures_coin_get_open_orders.__doc__ async def futures_coin_get_all_orders(self, **params): return await self._request_futures_coin_api( "get", "allOrders", signed=True, data=params ) futures_coin_get_all_orders.__doc__ = Client.futures_coin_get_all_orders.__doc__ async def futures_coin_cancel_order(self, **params): return await self._request_futures_coin_api( "delete", "order", signed=True, data=params ) futures_coin_cancel_order.__doc__ = Client.futures_coin_cancel_order.__doc__ async def futures_coin_cancel_all_open_orders(self, **params): return await self._request_futures_coin_api( "delete", "allOpenOrders", signed=True, data=params, force_params=True ) futures_coin_cancel_all_open_orders.__doc__ = Client.futures_coin_cancel_all_open_orders.__doc__ async def futures_coin_cancel_orders(self, **params): if params.get("orderidlist"): params["orderidlist"] = quote( convert_list_to_json_array(params["orderidlist"]) ) if params.get("origclientorderidlist"): params["origclientorderidlist"] = quote( convert_list_to_json_array(params["origclientorderidlist"]) ) return await self._request_futures_coin_api( "delete", "batchOrders", True, data=params ) futures_coin_cancel_orders.__doc__ = Client.futures_coin_cancel_orders.__doc__ async def futures_coin_account_balance(self, **params): return await self._request_futures_coin_api( "get", "balance", signed=True, data=params ) futures_coin_account_balance.__doc__ = Client.futures_coin_account_balance.__doc__ async def futures_coin_account(self, **params): return await self._request_futures_coin_api( "get", "account", signed=True, data=params ) futures_coin_account.__doc__ = Client.futures_coin_account.__doc__ async def futures_coin_change_leverage(self, **params): return await self._request_futures_coin_api( "post", "leverage", signed=True, data=params ) futures_coin_change_leverage.__doc__ = Client.futures_coin_change_leverage.__doc__ async def futures_coin_change_margin_type(self, **params): return await self._request_futures_coin_api( "post", "marginType", signed=True, data=params ) futures_coin_change_margin_type.__doc__ = Client.futures_coin_change_margin_type.__doc__ async def futures_coin_change_position_margin(self, **params): return await self._request_futures_coin_api( "post", "positionMargin", True, data=params ) futures_coin_change_position_margin.__doc__ = Client.futures_coin_change_position_margin.__doc__ async def futures_coin_position_margin_history(self, **params): return await self._request_futures_coin_api( "get", "positionMargin/history", True, data=params ) futures_coin_position_margin_history.__doc__ = Client.futures_coin_position_margin_history.__doc__ async def futures_coin_position_information(self, **params): return await self._request_futures_coin_api( "get", "positionRisk", True, data=params ) futures_coin_position_information.__doc__ = Client.futures_coin_position_information.__doc__ async def futures_coin_account_trades(self, **params): return await self._request_futures_coin_api( "get", "userTrades", True, data=params ) futures_coin_account_trades.__doc__ = Client.futures_coin_account_trades.__doc__ async def futures_coin_income_history(self, **params): return await self._request_futures_coin_api("get", "income", True, data=params) futures_coin_income_history.__doc__ = Client.futures_coin_income_history.__doc__ async def futures_coin_change_position_mode(self, **params): return await self._request_futures_coin_api( "post", "positionSide/dual", True, data=params ) futures_coin_change_position_mode.__doc__ = Client.futures_coin_change_position_mode.__doc__ async def futures_coin_get_position_mode(self, **params): return await self._request_futures_coin_api( "get", "positionSide/dual", True, data=params ) futures_coin_get_position_mode.__doc__ = Client.futures_coin_get_position_mode.__doc__ async def futures_coin_stream_get_listen_key(self): res = await self._request_futures_coin_api( "post", "listenKey", signed=False, data={} ) return res["listenKey"] futures_coin_stream_get_listen_key.__doc__ = Client.futures_coin_stream_get_listen_key.__doc__ async def futures_coin_stream_keepalive(self, listenKey): params = {"listenKey": listenKey} return await self._request_futures_coin_api( "put", "listenKey", signed=False, data=params ) futures_coin_stream_keepalive.__doc__ = Client.futures_coin_stream_keepalive.__doc__ async def futures_coin_account_order_history_download(self, **params): return await self._request_futures_coin_api( "get", "order/asyn", True, data=params ) futures_coin_account_order_history_download.__doc__ = ( Client.futures_coin_account_order_history_download.__doc__ ) async def futures_coin_account_order_history_download_link(self, **params): return await self._request_futures_coin_api( "get", "order/asyn/id", True, data=params ) futures_coin_account_order_history_download_link.__doc__ = ( Client.futures_coin_accout_order_history_download_link.__doc__ ) async def futures_coin_account_trade_history_download(self, **params): return await self._request_futures_coin_api( "get", "trade/asyn", True, data=params ) futures_coin_account_trade_history_download.__doc__ = ( Client.futures_coin_account_trade_history_download.__doc__ ) async def futures_coin_account_trade_history_download_link(self, **params): return await self._request_futures_coin_api( "get", "trade/asyn/id", True, data=params ) futures_coin_account_trade_history_download_link.__doc__ = ( Client.futures_coin_account_trade_history_download_link.__doc__ ) async def futures_coin_stream_close(self, listenKey): params = {"listenKey": listenKey} return await self._request_futures_coin_api( "delete", "listenKey", signed=False, data=params ) futures_coin_stream_close.__doc__ = Client.futures_coin_stream_close.__doc__ async def get_all_coins_info(self, **params): return await self._request_margin_api( "get", "capital/config/getall", True, data=params ) get_all_coins_info.__doc__ = Client.get_all_coins_info.__doc__ async def get_account_snapshot(self, **params): return await self._request_margin_api( "get", "accountSnapshot", True, data=params ) get_account_snapshot.__doc__ = Client.get_account_snapshot.__doc__ async def disable_fast_withdraw_switch(self, **params): return await self._request_margin_api( "post", "disableFastWithdrawSwitch", True, data=params ) disable_fast_withdraw_switch.__doc__ = Client.disable_fast_withdraw_switch.__doc__ async def enable_fast_withdraw_switch(self, **params): return await self._request_margin_api( "post", "enableFastWithdrawSwitch", True, data=params ) """ ==================================================================================================================== Options API ==================================================================================================================== """ # Quoting interface endpoints enable_fast_withdraw_switch.__doc__ = Client.enable_fast_withdraw_switch.__doc__ async def options_ping(self): return await self._request_options_api("get", "ping") options_ping.__doc__ = Client.options_ping.__doc__ async def options_time(self): return await self._request_options_api("get", "time") options_time.__doc__ = Client.options_time.__doc__ async def options_info(self): return await self._request_options_api("get", "optionInfo") options_info.__doc__ = Client.options_info.__doc__ async def options_exchange_info(self): return await self._request_options_api("get", "exchangeInfo") options_exchange_info.__doc__ = Client.options_exchange_info.__doc__ async def options_index_price(self, **params): return await self._request_options_api("get", "index", data=params) options_index_price.__doc__ = Client.options_index_price.__doc__ async def options_price(self, **params): return await self._request_options_api("get", "ticker", data=params) options_price.__doc__ = Client.options_price.__doc__ async def options_mark_price(self, **params): return await self._request_options_api("get", "mark", data=params) options_mark_price.__doc__ = Client.options_mark_price.__doc__ async def options_order_book(self, **params): return await self._request_options_api("get", "depth", data=params) options_order_book.__doc__ = Client.options_order_book.__doc__ async def options_klines(self, **params): return await self._request_options_api("get", "klines", data=params) options_klines.__doc__ = Client.options_klines.__doc__ async def options_recent_trades(self, **params): return await self._request_options_api("get", "trades", data=params) options_recent_trades.__doc__ = Client.options_recent_trades.__doc__ async def options_historical_trades(self, **params): return await self._request_options_api("get", "historicalTrades", data=params) # Account and trading interface endpoints options_historical_trades.__doc__ = Client.options_historical_trades.__doc__ async def options_account_info(self, **params): return await self._request_options_api( "get", "account", signed=True, data=params ) options_account_info.__doc__ = Client.options_account_info.__doc__ async def options_funds_transfer(self, **params): return await self._request_options_api( "post", "transfer", signed=True, data=params ) options_funds_transfer.__doc__ = Client.options_funds_transfer.__doc__ async def options_positions(self, **params): return await self._request_options_api( "get", "position", signed=True, data=params ) options_positions.__doc__ = Client.options_positions.__doc__ async def options_bill(self, **params): return await self._request_options_api("post", "bill", signed=True, data=params) options_bill.__doc__ = Client.options_bill.__doc__ async def options_place_order(self, **params): if "clientOrderId" not in params: params["clientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return await self._request_options_api( "post", "order", signed=True, data=params ) options_place_order.__doc__ = Client.options_place_order.__doc__ async def options_place_batch_order(self, **params): for order in params["batchOrders"]: if "newClientOrderId" not in order: order["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return await self._request_options_api( "post", "batchOrders", signed=True, data=params ) options_place_batch_order.__doc__ = Client.options_place_batch_order.__doc__ async def options_cancel_order(self, **params): return await self._request_options_api( "delete", "order", signed=True, data=params ) options_cancel_order.__doc__ = Client.options_cancel_order.__doc__ async def options_cancel_batch_order(self, **params): return await self._request_options_api( "delete", "batchOrders", signed=True, data=params ) options_cancel_batch_order.__doc__ = Client.options_cancel_batch_order.__doc__ async def options_cancel_all_orders(self, **params): return await self._request_options_api( "delete", "allOpenOrders", signed=True, data=params ) options_cancel_all_orders.__doc__ = Client.options_cancel_all_orders.__doc__ async def options_query_order(self, **params): return await self._request_options_api("get", "order", signed=True, data=params) options_query_order.__doc__ = Client.options_query_order.__doc__ async def options_query_pending_orders(self, **params): return await self._request_options_api( "get", "openOrders", signed=True, data=params ) options_query_pending_orders.__doc__ = Client.options_query_pending_orders.__doc__ async def options_query_order_history(self, **params): return await self._request_options_api( "get", "historyOrders", signed=True, data=params ) options_query_order_history.__doc__ = Client.options_query_order_history.__doc__ async def options_user_trades(self, **params): return await self._request_options_api( "get", "userTrades", signed=True, data=params ) # Fiat Endpoints options_user_trades.__doc__ = Client.options_user_trades.__doc__ async def get_fiat_deposit_withdraw_history(self, **params): return await self._request_margin_api( "get", "fiat/orders", signed=True, data=params ) get_fiat_deposit_withdraw_history.__doc__ = Client.get_fiat_deposit_withdraw_history.__doc__ async def get_fiat_payments_history(self, **params): return await self._request_margin_api( "get", "fiat/payments", signed=True, data=params ) # C2C Endpoints get_fiat_payments_history.__doc__ = Client.get_fiat_payments_history.__doc__ async def get_c2c_trade_history(self, **params): return await self._request_margin_api( "get", "c2c/orderMatch/listUserOrderHistory", signed=True, data=params ) # Pay Endpoints get_c2c_trade_history.__doc__ = Client.get_c2c_trade_history.__doc__ async def get_pay_trade_history(self, **params): return await self._request_margin_api( "get", "pay/transactions", signed=True, data=params ) get_pay_trade_history.__doc__ = Client.get_pay_trade_history.__doc__ # Convert Endpoints async def get_convert_trade_history(self, **params): return await self._request_margin_api( "get", "convert/tradeFlow", signed=True, data=params ) get_convert_trade_history.__doc__ = Client.get_convert_trade_history.__doc__ async def convert_request_quote(self, **params): return await self._request_margin_api( "post", "convert/getQuote", signed=True, data=params ) convert_request_quote.__doc__ = Client.convert_request_quote.__doc__ async def convert_accept_quote(self, **params): return await self._request_margin_api( "post", "convert/acceptQuote", signed=True, data=params ) convert_accept_quote.__doc__ = Client.convert_accept_quote.__doc__ """ ==================================================================================================================== PortfolioMargin API ==================================================================================================================== """ async def papi_stream_get_listen_key(self): res = await self._request_papi_api("post", "listenKey", signed=False, data={}) return res["listenKey"] papi_stream_get_listen_key.__doc__ = Client.papi_stream_get_listen_key.__doc__ async def papi_stream_keepalive(self, listenKey): params = {"listenKey": listenKey} return await self._request_papi_api( "put", "listenKey", signed=False, data=params ) papi_stream_keepalive.__doc__ = Client.papi_stream_keepalive.__doc__ async def papi_stream_close(self, listenKey): params = {"listenKey": listenKey} return await self._request_papi_api( "delete", "listenKey", signed=False, data=params ) papi_stream_close.__doc__ = Client.papi_stream_close.__doc__ async def papi_get_balance(self, **params): return await self._request_papi_api("get", "balance", signed=True, data=params) papi_get_balance.__doc__ = Client.papi_get_balance.__doc__ async def papi_get_rate_limit(self, **params): return await self._request_papi_api("get", "rateLimit/order", signed=True, data=params) papi_get_rate_limit.__doc__ = Client.papi_get_rate_limit.__doc__ async def papi_get_account(self, **params): return await self._request_papi_api("get", "account", signed=True, data=params) papi_get_account.__doc__ = Client.papi_get_account.__doc__ async def papi_get_margin_max_borrowable(self, **params): return await self._request_papi_api( "get", "margin/maxBorrowable", signed=True, data=params ) papi_get_margin_max_borrowable.__doc__ = Client.papi_get_margin_max_borrowable.__doc__ async def papi_get_margin_max_withdraw(self, **params): return await self._request_papi_api( "get", "margin/maxWithdraw", signed=True, data=params ) papi_get_margin_max_withdraw.__doc__ = Client.papi_get_margin_max_withdraw.__doc__ async def papi_get_um_position_risk(self, **params): return await self._request_papi_api( "get", "um/positionRisk", signed=True, data=params ) papi_get_um_position_risk.__doc__ = Client.papi_get_um_position_risk.__doc__ async def papi_get_cm_position_risk(self, **params): return await self._request_papi_api( "get", "cm/positionRisk", signed=True, data=params ) papi_get_cm_position_risk.__doc__ = Client.papi_get_cm_position_risk.__doc__ async def papi_set_um_leverage(self, **params): return await self._request_papi_api( "post", "um/leverage", signed=True, data=params ) papi_set_um_leverage.__doc__ = Client.papi_set_um_leverage.__doc__ async def papi_set_cm_leverage(self, **params): return await self._request_papi_api( "post", "cm/leverage", signed=True, data=params ) papi_set_cm_leverage.__doc__ = Client.papi_set_cm_leverage.__doc__ async def papi_change_um_position_side_dual(self, **params): return await self._request_papi_api( "post", "um/positionSide/dual", signed=True, data=params ) papi_change_um_position_side_dual.__doc__ = Client.papi_change_um_position_side_dual.__doc__ async def papi_get_um_position_side_dual(self, **params): return await self._request_papi_api( "get", "um/positionSide/dual", signed=True, data=params ) papi_get_um_position_side_dual.__doc__ = Client.papi_get_um_position_side_dual.__doc__ async def papi_get_cm_position_side_dual(self, **params): return await self._request_papi_api( "get", "cm/positionSide/dual", signed=True, data=params ) papi_get_cm_position_side_dual.__doc__ = Client.papi_get_cm_position_side_dual.__doc__ async def papi_get_um_leverage_bracket(self, **params): return await self._request_papi_api( "get", "um/leverageBracket", signed=True, data=params ) papi_get_um_leverage_bracket.__doc__ = Client.papi_get_um_leverage_bracket.__doc__ async def papi_get_cm_leverage_bracket(self, **params): return await self._request_papi_api( "get", "cm/leverageBracket", signed=True, data=params ) papi_get_cm_leverage_bracket.__doc__ = Client.papi_get_cm_leverage_bracket.__doc__ async def papi_get_um_api_trading_status(self, **params): return await self._request_papi_api( "get", "um/apiTradingStatus", signed=True, data=params ) papi_get_um_api_trading_status.__doc__ = Client.papi_get_um_api_trading_status.__doc__ async def papi_get_um_comission_rate(self, **params): return await self._request_papi_api( "get", "um/commissionRate", signed=True, data=params ) papi_get_um_comission_rate.__doc__ = Client.papi_get_um_comission_rate.__doc__ async def papi_get_cm_comission_rate(self, **params): return await self._request_papi_api( "get", "cm/commissionRate", signed=True, data=params ) papi_get_cm_comission_rate.__doc__ = Client.papi_get_cm_comission_rate.__doc__ async def papi_get_margin_margin_loan(self, **params): return await self._request_papi_api( "get", "margin/marginLoan", signed=True, data=params ) papi_get_margin_margin_loan.__doc__ = Client.papi_get_margin_margin_loan.__doc__ async def papi_get_margin_repay_loan(self, **params): return await self._request_papi_api( "get", "margin/repayLoan", signed=True, data=params ) papi_get_margin_repay_loan.__doc__ = Client.papi_get_margin_repay_loan.__doc__ async def papi_get_repay_futures_switch(self, **params): return await self._request_papi_api( "get", "repay-futures-switch", signed=True, data=params ) papi_get_repay_futures_switch.__doc__ = Client.papi_get_repay_futures_switch.__doc__ async def papi_repay_futures_switch(self, **params): return await self._request_papi_api( "post", "repay-futures-switch", signed=True, data=params ) papi_repay_futures_switch.__doc__ = Client.papi_repay_futures_switch.__doc__ async def papi_get_margin_interest_history(self, **params): return await self._request_papi_api( "get", "margin/marginInterestHistory", signed=True, data=params ) papi_get_margin_interest_history.__doc__ = Client.papi_get_margin_interest_history.__doc__ async def papi_repay_futures_negative_balance(self, **params): return await self._request_papi_api( "post", "repay-futures-negative-balance", signed=True, data=params ) papi_repay_futures_negative_balance.__doc__ = Client.papi_repay_futures_negative_balance.__doc__ async def papi_get_portfolio_interest_history(self, **params): return await self._request_papi_api( "get", "portfolio/interest-history", signed=True, data=params ) papi_get_portfolio_interest_history.__doc__ = Client.papi_get_portfolio_interest_history.__doc__ async def papi_get_portfolio_negative_balance_exchange_record(self, **params): return await self._request_papi_api( "get", "portfolio/negative-balance-exchange-record", signed=True, data=params ) papi_get_portfolio_negative_balance_exchange_record.__doc__ = Client.papi_get_portfolio_negative_balance_exchange_record.__doc__ async def papi_fund_auto_collection(self, **params): return await self._request_papi_api( "post", "auto-collection", signed=True, data=params ) papi_fund_auto_collection.__doc__ = Client.papi_fund_auto_collection.__doc__ async def papi_fund_asset_collection(self, **params): return await self._request_papi_api( "post", "asset-collection", signed=True, data=params ) papi_fund_asset_collection.__doc__ = Client.papi_fund_asset_collection.__doc__ async def papi_bnb_transfer(self, **params): return await self._request_papi_api( "post", "bnb-transfer", signed=True, data=params ) papi_bnb_transfer.__doc__ = Client.papi_bnb_transfer.__doc__ async def papi_get_um_income_history(self, **params): return await self._request_papi_api( "get", "um/income", signed=True, data=params ) papi_get_um_income_history.__doc__ = Client.papi_get_um_income_history.__doc__ async def papi_get_cm_income_history(self, **params): return await self._request_papi_api( "get", "cm/income", signed=True, data=params ) papi_get_cm_income_history.__doc__ = Client.papi_get_cm_income_history.__doc__ async def papi_get_um_account(self, **params): return await self._request_papi_api( "get", "um/account", signed=True, data=params ) papi_get_um_account.__doc__ = Client.papi_get_um_account.__doc__ async def papi_get_um_account_v2(self, **params): return await self._request_papi_api( "get", "um/account", version=2, signed=True, data=params ) papi_get_um_account_v2.__doc__ = Client.papi_get_um_account_v2.__doc__ async def papi_get_cm_account(self, **params): return await self._request_papi_api( "get", "cm/account", signed=True, data=params ) papi_get_cm_account.__doc__ = Client.papi_get_cm_account.__doc__ async def papi_get_um_account_config(self, **params): return await self._request_papi_api( "get", "um/accountConfig", signed=True, data=params ) papi_get_um_account_config.__doc__ = Client.papi_get_um_account_config.__doc__ async def papi_get_um_symbol_config(self, **params): return await self._request_papi_api( "get", "um/symbolConfig", signed=True, data=params ) papi_get_um_symbol_config.__doc__ = Client.papi_get_um_symbol_config.__doc__ async def papi_get_um_trade_asyn(self, **params): return await self._request_papi_api( "get", "um/trade/asyn", signed=True, data=params ) papi_get_um_trade_asyn.__doc__ = Client.papi_get_um_trade_asyn.__doc__ async def papi_get_um_trade_asyn_id(self, **params): return await self._request_papi_api( "get", "um/trade/asyn/id", signed=True, data=params ) papi_get_um_trade_asyn_id.__doc__ = Client.papi_get_um_trade_asyn_id.__doc__ async def papi_get_um_order_asyn(self, **params): return await self._request_papi_api( "get", "um/order/asyn", signed=True, data=params ) papi_get_um_order_asyn.__doc__ = Client.papi_get_um_order_asyn.__doc__ async def papi_get_um_order_asyn_id(self, **params): return await self._request_papi_api( "get", "um/order/asyn/id", signed=True, data=params ) papi_get_um_order_asyn_id.__doc__ = Client.papi_get_um_order_asyn_id.__doc__ async def papi_get_um_income_asyn(self, **params): return await self._request_papi_api( "get", "um/income/asyn", signed=True, data=params ) papi_get_um_income_asyn.__doc__ = Client.papi_get_um_income_asyn.__doc__ async def papi_get_um_income_asyn_id(self, **params): return await self._request_papi_api( "get", "um/income/asyn/id", signed=True, data=params ) papi_get_um_income_asyn_id.__doc__ = Client.papi_get_um_income_asyn_id.__doc__ async def papi_ping(self, **params): return await self._request_papi_api("get", "ping", signed=False, data=params) # papi trading endpoints papi_ping.__doc__ = Client.papi_ping.__doc__ async def papi_create_um_order(self, **params): """Place new UM order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade :returns: API response """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return await self._request_papi_api( "post", "um/order", signed=True, data=params ) async def papi_create_um_conditional_order(self, **params): """Place new UM Conditional order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/New-UM-Conditional-Order :returns: API response """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return await self._request_papi_api( "post", "um/conditional/order", signed=True, data=params ) async def papi_create_cm_order(self, **params): """Place new CM order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/New-CM-Order :returns: API response """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return await self._request_papi_api( "post", "cm/order", signed=True, data=params ) async def papi_create_cm_conditional_order(self, **params): """Place new CM Conditional order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/New-CM-Conditional-Order :returns: API response """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return await self._request_papi_api( "post", "cm/conditional/order", signed=True, data=params ) async def papi_create_margin_order(self, **params): """New Margin Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/New-Margin-Order :returns: API response """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return await self._request_papi_api( "post", "margin/order", signed=True, data=params ) async def papi_margin_loan(self, **params): """Apply for a margin loan. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Margin-Account-Borrow :returns: API response """ return await self._request_papi_api( "post", "marginLoan", signed=True, data=params ) async def papi_repay_loan(self, **params): """Repay for a margin loan. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Margin-Account-Repay :returns: API response """ return await self._request_papi_api( "post", "repayLoan", signed=True, data=params ) async def papi_margin_order_oco(self, **params): """Send in a new OCO for a margin account. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Margin-Account-New-OCO :returns: API response """ return await self._request_papi_api( "post", "margin/order/oco", signed=True, data=params ) async def papi_cancel_um_order(self, **params): """Cancel an active UM LIMIT order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-UM-Order :returns: API response """ return await self._request_papi_api( "delete", "um/order", signed=True, data=params ) async def papi_cancel_um_all_open_orders(self, **params): """Cancel an active UM LIMIT order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-All-UM-Open-Orders :returns: API response """ return await self._request_papi_api( "delete", "um/allOpenOrders", signed=True, data=params ) async def papi_cancel_um_conditional_order(self, **params): """Cancel UM Conditional Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-UM-Conditional-Order :returns: API response """ return await self._request_papi_api( "delete", "um/conditional/order", signed=True, data=params ) async def papi_cancel_um_conditional_all_open_orders(self, **params): """Cancel All UM Open Conditional Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-All-UM-Open-Conditional-Orders :returns: API response """ return await self._request_papi_api( "delete", "um/conditional/allOpenOrders", signed=True, data=params ) async def papi_cancel_cm_order(self, **params): """Cancel an active CM LIMIT order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-CM-Order :returns: API response """ return await self._request_papi_api( "delete", "cm/order", signed=True, data=params ) async def papi_cancel_cm_all_open_orders(self, **params): """Cancel an active CM LIMIT order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-All-CM-Open-Orders :returns: API response """ return await self._request_papi_api( "delete", "cm/allOpenOrders", signed=True, data=params ) async def papi_cancel_cm_conditional_order(self, **params): """Cancel CM Conditional Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-CM-Conditional-Order :returns: API response """ return await self._request_papi_api( "delete", "cm/conditional/order", signed=True, data=params ) async def papi_cancel_cm_conditional_all_open_orders(self, **params): """Cancel All CM Open Conditional Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-All-CM-Open-Conditional-Orders :returns: API response """ return await self._request_papi_api( "delete", "cm/conditional/allOpenOrders", signed=True, data=params ) async def papi_cancel_margin_order(self, **params): """Cancel Margin Account Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-Margin-Account-Order :returns: API response """ return await self._request_papi_api( "delete", "margin/order", signed=True, data=params ) async def papi_cancel_margin_order_list(self, **params): """Cancel Margin Account OCO Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-Margin-Account-OCO-Orders :returns: API response """ return await self._request_papi_api( "delete", "margin/orderList", signed=True, data=params ) async def papi_cancel_margin_all_open_orders(self, **params): """Cancel Margin Account All Open Orders on a Symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-Margin-Account-All-Open-Orders-on-a-Symbol :returns: API response """ return await self._request_papi_api( "delete", "margin/allOpenOrders", signed=True, data=params ) async def papi_modify_um_order(self, **params): """Order modify function, currently only LIMIT order modification is supported, modified orders will be reordered in the match queue. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Modify-UM-Order :returns: API response """ return await self._request_papi_api("put", "um/order", signed=True, data=params) async def papi_modify_cm_order(self, **params): """Order modify function, currently only LIMIT order modification is supported, modified orders will be reordered in the match queue. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Modify-CM-Order :returns: API response """ return await self._request_papi_api("put", "cm/order", signed=True, data=params) async def papi_get_um_order(self, **params): """Check an UM order's status. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-UM-Order :returns: API response """ return await self._request_papi_api("get", "um/order", signed=True, data=params) async def papi_get_um_all_orders(self, **params): """Get all account UM orders; active, canceled, or filled. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-UM-Order :returns: API response """ return await self._request_papi_api( "get", "um/allOrders", signed=True, data=params ) async def papi_get_um_open_order(self, **params): """Query current UM open order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Current-UM-Open-Order :returns: API response """ return await self._request_papi_api( "get", "um/openOrder", signed=True, data=params ) async def papi_get_um_open_orders(self, **params): """Get all open orders on a symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-Current-UM-Open-Orders :returns: API response """ return await self._request_papi_api( "get", "um/openOrders", signed=True, data=params ) async def papi_get_um_conditional_all_orders(self, **params): """Query All UM Conditional Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-UM-Conditional-Orders :returns: API response """ return await self._request_papi_api( "get", "um/conditional/allOrders", signed=True, data=params ) async def papi_get_um_conditional_open_orders(self, **params): """Get all open conditional orders on a symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-Current-UM-Open-Conditional-Orders :returns: API response """ return await self._request_papi_api( "get", "um/conditional/openOrders", signed=True, data=params ) async def papi_get_um_conditional_open_order(self, **params): """Query Current UM Open Conditional Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Current-UM-Open-Conditional-Order :returns: API response """ return await self._request_papi_api( "get", "um/conditional/openOrder", signed=True, data=params ) async def papi_get_um_conditional_order_history(self, **params): """Get all open conditional orders on a symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-UM-Conditional-Order-History :returns: API response """ return await self._request_papi_api( "get", "um/conditional/orderHistory", signed=True, data=params ) async def papi_get_cm_order(self, **params): """Check an CM order's status. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-CM-Order :returns: API response """ return await self._request_papi_api("get", "cm/order", signed=True, data=params) async def papi_get_cm_all_orders(self, **params): """Get all account CM orders; active, canceled, or filled. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-CM-Order :returns: API response """ return await self._request_papi_api( "get", "cm/allOrders", signed=True, data=params ) async def papi_get_cm_open_order(self, **params): """Query current CM open order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Current-CM-Open-Order :returns: API response """ return await self._request_papi_api( "get", "cm/openOrder", signed=True, data=params ) async def papi_get_cm_open_orders(self, **params): """Get all open orders on a symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-Current-CM-Open-Orders :returns: API response """ return await self._request_papi_api( "get", "cm/openOrders", signed=True, data=params ) async def papi_get_cm_conditional_all_orders(self, **params): """Query All CM Conditional Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-CM-Conditional-Orders :returns: API response """ return await self._request_papi_api( "get", "cm/conditional/allOrders", signed=True, data=params ) async def papi_get_cm_conditional_open_orders(self, **params): """Get all open conditional orders on a symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-Current-CM-Open-Conditional-Orders :returns: API response """ return await self._request_papi_api( "get", "cm/conditional/openOrders", signed=True, data=params ) async def papi_get_cm_conditional_open_order(self, **params): """Query Current UM Open Conditional Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Current-CM-Open-Conditional-Order :returns: API response """ return await self._request_papi_api( "get", "cm/conditional/openOrder", signed=True, data=params ) async def papi_get_cm_conditional_order_history(self, **params): """Get all open conditional orders on a symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-CM-Conditional-Order-History :returns: API response """ return await self._request_papi_api( "get", "cm/conditional/orderHistory", signed=True, data=params ) async def papi_get_um_force_orders(self, **params): """Query User's UM Force Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Users-UM-Force-Orders :returns: API response """ return await self._request_papi_api( "get", "um/forceOrders", signed=True, data=params ) async def papi_get_cm_force_orders(self, **params): """Query User's CM Force Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Users-CM-Force-Orders :returns: API response """ return await self._request_papi_api( "get", "cm/forceOrders", signed=True, data=params ) async def papi_get_um_order_amendment(self, **params): """Get order modification history. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-UM-Modify-Order-History :returns: API response """ return await self._request_papi_api( "get", "um/orderAmendment", signed=True, data=params ) async def papi_get_cm_order_amendment(self, **params): """Get order modification history. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-CM-Modify-Order-History :returns: API response """ return await self._request_papi_api( "get", "cm/orderAmendment", signed=True, data=params ) async def papi_get_margin_force_orders(self, **params): """Query user's margin force orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Users-Margin-Force-Orders :returns: API response """ return await self._request_papi_api( "get", "margin/forceOrders", signed=True, data=params ) async def papi_get_um_user_trades(self, **params): """Get trades for a specific account and UM symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/UM-Account-Trade-List :returns: API response """ return await self._request_papi_api( "get", "um/userTrades", signed=True, data=params ) async def papi_get_cm_user_trades(self, **params): """Get trades for a specific account and CM symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/CM-Account-Trade-List :returns: API response """ return await self._request_papi_api( "get", "cm/userTrades", signed=True, data=params ) async def papi_get_um_adl_quantile(self, **params): """Query UM Position ADL Quantile Estimation. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/UM-Position-ADL-Quantile-Estimation :returns: API response """ return await self._request_papi_api( "get", "um/adlQuantile", signed=True, data=params ) async def papi_get_cm_adl_quantile(self, **params): """Query CM Position ADL Quantile Estimation. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/CM-Position-ADL-Quantile-Estimation :returns: API response """ return await self._request_papi_api( "get", "cm/adlQuantile", signed=True, data=params ) async def papi_set_um_fee_burn(self, **params): """Change user's BNB Fee Discount for UM Futures (Fee Discount On or Fee Discount Off ) on EVERY symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Toggle-BNB-Burn-On-UM-Futures-Trade :returns: API response """ return await self._request_papi_api( "post", "um/feeBurn", signed=True, data=params ) async def papi_get_um_fee_burn(self, **params): """Get user's BNB Fee Discount for UM Futures (Fee Discount On or Fee Discount Off). https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Get-UM-Futures-BNB-Burn-Status :returns: API response """ return await self._request_papi_api( "get", "um/feeBurn", signed=True, data=params ) async def papi_get_margin_order(self, **params): """Query Margin Account Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Margin-Account-Order :returns: API response """ return await self._request_papi_api( "get", "margin/order", signed=True, data=params ) async def papi_get_margin_open_orders(self, **params): """Query Current Margin Open Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Margin-Account-Order :returns: API response """ return await self._request_papi_api( "get", "margin/openOrders", signed=True, data=params ) async def papi_get_margin_all_orders(self, **params): """Query All Margin Account Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-Margin-Account-Orders :returns: API response """ return await self._request_papi_api( "get", "margin/allOrders", signed=True, data=params ) async def papi_get_margin_order_list(self, **params): """Retrieves a specific OCO based on provided optional parameters. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Margin-Account-OCO :returns: API response """ return await self._request_papi_api( "get", "margin/orderList", signed=True, data=params ) async def papi_get_margin_all_order_list(self, **params): """Query all OCO for a specific margin account based on provided optional parameters. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Margin-Account-all-OCO :returns: API response """ return await self._request_papi_api( "get", "margin/allOrderList", signed=True, data=params ) async def papi_get_margin_open_order_list(self, **params): """Query Margin Account's Open OCO. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Margin-Account-Open-OCO :returns: API response """ return await self._request_papi_api( "get", "margin/openOrderList", signed=True, data=params ) async def papi_get_margin_my_trades(self, **params): """Margin Account Trade List. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Margin-Account-Trade-List :returns: API response """ return await self._request_papi_api( "get", "margin/myTrades", signed=True, data=params ) async def papi_get_margin_repay_debt(self, **params): """Repay debt for a margin loan. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Margin-Account-Trade-List :returns: API response """ return await self._request_papi_api( "post", "margin/repay-debt", signed=True, data=params ) async def create_oco_order(self, **params): if "listClientOrderId" not in params: params["listClientOrderId"] = self.SPOT_ORDER_PREFIX + self.uuid22() return await self._post("orderList/oco", True, data=params) ############################################################ # WebSocket API methods ############################################################ create_oco_order.__doc__ = Client.create_oco_order.__doc__ async def ws_create_test_order(self, **params): """Test new order creation and signature/recvWindow long. Creates and validates a new order but does not send it into the matching engine. https://binance-docs.github.io/apidocs/websocket_api/en/#test-new-order-trade :param symbol: required :type symbol: str :param side: required :type side: str :param type: required :type type: str :param timeInForce: required if limit order :type timeInForce: str :param quantity: required :type quantity: decimal :param price: required :type price: str :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param icebergQty: Used with iceberg orders :type icebergQty: decimal :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: The number of milliseconds the request is valid for :type recvWindow: int :returns: WS response .. code-block:: python {} """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.SPOT_ORDER_PREFIX + self.uuid22() return await self._ws_api_request("order.test", True, params) async def ws_create_order(self, **params): """Create an order via WebSocket. https://binance-docs.github.io/apidocs/websocket_api/en/#place-new-order-trade :param id: The request ID to be used. By default uuid22() is used. :param symbol: The symbol to create an order for :param side: BUY or SELL :param type: Order type (e.g., LIMIT, MARKET) :param quantity: The amount to buy or sell :param kwargs: Additional order parameters """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.SPOT_ORDER_PREFIX + self.uuid22() return await self._ws_api_request("order.place", True, params) async def ws_order_limit(self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params): """Send in a new limit order Any order with an icebergQty MUST have timeInForce set to GTC. :param symbol: required :type symbol: str :param side: required :type side: str :param quantity: required :type quantity: decimal :param price: required :type price: str :param timeInForce: default Good till cancelled :type timeInForce: str :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param icebergQty: Used with LIMIT, STOP_LOSS_LIMIT, and TAKE_PROFIT_LIMIT to create an iceberg order. :type icebergQty: decimal :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: WS response See order endpoint for full response options """ params.update({ "type": self.ORDER_TYPE_LIMIT, "timeInForce": timeInForce, }) return await self.ws_create_order(**params) async def ws_order_limit_buy( self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params ): """Send in a new limit buy order Any order with an icebergQty MUST have timeInForce set to GTC. :param symbol: required :type symbol: str :param quantity: required :type quantity: decimal :param price: required :type price: str :param timeInForce: default Good till cancelled :type timeInForce: str :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param stopPrice: Used with stop orders :type stopPrice: decimal :param icebergQty: Used with iceberg orders :type icebergQty: decimal :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: WS response See order endpoint for full response options """ params.update({ "side": self.SIDE_BUY, }) return await self.ws_order_limit(timeInForce=timeInForce, **params) async def ws_order_limit_sell( self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params ): """Send in a new limit sell order :param symbol: required :type symbol: str :param quantity: required :type quantity: decimal :param price: required :type price: str :param timeInForce: default Good till cancelled :type timeInForce: str :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param stopPrice: Used with stop orders :type stopPrice: decimal :param icebergQty: Used with iceberg orders :type icebergQty: decimal :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: WS response See order endpoint for full response options """ params.update({"side": self.SIDE_SELL}) return await self.ws_order_limit(timeInForce=timeInForce, **params) async def ws_order_market(self, **params): """Send in a new market order :param symbol: required :type symbol: str :param side: required :type side: str :param quantity: required :type quantity: decimal :param quoteOrderQty: amount the user wants to spend (when buying) or receive (when selling) of the quote asset :type quoteOrderQty: decimal :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: WS response See order endpoint for full response options """ params.update({"type": self.ORDER_TYPE_MARKET}) return await self.ws_create_order(**params) async def ws_order_market_buy(self, **params): """Send in a new market buy order :param symbol: required :type symbol: str :param quantity: required :type quantity: decimal :param quoteOrderQty: the amount the user wants to spend of the quote asset :type quoteOrderQty: decimal :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: WS response See order endpoint for full response options """ params.update({"side": self.SIDE_BUY}) return await self.ws_order_market(**params) async def ws_order_market_sell(self, **params): """Send in a new market sell order :param symbol: required :type symbol: str :param quantity: required :type quantity: decimal :param quoteOrderQty: the amount the user wants to receive of the quote asset :type quoteOrderQty: decimal :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: WS response See order endpoint for full response options """ params.update({"side": self.SIDE_SELL}) return await self.ws_order_market(**params) async def ws_get_order(self, **params): """Check an order's status. Either orderId or origClientOrderId must be sent. https://binance-docs.github.io/apidocs/websocket_api/en/#query-order-user_data :param symbol: required :type symbol: str :param orderId: The unique order id :type orderId: int :param origClientOrderId: optional :type origClientOrderId: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int """ return await self._ws_api_request("order.status", True, params) async def ws_cancel_order(self, **params): return await self._ws_api_request("order.cancel", True, params) ws_cancel_order.__doc__ = Client.ws_cancel_order.__doc__ async def cancel_all_open_orders(self, **params): return await self._delete("openOrders", True, data=params) cancel_all_open_orders.__doc__ = Client.cancel_all_open_orders.__doc__ async def cancel_replace_order(self, **params): if "newClientOrderId" not in params: params["newClientOrderId"] = self.SPOT_ORDER_PREFIX + self.uuid22() return await self._post("order/cancelReplace", signed=True, data=params) cancel_replace_order.__doc__ = Client.cancel_replace_order.__doc__ async def ws_cancel_and_replace_order(self, **params): return await self._ws_api_request("order.cancelReplace", True, params) ws_cancel_and_replace_order.__doc__ = Client.ws_cancel_and_replace_order.__doc__ async def ws_get_open_orders(self, **params): return await self._ws_api_request("openOrders.status", True, params) ws_get_open_orders.__doc__ = Client.ws_get_open_orders.__doc__ async def ws_cancel_all_open_orders(self, **params): return await self._ws_api_request("openOrders.cancelAll", True, params) ws_cancel_all_open_orders.__doc__ = Client.ws_cancel_all_open_orders.__doc__ async def ws_create_oco_order(self, **params): return await self._ws_api_request("orderList.place.oco", True, params) ws_create_oco_order.__doc__ = Client.ws_create_oco_order.__doc__ async def ws_create_oto_order(self, **params): return await self._ws_api_request("orderList.place.oto", True, params) ws_create_oto_order.__doc__ = Client.ws_create_oto_order.__doc__ async def ws_create_otoco_order(self, **params): return await self._ws_api_request("orderList.place.otoco", True, params) ws_create_otoco_order.__doc__ = Client.ws_create_otoco_order.__doc__ async def ws_get_oco_order(self, **params): return await self._ws_api_request("orderList.status", True, params) ws_get_oco_order.__doc__ = Client.ws_get_oco_order.__doc__ async def ws_cancel_oco_order(self, **params): return await self._ws_api_request("orderList.cancel", True, params) ws_cancel_oco_order.__doc__ = Client.ws_cancel_oco_order.__doc__ async def ws_get_oco_open_orders(self, **params): return await self._ws_api_request("openOrderLists.status", True, params) ws_get_oco_open_orders.__doc__ = Client.ws_get_oco_open_orders.__doc__ async def ws_create_sor_order(self, **params): return await self._ws_api_request("sor.order.place", True, params) ws_create_sor_order.__doc__ = Client.ws_create_sor_order.__doc__ async def ws_create_test_sor_order(self, **params): return await self._ws_api_request("sor.order.test", True, params) ws_create_test_sor_order.__doc__ = Client.ws_create_test_sor_order.__doc__ async def ws_get_account(self, **params): return await self._ws_api_request("account.status", True, params) ws_get_account.__doc__ = Client.ws_get_account.__doc__ async def ws_get_account_rate_limits_orders(self, **params): return await self._ws_api_request("account.rateLimits.orders", True, params) ws_get_account_rate_limits_orders.__doc__ = Client.ws_get_account_rate_limits_orders.__doc__ async def ws_get_all_orders(self, **params): return await self._ws_api_request("allOrders", True, params) ws_get_all_orders.__doc__ = Client.ws_get_all_orders.__doc__ async def ws_get_my_trades(self, **params): return await self._ws_api_request("myTrades", True, params) ws_get_my_trades.__doc__ = Client.ws_get_my_trades.__doc__ async def ws_get_prevented_matches(self, **params): return await self._ws_api_request("myPreventedMatches", True, params) ws_get_prevented_matches.__doc__ = Client.ws_get_prevented_matches.__doc__ async def ws_get_allocations(self, **params): return await self._ws_api_request("myAllocations", True, params) ws_get_allocations.__doc__ = Client.ws_get_allocations.__doc__ async def ws_get_commission_rates(self, **params): return await self._ws_api_request("account.commission", True, params) ws_get_commission_rates.__doc__ = Client.ws_get_commission_rates.__doc__ async def ws_get_order_book(self, **params): return await self._ws_api_request("depth", False, params) ws_get_order_book.__doc__ = Client.ws_get_order_book.__doc__ async def ws_get_recent_trades(self, **params): return await self._ws_api_request("trades.recent", False, params) ws_get_recent_trades.__doc__ = Client.ws_get_recent_trades.__doc__ async def ws_get_historical_trades(self, **params): return await self._ws_api_request("trades.historical", False, params) ws_get_historical_trades.__doc__ = Client.ws_get_historical_trades.__doc__ async def ws_get_aggregate_trades(self, **params): return await self._ws_api_request("trades.aggregate", False, params) ws_get_aggregate_trades.__doc__ = Client.ws_get_aggregate_trades.__doc__ async def ws_get_klines(self, **params): return await self._ws_api_request("klines", False, params) ws_get_klines.__doc__ = Client.ws_get_klines.__doc__ async def ws_get_uiKlines(self, **params): return await self._ws_api_request("uiKlines", False, params) ws_get_uiKlines.__doc__ = Client.ws_get_uiKlines.__doc__ async def ws_get_avg_price(self, **params): return await self._ws_api_request("avgPrice", False, params) ws_get_avg_price.__doc__ = Client.ws_get_avg_price.__doc__ async def ws_get_ticker(self, **params): return await self._ws_api_request("ticker.24hr", False, params) ws_get_ticker.__doc__ = Client.ws_get_ticker.__doc__ async def ws_get_trading_day_ticker(self, **params): return await self._ws_api_request("ticker.tradingDay", False, params) ws_get_trading_day_ticker.__doc__ = Client.ws_get_trading_day_ticker.__doc__ async def ws_get_symbol_ticker_window(self, **params): return await self._ws_api_request("ticker", False, params) ws_get_symbol_ticker_window.__doc__ = Client.ws_get_symbol_ticker_window.__doc__ async def ws_get_symbol_ticker(self, **params): return await self._ws_api_request("ticker.price", False, params) ws_get_symbol_ticker.__doc__ = Client.ws_get_symbol_ticker.__doc__ async def ws_get_orderbook_ticker(self, **params): return await self._ws_api_request("ticker.book", False, params) ws_get_orderbook_ticker.__doc__ = Client.ws_get_orderbook_ticker.__doc__ async def ws_ping(self, **params): return await self._ws_api_request("ping", False, params) ws_ping.__doc__ = Client.ws_ping.__doc__ async def ws_get_time(self, **params): return await self._ws_api_request("time", False, params) ws_get_time.__doc__ = Client.ws_get_time.__doc__ async def ws_get_exchange_info(self, **params): return await self._ws_api_request("exchangeInfo", False, params) ws_get_exchange_info.__doc__ = Client.ws_get_exchange_info.__doc__ #################################################### # FUTURES WS API Endpoints #################################################### async def ws_futures_get_order_book(self, **params): """ Get the order book for a symbol https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/websocket-api """ return await self._ws_futures_api_request("depth", False, params) async def ws_futures_get_all_tickers(self, **params): """ Latest price for a symbol or symbols https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/websocket-api/Symbol-Price-Ticker """ return await self._ws_futures_api_request("ticker.price", False, params) async def ws_futures_get_order_book_ticker(self, **params): """ Best price/qty on the order book for a symbol or symbols. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/websocket-api/Symbol-Order-Book-Ticker """ return await self._ws_futures_api_request("ticker.book", False, params) async def ws_futures_create_order(self, **params): """ Send in a new order https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api """ # Check if this is a conditional order type that needs to use algo endpoint order_type = params.get("type", "").upper() conditional_types = [ "STOP", "STOP_MARKET", "TAKE_PROFIT", "TAKE_PROFIT_MARKET", "TRAILING_STOP_MARKET", ] if order_type in conditional_types: # Route to algo order endpoint if "clientAlgoId" not in params: params["clientAlgoId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() # Remove newClientOrderId if it was added by default params.pop("newClientOrderId", None) if "algoType" not in params: params["algoType"] = "CONDITIONAL" # Convert stopPrice to triggerPrice for algo orders if "stopPrice" in params and "triggerPrice" not in params: params["triggerPrice"] = params.pop("stopPrice") return await self._ws_futures_api_request("algoOrder.place", True, params) else: # Use regular order endpoint if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return await self._ws_futures_api_request("order.place", True, params) async def ws_futures_edit_order(self, **params): """ Edit an order https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Modify-Order """ return await self._ws_futures_api_request("order.modify", True, params) async def ws_futures_cancel_order(self, **params): """ cancel an order https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Cancel-Order """ is_conditional = False if "algoId" in params or "clientAlgoId" in params: is_conditional = True if is_conditional: return await self._ws_futures_api_request("algoOrder.cancel", True, params) else: return await self._ws_futures_api_request("order.cancel", True, params) async def ws_futures_get_order(self, **params): """ Get an order https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Query-Order Note: Algo/conditional orders cannot be queried via websocket API """ return await self._ws_futures_api_request("order.status", True, params) async def ws_futures_v2_account_position(self, **params): """ Get current position information(only symbol that has position or open orders will be return awaited). https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Position-Info-V2 """ return await self._ws_futures_api_request("v2/account.position", True, params) async def ws_futures_account_position(self, **params): """ Get current position information. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Position-Information """ return await self._ws_futures_api_request("account.position", True, params) async def ws_futures_v2_account_balance(self, **params): """ Get current account information. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/websocket-api#api-description """ return await self._ws_futures_api_request("v2/account.balance", True, params) async def ws_futures_account_balance(self, **params): """ Get current account information. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/websocket-api/Futures-Account-Balance """ return await self._ws_futures_api_request("account.balance", True, params) async def ws_futures_v2_account_status(self, **params): """ Get current account information. User in single-asset/ multi-assets mode will see different value, see comments in response section for detail. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/websocket-api/Account-Information-V2 """ return await self._ws_futures_api_request("v2/account.status", True, params) async def ws_futures_account_status(self, **params): """ Get current account information. User in single-asset/ multi-assets mode will see different value, see comments in response section for detail. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/websocket-api/Account-Information """ return await self._ws_futures_api_request("account.status", True, params) async def ws_futures_create_algo_order(self, **params): if "clientAlgoId" not in params: params["clientAlgoId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return await self._ws_futures_api_request("algoOrder.place", True, params) ws_futures_create_algo_order.__doc__ = Client.ws_futures_create_algo_order.__doc__ async def ws_futures_cancel_algo_order(self, **params): return await self._ws_futures_api_request("algoOrder.cancel", True, params) ws_futures_cancel_algo_order.__doc__ = Client.ws_futures_cancel_algo_order.__doc__ #################################################### # Gift Card API Endpoints #################################################### async def gift_card_fetch_token_limit(self, **params): return await self._request_margin_api( "get", "giftcard/buyCode/token-limit", signed=True, data=params ) gift_card_fetch_token_limit.__doc__ = Client.gift_card_fetch_token_limit.__doc__ async def gift_card_fetch_rsa_public_key(self, **params): return await self._request_margin_api( "get", "giftcard/cryptography/rsa-public-key", signed=True, data=params ) gift_card_fetch_rsa_public_key.__doc__ = ( Client.gift_card_fetch_rsa_public_key.__doc__ ) async def gift_card_verify(self, **params): return await self._request_margin_api( "get", "giftcard/verify", signed=True, data=params ) gift_card_verify.__doc__ = Client.gift_card_verify.__doc__ async def gift_card_redeem(self, **params): return await self._request_margin_api( "post", "giftcard/redeemCode", signed=True, data=params ) gift_card_redeem.__doc__ = Client.gift_card_redeem.__doc__ async def gift_card_create(self, **params): return await self._request_margin_api( "post", "giftcard/createCode", signed=True, data=params ) gift_card_create.__doc__ = Client.gift_card_create.__doc__ async def gift_card_create_dual_token(self, **params): return await self._request_margin_api( "post", "giftcard/buyCode", signed=True, data=params ) gift_card_create_dual_token.__doc__ = Client.gift_card_create_dual_token.__doc__ #################################################### # Options - Market Maker Block Trade #################################################### async def options_create_block_trade_order(self, **params): return await self._request_options_api( "post", "block/order/create", signed=True, data=params ) options_create_block_trade_order.__doc__ = ( Client.options_create_block_trade_order.__doc__ ) async def options_cancel_block_trade_order(self, **params): return await self._request_options_api( "delete", "block/order/create", signed=True, data=params ) options_cancel_block_trade_order.__doc__ = ( Client.options_cancel_block_trade_order.__doc__ ) async def options_extend_block_trade_order(self, **params): return await self._request_options_api( "put", "block/order/create", signed=True, data=params ) options_extend_block_trade_order.__doc__ = ( Client.options_extend_block_trade_order.__doc__ ) async def options_get_block_trade_orders(self, **params): return await self._request_options_api( "get", "block/order/orders", signed=True, data=params ) options_get_block_trade_orders.__doc__ = ( Client.options_get_block_trade_orders.__doc__ ) async def options_accept_block_trade_order(self, **params): return await self._request_options_api( "post", "block/order/execute", signed=True, data=params ) options_accept_block_trade_order.__doc__ = ( Client.options_accept_block_trade_order.__doc__ ) async def options_get_block_trade_order(self, **params): return await self._request_options_api( "get", "block/order/execute", signed=True, data=params ) options_get_block_trade_order.__doc__ = Client.options_get_block_trade_order.__doc__ async def options_account_get_block_trades(self, **params): return await self._request_options_api( "get", "block/user-trades", signed=True, data=params ) options_account_get_block_trades.__doc__ = ( Client.options_account_get_block_trades.__doc__ ) async def margin_next_hourly_interest_rate(self, **params): return await self._request_margin_api( "get", "margin/next-hourly-interest-rate", signed=True, data=params ) margin_next_hourly_interest_rate.__doc__ = ( Client.margin_next_hourly_interest_rate.__doc__ ) async def margin_interest_history(self, **params): return await self._request_margin_api( "get", "margin/interestHistory", signed=True, data=params ) margin_interest_history.__doc__ = Client.margin_interest_history.__doc__ async def margin_borrow_repay(self, **params): return await self._request_margin_api( "post", "margin/borrow-repay", signed=True, data=params ) margin_borrow_repay.__doc__ = Client.margin_borrow_repay.__doc__ async def margin_get_borrow_repay_records(self, **params): return await self._request_margin_api( "get", "margin/borrow-repay", signed=True, data=params ) margin_get_borrow_repay_records.__doc__ = ( Client.margin_get_borrow_repay_records.__doc__ ) async def margin_interest_rate_history(self, **params): return await self._request_margin_api( "get", "margin/interestRateHistory", signed=True, data=params ) margin_interest_rate_history.__doc__ = Client.margin_interest_rate_history.__doc__ async def margin_max_borrowable(self, **params): return await self._request_margin_api( "get", "margin/maxBorrowable", signed=True, data=params ) margin_max_borrowable.__doc__ = Client.margin_max_borrowable.__doc__ #################################################### # Futures Data #################################################### async def futures_historical_data_link(self, **params): return await self._request_margin_api("get", "futures/data/histDataLink", signed=True, data=params) futures_historical_data_link.__doc__ = Client.futures_historical_data_link.__doc__ async def margin_v1_get_loan_vip_ongoing_orders(self, **params): return await self._request_margin_api("get", "loan/vip/ongoing/orders", signed=True, data=params, version=1) margin_v1_get_loan_vip_ongoing_orders.__doc__ = Client.margin_v1_get_loan_vip_ongoing_orders.__doc__ async def margin_v1_get_mining_payment_other(self, **params): return await self._request_margin_api("get", "mining/payment/other", signed=True, data=params, version=1) margin_v1_get_mining_payment_other.__doc__ = Client.margin_v1_get_mining_payment_other.__doc__ async def futures_coin_v1_get_income_asyn_id(self, **params): return await self._request_futures_coin_api("get", "income/asyn/id", signed=True, data=params, version=1) futures_coin_v1_get_income_asyn_id.__doc__ = Client.futures_coin_v1_get_income_asyn_id.__doc__ async def margin_v1_get_simple_earn_flexible_history_subscription_record(self, **params): return await self._request_margin_api("get", "simple-earn/flexible/history/subscriptionRecord", signed=True, data=params, version=1) margin_v1_get_simple_earn_flexible_history_subscription_record.__doc__ = Client.margin_v1_get_simple_earn_flexible_history_subscription_record.__doc__ async def margin_v1_post_lending_auto_invest_one_off(self, **params): return await self._request_margin_api("post", "lending/auto-invest/one-off", signed=True, data=params, version=1) margin_v1_post_lending_auto_invest_one_off.__doc__ = Client.margin_v1_post_lending_auto_invest_one_off.__doc__ async def margin_v1_post_broker_sub_account_api_commission_coin_futures(self, **params): return await self._request_margin_api("post", "broker/subAccountApi/commission/coinFutures", signed=True, data=params, version=1) margin_v1_post_broker_sub_account_api_commission_coin_futures.__doc__ = Client.margin_v1_post_broker_sub_account_api_commission_coin_futures.__doc__ async def v3_post_order_list_otoco(self, **params): return await self._request_api("post", "orderList/otoco", signed=True, data=params, version="v3") v3_post_order_list_otoco.__doc__ = Client.v3_post_order_list_otoco.__doc__ async def futures_v1_get_order_asyn(self, **params): return await self._request_futures_api("get", "order/asyn", signed=True, data=params, version=1) futures_v1_get_order_asyn.__doc__ = Client.futures_v1_get_order_asyn.__doc__ async def margin_v1_get_asset_custody_transfer_history(self, **params): return await self._request_margin_api("get", "asset/custody/transfer-history", signed=True, data=params, version=1) margin_v1_get_asset_custody_transfer_history.__doc__ = Client.margin_v1_get_asset_custody_transfer_history.__doc__ async def margin_v1_post_broker_sub_account_blvt(self, **params): return await self._request_margin_api("post", "broker/subAccount/blvt", signed=True, data=params, version=1) margin_v1_post_broker_sub_account_blvt.__doc__ = Client.margin_v1_post_broker_sub_account_blvt.__doc__ async def margin_v1_post_sol_staking_sol_redeem(self, **params): return await self._request_margin_api("post", "sol-staking/sol/redeem", signed=True, data=params, version=1) margin_v1_post_sol_staking_sol_redeem.__doc__ = Client.margin_v1_post_sol_staking_sol_redeem.__doc__ async def options_v1_get_countdown_cancel_all(self, **params): return await self._request_options_api("get", "countdownCancelAll", signed=True, data=params) options_v1_get_countdown_cancel_all.__doc__ = Client.options_v1_get_countdown_cancel_all.__doc__ async def margin_v1_get_margin_trade_coeff(self, **params): return await self._request_margin_api("get", "margin/tradeCoeff", signed=True, data=params, version=1) margin_v1_get_margin_trade_coeff.__doc__ = Client.margin_v1_get_margin_trade_coeff.__doc__ async def futures_coin_v1_get_order_amendment(self, **params): return await self._request_futures_coin_api("get", "orderAmendment", signed=True, data=params, version=1) futures_coin_v1_get_order_amendment.__doc__ = Client.futures_coin_v1_get_order_amendment.__doc__ async def margin_v1_get_margin_available_inventory(self, **params): return await self._request_margin_api("get", "margin/available-inventory", signed=True, data=params, version=1) margin_v1_get_margin_available_inventory.__doc__ = Client.margin_v1_get_margin_available_inventory.__doc__ async def margin_v1_post_account_api_restrictions_ip_restriction_ip_list(self, **params): return await self._request_margin_api("post", "account/apiRestrictions/ipRestriction/ipList", signed=True, data=params, version=1) margin_v1_post_account_api_restrictions_ip_restriction_ip_list.__doc__ = Client.margin_v1_post_account_api_restrictions_ip_restriction_ip_list.__doc__ async def margin_v2_get_eth_staking_account(self, **params): return await self._request_margin_api("get", "eth-staking/account", signed=True, data=params, version=2) margin_v2_get_eth_staking_account.__doc__ = Client.margin_v2_get_eth_staking_account.__doc__ async def margin_v1_get_loan_income(self, **params): return await self._request_margin_api("get", "loan/income", signed=True, data=params, version=1) margin_v1_get_loan_income.__doc__ = Client.margin_v1_get_loan_income.__doc__ async def futures_coin_v1_get_pm_account_info(self, **params): return await self._request_futures_coin_api("get", "pmAccountInfo", signed=True, data=params, version=1) futures_coin_v1_get_pm_account_info.__doc__ = Client.futures_coin_v1_get_pm_account_info.__doc__ async def margin_v1_get_managed_subaccount_query_trans_log_for_investor(self, **params): return await self._request_margin_api("get", "managed-subaccount/queryTransLogForInvestor", signed=True, data=params, version=1) margin_v1_get_managed_subaccount_query_trans_log_for_investor.__doc__ = Client.margin_v1_get_managed_subaccount_query_trans_log_for_investor.__doc__ async def margin_v1_post_dci_product_auto_compound_edit_status(self, **params): return await self._request_margin_api("post", "dci/product/auto_compound/edit-status", signed=True, data=params, version=1) margin_v1_post_dci_product_auto_compound_edit_status.__doc__ = Client.margin_v1_post_dci_product_auto_compound_edit_status.__doc__ async def futures_v1_get_trade_asyn(self, **params): return await self._request_futures_api("get", "trade/asyn", signed=True, data=params, version=1) futures_v1_get_trade_asyn.__doc__ = Client.futures_v1_get_trade_asyn.__doc__ async def margin_v1_get_loan_vip_request_interest_rate(self, **params): return await self._request_margin_api("get", "loan/vip/request/interestRate", signed=True, data=params, version=1) margin_v1_get_loan_vip_request_interest_rate.__doc__ = Client.margin_v1_get_loan_vip_request_interest_rate.__doc__ async def futures_v1_get_funding_info(self, **params): return await self._request_futures_api("get", "fundingInfo", signed=False, data=params, version=1) futures_v1_get_funding_info.__doc__ = Client.futures_v1_get_funding_info.__doc__ async def v3_get_all_orders(self, **params): return await self._request_api("get", "allOrders", signed=True, data=params, version="v3") async def margin_v2_get_loan_flexible_repay_rate(self, **params): return await self._request_margin_api("get", "loan/flexible/repay/rate", signed=True, data=params, version=2) margin_v2_get_loan_flexible_repay_rate.__doc__ = Client.margin_v2_get_loan_flexible_repay_rate.__doc__ async def margin_v1_get_lending_auto_invest_plan_id(self, **params): return await self._request_margin_api("get", "lending/auto-invest/plan/id", signed=True, data=params, version=1) margin_v1_get_lending_auto_invest_plan_id.__doc__ = Client.margin_v1_get_lending_auto_invest_plan_id.__doc__ async def margin_v1_post_loan_adjust_ltv(self, **params): return await self._request_margin_api("post", "loan/adjust/ltv", signed=True, data=params, version=1) margin_v1_post_loan_adjust_ltv.__doc__ = Client.margin_v1_post_loan_adjust_ltv.__doc__ async def margin_v1_get_mining_statistics_user_status(self, **params): return await self._request_margin_api("get", "mining/statistics/user/status", signed=True, data=params, version=1) margin_v1_get_mining_statistics_user_status.__doc__ = Client.margin_v1_get_mining_statistics_user_status.__doc__ async def margin_v1_get_broker_transfer_futures(self, **params): return await self._request_margin_api("get", "broker/transfer/futures", signed=True, data=params, version=1) margin_v1_get_broker_transfer_futures.__doc__ = Client.margin_v1_get_broker_transfer_futures.__doc__ async def margin_v1_post_algo_spot_new_order_twap(self, **params): return await self._request_margin_api("post", "algo/spot/newOrderTwap", signed=True, data=params, version=1) margin_v1_post_algo_spot_new_order_twap.__doc__ = Client.margin_v1_post_algo_spot_new_order_twap.__doc__ async def margin_v1_get_lending_auto_invest_target_asset_list(self, **params): return await self._request_margin_api("get", "lending/auto-invest/target-asset/list", signed=True, data=params, version=1) margin_v1_get_lending_auto_invest_target_asset_list.__doc__ = Client.margin_v1_get_lending_auto_invest_target_asset_list.__doc__ async def margin_v1_get_capital_deposit_address_list(self, **params): return await self._request_margin_api("get", "capital/deposit/address/list", signed=True, data=params, version=1) margin_v1_get_capital_deposit_address_list.__doc__ = Client.margin_v1_get_capital_deposit_address_list.__doc__ async def margin_v1_post_broker_sub_account_bnb_burn_margin_interest(self, **params): return await self._request_margin_api("post", "broker/subAccount/bnbBurn/marginInterest", signed=True, data=params, version=1) margin_v1_post_broker_sub_account_bnb_burn_margin_interest.__doc__ = Client.margin_v1_post_broker_sub_account_bnb_burn_margin_interest.__doc__ async def margin_v2_post_loan_flexible_repay(self, **params): return await self._request_margin_api("post", "loan/flexible/repay", signed=True, data=params, version=2) margin_v2_post_loan_flexible_repay.__doc__ = Client.margin_v2_post_loan_flexible_repay.__doc__ async def margin_v2_get_loan_flexible_loanable_data(self, **params): return await self._request_margin_api("get", "loan/flexible/loanable/data", signed=True, data=params, version=2) margin_v2_get_loan_flexible_loanable_data.__doc__ = Client.margin_v2_get_loan_flexible_loanable_data.__doc__ async def margin_v1_post_broker_sub_account_api_permission(self, **params): return await self._request_margin_api("post", "broker/subAccountApi/permission", signed=True, data=params, version=1) margin_v1_post_broker_sub_account_api_permission.__doc__ = Client.margin_v1_post_broker_sub_account_api_permission.__doc__ async def margin_v1_post_broker_sub_account_api(self, **params): return await self._request_margin_api("post", "broker/subAccountApi", signed=True, data=params, version=1) margin_v1_post_broker_sub_account_api.__doc__ = Client.margin_v1_post_broker_sub_account_api.__doc__ async def margin_v1_get_dci_product_positions(self, **params): return await self._request_margin_api("get", "dci/product/positions", signed=True, data=params, version=1) margin_v1_get_dci_product_positions.__doc__ = Client.margin_v1_get_dci_product_positions.__doc__ async def margin_v1_post_convert_limit_cancel_order(self, **params): return await self._request_margin_api("post", "convert/limit/cancelOrder", signed=True, data=params, version=1) margin_v1_post_convert_limit_cancel_order.__doc__ = Client.margin_v1_post_convert_limit_cancel_order.__doc__ async def v3_post_order_list_oto(self, **params): return await self._request_api("post", "orderList/oto", signed=True, data=params, version="v3") v3_post_order_list_oto.__doc__ = Client.v3_post_order_list_oto.__doc__ async def margin_v1_get_mining_hash_transfer_config_details_list(self, **params): return await self._request_margin_api("get", "mining/hash-transfer/config/details/list", signed=True, data=params, version=1) margin_v1_get_mining_hash_transfer_config_details_list.__doc__ = Client.margin_v1_get_mining_hash_transfer_config_details_list.__doc__ async def margin_v1_get_mining_hash_transfer_profit_details(self, **params): return await self._request_margin_api("get", "mining/hash-transfer/profit/details", signed=True, data=params, version=1) margin_v1_get_mining_hash_transfer_profit_details.__doc__ = Client.margin_v1_get_mining_hash_transfer_profit_details.__doc__ async def margin_v1_get_broker_sub_account(self, **params): return await self._request_margin_api("get", "broker/subAccount", signed=True, data=params, version=1) margin_v1_get_broker_sub_account.__doc__ = Client.margin_v1_get_broker_sub_account.__doc__ async def margin_v1_get_portfolio_balance(self, **params): return await self._request_margin_api("get", "portfolio/balance", signed=True, data=params, version=1) margin_v1_get_portfolio_balance.__doc__ = Client.margin_v1_get_portfolio_balance.__doc__ async def margin_v1_post_sub_account_eoptions_enable(self, **params): return await self._request_margin_api("post", "sub-account/eoptions/enable", signed=True, data=params, version=1) margin_v1_post_sub_account_eoptions_enable.__doc__ = Client.margin_v1_post_sub_account_eoptions_enable.__doc__ async def papi_v1_post_ping(self, **params): return await self._request_papi_api("post", "ping", signed=True, data=params, version=1) papi_v1_post_ping.__doc__ = Client.papi_v1_post_ping.__doc__ async def margin_v1_get_loan_loanable_data(self, **params): return await self._request_margin_api("get", "loan/loanable/data", signed=True, data=params, version=1) margin_v1_get_loan_loanable_data.__doc__ = Client.margin_v1_get_loan_loanable_data.__doc__ async def margin_v1_post_eth_staking_wbeth_unwrap(self, **params): return await self._request_margin_api("post", "eth-staking/wbeth/unwrap", signed=True, data=params, version=1) margin_v1_post_eth_staking_wbeth_unwrap.__doc__ = Client.margin_v1_post_eth_staking_wbeth_unwrap.__doc__ async def margin_v1_get_eth_staking_eth_history_staking_history(self, **params): return await self._request_margin_api("get", "eth-staking/eth/history/stakingHistory", signed=True, data=params, version=1) margin_v1_get_eth_staking_eth_history_staking_history.__doc__ = Client.margin_v1_get_eth_staking_eth_history_staking_history.__doc__ async def margin_v1_get_staking_staking_record(self, **params): return await self._request_margin_api("get", "staking/stakingRecord", signed=True, data=params, version=1) margin_v1_get_staking_staking_record.__doc__ = Client.margin_v1_get_staking_staking_record.__doc__ async def margin_v1_get_broker_rebate_recent_record(self, **params): return await self._request_margin_api("get", "broker/rebate/recentRecord", signed=True, data=params, version=1) margin_v1_get_broker_rebate_recent_record.__doc__ = Client.margin_v1_get_broker_rebate_recent_record.__doc__ async def v3_delete_user_data_stream(self, **params): return await self._request_api("delete", "userDataStream", signed=True, data=params, version="v3") async def v3_get_open_order_list(self, **params): return await self._request_api("get", "openOrderList", signed=True, data=params, version="v3") async def margin_v1_get_loan_vip_collateral_account(self, **params): return await self._request_margin_api("get", "loan/vip/collateral/account", signed=True, data=params, version=1) margin_v1_get_loan_vip_collateral_account.__doc__ = Client.margin_v1_get_loan_vip_collateral_account.__doc__ async def margin_v1_get_algo_spot_open_orders(self, **params): return await self._request_margin_api("get", "algo/spot/openOrders", signed=True, data=params, version=1) margin_v1_get_algo_spot_open_orders.__doc__ = Client.margin_v1_get_algo_spot_open_orders.__doc__ async def margin_v1_post_loan_repay(self, **params): return await self._request_margin_api("post", "loan/repay", signed=True, data=params, version=1) margin_v1_post_loan_repay.__doc__ = Client.margin_v1_post_loan_repay.__doc__ async def futures_coin_v1_get_funding_info(self, **params): return await self._request_futures_coin_api("get", "fundingInfo", signed=False, data=params, version=1) futures_coin_v1_get_funding_info.__doc__ = Client.futures_coin_v1_get_funding_info.__doc__ async def margin_v1_get_margin_leverage_bracket(self, **params): return await self._request_margin_api("get", "margin/leverageBracket", signed=True, data=params, version=1) margin_v1_get_margin_leverage_bracket.__doc__ = Client.margin_v1_get_margin_leverage_bracket.__doc__ async def margin_v2_get_portfolio_collateral_rate(self, **params): return await self._request_margin_api("get", "portfolio/collateralRate", signed=True, data=params, version=2) margin_v2_get_portfolio_collateral_rate.__doc__ = Client.margin_v2_get_portfolio_collateral_rate.__doc__ async def margin_v2_post_loan_flexible_adjust_ltv(self, **params): return await self._request_margin_api("post", "loan/flexible/adjust/ltv", signed=True, data=params, version=2) margin_v2_post_loan_flexible_adjust_ltv.__doc__ = Client.margin_v2_post_loan_flexible_adjust_ltv.__doc__ async def margin_v1_get_convert_order_status(self, **params): return await self._request_margin_api("get", "convert/orderStatus", signed=True, data=params, version=1) margin_v1_get_convert_order_status.__doc__ = Client.margin_v1_get_convert_order_status.__doc__ async def margin_v1_get_broker_sub_account_api_ip_restriction(self, **params): return await self._request_margin_api("get", "broker/subAccountApi/ipRestriction", signed=True, data=params, version=1) margin_v1_get_broker_sub_account_api_ip_restriction.__doc__ = Client.margin_v1_get_broker_sub_account_api_ip_restriction.__doc__ async def margin_v1_post_dci_product_subscribe(self, **params): return await self._request_margin_api("post", "dci/product/subscribe", signed=True, data=params, version=1) margin_v1_post_dci_product_subscribe.__doc__ = Client.margin_v1_post_dci_product_subscribe.__doc__ async def futures_v1_get_income_asyn_id(self, **params): return await self._request_futures_api("get", "income/asyn/id", signed=True, data=params, version=1) futures_v1_get_income_asyn_id.__doc__ = Client.futures_v1_get_income_asyn_id.__doc__ async def options_v1_post_countdown_cancel_all(self, **params): return await self._request_options_api("post", "countdownCancelAll", signed=True, data=params) options_v1_post_countdown_cancel_all.__doc__ = Client.options_v1_post_countdown_cancel_all.__doc__ async def margin_v1_post_mining_hash_transfer_config_cancel(self, **params): return await self._request_margin_api("post", "mining/hash-transfer/config/cancel", signed=True, data=params, version=1) margin_v1_post_mining_hash_transfer_config_cancel.__doc__ = Client.margin_v1_post_mining_hash_transfer_config_cancel.__doc__ async def margin_v1_get_broker_sub_account_deposit_hist(self, **params): return await self._request_margin_api("get", "broker/subAccount/depositHist", signed=True, data=params, version=1) margin_v1_get_broker_sub_account_deposit_hist.__doc__ = Client.margin_v1_get_broker_sub_account_deposit_hist.__doc__ async def margin_v1_get_mining_payment_list(self, **params): return await self._request_margin_api("get", "mining/payment/list", signed=True, data=params, version=1) margin_v1_get_mining_payment_list.__doc__ = Client.margin_v1_get_mining_payment_list.__doc__ async def futures_v1_get_pm_account_info(self, **params): return await self._request_futures_api("get", "pmAccountInfo", signed=True, data=params, version=1) futures_v1_get_pm_account_info.__doc__ = Client.futures_v1_get_pm_account_info.__doc__ async def futures_coin_v1_get_adl_quantile(self, **params): return await self._request_futures_coin_api("get", "adlQuantile", signed=True, data=params, version=1) futures_coin_v1_get_adl_quantile.__doc__ = Client.futures_coin_v1_get_adl_quantile.__doc__ async def options_v1_get_income_asyn_id(self, **params): return await self._request_options_api("get", "income/asyn/id", signed=True, data=params) options_v1_get_income_asyn_id.__doc__ = Client.options_v1_get_income_asyn_id.__doc__ async def v3_post_cancel_replace(self, **params): return await self._request_api("post", "cancelReplace", signed=True, data=params, version="v3") v3_post_cancel_replace.__doc__ = Client.v3_post_cancel_replace.__doc__ async def v3_post_order_test(self, **params): return await self._request_api("post", "order/test", signed=True, data=params, version="v3") async def margin_v1_post_account_enable_fast_withdraw_switch(self, **params): return await self._request_margin_api("post", "account/enableFastWithdrawSwitch", signed=True, data=params, version=1) margin_v1_post_account_enable_fast_withdraw_switch.__doc__ = Client.margin_v1_post_account_enable_fast_withdraw_switch.__doc__ async def margin_v1_post_broker_transfer_futures(self, **params): return await self._request_margin_api("post", "broker/transfer/futures", signed=True, data=params, version=1) margin_v1_post_broker_transfer_futures.__doc__ = Client.margin_v1_post_broker_transfer_futures.__doc__ async def margin_v1_get_margin_isolated_transfer(self, **params): return await self._request_margin_api("get", "margin/isolated/transfer", signed=True, data=params, version=1) async def v3_post_order_cancel_replace(self, **params): return await self._request_api("post", "order/cancelReplace", signed=True, data=params, version="v3") async def margin_v1_post_sol_staking_sol_stake(self, **params): return await self._request_margin_api("post", "sol-staking/sol/stake", signed=True, data=params, version=1) margin_v1_post_sol_staking_sol_stake.__doc__ = Client.margin_v1_post_sol_staking_sol_stake.__doc__ async def margin_v1_post_loan_borrow(self, **params): return await self._request_margin_api("post", "loan/borrow", signed=True, data=params, version=1) margin_v1_post_loan_borrow.__doc__ = Client.margin_v1_post_loan_borrow.__doc__ async def margin_v1_get_managed_subaccount_info(self, **params): return await self._request_margin_api("get", "managed-subaccount/info", signed=True, data=params, version=1) margin_v1_get_managed_subaccount_info.__doc__ = Client.margin_v1_get_managed_subaccount_info.__doc__ async def margin_v1_post_lending_auto_invest_plan_edit_status(self, **params): return await self._request_margin_api("post", "lending/auto-invest/plan/edit-status", signed=True, data=params, version=1) margin_v1_post_lending_auto_invest_plan_edit_status.__doc__ = Client.margin_v1_post_lending_auto_invest_plan_edit_status.__doc__ async def margin_v1_get_sol_staking_sol_history_unclaimed_rewards(self, **params): return await self._request_margin_api("get", "sol-staking/sol/history/unclaimedRewards", signed=True, data=params, version=1) margin_v1_get_sol_staking_sol_history_unclaimed_rewards.__doc__ = Client.margin_v1_get_sol_staking_sol_history_unclaimed_rewards.__doc__ async def margin_v1_post_asset_convert_transfer_query_by_page(self, **params): return await self._request_margin_api("post", "asset/convert-transfer/queryByPage", signed=True, data=params, version=1) margin_v1_post_asset_convert_transfer_query_by_page.__doc__ = Client.margin_v1_post_asset_convert_transfer_query_by_page.__doc__ async def margin_v1_get_sol_staking_sol_history_boost_rewards_history(self, **params): return await self._request_margin_api("get", "sol-staking/sol/history/boostRewardsHistory", signed=True, data=params, version=1) margin_v1_get_sol_staking_sol_history_boost_rewards_history.__doc__ = Client.margin_v1_get_sol_staking_sol_history_boost_rewards_history.__doc__ async def margin_v1_get_lending_auto_invest_one_off_status(self, **params): return await self._request_margin_api("get", "lending/auto-invest/one-off/status", signed=True, data=params, version=1) margin_v1_get_lending_auto_invest_one_off_status.__doc__ = Client.margin_v1_get_lending_auto_invest_one_off_status.__doc__ async def margin_v1_post_broker_sub_account(self, **params): return await self._request_margin_api("post", "broker/subAccount", signed=True, data=params, version=1) margin_v1_post_broker_sub_account.__doc__ = Client.margin_v1_post_broker_sub_account.__doc__ async def margin_v1_get_asset_ledger_transfer_cloud_mining_query_by_page(self, **params): return await self._request_margin_api("get", "asset/ledger-transfer/cloud-mining/queryByPage", signed=True, data=params, version=1) margin_v1_get_asset_ledger_transfer_cloud_mining_query_by_page.__doc__ = Client.margin_v1_get_asset_ledger_transfer_cloud_mining_query_by_page.__doc__ async def margin_v1_get_mining_pub_coin_list(self, **params): return await self._request_margin_api("get", "mining/pub/coinList", signed=True, data=params, version=1) margin_v1_get_mining_pub_coin_list.__doc__ = Client.margin_v1_get_mining_pub_coin_list.__doc__ async def margin_v2_get_loan_flexible_repay_history(self, **params): return await self._request_margin_api("get", "loan/flexible/repay/history", signed=True, data=params, version=2) margin_v2_get_loan_flexible_repay_history.__doc__ = Client.margin_v2_get_loan_flexible_repay_history.__doc__ async def v3_post_sor_order(self, **params): return await self._request_api("post", "sor/order", signed=True, data=params, version="v3") v3_post_sor_order.__doc__ = Client.v3_post_sor_order.__doc__ async def margin_v1_post_capital_deposit_credit_apply(self, **params): return await self._request_margin_api("post", "capital/deposit/credit-apply", signed=True, data=params, version=1) margin_v1_post_capital_deposit_credit_apply.__doc__ = Client.margin_v1_post_capital_deposit_credit_apply.__doc__ async def futures_v1_put_batch_order(self, **params): return await self._request_futures_api("put", "batchOrder", signed=True, data=params, version=1) futures_v1_put_batch_order.__doc__ = Client.futures_v1_put_batch_order.__doc__ async def v3_get_my_prevented_matches(self, **params): return await self._request_api("get", "myPreventedMatches", signed=True, data=params, version="v3") async def margin_v1_get_mining_statistics_user_list(self, **params): return await self._request_margin_api("get", "mining/statistics/user/list", signed=True, data=params, version=1) margin_v1_get_mining_statistics_user_list.__doc__ = Client.margin_v1_get_mining_statistics_user_list.__doc__ async def futures_v1_post_batch_order(self, **params): return await self._request_futures_api("post", "batchOrder", signed=True, data=params, version=1) futures_v1_post_batch_order.__doc__ = Client.futures_v1_post_batch_order.__doc__ async def v3_get_ticker_trading_day(self, **params): return await self._request_api("get", "ticker/tradingDay", signed=False, data=params, version="v3") v3_get_ticker_trading_day.__doc__ = Client.v3_get_ticker_trading_day.__doc__ async def margin_v1_get_mining_worker_detail(self, **params): return await self._request_margin_api("get", "mining/worker/detail", signed=True, data=params, version=1) margin_v1_get_mining_worker_detail.__doc__ = Client.margin_v1_get_mining_worker_detail.__doc__ async def margin_v1_get_managed_subaccount_fetch_future_asset(self, **params): return await self._request_margin_api("get", "managed-subaccount/fetch-future-asset", signed=True, data=params, version=1) margin_v1_get_managed_subaccount_fetch_future_asset.__doc__ = Client.margin_v1_get_managed_subaccount_fetch_future_asset.__doc__ async def margin_v1_get_margin_rate_limit_order(self, **params): return await self._request_margin_api("get", "margin/rateLimit/order", signed=True, data=params, version=1) margin_v1_get_margin_rate_limit_order.__doc__ = Client.margin_v1_get_margin_rate_limit_order.__doc__ async def margin_v1_get_localentity_vasp(self, **params): return await self._request_margin_api("get", "localentity/vasp", signed=True, data=params, version=1) margin_v1_get_localentity_vasp.__doc__ = Client.margin_v1_get_localentity_vasp.__doc__ async def margin_v1_get_sol_staking_sol_history_rate_history(self, **params): return await self._request_margin_api("get", "sol-staking/sol/history/rateHistory", signed=True, data=params, version=1) margin_v1_get_sol_staking_sol_history_rate_history.__doc__ = Client.margin_v1_get_sol_staking_sol_history_rate_history.__doc__ async def margin_v1_post_broker_sub_account_api_ip_restriction(self, **params): return await self._request_margin_api("post", "broker/subAccountApi/ipRestriction", signed=True, data=params, version=1) margin_v1_post_broker_sub_account_api_ip_restriction.__doc__ = Client.margin_v1_post_broker_sub_account_api_ip_restriction.__doc__ async def margin_v1_get_broker_transfer(self, **params): return await self._request_margin_api("get", "broker/transfer", signed=True, data=params, version=1) margin_v1_get_broker_transfer.__doc__ = Client.margin_v1_get_broker_transfer.__doc__ async def margin_v1_get_sol_staking_account(self, **params): return await self._request_margin_api("get", "sol-staking/account", signed=True, data=params, version=1) margin_v1_get_sol_staking_account.__doc__ = Client.margin_v1_get_sol_staking_account.__doc__ async def margin_v1_get_account_info(self, **params): return await self._request_margin_api("get", "account/info", signed=True, data=params, version=1) margin_v1_get_account_info.__doc__ = Client.margin_v1_get_account_info.__doc__ async def margin_v1_post_portfolio_repay_futures_switch(self, **params): return await self._request_margin_api("post", "portfolio/repay-futures-switch", signed=True, data=params, version=1) margin_v1_post_portfolio_repay_futures_switch.__doc__ = Client.margin_v1_post_portfolio_repay_futures_switch.__doc__ async def margin_v1_post_loan_vip_borrow(self, **params): return await self._request_margin_api("post", "loan/vip/borrow", signed=True, data=params, version=1) margin_v1_post_loan_vip_borrow.__doc__ = Client.margin_v1_post_loan_vip_borrow.__doc__ async def margin_v2_get_loan_flexible_ltv_adjustment_history(self, **params): return await self._request_margin_api("get", "loan/flexible/ltv/adjustment/history", signed=True, data=params, version=2) margin_v2_get_loan_flexible_ltv_adjustment_history.__doc__ = Client.margin_v2_get_loan_flexible_ltv_adjustment_history.__doc__ async def options_v1_delete_all_open_orders_by_underlying(self, **params): return await self._request_options_api("delete", "allOpenOrdersByUnderlying", signed=True, data=params) options_v1_delete_all_open_orders_by_underlying.__doc__ = Client.options_v1_delete_all_open_orders_by_underlying.__doc__ async def margin_v1_get_broker_sub_account_futures_summary(self, **params): return await self._request_margin_api("get", "broker/subAccount/futuresSummary", signed=True, data=params, version=1) margin_v1_get_broker_sub_account_futures_summary.__doc__ = Client.margin_v1_get_broker_sub_account_futures_summary.__doc__ async def margin_v1_get_broker_sub_account_spot_summary(self, **params): return await self._request_margin_api("get", "broker/subAccount/spotSummary", signed=True, data=params, version=1) margin_v1_get_broker_sub_account_spot_summary.__doc__ = Client.margin_v1_get_broker_sub_account_spot_summary.__doc__ async def margin_v1_post_sub_account_blvt_enable(self, **params): return await self._request_margin_api("post", "sub-account/blvt/enable", signed=True, data=params, version=1) margin_v1_post_sub_account_blvt_enable.__doc__ = Client.margin_v1_post_sub_account_blvt_enable.__doc__ async def margin_v1_get_algo_spot_historical_orders(self, **params): return await self._request_margin_api("get", "algo/spot/historicalOrders", signed=True, data=params, version=1) margin_v1_get_algo_spot_historical_orders.__doc__ = Client.margin_v1_get_algo_spot_historical_orders.__doc__ async def margin_v1_get_loan_vip_repay_history(self, **params): return await self._request_margin_api("get", "loan/vip/repay/history", signed=True, data=params, version=1) margin_v1_get_loan_vip_repay_history.__doc__ = Client.margin_v1_get_loan_vip_repay_history.__doc__ async def margin_v1_get_loan_borrow_history(self, **params): return await self._request_margin_api("get", "loan/borrow/history", signed=True, data=params, version=1) margin_v1_get_loan_borrow_history.__doc__ = Client.margin_v1_get_loan_borrow_history.__doc__ async def margin_v1_post_lending_auto_invest_redeem(self, **params): return await self._request_margin_api("post", "lending/auto-invest/redeem", signed=True, data=params, version=1) margin_v1_post_lending_auto_invest_redeem.__doc__ = Client.margin_v1_post_lending_auto_invest_redeem.__doc__ async def v3_get_account(self, **params): return await self._request_api("get", "account", signed=True, data=params, version="v3") async def v3_delete_order(self, **params): return await self._request_api("delete", "order", signed=True, data=params, version="v3") async def futures_coin_v1_get_income_asyn(self, **params): return await self._request_futures_coin_api("get", "income/asyn", signed=True, data=params, version=1) futures_coin_v1_get_income_asyn.__doc__ = Client.futures_coin_v1_get_income_asyn.__doc__ async def margin_v1_post_managed_subaccount_deposit(self, **params): return await self._request_margin_api("post", "managed-subaccount/deposit", signed=True, data=params, version=1) margin_v1_post_managed_subaccount_deposit.__doc__ = Client.margin_v1_post_managed_subaccount_deposit.__doc__ async def margin_v1_post_lending_daily_purchase(self, **params): return await self._request_margin_api("post", "lending/daily/purchase", signed=True, data=params, version=1) margin_v1_post_lending_daily_purchase.__doc__ = Client.margin_v1_post_lending_daily_purchase.__doc__ async def futures_v1_get_trade_asyn_id(self, **params): return await self._request_futures_api("get", "trade/asyn/id", signed=True, data=params, version=1) futures_v1_get_trade_asyn_id.__doc__ = Client.futures_v1_get_trade_asyn_id.__doc__ async def margin_v1_delete_sub_account_sub_account_api_ip_restriction_ip_list(self, **params): return await self._request_margin_api("delete", "sub-account/subAccountApi/ipRestriction/ipList", signed=True, data=params, version=1) margin_v1_delete_sub_account_sub_account_api_ip_restriction_ip_list.__doc__ = Client.margin_v1_delete_sub_account_sub_account_api_ip_restriction_ip_list.__doc__ async def margin_v1_get_copy_trading_futures_user_status(self, **params): return await self._request_margin_api("get", "copyTrading/futures/userStatus", signed=True, data=params, version=1) margin_v1_get_copy_trading_futures_user_status.__doc__ = Client.margin_v1_get_copy_trading_futures_user_status.__doc__ async def options_v1_get_margin_account(self, **params): return await self._request_options_api("get", "marginAccount", signed=True, data=params) options_v1_get_margin_account.__doc__ = Client.options_v1_get_margin_account.__doc__ async def margin_v1_post_localentity_withdraw_apply(self, **params): return await self._request_margin_api("post", "localentity/withdraw/apply", signed=True, data=params, version=1) margin_v1_post_localentity_withdraw_apply.__doc__ = Client.margin_v1_post_localentity_withdraw_apply.__doc__ async def v3_put_user_data_stream(self, **params): return await self._request_api("put", "userDataStream", signed=True, data=params, version="v3") async def margin_v1_get_asset_wallet_balance(self, **params): return await self._request_margin_api("get", "asset/wallet/balance", signed=True, data=params, version=1) margin_v1_get_asset_wallet_balance.__doc__ = Client.margin_v1_get_asset_wallet_balance.__doc__ async def margin_v1_post_broker_transfer(self, **params): return await self._request_margin_api("post", "broker/transfer", signed=True, data=params, version=1) margin_v1_post_broker_transfer.__doc__ = Client.margin_v1_post_broker_transfer.__doc__ async def margin_v1_post_lending_customized_fixed_purchase(self, **params): return await self._request_margin_api("post", "lending/customizedFixed/purchase", signed=True, data=params, version=1) margin_v1_post_lending_customized_fixed_purchase.__doc__ = Client.margin_v1_post_lending_customized_fixed_purchase.__doc__ async def margin_v1_post_algo_futures_new_order_twap(self, **params): return await self._request_margin_api("post", "algo/futures/newOrderTwap", signed=True, data=params, version=1) margin_v1_post_algo_futures_new_order_twap.__doc__ = Client.margin_v1_post_algo_futures_new_order_twap.__doc__ async def margin_v2_post_eth_staking_eth_stake(self, **params): return await self._request_margin_api("post", "eth-staking/eth/stake", signed=True, data=params, version=2) margin_v2_post_eth_staking_eth_stake.__doc__ = Client.margin_v2_post_eth_staking_eth_stake.__doc__ async def margin_v1_post_loan_flexible_repay_history(self, **params): return await self._request_margin_api("post", "loan/flexible/repay/history", signed=True, data=params, version=1) margin_v1_post_loan_flexible_repay_history.__doc__ = Client.margin_v1_post_loan_flexible_repay_history.__doc__ async def v3_post_user_data_stream(self, **params): return await self._request_api("post", "userDataStream", signed=True, data=params, version="v3") async def margin_v1_get_lending_auto_invest_index_info(self, **params): return await self._request_margin_api("get", "lending/auto-invest/index/info", signed=True, data=params, version=1) margin_v1_get_lending_auto_invest_index_info.__doc__ = Client.margin_v1_get_lending_auto_invest_index_info.__doc__ async def margin_v1_get_sol_staking_sol_history_redemption_history(self, **params): return await self._request_margin_api("get", "sol-staking/sol/history/redemptionHistory", signed=True, data=params, version=1) margin_v1_get_sol_staking_sol_history_redemption_history.__doc__ = Client.margin_v1_get_sol_staking_sol_history_redemption_history.__doc__ async def margin_v1_get_broker_rebate_futures_recent_record(self, **params): return await self._request_margin_api("get", "broker/rebate/futures/recentRecord", signed=True, data=params, version=1) margin_v1_get_broker_rebate_futures_recent_record.__doc__ = Client.margin_v1_get_broker_rebate_futures_recent_record.__doc__ async def margin_v3_get_broker_sub_account_futures_summary(self, **params): return await self._request_margin_api("get", "broker/subAccount/futuresSummary", signed=True, data=params, version=3) margin_v3_get_broker_sub_account_futures_summary.__doc__ = Client.margin_v3_get_broker_sub_account_futures_summary.__doc__ async def margin_v1_post_margin_manual_liquidation(self, **params): return await self._request_margin_api("post", "margin/manual-liquidation", signed=True, data=params, version=1) async def margin_v1_get_lending_auto_invest_target_asset_roi_list(self, **params): return await self._request_margin_api("get", "lending/auto-invest/target-asset/roi/list", signed=True, data=params, version=1) margin_v1_get_lending_auto_invest_target_asset_roi_list.__doc__ = Client.margin_v1_get_lending_auto_invest_target_asset_roi_list.__doc__ async def margin_v1_get_broker_universal_transfer(self, **params): return await self._request_margin_api("get", "broker/universalTransfer", signed=True, data=params, version=1) margin_v1_get_broker_universal_transfer.__doc__ = Client.margin_v1_get_broker_universal_transfer.__doc__ async def futures_v1_put_batch_orders(self, **params): return await self._request_futures_api("put", "batchOrders", signed=True, data=params, version=1) futures_v1_put_batch_orders.__doc__ = Client.futures_v1_put_batch_orders.__doc__ async def options_v1_post_countdown_cancel_all_heart_beat(self, **params): return await self._request_options_api("post", "countdownCancelAllHeartBeat", signed=True, data=params) options_v1_post_countdown_cancel_all_heart_beat.__doc__ = Client.options_v1_post_countdown_cancel_all_heart_beat.__doc__ async def margin_v1_get_loan_collateral_data(self, **params): return await self._request_margin_api("get", "loan/collateral/data", signed=True, data=params, version=1) margin_v1_get_loan_collateral_data.__doc__ = Client.margin_v1_get_loan_collateral_data.__doc__ async def margin_v1_get_loan_repay_history(self, **params): return await self._request_margin_api("get", "loan/repay/history", signed=True, data=params, version=1) margin_v1_get_loan_repay_history.__doc__ = Client.margin_v1_get_loan_repay_history.__doc__ async def margin_v1_post_convert_limit_place_order(self, **params): return await self._request_margin_api("post", "convert/limit/placeOrder", signed=True, data=params, version=1) margin_v1_post_convert_limit_place_order.__doc__ = Client.margin_v1_post_convert_limit_place_order.__doc__ async def futures_v1_get_convert_exchange_info(self, **params): return await self._request_futures_api("get", "convert/exchangeInfo", signed=False, data=params, version=1) futures_v1_get_convert_exchange_info.__doc__ = Client.futures_v1_get_convert_exchange_info.__doc__ async def v3_get_all_order_list(self, **params): return await self._request_api("get", "allOrderList", signed=True, data=params, version="v3") v3_get_all_order_list.__doc__ = Client.v3_get_all_order_list.__doc__ async def margin_v1_delete_broker_sub_account_api_ip_restriction_ip_list(self, **params): return await self._request_margin_api("delete", "broker/subAccountApi/ipRestriction/ipList", signed=True, data=params, version=1) margin_v1_delete_broker_sub_account_api_ip_restriction_ip_list.__doc__ = Client.margin_v1_delete_broker_sub_account_api_ip_restriction_ip_list.__doc__ async def margin_v1_post_sub_account_virtual_sub_account(self, **params): return await self._request_margin_api("post", "sub-account/virtualSubAccount", signed=True, data=params, version=1) margin_v1_post_sub_account_virtual_sub_account.__doc__ = Client.margin_v1_post_sub_account_virtual_sub_account.__doc__ async def margin_v1_put_localentity_deposit_provide_info(self, **params): return await self._request_margin_api("put", "localentity/deposit/provide-info", signed=True, data=params, version=1) margin_v1_put_localentity_deposit_provide_info.__doc__ = Client.margin_v1_put_localentity_deposit_provide_info.__doc__ async def margin_v1_post_portfolio_mint(self, **params): return await self._request_margin_api("post", "portfolio/mint", signed=True, data=params, version=1) margin_v1_post_portfolio_mint.__doc__ = Client.margin_v1_post_portfolio_mint.__doc__ async def futures_v1_get_order_amendment(self, **params): return await self._request_futures_api("get", "orderAmendment", signed=True, data=params, version=1) futures_v1_get_order_amendment.__doc__ = Client.futures_v1_get_order_amendment.__doc__ async def margin_v1_post_sol_staking_sol_claim(self, **params): return await self._request_margin_api("post", "sol-staking/sol/claim", signed=True, data=params, version=1) margin_v1_post_sol_staking_sol_claim.__doc__ = Client.margin_v1_post_sol_staking_sol_claim.__doc__ async def margin_v1_post_lending_daily_redeem(self, **params): return await self._request_margin_api("post", "lending/daily/redeem", signed=True, data=params, version=1) margin_v1_post_lending_daily_redeem.__doc__ = Client.margin_v1_post_lending_daily_redeem.__doc__ async def margin_v1_post_mining_hash_transfer_config(self, **params): return await self._request_margin_api("post", "mining/hash-transfer/config", signed=True, data=params, version=1) margin_v1_post_mining_hash_transfer_config.__doc__ = Client.margin_v1_post_mining_hash_transfer_config.__doc__ async def margin_v1_get_lending_auto_invest_rebalance_history(self, **params): return await self._request_margin_api("get", "lending/auto-invest/rebalance/history", signed=True, data=params, version=1) margin_v1_get_lending_auto_invest_rebalance_history.__doc__ = Client.margin_v1_get_lending_auto_invest_rebalance_history.__doc__ async def margin_v1_get_loan_repay_collateral_rate(self, **params): return await self._request_margin_api("get", "loan/repay/collateral/rate", signed=True, data=params, version=1) margin_v1_get_loan_repay_collateral_rate.__doc__ = Client.margin_v1_get_loan_repay_collateral_rate.__doc__ async def futures_v1_get_income_asyn(self, **params): return await self._request_futures_api("get", "income/asyn", signed=True, data=params, version=1) futures_v1_get_income_asyn.__doc__ = Client.futures_v1_get_income_asyn.__doc__ async def margin_v1_get_mining_payment_uid(self, **params): return await self._request_margin_api("get", "mining/payment/uid", signed=True, data=params, version=1) margin_v1_get_mining_payment_uid.__doc__ = Client.margin_v1_get_mining_payment_uid.__doc__ async def margin_v2_get_loan_flexible_borrow_history(self, **params): return await self._request_margin_api("get", "loan/flexible/borrow/history", signed=True, data=params, version=2) margin_v2_get_loan_flexible_borrow_history.__doc__ = Client.margin_v2_get_loan_flexible_borrow_history.__doc__ async def v3_get_order(self, **params): return await self._request_api("get", "order", signed=True, data=params, version="v3") async def margin_v1_get_capital_contract_convertible_coins(self, **params): return await self._request_margin_api("get", "capital/contract/convertible-coins", signed=True, data=params, version=1) margin_v1_get_capital_contract_convertible_coins.__doc__ = Client.margin_v1_get_capital_contract_convertible_coins.__doc__ async def margin_v1_post_broker_sub_account_api_permission_vanilla_options(self, **params): return await self._request_margin_api("post", "broker/subAccountApi/permission/vanillaOptions", signed=True, data=params, version=1) margin_v1_post_broker_sub_account_api_permission_vanilla_options.__doc__ = Client.margin_v1_post_broker_sub_account_api_permission_vanilla_options.__doc__ async def margin_v1_get_lending_auto_invest_redeem_history(self, **params): return await self._request_margin_api("get", "lending/auto-invest/redeem/history", signed=True, data=params, version=1) margin_v1_get_lending_auto_invest_redeem_history.__doc__ = Client.margin_v1_get_lending_auto_invest_redeem_history.__doc__ async def margin_v2_get_localentity_withdraw_history(self, **params): return await self._request_margin_api("get", "localentity/withdraw/history", signed=True, data=params, version=2) margin_v2_get_localentity_withdraw_history.__doc__ = Client.margin_v2_get_localentity_withdraw_history.__doc__ async def margin_v1_get_eth_staking_eth_history_redemption_history(self, **params): return await self._request_margin_api("get", "eth-staking/eth/history/redemptionHistory", signed=True, data=params, version=1) margin_v1_get_eth_staking_eth_history_redemption_history.__doc__ = Client.margin_v1_get_eth_staking_eth_history_redemption_history.__doc__ async def futures_v1_get_fee_burn(self, **params): return await self._request_futures_api("get", "feeBurn", signed=True, data=params, version=1) futures_v1_get_fee_burn.__doc__ = Client.futures_v1_get_fee_burn.__doc__ async def margin_v1_get_lending_auto_invest_index_user_summary(self, **params): return await self._request_margin_api("get", "lending/auto-invest/index/user-summary", signed=True, data=params, version=1) margin_v1_get_lending_auto_invest_index_user_summary.__doc__ = Client.margin_v1_get_lending_auto_invest_index_user_summary.__doc__ async def margin_v2_post_loan_flexible_borrow(self, **params): return await self._request_margin_api("post", "loan/flexible/borrow", signed=True, data=params, version=2) margin_v2_post_loan_flexible_borrow.__doc__ = Client.margin_v2_post_loan_flexible_borrow.__doc__ async def margin_v1_post_loan_vip_repay(self, **params): return await self._request_margin_api("post", "loan/vip/repay", signed=True, data=params, version=1) margin_v1_post_loan_vip_repay.__doc__ = Client.margin_v1_post_loan_vip_repay.__doc__ async def futures_coin_v1_get_commission_rate(self, **params): return await self._request_futures_coin_api("get", "commissionRate", signed=True, data=params, version=1) futures_coin_v1_get_commission_rate.__doc__ = Client.futures_coin_v1_get_commission_rate.__doc__ async def margin_v1_get_convert_asset_info(self, **params): return await self._request_margin_api("get", "convert/assetInfo", signed=True, data=params, version=1) margin_v1_get_convert_asset_info.__doc__ = Client.margin_v1_get_convert_asset_info.__doc__ async def v3_post_sor_order_test(self, **params): return await self._request_api("post", "sor/order/test", signed=True, data=params, version="v3") v3_post_sor_order_test.__doc__ = Client.v3_post_sor_order_test.__doc__ async def margin_v1_post_broker_universal_transfer(self, **params): return await self._request_margin_api("post", "broker/universalTransfer", signed=True, data=params, version=1) margin_v1_post_broker_universal_transfer.__doc__ = Client.margin_v1_post_broker_universal_transfer.__doc__ async def margin_v1_post_account_disable_fast_withdraw_switch(self, **params): return await self._request_margin_api("post", "account/disableFastWithdrawSwitch", signed=True, data=params, version=1) margin_v1_post_account_disable_fast_withdraw_switch.__doc__ = Client.margin_v1_post_account_disable_fast_withdraw_switch.__doc__ async def futures_v1_get_asset_index(self, **params): return await self._request_futures_api("get", "assetIndex", signed=False, data=params, version=1) futures_v1_get_asset_index.__doc__ = Client.futures_v1_get_asset_index.__doc__ async def v3_get_rate_limit_order(self, **params): return await self._request_api("get", "rateLimit/order", signed=True, data=params, version="v3") async def margin_v1_get_account_api_restrictions_ip_restriction(self, **params): return await self._request_margin_api("get", "account/apiRestrictions/ipRestriction", signed=True, data=params, version=1) margin_v1_get_account_api_restrictions_ip_restriction.__doc__ = Client.margin_v1_get_account_api_restrictions_ip_restriction.__doc__ async def margin_v1_post_broker_sub_account_bnb_burn_spot(self, **params): return await self._request_margin_api("post", "broker/subAccount/bnbBurn/spot", signed=True, data=params, version=1) margin_v1_post_broker_sub_account_bnb_burn_spot.__doc__ = Client.margin_v1_post_broker_sub_account_bnb_burn_spot.__doc__ async def futures_coin_v1_put_batch_orders(self, **params): return await self._request_futures_coin_api("put", "batchOrders", signed=True, data=params, version=1) futures_coin_v1_put_batch_orders.__doc__ = Client.futures_coin_v1_put_batch_orders.__doc__ async def v3_delete_open_orders(self, **params): return await self._request_api("delete", "openOrders", signed=True, data=params, version="v3") async def margin_v1_post_broker_sub_account_api_permission_universal_transfer(self, **params): return await self._request_margin_api("post", "broker/subAccountApi/permission/universalTransfer", signed=True, data=params, version=1) margin_v1_post_broker_sub_account_api_permission_universal_transfer.__doc__ = Client.margin_v1_post_broker_sub_account_api_permission_universal_transfer.__doc__ async def v3_get_my_allocations(self, **params): return await self._request_api("get", "myAllocations", signed=True, data=params, version="v3") async def margin_v1_get_loan_ltv_adjustment_history(self, **params): return await self._request_margin_api("get", "loan/ltv/adjustment/history", signed=True, data=params, version=1) margin_v1_get_loan_ltv_adjustment_history.__doc__ = Client.margin_v1_get_loan_ltv_adjustment_history.__doc__ async def margin_v1_get_localentity_withdraw_history(self, **params): return await self._request_margin_api("get", "localentity/withdraw/history", signed=True, data=params, version=1) margin_v1_get_localentity_withdraw_history.__doc__ = Client.margin_v1_get_localentity_withdraw_history.__doc__ async def margin_v2_post_sub_account_sub_account_api_ip_restriction(self, **params): return await self._request_margin_api("post", "sub-account/subAccountApi/ipRestriction", signed=True, data=params, version=2) margin_v2_post_sub_account_sub_account_api_ip_restriction.__doc__ = Client.margin_v2_post_sub_account_sub_account_api_ip_restriction.__doc__ async def futures_v1_get_rate_limit_order(self, **params): return await self._request_futures_api("get", "rateLimit/order", signed=True, data=params, version=1) futures_v1_get_rate_limit_order.__doc__ = Client.futures_v1_get_rate_limit_order.__doc__ async def margin_v1_get_broker_sub_account_api_commission_futures(self, **params): return await self._request_margin_api("get", "broker/subAccountApi/commission/futures", signed=True, data=params, version=1) margin_v1_get_broker_sub_account_api_commission_futures.__doc__ = Client.margin_v1_get_broker_sub_account_api_commission_futures.__doc__ async def margin_v1_get_sol_staking_sol_history_staking_history(self, **params): return await self._request_margin_api("get", "sol-staking/sol/history/stakingHistory", signed=True, data=params, version=1) margin_v1_get_sol_staking_sol_history_staking_history.__doc__ = Client.margin_v1_get_sol_staking_sol_history_staking_history.__doc__ async def futures_v1_get_open_order(self, **params): return await self._request_futures_api("get", "openOrder", signed=True, data=params, version=1) futures_v1_get_open_order.__doc__ = Client.futures_v1_get_open_order.__doc__ async def margin_v1_delete_algo_spot_order(self, **params): return await self._request_margin_api("delete", "algo/spot/order", signed=True, data=params, version=1) margin_v1_delete_algo_spot_order.__doc__ = Client.margin_v1_delete_algo_spot_order.__doc__ async def v3_post_order(self, **params): return await self._request_api("post", "order", signed=True, data=params, version="v3") async def margin_v1_delete_account_api_restrictions_ip_restriction_ip_list(self, **params): return await self._request_margin_api("delete", "account/apiRestrictions/ipRestriction/ipList", signed=True, data=params, version=1) margin_v1_delete_account_api_restrictions_ip_restriction_ip_list.__doc__ = Client.margin_v1_delete_account_api_restrictions_ip_restriction_ip_list.__doc__ async def margin_v1_post_capital_contract_convertible_coins(self, **params): return await self._request_margin_api("post", "capital/contract/convertible-coins", signed=True, data=params, version=1) margin_v1_post_capital_contract_convertible_coins.__doc__ = Client.margin_v1_post_capital_contract_convertible_coins.__doc__ async def margin_v1_get_managed_subaccount_margin_asset(self, **params): return await self._request_margin_api("get", "managed-subaccount/marginAsset", signed=True, data=params, version=1) margin_v1_get_managed_subaccount_margin_asset.__doc__ = Client.margin_v1_get_managed_subaccount_margin_asset.__doc__ async def v3_delete_order_list(self, **params): return await self._request_api("delete", "orderList", signed=True, data=params, version="v3") v3_delete_order_list.__doc__ = Client.v3_delete_order_list.__doc__ async def margin_v1_post_sub_account_sub_account_api_ip_restriction_ip_list(self, **params): return await self._request_margin_api("post", "sub-account/subAccountApi/ipRestriction/ipList", signed=True, data=params, version=1) margin_v1_post_sub_account_sub_account_api_ip_restriction_ip_list.__doc__ = Client.margin_v1_post_sub_account_sub_account_api_ip_restriction_ip_list.__doc__ async def margin_v1_post_broker_sub_account_api_commission(self, **params): return await self._request_margin_api("post", "broker/subAccountApi/commission", signed=True, data=params, version=1) margin_v1_post_broker_sub_account_api_commission.__doc__ = Client.margin_v1_post_broker_sub_account_api_commission.__doc__ async def futures_v1_post_fee_burn(self, **params): return await self._request_futures_api("post", "feeBurn", signed=True, data=params, version=1) futures_v1_post_fee_burn.__doc__ = Client.futures_v1_post_fee_burn.__doc__ async def margin_v1_get_broker_sub_account_margin_summary(self, **params): return await self._request_margin_api("get", "broker/subAccount/marginSummary", signed=True, data=params, version=1) margin_v1_get_broker_sub_account_margin_summary.__doc__ = Client.margin_v1_get_broker_sub_account_margin_summary.__doc__ async def margin_v1_get_lending_auto_invest_plan_list(self, **params): return await self._request_margin_api("get", "lending/auto-invest/plan/list", signed=True, data=params, version=1) margin_v1_get_lending_auto_invest_plan_list.__doc__ = Client.margin_v1_get_lending_auto_invest_plan_list.__doc__ async def margin_v1_get_loan_vip_loanable_data(self, **params): return await self._request_margin_api("get", "loan/vip/loanable/data", signed=True, data=params, version=1) margin_v1_get_loan_vip_loanable_data.__doc__ = Client.margin_v1_get_loan_vip_loanable_data.__doc__ async def margin_v2_get_loan_flexible_collateral_data(self, **params): return await self._request_margin_api("get", "loan/flexible/collateral/data", signed=True, data=params, version=2) margin_v2_get_loan_flexible_collateral_data.__doc__ = Client.margin_v2_get_loan_flexible_collateral_data.__doc__ async def margin_v1_delete_broker_sub_account_api(self, **params): return await self._request_margin_api("delete", "broker/subAccountApi", signed=True, data=params, version=1) margin_v1_delete_broker_sub_account_api.__doc__ = Client.margin_v1_delete_broker_sub_account_api.__doc__ async def margin_v1_get_sol_staking_sol_history_bnsol_rewards_history(self, **params): return await self._request_margin_api("get", "sol-staking/sol/history/bnsolRewardsHistory", signed=True, data=params, version=1) margin_v1_get_sol_staking_sol_history_bnsol_rewards_history.__doc__ = Client.margin_v1_get_sol_staking_sol_history_bnsol_rewards_history.__doc__ async def margin_v1_get_convert_limit_query_open_orders(self, **params): return await self._request_margin_api("get", "convert/limit/queryOpenOrders", signed=True, data=params, version=1) margin_v1_get_convert_limit_query_open_orders.__doc__ = Client.margin_v1_get_convert_limit_query_open_orders.__doc__ async def v3_get_account_commission(self, **params): return await self._request_api("get", "account/commission", signed=True, data=params, version="v3") v3_get_account_commission.__doc__ = Client.v3_get_account_commission.__doc__ async def v3_post_order_list_oco(self, **params): return await self._request_api("post", "orderList/oco", signed=True, data=params, version="v3") async def margin_v1_get_managed_subaccount_query_trans_log(self, **params): return await self._request_margin_api("get", "managed-subaccount/query-trans-log", signed=True, data=params, version=1) margin_v1_get_managed_subaccount_query_trans_log.__doc__ = Client.margin_v1_get_managed_subaccount_query_trans_log.__doc__ async def margin_v2_post_broker_sub_account_api_ip_restriction(self, **params): return await self._request_margin_api("post", "broker/subAccountApi/ipRestriction", signed=True, data=params, version=2) margin_v2_post_broker_sub_account_api_ip_restriction.__doc__ = Client.margin_v2_post_broker_sub_account_api_ip_restriction.__doc__ async def margin_v1_get_lending_auto_invest_all_asset(self, **params): return await self._request_margin_api("get", "lending/auto-invest/all/asset", signed=True, data=params, version=1) margin_v1_get_lending_auto_invest_all_asset.__doc__ = Client.margin_v1_get_lending_auto_invest_all_asset.__doc__ async def futures_v1_post_convert_accept_quote(self, **params): return await self._request_futures_api("post", "convert/acceptQuote", signed=True, data=params, version=1) futures_v1_post_convert_accept_quote.__doc__ = Client.futures_v1_post_convert_accept_quote.__doc__ async def margin_v1_get_spot_delist_schedule(self, **params): return await self._request_margin_api("get", "spot/delist-schedule", signed=True, data=params, version=1) margin_v1_get_spot_delist_schedule.__doc__ = Client.margin_v1_get_spot_delist_schedule.__doc__ async def margin_v1_post_account_api_restrictions_ip_restriction(self, **params): return await self._request_margin_api("post", "account/apiRestrictions/ipRestriction", signed=True, data=params, version=1) margin_v1_post_account_api_restrictions_ip_restriction.__doc__ = Client.margin_v1_post_account_api_restrictions_ip_restriction.__doc__ async def margin_v1_get_dci_product_accounts(self, **params): return await self._request_margin_api("get", "dci/product/accounts", signed=True, data=params, version=1) margin_v1_get_dci_product_accounts.__doc__ = Client.margin_v1_get_dci_product_accounts.__doc__ async def margin_v1_get_sub_account_sub_account_api_ip_restriction(self, **params): return await self._request_margin_api("get", "sub-account/subAccountApi/ipRestriction", signed=True, data=params, version=1) margin_v1_get_sub_account_sub_account_api_ip_restriction.__doc__ = Client.margin_v1_get_sub_account_sub_account_api_ip_restriction.__doc__ async def margin_v1_get_sub_account_transaction_statistics(self, **params): return await self._request_margin_api("get", "sub-account/transaction-statistics", signed=True, data=params, version=1) margin_v1_get_sub_account_transaction_statistics.__doc__ = Client.margin_v1_get_sub_account_transaction_statistics.__doc__ async def margin_v1_get_managed_subaccount_deposit_address(self, **params): return await self._request_margin_api("get", "managed-subaccount/deposit/address", signed=True, data=params, version=1) margin_v1_get_managed_subaccount_deposit_address.__doc__ = Client.margin_v1_get_managed_subaccount_deposit_address.__doc__ async def margin_v2_get_portfolio_account(self, **params): return await self._request_margin_api("get", "portfolio/account", signed=True, data=params, version=2) margin_v2_get_portfolio_account.__doc__ = Client.margin_v2_get_portfolio_account.__doc__ async def margin_v1_get_simple_earn_locked_history_redemption_record(self, **params): return await self._request_margin_api("get", "simple-earn/locked/history/redemptionRecord", signed=True, data=params, version=1) margin_v1_get_simple_earn_locked_history_redemption_record.__doc__ = Client.margin_v1_get_simple_earn_locked_history_redemption_record.__doc__ async def futures_v1_get_order_asyn_id(self, **params): return await self._request_futures_api("get", "order/asyn/id", signed=True, data=params, version=1) futures_v1_get_order_asyn_id.__doc__ = Client.futures_v1_get_order_asyn_id.__doc__ async def margin_v1_post_managed_subaccount_withdraw(self, **params): return await self._request_margin_api("post", "managed-subaccount/withdraw", signed=True, data=params, version=1) margin_v1_post_managed_subaccount_withdraw.__doc__ = Client.margin_v1_post_managed_subaccount_withdraw.__doc__ async def margin_v1_get_localentity_deposit_history(self, **params): return await self._request_margin_api("get", "localentity/deposit/history", signed=True, data=params, version=1) margin_v1_get_localentity_deposit_history.__doc__ = Client.margin_v1_get_localentity_deposit_history.__doc__ async def margin_v1_post_eth_staking_wbeth_wrap(self, **params): return await self._request_margin_api("post", "eth-staking/wbeth/wrap", signed=True, data=params, version=1) margin_v1_post_eth_staking_wbeth_wrap.__doc__ = Client.margin_v1_post_eth_staking_wbeth_wrap.__doc__ async def margin_v1_post_simple_earn_locked_set_redeem_option(self, **params): return await self._request_margin_api("post", "simple-earn/locked/setRedeemOption", signed=True, data=params, version=1) margin_v1_post_simple_earn_locked_set_redeem_option.__doc__ = Client.margin_v1_post_simple_earn_locked_set_redeem_option.__doc__ async def margin_v1_post_broker_sub_account_api_ip_restriction_ip_list(self, **params): return await self._request_margin_api("post", "broker/subAccountApi/ipRestriction/ipList", signed=True, data=params, version=1) margin_v1_post_broker_sub_account_api_ip_restriction_ip_list.__doc__ = Client.margin_v1_post_broker_sub_account_api_ip_restriction_ip_list.__doc__ async def margin_v1_post_broker_sub_account_api_commission_futures(self, **params): return await self._request_margin_api("post", "broker/subAccountApi/commission/futures", signed=True, data=params, version=1) margin_v1_post_broker_sub_account_api_commission_futures.__doc__ = Client.margin_v1_post_broker_sub_account_api_commission_futures.__doc__ async def v3_get_open_orders(self, **params): return await self._request_api("get", "openOrders", signed=True, data=params, version="v3") async def margin_v1_get_lending_auto_invest_history_list(self, **params): return await self._request_margin_api("get", "lending/auto-invest/history/list", signed=True, data=params, version=1) margin_v1_get_lending_auto_invest_history_list.__doc__ = Client.margin_v1_get_lending_auto_invest_history_list.__doc__ async def margin_v1_post_loan_customize_margin_call(self, **params): return await self._request_margin_api("post", "loan/customize/margin_call", signed=True, data=params, version=1) margin_v1_post_loan_customize_margin_call.__doc__ = Client.margin_v1_post_loan_customize_margin_call.__doc__ async def margin_v1_get_broker_sub_account_bnb_burn_status(self, **params): return await self._request_margin_api("get", "broker/subAccount/bnbBurn/status", signed=True, data=params, version=1) margin_v1_get_broker_sub_account_bnb_burn_status.__doc__ = Client.margin_v1_get_broker_sub_account_bnb_burn_status.__doc__ async def margin_v1_get_managed_subaccount_account_snapshot(self, **params): return await self._request_margin_api("get", "managed-subaccount/accountSnapshot", signed=True, data=params, version=1) margin_v1_get_managed_subaccount_account_snapshot.__doc__ = Client.margin_v1_get_managed_subaccount_account_snapshot.__doc__ async def margin_v1_post_asset_convert_transfer(self, **params): return await self._request_margin_api("post", "asset/convert-transfer", signed=True, data=params, version=1) margin_v1_post_asset_convert_transfer.__doc__ = Client.margin_v1_post_asset_convert_transfer.__doc__ async def options_v1_get_income_asyn(self, **params): return await self._request_options_api("get", "income/asyn", signed=True, data=params) options_v1_get_income_asyn.__doc__ = Client.options_v1_get_income_asyn.__doc__ async def margin_v1_get_broker_sub_account_api_commission_coin_futures(self, **params): return await self._request_margin_api("get", "broker/subAccountApi/commission/coinFutures", signed=True, data=params, version=1) margin_v1_get_broker_sub_account_api_commission_coin_futures.__doc__ = Client.margin_v1_get_broker_sub_account_api_commission_coin_futures.__doc__ async def margin_v2_get_broker_sub_account_futures_summary(self, **params): return await self._request_margin_api("get", "broker/subAccount/futuresSummary", signed=True, data=params, version=2) margin_v2_get_broker_sub_account_futures_summary.__doc__ = Client.margin_v2_get_broker_sub_account_futures_summary.__doc__ async def margin_v1_get_loan_ongoing_orders(self, **params): return await self._request_margin_api("get", "loan/ongoing/orders", signed=True, data=params, version=1) margin_v1_get_loan_ongoing_orders.__doc__ = Client.margin_v1_get_loan_ongoing_orders.__doc__ async def margin_v2_get_loan_flexible_ongoing_orders(self, **params): return await self._request_margin_api("get", "loan/flexible/ongoing/orders", signed=True, data=params, version=2) margin_v2_get_loan_flexible_ongoing_orders.__doc__ = Client.margin_v2_get_loan_flexible_ongoing_orders.__doc__ async def margin_v1_post_algo_futures_new_order_vp(self, **params): return await self._request_margin_api("post", "algo/futures/newOrderVp", signed=True, data=params, version=1) margin_v1_post_algo_futures_new_order_vp.__doc__ = Client.margin_v1_post_algo_futures_new_order_vp.__doc__ async def futures_v1_post_convert_get_quote(self, **params): return await self._request_futures_api("post", "convert/getQuote", signed=True, data=params, version=1) futures_v1_post_convert_get_quote.__doc__ = Client.futures_v1_post_convert_get_quote.__doc__ async def margin_v1_get_algo_spot_sub_orders(self, **params): return await self._request_margin_api("get", "algo/spot/subOrders", signed=True, data=params, version=1) margin_v1_get_algo_spot_sub_orders.__doc__ = Client.margin_v1_get_algo_spot_sub_orders.__doc__ async def margin_v1_post_portfolio_redeem(self, **params): return await self._request_margin_api("post", "portfolio/redeem", signed=True, data=params, version=1) margin_v1_post_portfolio_redeem.__doc__ = Client.margin_v1_post_portfolio_redeem.__doc__ async def margin_v1_post_lending_auto_invest_plan_add(self, **params): return await self._request_margin_api("post", "lending/auto-invest/plan/add", signed=True, data=params, version=1) margin_v1_post_lending_auto_invest_plan_add.__doc__ = Client.margin_v1_post_lending_auto_invest_plan_add.__doc__ async def v3_get_order_list(self, **params): return await self._request_api("get", "orderList", signed=True, data=params, version="v3") v3_get_order_list.__doc__ = Client.v3_get_order_list.__doc__ async def v3_get_my_trades(self, **params): return await self._request_api("get", "myTrades", signed=True, data=params, version="v3") async def margin_v1_get_lending_auto_invest_source_asset_list(self, **params): return await self._request_margin_api("get", "lending/auto-invest/source-asset/list", signed=True, data=params, version=1) margin_v1_get_lending_auto_invest_source_asset_list.__doc__ = Client.margin_v1_get_lending_auto_invest_source_asset_list.__doc__ async def margin_v1_get_margin_all_order_list(self, **params): return await self._request_margin_api("get", "margin/allOrderList", signed=True, data=params, version=1) margin_v1_get_margin_all_order_list.__doc__ = Client.margin_v1_get_margin_all_order_list.__doc__ async def margin_v1_post_eth_staking_eth_redeem(self, **params): return await self._request_margin_api("post", "eth-staking/eth/redeem", signed=True, data=params, version=1) margin_v1_post_eth_staking_eth_redeem.__doc__ = Client.margin_v1_post_eth_staking_eth_redeem.__doc__ async def margin_v1_get_broker_rebate_historical_record(self, **params): return await self._request_margin_api("get", "broker/rebate/historicalRecord", signed=True, data=params, version=1) margin_v1_get_broker_rebate_historical_record.__doc__ = Client.margin_v1_get_broker_rebate_historical_record.__doc__ async def margin_v1_get_simple_earn_locked_history_subscription_record(self, **params): return await self._request_margin_api("get", "simple-earn/locked/history/subscriptionRecord", signed=True, data=params, version=1) margin_v1_get_simple_earn_locked_history_subscription_record.__doc__ = Client.margin_v1_get_simple_earn_locked_history_subscription_record.__doc__ async def futures_coin_v1_put_order(self, **params): return await self._request_futures_coin_api("put", "order", signed=True, data=params, version=1) futures_coin_v1_put_order.__doc__ = Client.futures_coin_v1_put_order.__doc__ async def margin_v1_get_managed_subaccount_asset(self, **params): return await self._request_margin_api("get", "managed-subaccount/asset", signed=True, data=params, version=1) margin_v1_get_managed_subaccount_asset.__doc__ = Client.margin_v1_get_managed_subaccount_asset.__doc__ async def margin_v1_get_sol_staking_sol_quota(self, **params): return await self._request_margin_api("get", "sol-staking/sol/quota", signed=True, data=params, version=1) margin_v1_get_sol_staking_sol_quota.__doc__ = Client.margin_v1_get_sol_staking_sol_quota.__doc__ async def margin_v1_post_loan_vip_renew(self, **params): return await self._request_margin_api("post", "loan/vip/renew", signed=True, data=params, version=1) margin_v1_post_loan_vip_renew.__doc__ = Client.margin_v1_post_loan_vip_renew.__doc__ async def margin_v1_get_managed_subaccount_query_trans_log_for_trade_parent(self, **params): return await self._request_margin_api("get", "managed-subaccount/queryTransLogForTradeParent", signed=True, data=params, version=1) margin_v1_get_managed_subaccount_query_trans_log_for_trade_parent.__doc__ = Client.margin_v1_get_managed_subaccount_query_trans_log_for_trade_parent.__doc__ async def margin_v1_post_sub_account_sub_account_api_ip_restriction(self, **params): return await self._request_margin_api("post", "sub-account/subAccountApi/ipRestriction", signed=True, data=params, version=1) margin_v1_post_sub_account_sub_account_api_ip_restriction.__doc__ = Client.margin_v1_post_sub_account_sub_account_api_ip_restriction.__doc__ async def margin_v1_get_simple_earn_flexible_history_redemption_record(self, **params): return await self._request_margin_api("get", "simple-earn/flexible/history/redemptionRecord", signed=True, data=params, version=1) margin_v1_get_simple_earn_flexible_history_redemption_record.__doc__ = Client.margin_v1_get_simple_earn_flexible_history_redemption_record.__doc__ async def margin_v1_get_broker_sub_account_api(self, **params): return await self._request_margin_api("get", "broker/subAccountApi", signed=True, data=params, version=1) margin_v1_get_broker_sub_account_api.__doc__ = Client.margin_v1_get_broker_sub_account_api.__doc__ async def options_v1_get_exercise_history(self, **params): return await self._request_options_api("get", "exerciseHistory", signed=False, data=params) options_v1_get_exercise_history.__doc__ = Client.options_v1_get_exercise_history.__doc__ async def margin_v1_get_convert_exchange_info(self, **params): return await self._request_margin_api("get", "convert/exchangeInfo", signed=False, data=params, version=1) margin_v1_get_convert_exchange_info.__doc__ = Client.margin_v1_get_convert_exchange_info.__doc__ async def futures_v1_delete_batch_order(self, **params): return await self._request_futures_api("delete", "batchOrder", signed=True, data=params, version=1) futures_v1_delete_batch_order.__doc__ = Client.futures_v1_delete_batch_order.__doc__ async def margin_v1_get_eth_staking_eth_history_wbeth_rewards_history(self, **params): return await self._request_margin_api("get", "eth-staking/eth/history/wbethRewardsHistory", signed=True, data=params, version=1) margin_v1_get_eth_staking_eth_history_wbeth_rewards_history.__doc__ = Client.margin_v1_get_eth_staking_eth_history_wbeth_rewards_history.__doc__ async def margin_v1_get_mining_pub_algo_list(self, **params): return await self._request_margin_api("get", "mining/pub/algoList", signed=True, data=params, version=1) margin_v1_get_mining_pub_algo_list.__doc__ = Client.margin_v1_get_mining_pub_algo_list.__doc__ async def options_v1_get_block_trades(self, **params): return await self._request_options_api("get", "blockTrades", signed=False, data=params) options_v1_get_block_trades.__doc__ = Client.options_v1_get_block_trades.__doc__ async def margin_v1_get_copy_trading_futures_lead_symbol(self, **params): return await self._request_margin_api("get", "copyTrading/futures/leadSymbol", signed=True, data=params, version=1) margin_v1_get_copy_trading_futures_lead_symbol.__doc__ = Client.margin_v1_get_copy_trading_futures_lead_symbol.__doc__ async def margin_v1_get_mining_worker_list(self, **params): return await self._request_margin_api("get", "mining/worker/list", signed=True, data=params, version=1) margin_v1_get_mining_worker_list.__doc__ = Client.margin_v1_get_mining_worker_list.__doc__ async def margin_v1_get_dci_product_list(self, **params): return await self._request_margin_api("get", "dci/product/list", signed=True, data=params, version=1) margin_v1_get_dci_product_list.__doc__ = Client.margin_v1_get_dci_product_list.__doc__ async def futures_v1_get_convert_order_status(self, **params): return await self._request_futures_api("get", "convert/orderStatus", signed=True, data=params, version=1) futures_v1_get_convert_order_status.__doc__ = Client.futures_v1_get_convert_order_status.__doc__ ================================================ FILE: binance/base_client.py ================================================ from base64 import b64encode from pathlib import Path import random from typing import Dict, Optional, List, Tuple, Union, Any import asyncio import hashlib import hmac import logging import time from Crypto.PublicKey import RSA, ECC from Crypto.Hash import SHA256 from Crypto.Signature import pkcs1_15, eddsa import urllib.parse as _urlencode from operator import itemgetter from urllib.parse import urlencode from binance.ws.websocket_api import WebsocketAPI from .helpers import get_loop class BaseClient: API_URL = "https://api{}.binance.{}/api" API_TESTNET_URL = "https://testnet.binance.vision/api" API_DEMO_URL = "https://demo-api.binance.com/api" MARGIN_API_URL = "https://api{}.binance.{}/sapi" WEBSITE_URL = "https://www.binance.{}" FUTURES_URL = "https://fapi.binance.{}/fapi" FUTURES_TESTNET_URL = "https://testnet.binancefuture.com/fapi" FUTURES_DEMO_URL = "https://demo-fapi.binance.com/fapi" FUTURES_DATA_URL = "https://fapi.binance.{}/futures/data" FUTURES_DATA_TESTNET_URL = "https://testnet.binancefuture.com/futures/data" FUTURES_COIN_URL = "https://dapi.binance.{}/dapi" FUTURES_COIN_TESTNET_URL = "https://testnet.binancefuture.com/dapi" FUTURES_COIN_DEMO_URL = "https://demo-dapi.binance.com/dapi" FUTURES_COIN_DATA_URL = "https://dapi.binance.{}/futures/data" FUTURES_COIN_DATA_TESTNET_URL = "https://testnet.binancefuture.com/futures/data" OPTIONS_URL = "https://eapi.binance.{}/eapi" OPTIONS_TESTNET_URL = "https://testnet.binanceops.{}/eapi" PAPI_URL = "https://papi.binance.{}/papi" WS_API_URL = "wss://ws-api.binance.{}/ws-api/v3" WS_API_TESTNET_URL = "wss://ws-api.testnet.binance.vision/ws-api/v3" WS_API_DEMO_URL = "wss://demo-ws-api.binance.com/ws-api/v3" WS_FUTURES_URL = "wss://ws-fapi.binance.{}/ws-fapi/v1" WS_FUTURES_TESTNET_URL = "wss://testnet.binancefuture.com/ws-fapi/v1" WS_FUTURES_DEMO_URL = "wss://testnet.binancefuture.com/ws-fapi/v1" PUBLIC_API_VERSION = "v3" PRIVATE_API_VERSION = "v3" MARGIN_API_VERSION = "v1" MARGIN_API_VERSION2 = "v2" MARGIN_API_VERSION3 = "v3" MARGIN_API_VERSION4 = "v4" FUTURES_API_VERSION = "v1" FUTURES_API_VERSION2 = "v2" FUTURES_API_VERSION3 = "v3" OPTIONS_API_VERSION = "v1" PORTFOLIO_API_VERSION = "v1" PORTFOLIO_API_VERSION2 = "v2" BASE_ENDPOINT_DEFAULT = "" BASE_ENDPOINT_1 = "1" BASE_ENDPOINT_2 = "2" BASE_ENDPOINT_3 = "3" BASE_ENDPOINT_4 = "4" REQUEST_TIMEOUT: float = 10 REQUEST_RECVWINDOW: int = 10000 # 10 seconds SYMBOL_TYPE_SPOT = "SPOT" ORDER_STATUS_NEW = "NEW" ORDER_STATUS_PARTIALLY_FILLED = "PARTIALLY_FILLED" ORDER_STATUS_FILLED = "FILLED" ORDER_STATUS_CANCELED = "CANCELED" ORDER_STATUS_PENDING_CANCEL = "PENDING_CANCEL" ORDER_STATUS_REJECTED = "REJECTED" ORDER_STATUS_EXPIRED = "EXPIRED" KLINE_INTERVAL_1SECOND = "1s" KLINE_INTERVAL_1MINUTE = "1m" KLINE_INTERVAL_3MINUTE = "3m" KLINE_INTERVAL_5MINUTE = "5m" KLINE_INTERVAL_15MINUTE = "15m" KLINE_INTERVAL_30MINUTE = "30m" KLINE_INTERVAL_1HOUR = "1h" KLINE_INTERVAL_2HOUR = "2h" KLINE_INTERVAL_4HOUR = "4h" KLINE_INTERVAL_6HOUR = "6h" KLINE_INTERVAL_8HOUR = "8h" KLINE_INTERVAL_12HOUR = "12h" KLINE_INTERVAL_1DAY = "1d" KLINE_INTERVAL_3DAY = "3d" KLINE_INTERVAL_1WEEK = "1w" KLINE_INTERVAL_1MONTH = "1M" SIDE_BUY = "BUY" SIDE_SELL = "SELL" ORDER_TYPE_LIMIT = "LIMIT" ORDER_TYPE_MARKET = "MARKET" ORDER_TYPE_STOP_LOSS = "STOP_LOSS" ORDER_TYPE_STOP_LOSS_LIMIT = "STOP_LOSS_LIMIT" ORDER_TYPE_TAKE_PROFIT = "TAKE_PROFIT" ORDER_TYPE_TAKE_PROFIT_LIMIT = "TAKE_PROFIT_LIMIT" ORDER_TYPE_LIMIT_MAKER = "LIMIT_MAKER" FUTURE_ORDER_TYPE_LIMIT = "LIMIT" FUTURE_ORDER_TYPE_MARKET = "MARKET" FUTURE_ORDER_TYPE_STOP = "STOP" FUTURE_ORDER_TYPE_STOP_MARKET = "STOP_MARKET" FUTURE_ORDER_TYPE_TAKE_PROFIT = "TAKE_PROFIT" FUTURE_ORDER_TYPE_TAKE_PROFIT_MARKET = "TAKE_PROFIT_MARKET" FUTURE_ORDER_TYPE_LIMIT_MAKER = "LIMIT_MAKER" TIME_IN_FORCE_GTC = "GTC" # Good till cancelled TIME_IN_FORCE_IOC = "IOC" # Immediate or cancel TIME_IN_FORCE_FOK = "FOK" # Fill or kill ORDER_RESP_TYPE_ACK = "ACK" ORDER_RESP_TYPE_RESULT = "RESULT" ORDER_RESP_TYPE_FULL = "FULL" # For accessing the data returned by Client.aggregate_trades(). AGG_ID = "a" AGG_PRICE = "p" AGG_QUANTITY = "q" AGG_FIRST_TRADE_ID = "f" AGG_LAST_TRADE_ID = "l" AGG_TIME = "T" AGG_BUYER_MAKES = "m" AGG_BEST_MATCH = "M" # new asset transfer api enum SPOT_TO_FIAT = "MAIN_C2C" SPOT_TO_USDT_FUTURE = "MAIN_UMFUTURE" SPOT_TO_COIN_FUTURE = "MAIN_CMFUTURE" SPOT_TO_MARGIN_CROSS = "MAIN_MARGIN" SPOT_TO_MINING = "MAIN_MINING" FIAT_TO_SPOT = "C2C_MAIN" FIAT_TO_USDT_FUTURE = "C2C_UMFUTURE" FIAT_TO_MINING = "C2C_MINING" USDT_FUTURE_TO_SPOT = "UMFUTURE_MAIN" USDT_FUTURE_TO_FIAT = "UMFUTURE_C2C" USDT_FUTURE_TO_MARGIN_CROSS = "UMFUTURE_MARGIN" COIN_FUTURE_TO_SPOT = "CMFUTURE_MAIN" MARGIN_CROSS_TO_SPOT = "MARGIN_MAIN" MARGIN_CROSS_TO_USDT_FUTURE = "MARGIN_UMFUTURE" MINING_TO_SPOT = "MINING_MAIN" MINING_TO_USDT_FUTURE = "MINING_UMFUTURE" MINING_TO_FIAT = "MINING_C2C" ## order ids SPOT_ORDER_PREFIX = "x-HNA2TXFJ" CONTRACT_ORDER_PREFIX = "x-Cb7ytekJ" def __init__( self, api_key: Optional[str] = None, api_secret: Optional[str] = None, requests_params: Optional[Dict[str, Any]] = None, tld: str = "com", base_endpoint: str = BASE_ENDPOINT_DEFAULT, testnet: bool = False, demo: bool = False, private_key: Optional[Union[str, Path]] = None, private_key_pass: Optional[str] = None, loop: Optional[asyncio.AbstractEventLoop] = None, time_unit: Optional[str] = None, verbose: bool = False, ): """Binance API Client constructor :param api_key: Api Key :type api_key: str. :param api_secret: Api Secret :type api_secret: str. :param requests_params: optional - Dictionary of requests params to use for all calls :type requests_params: dict. :param testnet: Use testnet environment - only available for vanilla options at the moment :type testnet: bool :param private_key: Path to private key, or string of file contents :type private_key: optional - str or Path :param private_key_pass: Password of private key :type private_key_pass: optional - str :param time_unit: Time unit to use for requests. Supported values: "MILLISECOND", "MICROSECOND" :type time_unit: optional - str :param verbose: Enable verbose logging for debugging :type verbose: bool """ self.tld = tld self.verbose = verbose self.logger = logging.getLogger(__name__) # Set logger level based on verbose flag # Users can override this by configuring logging externally if verbose: self.logger.setLevel(logging.DEBUG) self.API_URL = self.API_URL.format(base_endpoint, tld) self.MARGIN_API_URL = self.MARGIN_API_URL.format(base_endpoint, tld) self.WEBSITE_URL = self.WEBSITE_URL.format(tld) self.FUTURES_URL = self.FUTURES_URL.format(tld) self.FUTURES_DATA_URL = self.FUTURES_DATA_URL.format(tld) self.FUTURES_COIN_URL = self.FUTURES_COIN_URL.format(tld) self.FUTURES_COIN_DATA_URL = self.FUTURES_COIN_DATA_URL.format(tld) self.OPTIONS_URL = self.OPTIONS_URL.format(tld) self.OPTIONS_TESTNET_URL = self.OPTIONS_TESTNET_URL.format(tld) self.API_KEY = api_key self.API_SECRET = api_secret self.TIME_UNIT = time_unit self._is_rsa = False self.PRIVATE_KEY: Any = self._init_private_key(private_key, private_key_pass) self.session = self._init_session() self._requests_params = requests_params self.response = None self.testnet = testnet self.demo = demo self.timestamp_offset = 0 ws_api_url = self.WS_API_URL.format(tld) if testnet: ws_api_url = self.WS_API_TESTNET_URL elif demo: ws_api_url = self.WS_API_DEMO_URL if self.TIME_UNIT: ws_api_url += f"?timeUnit={self.TIME_UNIT}" # Extract proxy from requests_params for WebSocket connections https_proxy = None if requests_params and 'proxies' in requests_params: https_proxy = requests_params['proxies'].get('https') or requests_params['proxies'].get('http') self.ws_api = WebsocketAPI(url=ws_api_url, tld=tld, https_proxy=https_proxy) ws_future_url = self.WS_FUTURES_URL.format(tld) if testnet: ws_future_url = self.WS_FUTURES_TESTNET_URL elif demo: ws_future_url = self.WS_FUTURES_DEMO_URL self.ws_future = WebsocketAPI(url=ws_future_url, tld=tld, https_proxy=https_proxy) self.loop = loop or get_loop() def _get_headers(self) -> Dict: headers = { "Accept": "application/json", "Content-Type": "application/json", "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", # noqa } if self.API_KEY: assert self.API_KEY headers["X-MBX-APIKEY"] = self.API_KEY if self.TIME_UNIT: assert self.TIME_UNIT headers["X-MBX-TIME-UNIT"] = self.TIME_UNIT return headers def _init_session(self): raise NotImplementedError def _init_private_key( self, private_key: Optional[Union[str, Path]], private_key_pass: Optional[str] = None, ): if not private_key: return if isinstance(private_key, Path): with open(private_key, "r") as f: private_key = f.read() if len(private_key) > 120: self._is_rsa = True return RSA.import_key(private_key, passphrase=private_key_pass) return ECC.import_key(private_key) def _create_api_uri( self, path: str, signed: bool = True, version: str = PUBLIC_API_VERSION ) -> str: url = self.API_URL if self.testnet: url = self.API_TESTNET_URL elif self.demo: url = self.API_DEMO_URL v = self.PRIVATE_API_VERSION if signed else version return url + "/" + v + "/" + path def _create_margin_api_uri(self, path: str, version: int = 1) -> str: options = { 1: self.MARGIN_API_VERSION, 2: self.MARGIN_API_VERSION2, 3: self.MARGIN_API_VERSION3, 4: self.MARGIN_API_VERSION4, } return self.MARGIN_API_URL + "/" + options[version] + "/" + path def _create_papi_api_uri(self, path: str, version: int = 1) -> str: options = {1: self.PORTFOLIO_API_VERSION, 2: self.PORTFOLIO_API_VERSION2} return self.PAPI_URL.format(self.tld) + "/" + options[version] + "/" + path def _create_website_uri(self, path: str) -> str: return self.WEBSITE_URL + "/" + path def _create_futures_api_uri(self, path: str, version: int = 1) -> str: url = self.FUTURES_URL if self.testnet: url = self.FUTURES_TESTNET_URL elif self.demo: url = self.FUTURES_DEMO_URL options = { 1: self.FUTURES_API_VERSION, 2: self.FUTURES_API_VERSION2, 3: self.FUTURES_API_VERSION3, } return url + "/" + options[version] + "/" + path def _create_futures_data_api_uri(self, path: str) -> str: url = self.FUTURES_DATA_URL if self.testnet: url = self.FUTURES_DATA_TESTNET_URL return url + "/" + path def _create_futures_coin_api_url(self, path: str, version: int = 1) -> str: url = self.FUTURES_COIN_URL if self.testnet: url = self.FUTURES_COIN_TESTNET_URL elif self.demo: url = self.FUTURES_COIN_DEMO_URL options = { 1: self.FUTURES_API_VERSION, 2: self.FUTURES_API_VERSION2, 3: self.FUTURES_API_VERSION3, } return url + "/" + options[version] + "/" + path def _create_futures_coin_data_api_url(self, path: str, version: int = 1) -> str: url = self.FUTURES_COIN_DATA_URL if self.testnet: url = self.FUTURES_COIN_DATA_TESTNET_URL return url + "/" + path def _create_options_api_uri(self, path: str) -> str: url = self.OPTIONS_URL if self.testnet: url = self.OPTIONS_TESTNET_URL return url + "/" + self.OPTIONS_API_VERSION + "/" + path def _rsa_signature(self, query_string: str): assert self.PRIVATE_KEY h = SHA256.new(query_string.encode("utf-8")) signature = pkcs1_15.new(self.PRIVATE_KEY).sign(h) # type: ignore res = b64encode(signature).decode() # return self.encode_uri_component(res) return res @staticmethod def encode_uri_component(uri, safe="~()*!.'"): return _urlencode.quote(uri, safe=safe) @staticmethod def convert_to_dict(list_tuples): dictionary = dict((key, value) for key, value in list_tuples) return dictionary def _require_tld(self, required_tld: str, endpoint_name: str = "endpoint") -> None: """Validate client is configured for required TLD. :param required_tld: The required TLD (e.g., "us") :param endpoint_name: Description of the endpoint for error messages :raises BinanceRegionException: If the client TLD doesn't match """ if self.tld != required_tld: from binance.exceptions import BinanceRegionException raise BinanceRegionException(required_tld, self.tld, endpoint_name) def _ed25519_signature(self, query_string: str): assert self.PRIVATE_KEY res = b64encode( eddsa.new(self.PRIVATE_KEY, "rfc8032").sign(query_string.encode()) ).decode() # type: ignore # return self.encode_uri_component(res) return res def _hmac_signature(self, query_string: str) -> str: assert self.API_SECRET, "API Secret required for private endpoints" m = hmac.new( self.API_SECRET.encode("utf-8"), query_string.encode("utf-8"), hashlib.sha256, ) return m.hexdigest() def _generate_signature(self, data: Dict, uri_encode=True) -> str: sig_func = self._hmac_signature if self.PRIVATE_KEY: if self._is_rsa: sig_func = self._rsa_signature else: sig_func = self._ed25519_signature query_string = "&".join([f"{d[0]}={_urlencode.quote(d[1]) if d[0] == 'symbol' else d[1]}" for d in self._order_params(data)]) res = sig_func(query_string) return self.encode_uri_component(res) if uri_encode else res def _sign_ws_params(self, params, signature_func): if "signature" in params: return params params.setdefault("apiKey", self.API_KEY) params.setdefault("timestamp", int(time.time() * 1000 + self.timestamp_offset)) params = dict(sorted(params.items())) return {**params, "signature": signature_func(params)} def _generate_ws_api_signature(self, data: Dict) -> str: sig_func = self._hmac_signature if self.PRIVATE_KEY: if self._is_rsa: sig_func = self._rsa_signature else: sig_func = self._ed25519_signature query_string = urlencode(data) return sig_func(query_string) async def _ws_futures_api_request(self, method: str, signed: bool, params: dict): """Send request and wait for response""" id = params.pop("id", self.uuid22()) payload = { "id": id, "method": method, "params": params, } if signed: payload["params"] = self._sign_ws_params(params, self._generate_signature) return await self.ws_future.request(id, payload) def _ws_futures_api_request_sync(self, method: str, signed: bool, params: dict): self.loop = get_loop() return self.loop.run_until_complete( self._ws_futures_api_request(method, signed, params) ) async def _make_sync(self, method): return asyncio.run(method) async def _ws_api_request(self, method: str, signed: bool, params: dict): """Send request and wait for response""" id = params.pop("id", self.uuid22()) payload = { "id": id, "method": method, "params": params, } if signed: payload["params"] = self._sign_ws_params( params, self._generate_ws_api_signature ) return await self.ws_api.request(id, payload) def _ws_api_request_sync(self, method: str, signed: bool, params: dict): """Send request to WS API and wait for response""" self.loop = get_loop() return self.loop.run_until_complete( self._ws_api_request(method, signed, params) ) @staticmethod def _get_version(version: int, **kwargs) -> int: if "data" in kwargs and "version" in kwargs["data"]: version_override = kwargs["data"].get("version") del kwargs["data"]["version"] return version_override return version @staticmethod def uuid22(length=22): return format(random.getrandbits(length * 4), "x") @staticmethod def _order_params(data: Dict) -> List[Tuple[str, str]]: """Convert params to list with signature as last element :param data: :return: """ data = dict(filter(lambda el: el[1] is not None, data.items())) has_signature = False params = [] for key, value in data.items(): if key == "signature": has_signature = True else: params.append((key, str(value))) # sort parameters by key params.sort(key=itemgetter(0)) if has_signature: params.append(("signature", data["signature"])) return params def _get_request_kwargs( self, method, signed: bool, force_params: bool = False, **kwargs ) -> Dict: # set default requests timeout kwargs["timeout"] = self.REQUEST_TIMEOUT # add our global requests params if self._requests_params: kwargs.update(self._requests_params) data = kwargs.get("data", None) if data and isinstance(data, dict): kwargs["data"] = data # find any requests params passed and apply them if "requests_params" in kwargs["data"]: # merge requests params into kwargs kwargs.update(kwargs["data"]["requests_params"]) del kwargs["data"]["requests_params"] if signed: # generate signature kwargs["data"]["timestamp"] = int( time.time() * 1000 + self.timestamp_offset ) if self.REQUEST_RECVWINDOW: kwargs["data"]["recvWindow"] = self.REQUEST_RECVWINDOW kwargs["data"]["signature"] = self._generate_signature(kwargs["data"]) # sort get and post params to match signature order if data: # sort post params and remove any arguments with values of None kwargs["data"] = self._order_params(kwargs["data"]) # Remove any arguments with values of None. null_args = [ i for i, (key, value) in enumerate(kwargs["data"]) if value is None ] for i in reversed(null_args): del kwargs["data"][i] # if get request assign data array to params value for requests lib if data and (method == "get" or force_params): kwargs["params"] = "&".join( "%s=%s" % (data[0], _urlencode.quote(data[1]) if data[0] == 'symbol' else data[1]) for data in kwargs["data"] ) del kwargs["data"] # Temporary fix for Signature issue while using batchOrders in AsyncClient if "params" in kwargs.keys(): if ( "batchOrders" in kwargs["params"] or "orderidlist" in kwargs["params"] or "origclientorderidlist" in kwargs["params"] ): kwargs["data"] = kwargs["params"] del kwargs["params"] return kwargs ================================================ FILE: binance/client.py ================================================ from pathlib import Path from typing import Dict, Optional, List, Union, Any import requests import time import warnings from urllib.parse import urlencode, quote from .base_client import BaseClient from .helpers import ( convert_list_to_json_array, interval_to_milliseconds, convert_ts_str, ) from .exceptions import ( BinanceAPIException, BinanceRequestException, NotImplementedException, ) from .enums import HistoricalKlinesType class Client(BaseClient): def __init__( self, api_key: Optional[str] = None, api_secret: Optional[str] = None, requests_params: Optional[Dict[str, Any]] = None, tld: str = "com", base_endpoint: str = BaseClient.BASE_ENDPOINT_DEFAULT, testnet: bool = False, demo: bool = False, private_key: Optional[Union[str, Path]] = None, private_key_pass: Optional[str] = None, ping: Optional[bool] = True, time_unit: Optional[str] = None, verbose: bool = False, ): super().__init__( api_key, api_secret, requests_params, tld, base_endpoint, testnet, demo, private_key, private_key_pass, time_unit=time_unit, verbose=verbose, ) # init DNS and SSL cert if ping: self.ping() def _init_session(self) -> requests.Session: headers = self._get_headers() session = requests.session() session.headers.update(headers) return session def _request( self, method, uri: str, signed: bool, force_params: bool = False, **kwargs ): headers = {} if method.upper() in ["POST", "PUT", "DELETE"]: headers.update({"Content-Type": "application/x-www-form-urlencoded"}) if "data" in kwargs: for key in kwargs["data"]: if key == "headers": headers.update(kwargs["data"][key]) del kwargs["data"][key] break kwargs = self._get_request_kwargs(method, signed, force_params, **kwargs) data = kwargs.get("data") if data is not None: del kwargs["data"] if signed and self.PRIVATE_KEY and data: # handle issues with signing using eddsa/rsa and POST requests dict_data = Client.convert_to_dict(data) signature = dict_data["signature"] if "signature" in dict_data else None if signature: del dict_data["signature"] url_encoded_data = urlencode(dict_data) data = f"{url_encoded_data}&signature={signature}" self.response = getattr(self.session, method)(uri, headers=headers, data=data, **kwargs) if self.verbose: self.logger.debug( "\nRequest: %s %s\nRequestHeaders: %s\nRequestBody: %s\nResponse: %s\nResponseHeaders: %s\nResponseBody: %s", method.upper(), uri, headers, data, self.response.status_code, dict(self.response.headers), self.response.text[:1000] if self.response.text else None ) return self._handle_response(self.response) @staticmethod def _handle_response(response: requests.Response): """Internal helper for handling API responses from the Binance server. Raises the appropriate exceptions when necessary; otherwise, returns the response. """ if not (200 <= response.status_code < 300): raise BinanceAPIException(response, response.status_code, response.text) if response.text == "": return {} try: return response.json() except ValueError: raise BinanceRequestException("Invalid Response: %s" % response.text) def _request_api( self, method, path: str, signed: bool = False, version=BaseClient.PUBLIC_API_VERSION, **kwargs, ): uri = self._create_api_uri(path, signed, version) return self._request(method, uri, signed, **kwargs) def _request_futures_api( self, method, path, signed=False, version: int = 1, **kwargs ) -> Dict: version = self._get_version(version, **kwargs) uri = self._create_futures_api_uri(path, version) force_params = kwargs.pop("force_params", False) return self._request(method, uri, signed, force_params, **kwargs) def _request_futures_data_api(self, method, path, signed=False, **kwargs) -> Dict: uri = self._create_futures_data_api_uri(path) force_params = kwargs.pop("force_params", True) return self._request(method, uri, signed, force_params, **kwargs) def _request_futures_coin_api( self, method, path, signed=False, version=1, **kwargs ) -> Dict: version = self._get_version(version, **kwargs) uri = self._create_futures_coin_api_url(path, version=version) force_params = kwargs.pop("force_params", False) return self._request(method, uri, signed, force_params, **kwargs) def _request_futures_coin_data_api( self, method, path, signed=False, version=1, **kwargs ) -> Dict: version = self._get_version(version, **kwargs) uri = self._create_futures_coin_data_api_url(path, version=version) force_params = kwargs.pop("force_params", True) return self._request(method, uri, signed, force_params, **kwargs) def _request_options_api(self, method, path, signed=False, **kwargs) -> Dict: """ https://developers.binance.com/docs/derivatives/option/market-data """ uri = self._create_options_api_uri(path) force_params = kwargs.pop("force_params", True) return self._request(method, uri, signed, force_params, **kwargs) def _request_margin_api( self, method, path, signed=False, version=1, **kwargs ) -> Dict: version = self._get_version(version, **kwargs) uri = self._create_margin_api_uri(path, version) force_params = kwargs.pop("force_params", False) return self._request(method, uri, signed, force_params, **kwargs) def _request_papi_api( self, method, path, signed=False, version=1, **kwargs ) -> Dict: version = self._get_version(version, **kwargs) uri = self._create_papi_api_uri(path, version) force_params = kwargs.pop("force_params", False) return self._request(method, uri, signed, force_params, **kwargs) def _request_website(self, method, path, signed=False, **kwargs) -> Dict: uri = self._create_website_uri(path) return self._request(method, uri, signed, **kwargs) def _get(self, path, signed=False, version=BaseClient.PUBLIC_API_VERSION, **kwargs): return self._request_api("get", path, signed, version, **kwargs) def _post( self, path, signed=False, version=BaseClient.PUBLIC_API_VERSION, **kwargs ) -> Dict: return self._request_api("post", path, signed, version, **kwargs) def _put( self, path, signed=False, version=BaseClient.PUBLIC_API_VERSION, **kwargs ) -> Dict: return self._request_api("put", path, signed, version, **kwargs) def _delete( self, path, signed=False, version=BaseClient.PUBLIC_API_VERSION, **kwargs ) -> Dict: return self._request_api("delete", path, signed, version, **kwargs) # Exchange Endpoints def get_products(self) -> Dict: """Return list of products currently listed on Binance Use get_exchange_info() call instead :returns: list - List of product dictionaries :raises: BinanceRequestException, BinanceAPIException """ products = self._request_website( "get", "bapi/asset/v2/public/asset-service/product/get-products?includeEtf=true", ) return products def get_exchange_info(self) -> Dict: """Return rate limits and list of symbols https://developers.binance.com/docs/binance-spot-api-docs/rest-api/general-endpoints#exchange-information :returns: list - List of product dictionaries .. code-block:: python { "timezone": "UTC", "serverTime": 1508631584636, "rateLimits": [ { "rateLimitType": "REQUESTS", "interval": "MINUTE", "limit": 1200 }, { "rateLimitType": "ORDERS", "interval": "SECOND", "limit": 10 }, { "rateLimitType": "ORDERS", "interval": "DAY", "limit": 100000 } ], "exchangeFilters": [], "symbols": [ { "symbol": "ETHBTC", "status": "TRADING", "baseAsset": "ETH", "baseAssetPrecision": 8, "quoteAsset": "BTC", "quotePrecision": 8, "orderTypes": ["LIMIT", "MARKET"], "icebergAllowed": false, "filters": [ { "filterType": "PRICE_FILTER", "minPrice": "0.00000100", "maxPrice": "100000.00000000", "tickSize": "0.00000100" }, { "filterType": "LOT_SIZE", "minQty": "0.00100000", "maxQty": "100000.00000000", "stepSize": "0.00100000" }, { "filterType": "MIN_NOTIONAL", "minNotional": "0.00100000" } ] } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._get("exchangeInfo") def get_symbol_info(self, symbol) -> Optional[Dict]: """Return information about a symbol https://developers.binance.com/docs/binance-spot-api-docs/rest-api/general-endpoints#exchange-information :param symbol: required e.g. BNBBTC :type symbol: str :returns: Dict if found, None if not .. code-block:: python { "symbol": "ETHBTC", "status": "TRADING", "baseAsset": "ETH", "baseAssetPrecision": 8, "quoteAsset": "BTC", "quotePrecision": 8, "orderTypes": ["LIMIT", "MARKET"], "icebergAllowed": false, "filters": [ { "filterType": "PRICE_FILTER", "minPrice": "0.00000100", "maxPrice": "100000.00000000", "tickSize": "0.00000100" }, { "filterType": "LOT_SIZE", "minQty": "0.00100000", "maxQty": "100000.00000000", "stepSize": "0.00100000" }, { "filterType": "MIN_NOTIONAL", "minNotional": "0.00100000" } ] } :raises: BinanceRequestException, BinanceAPIException """ res = self.get_exchange_info() for item in res["symbols"]: if item["symbol"] == symbol.upper(): return item return None # General Endpoints def ping(self) -> Dict: """Test connectivity to the Rest API. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/general-endpoints#test-connectivity :returns: Empty array .. code-block:: python {} :raises: BinanceRequestException, BinanceAPIException """ return self._get("ping") def get_server_time(self) -> Dict: """Test connectivity to the Rest API and get the current server time. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/general-endpoints#check-server-time :returns: Current server time .. code-block:: python { "serverTime": 1499827319559 } :raises: BinanceRequestException, BinanceAPIException """ return self._get("time") # Market Data Endpoints def get_all_tickers(self) -> List[Dict[str, str]]: """Latest price for all symbols. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#symbol-price-ticker :returns: List of market tickers .. code-block:: python [ { "symbol": "LTCBTC", "price": "4.00000200" }, { "symbol": "ETHBTC", "price": "0.07946600" } ] :raises: BinanceRequestException, BinanceAPIException """ response = self._get("ticker/price") if isinstance(response, list) and all(isinstance(item, dict) for item in response): return response raise TypeError("Expected a list of dictionaries") def get_orderbook_tickers(self, **params) -> Dict: """Best price/qty on the order book for all symbols. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#symbol-order-book-ticker :param symbol: optional :type symbol: str :param symbols: optional accepted format ["BTCUSDT","BNBUSDT"] or %5B%22BTCUSDT%22,%22BNBUSDT%22%5D :type symbols: str :returns: List of order book market entries .. code-block:: python [ { "symbol": "LTCBTC", "bidPrice": "4.00000000", "bidQty": "431.00000000", "askPrice": "4.00000200", "askQty": "9.00000000" }, { "symbol": "ETHBTC", "bidPrice": "0.07946700", "bidQty": "9.00000000", "askPrice": "100000.00000000", "askQty": "1000.00000000" } ] :raises: BinanceRequestException, BinanceAPIException """ data = {} if "symbol" in params: data["symbol"] = params["symbol"] elif "symbols" in params: data["symbols"] = params["symbols"] return self._get( "ticker/bookTicker", data=data ) def get_order_book(self, **params) -> Dict: """Get the Order Book for the market https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#order-book :param symbol: required :type symbol: str :param limit: Default 100; max 1000 :type limit: int :returns: API response .. code-block:: python { "lastUpdateId": 1027024, "bids": [ [ "4.00000000", # PRICE "431.00000000", # QTY [] # Can be ignored ] ], "asks": [ [ "4.00000200", "12.00000000", [] ] ] } :raises: BinanceRequestException, BinanceAPIException """ return self._get("depth", data=params) def get_recent_trades(self, **params) -> Dict: """Get recent trades (up to last 500). https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#recent-trades-list :param symbol: required :type symbol: str :param limit: Default 500; max 1000. :type limit: int :returns: API response .. code-block:: python [ { "id": 28457, "price": "4.00000100", "qty": "12.00000000", "time": 1499865549590, "isBuyerMaker": true, "isBestMatch": true } ] :raises: BinanceRequestException, BinanceAPIException """ return self._get("trades", data=params) def get_historical_trades(self, **params) -> Dict: """Get older trades. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#old-trade-lookup :param symbol: required :type symbol: str :param limit: Default 500; max 1000. :type limit: int :param fromId: TradeId to fetch from. Default gets most recent trades. :type fromId: str :returns: API response .. code-block:: python [ { "id": 28457, "price": "4.00000100", "qty": "12.00000000", "time": 1499865549590, "isBuyerMaker": true, "isBestMatch": true } ] :raises: BinanceRequestException, BinanceAPIException """ return self._get( "historicalTrades", data=params ) def get_aggregate_trades(self, **params) -> Dict: """Get compressed, aggregate trades. Trades that fill at the time, from the same order, with the same price will have the quantity aggregated. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#compressedaggregate-trades-list :param symbol: required :type symbol: str :param fromId: ID to get aggregate trades from INCLUSIVE. :type fromId: str :param startTime: Timestamp in ms to get aggregate trades from INCLUSIVE. :type startTime: int :param endTime: Timestamp in ms to get aggregate trades until INCLUSIVE. :type endTime: int :param limit: Default 500; max 1000. :type limit: int :returns: API response .. code-block:: python [ { "a": 26129, # Aggregate tradeId "p": "0.01633102", # Price "q": "4.70443515", # Quantity "f": 27781, # First tradeId "l": 27781, # Last tradeId "T": 1498793709153, # Timestamp "m": true, # Was the buyer the maker? "M": true # Was the trade the best price match? } ] :raises: BinanceRequestException, BinanceAPIException """ return self._get("aggTrades", data=params) def aggregate_trade_iter(self, symbol: str, start_str=None, last_id=None): """Iterate over aggregate trade data from (start_time or last_id) to the end of the history so far. If start_time is specified, start with the first trade after start_time. Meant to initialise a local cache of trade data. If last_id is specified, start with the trade after it. This is meant for updating a pre-existing local trade data cache. Only allows start_str or last_id—not both. Not guaranteed to work right if you're running more than one of these simultaneously. You will probably hit your rate limit. See dateparser docs for valid start and end string formats http://dateparser.readthedocs.io/en/latest/ If using offset strings for dates add "UTC" to date string e.g. "now UTC", "11 hours ago UTC" :param symbol: Symbol string e.g. ETHBTC :type symbol: str :param start_str: Start date string in UTC format or timestamp in milliseconds. The iterator will return the first trade occurring later than this time. :type start_str: str|int :param last_id: aggregate trade ID of the last known aggregate trade. Not a regular trade ID. See https://binance-docs.github.io/apidocs/spot/en/#compressed-aggregate-trades-list :returns: an iterator of JSON objects, one per trade. The format of each object is identical to Client.aggregate_trades(). :type last_id: int """ if start_str is not None and last_id is not None: raise ValueError( "start_time and last_id may not be simultaneously specified." ) # If there's no last_id, get one. if last_id is None: # Without a last_id, we actually need the first trade. Normally, # we'd get rid of it. See the next loop. if start_str is None: trades = self.get_aggregate_trades(symbol=symbol, fromId=0) else: # The difference between startTime and endTime should be less # or equal than an hour and the result set should contain at # least one trade. start_ts = convert_ts_str(start_str) # If the resulting set is empty (i.e. no trades in that interval) # then we just move forward hour by hour until we find at least one # trade or reach present moment while True: end_ts = start_ts + (60 * 60 * 1000) trades = self.get_aggregate_trades( symbol=symbol, startTime=start_ts, endTime=end_ts ) if len(trades) > 0: break # If we reach present moment and find no trades then there is # nothing to iterate, so we're done if end_ts > int(time.time() * 1000): return start_ts = end_ts for t in trades: yield t last_id = trades[-1][self.AGG_ID] while True: # There is no need to wait between queries, to avoid hitting the # rate limit. We're using blocking IO, and as long as we're the # only thread running calls like this, Binance will automatically # add the right delay time on their end, forcing us to wait for # data. That really simplifies this function's job. Binance is # fucking awesome. trades = self.get_aggregate_trades(symbol=symbol, fromId=last_id) # fromId=n returns a set starting with id n, but we already have # that one. So get rid of the first item in the result set. trades = trades[1:] if len(trades) == 0: return for t in trades: yield t last_id = trades[-1][self.AGG_ID] def get_ui_klines(self, **params) -> Dict: """Kline/candlestick bars for a symbol with UI enhancements. Klines are uniquely identified by their open time. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#uiklines :param symbol: required :type symbol: str :param interval: required - The interval for the klines (e.g., 1m, 3m, 5m, etc.) :type interval: str :param limit: optional - Default 500; max 1000. :type limit: int :param startTime: optional - Start time in milliseconds :type startTime: int :param endTime: optional - End time in milliseconds :type endTime: int :returns: API response .. code-block:: python [ [ 1499040000000, # Open time "0.01634790", # Open "0.80000000", # High "0.01575800", # Low "0.01577100", # Close "148976.11427815", # Volume 1499644799999, # Close time "2434.19055334", # Quote asset volume 308, # Number of trades "1756.87402397", # Taker buy base asset volume "28.46694368", # Taker buy quote asset volume "17928899.62484339" # Can be ignored ] ] :raises: BinanceRequestException, BinanceAPIException """ return self._get("uiKlines", data=params) def get_klines(self, **params) -> Dict: """Kline/candlestick bars for a symbol. Klines are uniquely identified by their open time. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#klinecandlestick-data :param symbol: required :type symbol: str :param interval: - :type interval: str :param limit: - Default 500; max 1000. :type limit: int :param startTime: :type startTime: int :param endTime: :type endTime: int :returns: API response .. code-block:: python [ [ 1499040000000, # Open time "0.01634790", # Open "0.80000000", # High "0.01575800", # Low "0.01577100", # Close "148976.11427815", # Volume 1499644799999, # Close time "2434.19055334", # Quote asset volume 308, # Number of trades "1756.87402397", # Taker buy base asset volume "28.46694368", # Taker buy quote asset volume "17928899.62484339" # Can be ignored ] ] :raises: BinanceRequestException, BinanceAPIException """ return self._get("klines", data=params) def _klines( self, klines_type: HistoricalKlinesType = HistoricalKlinesType.SPOT, **params ) -> Dict: """Get klines of spot (get_klines) or futures (futures_klines) endpoints. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#klinecandlestick-data https://developers.binance.com/docs/derivatives/option/market-data/Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Index-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Mark-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Premium-Index-Kline-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Index-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Mark-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Premium-Index-Kline-Data :param klines_type: Historical klines type: SPOT or FUTURES :type klines_type: HistoricalKlinesType :return: klines, see get_klines """ if "endTime" in params and not params["endTime"]: del params["endTime"] if HistoricalKlinesType.SPOT == klines_type: return self.get_klines(**params) elif HistoricalKlinesType.FUTURES == klines_type: return self.futures_klines(**params) elif HistoricalKlinesType.FUTURES_COIN == klines_type: return self.futures_coin_klines(**params) elif HistoricalKlinesType.FUTURES_MARK_PRICE == klines_type: return self.futures_mark_price_klines(**params) elif HistoricalKlinesType.FUTURES_INDEX_PRICE == klines_type: return self.futures_index_price_klines(**params) elif HistoricalKlinesType.FUTURES_COIN_MARK_PRICE == klines_type: return self.futures_coin_mark_price_klines(**params) elif HistoricalKlinesType.FUTURES_COIN_INDEX_PRICE == klines_type: return self.futures_coin_index_price_klines(**params) else: raise NotImplementedException(klines_type) def _get_earliest_valid_timestamp( self, symbol, interval, klines_type: HistoricalKlinesType = HistoricalKlinesType.SPOT, ): """Get the earliest valid open timestamp from Binance https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#klinecandlestick-data https://developers.binance.com/docs/derivatives/option/market-data/Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Index-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Mark-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Premium-Index-Kline-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Index-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Mark-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Premium-Index-Kline-Data :param symbol: Name of symbol pair e.g. BNBBTC :type symbol: str :param interval: Binance Kline interval :type interval: str :param klines_type: Historical klines type: SPOT or FUTURES :type klines_type: HistoricalKlinesType :return: first valid timestamp """ kline = self._klines( klines_type=klines_type, symbol=symbol, interval=interval, limit=1, startTime=0, endTime=int(time.time() * 1000), ) return kline[0][0] def get_historical_klines( self, symbol, interval, start_str=None, end_str=None, limit=None, klines_type: HistoricalKlinesType = HistoricalKlinesType.SPOT, ): """Get Historical Klines from Binance https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#klinecandlestick-data https://developers.binance.com/docs/derivatives/option/market-data/Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Index-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Mark-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Premium-Index-Kline-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Index-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Mark-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Premium-Index-Kline-Data :param symbol: Name of symbol pair e.g. BNBBTC :type symbol: str :param interval: Binance Kline interval :type interval: str :param start_str: optional - start date string in UTC format or timestamp in milliseconds :type start_str: str|int :param end_str: optional - end date string in UTC format or timestamp in milliseconds (default will fetch everything up to now) :type end_str: str|int :param limit: Default 1000; max 1000. :type limit: int :param klines_type: Historical klines type: SPOT or FUTURES :type klines_type: HistoricalKlinesType :return: list of OHLCV values (Open time, Open, High, Low, Close, Volume, Close time, Quote asset volume, Number of trades, Taker buy base asset volume, Taker buy quote asset volume, Ignore) """ return self._historical_klines( symbol, interval, start_str=start_str, end_str=end_str, limit=limit, klines_type=klines_type, ) def _historical_klines( self, symbol, interval, start_str=None, end_str=None, limit=None, klines_type: HistoricalKlinesType = HistoricalKlinesType.SPOT, ): """Get Historical Klines from Binance (spot or futures) See dateparser docs for valid start and end string formats https://dateparser.readthedocs.io/en/latest/ If using offset strings for dates add "UTC" to date string e.g. "now UTC", "11 hours ago UTC" :param symbol: Name of symbol pair e.g. BNBBTC :type symbol: str :param interval: Binance Kline interval :type interval: str :param start_str: optional - start date string in UTC format or timestamp in milliseconds :type start_str: str|int :param end_str: optional - end date string in UTC format or timestamp in milliseconds (default will fetch everything up to now) :type end_str: None|str|int :param limit: Default 1000; max 1000. :type limit: int :param klines_type: Historical klines type: SPOT or FUTURES :type klines_type: HistoricalKlinesType :return: list of OHLCV values (Open time, Open, High, Low, Close, Volume, Close time, Quote asset volume, Number of trades, Taker buy base asset volume, Taker buy quote asset volume, Ignore) """ initial_limit_set = True if limit is None: limit = 1000 initial_limit_set = False # init our list output_data = [] # convert interval to useful value in seconds timeframe = interval_to_milliseconds(interval) # if a start time was passed convert it start_ts = convert_ts_str(start_str) # establish first available start timestamp if start_ts is not None: first_valid_ts = self._get_earliest_valid_timestamp( symbol, interval, klines_type ) start_ts = max(start_ts, first_valid_ts) # if an end time was passed convert it end_ts = convert_ts_str(end_str) if end_ts and start_ts and end_ts <= start_ts: return output_data idx = 0 while True: # fetch the klines from start_ts up to max 500 entries or the end_ts if set temp_data = self._klines( klines_type=klines_type, symbol=symbol, interval=interval, limit=limit, startTime=start_ts, endTime=end_ts, ) # append this loops data to our output data if temp_data: output_data += temp_data # check if output_data is greater than limit and truncate if needed and break loop if initial_limit_set and len(output_data) > limit: output_data = output_data[:limit] break # handle the case where exactly the limit amount of data was returned last loop # check if we received less than the required limit and exit the loop if not len(temp_data) or len(temp_data) < limit: # exit the while loop break # increment next call by our timeframe start_ts = temp_data[-1][0] + timeframe # exit loop if we reached end_ts before reaching klines if end_ts and start_ts >= end_ts: break # sleep after every 3rd call to be kind to the API idx += 1 if idx % 3 == 0: time.sleep(1) return output_data def get_historical_klines_generator( self, symbol, interval, start_str=None, end_str=None, limit=None, klines_type: HistoricalKlinesType = HistoricalKlinesType.SPOT, ): """Get Historical Klines generator from Binance https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#klinecandlestick-data https://developers.binance.com/docs/derivatives/option/market-data/Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Index-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Mark-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Premium-Index-Kline-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Index-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Mark-Price-Kline-Candlestick-Data https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Premium-Index-Kline-Data :param symbol: Name of symbol pair e.g. BNBBTC :type symbol: str :param interval: Binance Kline interval :type interval: str :param start_str: optional - Start date string in UTC format or timestamp in milliseconds :type start_str: str|int :param end_str: optional - end date string in UTC format or timestamp in milliseconds (default will fetch everything up to now) :type end_str: str|int :param limit: amount of candles to return per request (default 1000) :type limit: int :param klines_type: Historical klines type: SPOT or FUTURES :type klines_type: HistoricalKlinesType :return: generator of OHLCV values """ return self._historical_klines_generator( symbol, interval, start_str, end_str, limit, klines_type=klines_type ) def _historical_klines_generator( self, symbol, interval, start_str=None, end_str=None, limit=None, klines_type: HistoricalKlinesType = HistoricalKlinesType.SPOT, ): """Get Historical Klines generator from Binance (spot or futures) See dateparser docs for valid start and end string formats https://dateparser.readthedocs.io/en/latest/ If using offset strings for dates add "UTC" to date string e.g. "now UTC", "11 hours ago UTC" :param symbol: Name of symbol pair e.g. BNBBTC :type symbol: str :param interval: Binance Kline interval :type interval: str :param start_str: optional - Start date string in UTC format or timestamp in milliseconds :type start_str: str|int :param end_str: optional - end date string in UTC format or timestamp in milliseconds (default will fetch everything up to now) :type end_str: str|int :param klines_type: Historical klines type: SPOT or FUTURES :type klines_type: HistoricalKlinesType :return: generator of OHLCV values """ initial_limit_set = True if limit is None: limit = 1000 initial_limit_set = False # convert interval to useful value in seconds timeframe = interval_to_milliseconds(interval) # if a start time was passed convert it start_ts = convert_ts_str(start_str) # establish first available start timestamp if start_ts is not None: first_valid_ts = self._get_earliest_valid_timestamp( symbol, interval, klines_type ) start_ts = max(start_ts, first_valid_ts) # if an end time was passed convert it end_ts = convert_ts_str(end_str) if end_ts and start_ts and end_ts <= start_ts: return idx = 0 while True: # fetch the klines from start_ts up to max 500 entries or the end_ts if set output_data = self._klines( klines_type=klines_type, symbol=symbol, interval=interval, limit=limit, startTime=start_ts, endTime=end_ts, ) # yield data if output_data: for o in output_data: yield o # handle the case where exactly the limit amount of data was returned last loop # check if we received less than the required limit and exit the loop if not len(output_data) or len(output_data) < limit: # exit the while loop break # set our start timestamp using the last value in the array # increment next call by our timeframe start_ts = output_data[-1][0] + timeframe # exit loop if we reached end_ts before reaching klines if end_ts and start_ts >= end_ts: break # sleep after every 3rd call to be kind to the API idx += 1 if idx % 3 == 0: time.sleep(1) def get_avg_price(self, **params): """Current average price for a symbol. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#current-average-price :param symbol: :type symbol: str :returns: API response .. code-block:: python { "mins": 5, "price": "9.35751834" } """ return self._get("avgPrice", data=params) def get_ticker(self, **params): """24 hour price change statistics. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#24hr-ticker-price-change-statistics :param symbol: :type symbol: str :returns: API response .. code-block:: python { "priceChange": "-94.99999800", "priceChangePercent": "-95.960", "weightedAvgPrice": "0.29628482", "prevClosePrice": "0.10002000", "lastPrice": "4.00000200", "bidPrice": "4.00000000", "askPrice": "4.00000200", "openPrice": "99.00000000", "highPrice": "100.00000000", "lowPrice": "0.10000000", "volume": "8913.30000000", "openTime": 1499783499040, "closeTime": 1499869899040, "fristId": 28385, # First tradeId "lastId": 28460, # Last tradeId "count": 76 # Trade count } OR .. code-block:: python [ { "priceChange": "-94.99999800", "priceChangePercent": "-95.960", "weightedAvgPrice": "0.29628482", "prevClosePrice": "0.10002000", "lastPrice": "4.00000200", "bidPrice": "4.00000000", "askPrice": "4.00000200", "openPrice": "99.00000000", "highPrice": "100.00000000", "lowPrice": "0.10000000", "volume": "8913.30000000", "openTime": 1499783499040, "closeTime": 1499869899040, "fristId": 28385, # First tradeId "lastId": 28460, # Last tradeId "count": 76 # Trade count } ] :raises: BinanceRequestException, BinanceAPIException """ return self._get("ticker/24hr", data=params) def get_symbol_ticker(self, **params): """Latest price for a symbol or symbols. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#symbol-price-ticker :param symbol: :type symbol: str :returns: API response .. code-block:: python { "symbol": "LTCBTC", "price": "4.00000200" } OR .. code-block:: python [ { "symbol": "LTCBTC", "price": "4.00000200" }, { "symbol": "ETHBTC", "price": "0.07946600" } ] :raises: BinanceRequestException, BinanceAPIException """ return self._get("ticker/price", data=params) def get_symbol_ticker_window(self, **params): """Latest price for a symbol or symbols. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#rolling-window-price-change-statistics :param symbol: :type symbol: str :returns: API response .. code-block:: python { "symbol": "LTCBTC", "price": "4.00000200" } OR .. code-block:: python [ { "symbol": "LTCBTC", "price": "4.00000200" }, { "symbol": "ETHBTC", "price": "0.07946600" } ] :raises: BinanceRequestException, BinanceAPIException """ return self._get("ticker", data=params) def get_orderbook_ticker(self, **params): """Latest price for a symbol or symbols. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#symbol-order-book-ticker :param symbol: :type symbol: str :returns: API response .. code-block:: python { "symbol": "LTCBTC", "bidPrice": "4.00000000", "bidQty": "431.00000000", "askPrice": "4.00000200", "askQty": "9.00000000" } OR .. code-block:: python [ { "symbol": "LTCBTC", "bidPrice": "4.00000000", "bidQty": "431.00000000", "askPrice": "4.00000200", "askQty": "9.00000000" }, { "symbol": "ETHBTC", "bidPrice": "0.07946700", "bidQty": "9.00000000", "askPrice": "100000.00000000", "askQty": "1000.00000000" } ] :raises: BinanceRequestException, BinanceAPIException """ return self._get( "ticker/bookTicker", data=params ) # Account Endpoints def create_order(self, **params): """Send in a new order Any order with an icebergQty MUST have timeInForce set to GTC. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#new-order-trade :param symbol: required :type symbol: str :param side: required :type side: str :param type: required :type type: str :param timeInForce: required if limit order :type timeInForce: str :param quantity: required :type quantity: decimal :param quoteOrderQty: amount the user wants to spend (when buying) or receive (when selling) of the quote asset, applicable to MARKET orders :type quoteOrderQty: decimal :param price: required :type price: str :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param icebergQty: Used with LIMIT, STOP_LOSS_LIMIT, and TAKE_PROFIT_LIMIT to create an iceberg order. :type icebergQty: decimal :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response Response ACK: .. code-block:: python { "symbol":"LTCBTC", "orderId": 1, "clientOrderId": "myOrder1" # Will be newClientOrderId "transactTime": 1499827319559 } Response RESULT: .. code-block:: python { "symbol": "BTCUSDT", "orderId": 28, "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP", "transactTime": 1507725176595, "price": "0.00000000", "origQty": "10.00000000", "executedQty": "10.00000000", "cummulativeQuoteQty": "10.00000000", "status": "FILLED", "timeInForce": "GTC", "type": "MARKET", "side": "SELL" } Response FULL: .. code-block:: python { "symbol": "BTCUSDT", "orderId": 28, "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP", "transactTime": 1507725176595, "price": "0.00000000", "origQty": "10.00000000", "executedQty": "10.00000000", "cummulativeQuoteQty": "10.00000000", "status": "FILLED", "timeInForce": "GTC", "type": "MARKET", "side": "SELL", "fills": [ { "price": "4000.00000000", "qty": "1.00000000", "commission": "4.00000000", "commissionAsset": "USDT" }, { "price": "3999.00000000", "qty": "5.00000000", "commission": "19.99500000", "commissionAsset": "USDT" }, { "price": "3998.00000000", "qty": "2.00000000", "commission": "7.99600000", "commissionAsset": "USDT" }, { "price": "3997.00000000", "qty": "1.00000000", "commission": "3.99700000", "commissionAsset": "USDT" }, { "price": "3995.00000000", "qty": "1.00000000", "commission": "3.99500000", "commissionAsset": "USDT" } ] } :raises: BinanceRequestException, BinanceAPIException, BinanceOrderException, BinanceOrderMinAmountException, BinanceOrderMinPriceException, BinanceOrderMinTotalException, BinanceOrderUnknownSymbolException, BinanceOrderInactiveSymbolException """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.SPOT_ORDER_PREFIX + self.uuid22() return self._post("order", True, data=params) def order_limit(self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params): """Send in a new limit order https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#new-order-trade Any order with an icebergQty MUST have timeInForce set to GTC. :param symbol: required :type symbol: str :param side: required :type side: str :param quantity: required :type quantity: decimal :param price: required :type price: str :param timeInForce: default Good till cancelled :type timeInForce: str :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param icebergQty: Used with LIMIT, STOP_LOSS_LIMIT, and TAKE_PROFIT_LIMIT to create an iceberg order. :type icebergQty: decimal :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response See order endpoint for full response options :raises: BinanceRequestException, BinanceAPIException, BinanceOrderException, BinanceOrderMinAmountException, BinanceOrderMinPriceException, BinanceOrderMinTotalException, BinanceOrderUnknownSymbolException, BinanceOrderInactiveSymbolException """ params.update({"type": self.ORDER_TYPE_LIMIT, "timeInForce": timeInForce}) return self.create_order(**params) def order_limit_buy(self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params): """Send in a new limit buy order https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#new-order-trade Any order with an icebergQty MUST have timeInForce set to GTC. :param symbol: required :type symbol: str :param quantity: required :type quantity: decimal :param price: required :type price: str :param timeInForce: default Good till cancelled :type timeInForce: str :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param stopPrice: Used with stop orders :type stopPrice: decimal :param icebergQty: Used with iceberg orders :type icebergQty: decimal :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response See order endpoint for full response options :raises: BinanceRequestException, BinanceAPIException, BinanceOrderException, BinanceOrderMinAmountException, BinanceOrderMinPriceException, BinanceOrderMinTotalException, BinanceOrderUnknownSymbolException, BinanceOrderInactiveSymbolException """ params.update({ "side": self.SIDE_BUY, }) return self.order_limit(timeInForce=timeInForce, **params) def order_limit_sell(self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params): """Send in a new limit sell order https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#new-order-trade :param symbol: required :type symbol: str :param quantity: required :type quantity: decimal :param price: required :type price: str :param timeInForce: default Good till cancelled :type timeInForce: str :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param stopPrice: Used with stop orders :type stopPrice: decimal :param icebergQty: Used with iceberg orders :type icebergQty: decimal :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response See order endpoint for full response options :raises: BinanceRequestException, BinanceAPIException, BinanceOrderException, BinanceOrderMinAmountException, BinanceOrderMinPriceException, BinanceOrderMinTotalException, BinanceOrderUnknownSymbolException, BinanceOrderInactiveSymbolException """ params.update({"side": self.SIDE_SELL}) return self.order_limit(timeInForce=timeInForce, **params) def order_market(self, **params): """Send in a new market order https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#new-order-trade :param symbol: required :type symbol: str :param side: required :type side: str :param quantity: required :type quantity: decimal :param quoteOrderQty: amount the user wants to spend (when buying) or receive (when selling) of the quote asset :type quoteOrderQty: decimal :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response See order endpoint for full response options :raises: BinanceRequestException, BinanceAPIException, BinanceOrderException, BinanceOrderMinAmountException, BinanceOrderMinPriceException, BinanceOrderMinTotalException, BinanceOrderUnknownSymbolException, BinanceOrderInactiveSymbolException """ params.update({"type": self.ORDER_TYPE_MARKET}) return self.create_order(**params) def order_market_buy(self, **params): """Send in a new market buy order https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#new-order-trade :param symbol: required :type symbol: str :param quantity: required :type quantity: decimal :param quoteOrderQty: the amount the user wants to spend of the quote asset :type quoteOrderQty: decimal :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response See order endpoint for full response options :raises: BinanceRequestException, BinanceAPIException, BinanceOrderException, BinanceOrderMinAmountException, BinanceOrderMinPriceException, BinanceOrderMinTotalException, BinanceOrderUnknownSymbolException, BinanceOrderInactiveSymbolException """ params.update({"side": self.SIDE_BUY}) return self.order_market(**params) def order_market_sell(self, **params): """Send in a new market sell order https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#new-order-trade :param symbol: required :type symbol: str :param quantity: required :type quantity: decimal :param quoteOrderQty: the amount the user wants to receive of the quote asset :type quoteOrderQty: decimal :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response See order endpoint for full response options :raises: BinanceRequestException, BinanceAPIException, BinanceOrderException, BinanceOrderMinAmountException, BinanceOrderMinPriceException, BinanceOrderMinTotalException, BinanceOrderUnknownSymbolException, BinanceOrderInactiveSymbolException """ params.update({"side": self.SIDE_SELL}) return self.order_market(**params) def create_oco_order(self, **params): """Send in an one-cancels-the-other (OCO) pair, where activation of one order immediately cancels the other. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#new-order-list---oco-trade An OCO has 2 orders called the above order and below order. One of the orders must be a LIMIT_MAKER/TAKE_PROFIT/TAKE_PROFIT_LIMIT order and the other must be STOP_LOSS or STOP_LOSS_LIMIT order. Price restrictions: If the OCO is on the SELL side: LIMIT_MAKER/TAKE_PROFIT_LIMIT price > Last Traded Price > STOP_LOSS/STOP_LOSS_LIMIT stopPrice TAKE_PROFIT stopPrice > Last Traded Price > STOP_LOSS/STOP_LOSS_LIMIT stopPrice If the OCO is on the BUY side: LIMIT_MAKER/TAKE_PROFIT_LIMIT price < Last Traded Price < stopPrice TAKE_PROFIT stopPrice < Last Traded Price < STOP_LOSS/STOP_LOSS_LIMIT stopPrice Weight: 1 :param symbol: required :type symbol: str :param listClientOrderId: Arbitrary unique ID among open order lists. Automatically generated if not sent. :type listClientOrderId: str :param side: required - BUY or SELL :type side: str :param quantity: required - Quantity for both orders of the order list :type quantity: decimal :param aboveType: required - STOP_LOSS_LIMIT, STOP_LOSS, LIMIT_MAKER, TAKE_PROFIT, TAKE_PROFIT_LIMIT :type aboveType: str :param aboveClientOrderId: Arbitrary unique ID among open orders for the above order :type aboveClientOrderId: str :param aboveIcebergQty: Note that this can only be used if aboveTimeInForce is GTC :type aboveIcebergQty: decimal :param abovePrice: Can be used if aboveType is STOP_LOSS_LIMIT, LIMIT_MAKER, or TAKE_PROFIT_LIMIT :type abovePrice: decimal :param aboveStopPrice: Can be used if aboveType is STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT :type aboveStopPrice: decimal :param aboveTrailingDelta: See Trailing Stop order FAQ :type aboveTrailingDelta: int :param aboveTimeInForce: Required if aboveType is STOP_LOSS_LIMIT or TAKE_PROFIT_LIMIT :type aboveTimeInForce: str :param aboveStrategyId: Arbitrary numeric value identifying the above order within an order strategy :type aboveStrategyId: int :param aboveStrategyType: Arbitrary numeric value identifying the above order strategy (>= 1000000) :type aboveStrategyType: int :param belowType: required - STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT :type belowType: str :param belowClientOrderId: Arbitrary unique ID among open orders for the below order :type belowClientOrderId: str :param belowIcebergQty: Note that this can only be used if belowTimeInForce is GTC :type belowIcebergQty: decimal :param belowPrice: Can be used if belowType is STOP_LOSS_LIMIT, LIMIT_MAKER, or TAKE_PROFIT_LIMIT :type belowPrice: decimal :param belowStopPrice: Can be used if belowType is STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT or TAKE_PROFIT_LIMIT :type belowStopPrice: decimal :param belowTrailingDelta: See Trailing Stop order FAQ :type belowTrailingDelta: int :param belowTimeInForce: Required if belowType is STOP_LOSS_LIMIT or TAKE_PROFIT_LIMIT :type belowTimeInForce: str :param belowStrategyId: Arbitrary numeric value identifying the below order within an order strategy :type belowStrategyId: int :param belowStrategyType: Arbitrary numeric value identifying the below order strategy (>= 1000000) :type belowStrategyType: int :param newOrderRespType: Select response format: ACK, RESULT, FULL :type newOrderRespType: str :param selfTradePreventionMode: The allowed enums is dependent on what is configured on the symbol :type selfTradePreventionMode: str :param recvWindow: The value cannot be greater than 60000 :type recvWindow: int :param timestamp: required :type timestamp: int :returns: API response { "orderListId": 1, "contingencyType": "OCO", "listStatusType": "EXEC_STARTED", "listOrderStatus": "EXECUTING", "listClientOrderId": "lH1YDkuQKWiXVXHPSKYEIp", "transactionTime": 1710485608839, "symbol": "LTCBTC", "orders": [ { "symbol": "LTCBTC", "orderId": 10, "clientOrderId": "44nZvqpemY7sVYgPYbvPih" }, { "symbol": "LTCBTC", "orderId": 11, "clientOrderId": "NuMp0nVYnciDiFmVqfpBqK" } ], "orderReports": [ { "symbol": "LTCBTC", "orderId": 10, "orderListId": 1, "clientOrderId": "44nZvqpemY7sVYgPYbvPih", "transactTime": 1710485608839, "price": "1.00000000", "origQty": "5.00000000", "executedQty": "0.00000000", "origQuoteOrderQty": "0.000000", "cummulativeQuoteQty": "0.00000000", "status": "NEW", "timeInForce": "GTC", "type": "STOP_LOSS_LIMIT", "side": "SELL", "stopPrice": "1.00000000", "workingTime": -1, "icebergQty": "1.00000000", "selfTradePreventionMode": "NONE" }, { "symbol": "LTCBTC", "orderId": 11, "orderListId": 1, "clientOrderId": "NuMp0nVYnciDiFmVqfpBqK", "transactTime": 1710485608839, "price": "3.00000000", "origQty": "5.00000000", "executedQty": "0.00000000", "origQuoteOrderQty": "0.000000", "cummulativeQuoteQty": "0.00000000", "status": "NEW", "timeInForce": "GTC", "type": "LIMIT_MAKER", "side": "SELL", "workingTime": 1710485608839, "selfTradePreventionMode": "NONE" } ] } :raises: BinanceRequestException, BinanceAPIException, BinanceOrderException, BinanceOrderMinAmountException, BinanceOrderMinPriceException, BinanceOrderMinTotalException, BinanceOrderUnknownSymbolException, BinanceOrderInactiveSymbolException """ if "listClientOrderId" not in params: params["listClientOrderId"] = self.SPOT_ORDER_PREFIX + self.uuid22() return self._post("orderList/oco", True, data=params) def order_oco_buy(self, **params): """Send in a new OCO buy order https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#new-order-list---oco-trade :param symbol: required :type symbol: str :param listClientOrderId: A unique id for the list order. Automatically generated if not sent. :type listClientOrderId: str :param quantity: required :type quantity: decimal :param limitClientOrderId: A unique id for the limit order. Automatically generated if not sent. :type limitClientOrderId: str :param price: required :type price: str :param limitIcebergQty: Used to make the LIMIT_MAKER leg an iceberg order. :type limitIcebergQty: decimal :param stopClientOrderId: A unique id for the stop order. Automatically generated if not sent. :type stopClientOrderId: str :param stopPrice: required :type stopPrice: str :param stopLimitPrice: If provided, stopLimitTimeInForce is required. :type stopLimitPrice: str :param stopIcebergQty: Used with STOP_LOSS_LIMIT leg to make an iceberg order. :type stopIcebergQty: decimal :param stopLimitTimeInForce: Valid values are GTC/FOK/IOC. :type stopLimitTimeInForce: str :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response See OCO order endpoint for full response options :raises: BinanceRequestException, BinanceAPIException, BinanceOrderException, BinanceOrderMinAmountException, BinanceOrderMinPriceException, BinanceOrderMinTotalException, BinanceOrderUnknownSymbolException, BinanceOrderInactiveSymbolException """ params.update({"side": self.SIDE_BUY}) return self.create_oco_order(**params) def order_oco_sell(self, **params): """Send in a new OCO sell order https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#new-order-list---oco-trade :param symbol: required :type symbol: str :param listClientOrderId: A unique id for the list order. Automatically generated if not sent. :type listClientOrderId: str :param quantity: required :type quantity: decimal :param limitClientOrderId: A unique id for the limit order. Automatically generated if not sent. :type limitClientOrderId: str :param price: required :type price: str :param limitIcebergQty: Used to make the LIMIT_MAKER leg an iceberg order. :type limitIcebergQty: decimal :param stopClientOrderId: A unique id for the stop order. Automatically generated if not sent. :type stopClientOrderId: str :param stopPrice: required :type stopPrice: str :param stopLimitPrice: If provided, stopLimitTimeInForce is required. :type stopLimitPrice: str :param stopIcebergQty: Used with STOP_LOSS_LIMIT leg to make an iceberg order. :type stopIcebergQty: decimal :param stopLimitTimeInForce: Valid values are GTC/FOK/IOC. :type stopLimitTimeInForce: str :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response See OCO order endpoint for full response options :raises: BinanceRequestException, BinanceAPIException, BinanceOrderException, BinanceOrderMinAmountException, BinanceOrderMinPriceException, BinanceOrderMinTotalException, BinanceOrderUnknownSymbolException, BinanceOrderInactiveSymbolException """ params.update({"side": self.SIDE_SELL}) return self.create_oco_order(**params) def create_test_order(self, **params): """Test new order creation and signature/recvWindow long. Creates and validates a new order but does not send it into the matching engine. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#test-new-order-trade :param symbol: required :type symbol: str :param side: required :type side: str :param type: required :type type: str :param timeInForce: required if limit order :type timeInForce: str :param quantity: required :type quantity: decimal :param price: required :type price: str :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param icebergQty: Used with iceberg orders :type icebergQty: decimal :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: The number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python {} :raises: BinanceRequestException, BinanceAPIException, BinanceOrderException, BinanceOrderMinAmountException, BinanceOrderMinPriceException, BinanceOrderMinTotalException, BinanceOrderUnknownSymbolException, BinanceOrderInactiveSymbolException """ return self._post("order/test", True, data=params) def get_order(self, **params): """Check an order's status. Either orderId or origClientOrderId must be sent. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/account-endpoints#query-order-user_data :param symbol: required :type symbol: str :param orderId: The unique order id :type orderId: int :param origClientOrderId: optional :type origClientOrderId: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "symbol": "LTCBTC", "orderId": 1, "clientOrderId": "myOrder1", "price": "0.1", "origQty": "1.0", "executedQty": "0.0", "status": "NEW", "timeInForce": "GTC", "type": "LIMIT", "side": "BUY", "stopPrice": "0.0", "icebergQty": "0.0", "time": 1499827319559 } :raises: BinanceRequestException, BinanceAPIException """ return self._get("order", True, data=params) def get_all_orders(self, **params): """Get all account orders; active, canceled, or filled. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/account-endpoints#all-orders-user_data :param symbol: required :type symbol: str :param orderId: The unique order id :type orderId: int :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param limit: Default 500; max 1000. :type limit: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python [ { "symbol": "LTCBTC", "orderId": 1, "clientOrderId": "myOrder1", "price": "0.1", "origQty": "1.0", "executedQty": "0.0", "status": "NEW", "timeInForce": "GTC", "type": "LIMIT", "side": "BUY", "stopPrice": "0.0", "icebergQty": "0.0", "time": 1499827319559 } ] :raises: BinanceRequestException, BinanceAPIException """ return self._get("allOrders", True, data=params) def cancel_order(self, **params): """Cancel an active order. Either orderId or origClientOrderId must be sent. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#cancel-order-trade :param symbol: required :type symbol: str :param orderId: The unique order id :type orderId: int :param origClientOrderId: optional :type origClientOrderId: str :param newClientOrderId: Used to uniquely identify this cancel. Automatically generated by default. :type newClientOrderId: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "symbol": "LTCBTC", "origClientOrderId": "myOrder1", "orderId": 1, "clientOrderId": "cancelMyOrder1" } :raises: BinanceRequestException, BinanceAPIException """ return self._delete("order", True, data=params) def cancel_all_open_orders(self, **params): """ Cancel all open orders on a symbol. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#cancel-all-open-orders-on-a-symbol-trade :param symbol: required :type symbol: str :returns: API response """ return self._delete("openOrders", True, data=params) def cancel_replace_order(self, **params): """Cancels an existing order and places a new order on the same symbol. Filters and Order Count are evaluated before the processing of the cancellation and order placement occurs. A new order that was not attempted (i.e. when newOrderResult: NOT_ATTEMPTED), will still increase the order count by 1. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#cancel-an-existing-order-and-send-a-new-order-trade :param symbol: required :type symbol: str :param side: required :type side: enum :param type: required :type type: enum :param cancelReplaceMode: required - STOP_ON_FAILURE or ALLOW_FAILURE :type cancelReplaceMode: enum :param timeInForce: optional :type timeInForce: enum :param quantity: optional :type quantity: decimal :param quoteOrderQty: optional :type quoteOrderQty: decimal :param price: optional :type price: decimal :param cancelNewClientOrderId: optional - Used to uniquely identify this cancel. Automatically generated by default. :type cancelNewClientOrderId: str :param cancelOrigClientOrderId: optional - Either the cancelOrigClientOrderId or cancelOrderId must be provided. If both are provided, cancelOrderId takes precedence. :type cancelOrigClientOrderId: str :param cancelOrderId: optional - Either the cancelOrigClientOrderId or cancelOrderId must be provided. If both are provided, cancelOrderId takes precedence. :type cancelOrderId: long :param newClientOrderId: optional - Used to identify the new order. :type newClientOrderId: str :param strategyId: optional :type strategyId: int :param strategyType: optional - The value cannot be less than 1000000. :type strategyType: int :param stopPrice: optional :type stopPrice: decimal :param trailingDelta: optional :type trailingDelta: long :param icebergQty: optional :type icebergQty: decimal :param newOrderRespType: optional - ACK, RESULT or FULL. MARKET and LIMIT orders types default to FULL; all other orders default to ACK :type newOrderRespType: enum :param selfTradePreventionMode: optional - EXPIRE_TAKER, EXPIRE_MAKER, EXPIRE_BOTH or NONE. :type selfTradePreventionMode: enum :param cancelRestrictions: optional - ONLY_NEW or ONLY_PARTIALLY_FILLED :type cancelRestrictions: enum :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: API response .. code-block:: python //Both the cancel order placement and new order placement succeeded. { "cancelResult": "SUCCESS", "newOrderResult": "SUCCESS", "cancelResponse": { "symbol": "BTCUSDT", "origClientOrderId": "DnLo3vTAQcjha43lAZhZ0y", "orderId": 9, "orderListId": -1, "clientOrderId": "osxN3JXAtJvKvCqGeMWMVR", "transactTime": 1684804350068, "price": "0.01000000", "origQty": "0.000100", "executedQty": "0.00000000", "cummulativeQuoteQty": "0.00000000", "status": "CANCELED", "timeInForce": "GTC", "type": "LIMIT", "side": "SELL", "selfTradePreventionMode": "NONE" }, "newOrderResponse": { "symbol": "BTCUSDT", "orderId": 10, "orderListId": -1, "clientOrderId": "wOceeeOzNORyLiQfw7jd8S", "transactTime": 1652928801803, "price": "0.02000000", "origQty": "0.040000", "executedQty": "0.00000000", "cummulativeQuoteQty": "0.00000000", "status": "NEW", "timeInForce": "GTC", "type": "LIMIT", "side": "BUY", "workingTime": 1669277163808, "fills": [], "selfTradePreventionMode": "NONE" } } Similar to POST /api/v3/order, additional mandatory parameters are determined by type. Response format varies depending on whether the processing of the message succeeded, partially succeeded, or failed. :raises: BinanceRequestException, BinanceAPIException """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.SPOT_ORDER_PREFIX + self.uuid22() return self._post("order/cancelReplace", True, data=params) def get_open_orders(self, **params): """Get all open orders on a symbol. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/account-endpoints#current-open-orders-user_data :param symbol: optional :type symbol: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python [ { "symbol": "LTCBTC", "orderId": 1, "clientOrderId": "myOrder1", "price": "0.1", "origQty": "1.0", "executedQty": "0.0", "status": "NEW", "timeInForce": "GTC", "type": "LIMIT", "side": "BUY", "stopPrice": "0.0", "icebergQty": "0.0", "time": 1499827319559 } ] :raises: BinanceRequestException, BinanceAPIException """ return self._get("openOrders", True, data=params) def get_open_oco_orders(self, **params): """Get all open orders on a symbol. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/account-endpoints#query-open-order-lists-user_data :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python [ { "orderListId": 31, "contingencyType": "OCO", "listStatusType": "EXEC_STARTED", "listOrderStatus": "EXECUTING", "listClientOrderId": "wuB13fmulKj3YjdqWEcsnp", "transactionTime": 1565246080644, "symbol": "LTCBTC", "orders": [ { "symbol": "LTCBTC", "orderId": 4, "clientOrderId": "r3EH2N76dHfLoSZWIUw1bT" }, { "symbol": "LTCBTC", "orderId": 5, "clientOrderId": "Cv1SnyPD3qhqpbjpYEHbd2" } ] } ] :raises: BinanceRequestException, BinanceAPIException """ return self._get("openOrderList", True, data=params) # User Stream Endpoints def get_account(self, **params): """Get current account information. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/account-endpoints#account-information-user_data :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "makerCommission": 15, "takerCommission": 15, "buyerCommission": 0, "sellerCommission": 0, "canTrade": true, "canWithdraw": true, "canDeposit": true, "balances": [ { "asset": "BTC", "free": "4723846.89208129", "locked": "0.00000000" }, { "asset": "LTC", "free": "4763368.68006011", "locked": "0.00000000" } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._get("account", True, data=params) def get_asset_balance(self, asset=None, **params): """Get current asset balance. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/account-endpoints#account-information-user_data :param asset: optional - the asset to get the balance of :type asset: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: dictionary or None if not found .. code-block:: python { "asset": "BTC", "free": "4723846.89208129", "locked": "0.00000000" } :raises: BinanceRequestException, BinanceAPIException """ res = self.get_account(**params) # find asset balance in list of balances if "balances" in res: if asset: for bal in res["balances"]: if bal["asset"].lower() == asset.lower(): return bal else: return res["balances"] return None def get_my_trades(self, **params): """Get trades for a specific symbol. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/account-endpoints#account-trade-list-user_data :param symbol: required :type symbol: str :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param limit: Default 500; max 1000. :type limit: int :param fromId: TradeId to fetch from. Default gets most recent trades. :type fromId: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python [ { "id": 28457, "price": "4.00000100", "qty": "12.00000000", "commission": "10.10000000", "commissionAsset": "BNB", "time": 1499865549590, "isBuyer": true, "isMaker": false, "isBestMatch": true } ] :raises: BinanceRequestException, BinanceAPIException """ return self._get("myTrades", True, data=params) def get_current_order_count(self, **params): """Displays the user's current order count usage for all intervals. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/account-endpoints#query-unfilled-order-count-user_data :returns: API response .. code-block:: python [ { "rateLimitType": "ORDERS", "interval": "SECOND", "intervalNum": 10, "limit": 10000, "count": 0 }, { "rateLimitType": "ORDERS", "interval": "DAY", "intervalNum": 1, "limit": 20000, "count": 0 } ] """ return self._get("rateLimit/order", True, data=params) def get_prevented_matches(self, **params): """Displays the list of orders that were expired because of STP. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/account-endpoints#query-prevented-matches-user_data :param symbol: required :type symbol: str :param preventedMatchId: optional :type preventedMatchId: int :param orderId: optional :type orderId: int :param fromPreventedMatchId: optional :type fromPreventedMatchId: int :param limit: optional, Default: 500; Max: 1000 :type limit: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python [ { "symbol": "BTCUSDT", "preventedMatchId": 1, "takerOrderId": 5, "makerOrderId": 3, "tradeGroupId": 1, "selfTradePreventionMode": "EXPIRE_MAKER", "price": "1.100000", "makerPreventedQuantity": "1.300000", "transactTime": 1669101687094 } ] """ return self._get("myPreventedMatches", True, data=params) def get_allocations(self, **params): """Retrieves allocations resulting from SOR order placement. https://developers.binance.com/docs/binance-spot-api-docs/rest-api/account-endpoints#query-allocations-user_data :param symbol: required :type symbol: str :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param fromAllocationId: optional :type fromAllocationId: int :param orderId: optional :type orderId: int :param limit: optional, Default: 500; Max: 1000 :type limit: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python [ { "symbol": "BTCUSDT", "allocationId": 0, "allocationType": "SOR", "orderId": 1, "orderListId": -1, "price": "1.00000000", "qty": "5.00000000", "quoteQty": "5.00000000", "commission": "0.00000000", "commissionAsset": "BTC", "time": 1687506878118, "isBuyer": true, "isMaker": false, "isAllocator": false } ] """ return self._get("myAllocations", True, data=params) def get_system_status(self): """Get system status detail. https://developers.binance.com/docs/wallet/others/system-status :returns: API response .. code-block:: python { "status": 0, # 0: normal,1:system maintenance "msg": "normal" # normal or System maintenance. } :raises: BinanceAPIException """ return self._request_margin_api("get", "system/status") def get_account_status(self, version=1, **params): """Get account status detail. https://binance-docs.github.io/apidocs/spot/en/#account-status-sapi-user_data https://developers.binance.com/docs/wallet/account/account-status :param version: the api version :param version: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "data": "Normal" } """ if self.tld == "us": path = "accountStatus" else: path = "account/status" return self._request_margin_api("get", path, True, version, data=params) def get_account_api_trading_status(self, **params): """Fetch account api trading status detail. https://developers.binance.com/docs/wallet/account/account-api-trading-status :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "data": { // API trading status detail "isLocked": false, // API trading function is locked or not "plannedRecoverTime": 0, // If API trading function is locked, this is the planned recover time "triggerCondition": { "GCR": 150, // Number of GTC orders "IFER": 150, // Number of FOK/IOC orders "UFR": 300 // Number of orders }, "indicators": { // The indicators updated every 30 seconds "BTCUSDT": [ // The symbol { "i": "UFR", // Unfilled Ratio (UFR) "c": 20, // Count of all orders "v": 0.05, // Current UFR value "t": 0.995 // Trigger UFR value }, { "i": "IFER", // IOC/FOK Expiration Ratio (IFER) "c": 20, // Count of FOK/IOC orders "v": 0.99, // Current IFER value "t": 0.99 // Trigger IFER value }, { "i": "GCR", // GTC Cancellation Ratio (GCR) "c": 20, // Count of GTC orders "v": 0.99, // Current GCR value "t": 0.99 // Trigger GCR value } ], "ETHUSDT": [ { "i": "UFR", "c": 20, "v": 0.05, "t": 0.995 }, { "i": "IFER", "c": 20, "v": 0.99, "t": 0.99 }, { "i": "GCR", "c": 20, "v": 0.99, "t": 0.99 } ] }, "updateTime": 1547630471725 } } """ return self._request_margin_api( "get", "account/apiTradingStatus", True, data=params ) def get_account_api_permissions(self, **params): """Fetch api key permissions. https://developers.binance.com/docs/wallet/account/api-key-permission :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "ipRestrict": false, "createTime": 1623840271000, "enableWithdrawals": false, // This option allows you to withdraw via API. You must apply the IP Access Restriction filter in order to enable withdrawals "enableInternalTransfer": true, // This option authorizes this key to transfer funds between your master account and your sub account instantly "permitsUniversalTransfer": true, // Authorizes this key to be used for a dedicated universal transfer API to transfer multiple supported currencies. Each business's own transfer API rights are not affected by this authorization "enableVanillaOptions": false, // Authorizes this key to Vanilla options trading "enableReading": true, "enableFutures": false, // API Key created before your futures account opened does not support futures API service "enableMargin": false, // This option can be adjusted after the Cross Margin account transfer is completed "enableSpotAndMarginTrading": false, // Spot and margin trading "tradingAuthorityExpirationTime": 1628985600000 // Expiration time for spot and margin trading permission } """ return self._request_margin_api( "get", "account/apiRestrictions", True, data=params ) def get_dust_assets(self, **params): """Get assets that can be converted into BNB https://developers.binance.com/docs/wallet/asset/assets-can-convert-bnb :returns: API response .. code-block:: python { "details": [ { "asset": "ADA", "assetFullName": "ADA", "amountFree": "6.21", //Convertible amount "toBTC": "0.00016848", //BTC amount "toBNB": "0.01777302", //BNB amount(Not deducted commission fee) "toBNBOffExchange": "0.01741756", //BNB amount(Deducted commission fee) "exchange": "0.00035546" //Commission fee } ], "totalTransferBtc": "0.00016848", "totalTransferBNB": "0.01777302", "dribbletPercentage": "0.02" //Commission fee } """ return self._request_margin_api("post", "asset/dust-btc", True, data=params) def get_dust_log(self, **params): """Get log of small amounts exchanged for BNB. https://developers.binance.com/docs/wallet/asset/dust-log :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "total": 8, //Total counts of exchange "userAssetDribblets": [ { "totalTransferedAmount": "0.00132256", // Total transfered BNB amount for this exchange. "totalServiceChargeAmount": "0.00002699", //Total service charge amount for this exchange. "transId": 45178372831, "userAssetDribbletDetails": [ //Details of this exchange. { "transId": 4359321, "serviceChargeAmount": "0.000009", "amount": "0.0009", "operateTime": 1615985535000, "transferedAmount": "0.000441", "fromAsset": "USDT" }, { "transId": 4359321, "serviceChargeAmount": "0.00001799", "amount": "0.0009", "operateTime": "2018-05-03 17:07:04", "transferedAmount": "0.00088156", "fromAsset": "ETH" } ] }, { "operateTime":1616203180000, "totalTransferedAmount": "0.00058795", "totalServiceChargeAmount": "0.000012", "transId": 4357015, "userAssetDribbletDetails": [ { "transId": 4357015, "serviceChargeAmount": "0.00001" "amount": "0.001", "operateTime": 1616203180000, "transferedAmount": "0.00049", "fromAsset": "USDT" }, { "transId": 4357015, "serviceChargeAmount": "0.000002" "amount": "0.0001", "operateTime": 1616203180000, "transferedAmount": "0.00009795", "fromAsset": "ETH" } ] } ] } """ return self._request_margin_api("get", "asset/dribblet", True, data=params) def transfer_dust(self, **params): """Convert dust assets to BNB. https://developers.binance.com/docs/wallet/asset/dust-transfer :param asset: The asset being converted. e.g: 'ONE' :type asset: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int .. code-block:: python result = client.transfer_dust(asset='ONE') :returns: API response .. code-block:: python { "totalServiceCharge":"0.02102542", "totalTransfered":"1.05127099", "transferResult":[ { "amount":"0.03000000", "fromAsset":"ETH", "operateTime":1563368549307, "serviceChargeAmount":"0.00500000", "tranId":2970932918, "transferedAmount":"0.25000000" } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("post", "asset/dust", True, data=params) def get_asset_dividend_history(self, **params): """Query asset dividend record. https://developers.binance.com/docs/wallet/asset/assets-divided-record :param asset: optional :type asset: str :param startTime: optional :type startTime: long :param endTime: optional :type endTime: long :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int .. code-block:: python result = client.get_asset_dividend_history() :returns: API response .. code-block:: python { "rows":[ { "amount":"10.00000000", "asset":"BHFT", "divTime":1563189166000, "enInfo":"BHFT distribution", "tranId":2968885920 }, { "amount":"10.00000000", "asset":"BHFT", "divTime":1563189165000, "enInfo":"BHFT distribution", "tranId":2968885920 } ], "total":2 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("get", "asset/assetDividend", True, data=params) def make_universal_transfer(self, **params): """User Universal Transfer https://developers.binance.com/docs/wallet/asset/user-universal-transfer :param type: required :type type: str (ENUM) :param asset: required :type asset: str :param amount: required :type amount: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int .. code-block:: python transfer_status = client.make_universal_transfer(params) :returns: API response .. code-block:: python { "tranId":13526853623 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "asset/transfer", signed=True, data=params ) def query_universal_transfer_history(self, **params): """Query User Universal Transfer History https://developers.binance.com/docs/wallet/asset/query-user-universal-transfer :param type: required :type type: str (ENUM) :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param current: optional - Default 1 :type current: int :param size: required - Default 10, Max 100 :type size: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int .. code-block:: python transfer_status = client.query_universal_transfer_history(params) :returns: API response .. code-block:: python { "total":2, "rows":[ { "asset":"USDT", "amount":"1", "type":"MAIN_UMFUTURE" "status": "CONFIRMED", "tranId": 11415955596, "timestamp":1544433328000 }, { "asset":"USDT", "amount":"2", "type":"MAIN_UMFUTURE", "status": "CONFIRMED", "tranId": 11366865406, "timestamp":1544433328000 } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "asset/transfer", signed=True, data=params ) def get_trade_fee(self, **params): """Get trade fee. https://developers.binance.com/docs/wallet/asset/trade-fee :param symbol: optional :type symbol: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python [ { "symbol": "ADABNB", "makerCommission": "0.001", "takerCommission": "0.001" }, { "symbol": "BNBBTC", "makerCommission": "0.001", "takerCommission": "0.001" } ] """ if self.tld == "us": endpoint = "asset/query/trading-fee" else: endpoint = "asset/tradeFee" return self._request_margin_api("get", endpoint, True, data=params) def get_asset_details(self, **params): """Fetch details on assets. https://developers.binance.com/docs/wallet/asset :param asset: optional :type asset: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "CTR": { "minWithdrawAmount": "70.00000000", //min withdraw amount "depositStatus": false,//deposit status (false if ALL of networks' are false) "withdrawFee": 35, // withdraw fee "withdrawStatus": true, //withdraw status (false if ALL of networks' are false) "depositTip": "Delisted, Deposit Suspended" //reason }, "SKY": { "minWithdrawAmount": "0.02000000", "depositStatus": true, "withdrawFee": 0.01, "withdrawStatus": true } } """ return self._request_margin_api("get", "asset/assetDetail", True, data=params) def get_spot_delist_schedule(self, **params): """Get symbols delist schedule for spot https://developers.binance.com/docs/wallet/others/delist-schedule :param recvWindow: optional - the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python [ { "delistTime": 1686161202000, "symbols": [ "ADAUSDT", "BNBUSDT" ] }, { "delistTime": 1686222232000, "symbols": [ "ETHUSDT" ] } ] """ return self._request_margin_api( "get", "spot/delist-schedule", False, data=params ) # Withdraw Endpoints def withdraw(self, **params): """Submit a withdraw request. https://developers.binance.com/docs/wallet/capital/withdraw Assumptions: - You must have Withdraw permissions enabled on your API key - You must have withdrawn to the address specified through the website and approved the transaction via email :param coin: required :type coin: str :param withdrawOrderId: optional - client id for withdraw :type withdrawOrderId: str :param network: optional :type network: str :param address: optional :type address: str :type addressTag: optional - Secondary address identifier for coins like XRP,XMR etc. :param amount: required :type amount: decimal :param transactionFeeFlag: required - When making internal transfer, true for returning the fee to the destination account; false for returning the fee back to the departure account. Default false. :type transactionFeeFlag: bool :param name: optional - Description of the address, default asset value passed will be used :type name: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "id":"7213fea8e94b4a5593d507237e5a555b" } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "capital/withdraw/apply", True, data=params ) def get_deposit_history(self, **params): """Fetch deposit history. https://developers.binance.com/docs/wallet/capital/deposite-history :param coin: optional :type coin: str :type status: optional - 0(0:pending,1:success) optional :type status: int :param startTime: optional :type startTime: long :param endTime: optional :type endTime: long :param offset: optional - default:0 :type offset: long :param limit: optional :type limit: long :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python [ { "amount":"0.00999800", "coin":"PAXG", "network":"ETH", "status":1, "address":"0x788cabe9236ce061e5a892e1a59395a81fc8d62c", "addressTag":"", "txId":"0xaad4654a3234aa6118af9b4b335f5ae81c360b2394721c019b5d1e75328b09f3", "insertTime":1599621997000, "transferType":0, "confirmTimes":"12/12" }, { "amount":"0.50000000", "coin":"IOTA", "network":"IOTA", "status":1, "address":"SIZ9VLMHWATXKV99LH99CIGFJFUMLEHGWVZVNNZXRJJVWBPHYWPPBOSDORZ9EQSHCZAMPVAPGFYQAUUV9DROOXJLNW", "addressTag":"", "txId":"ESBFVQUTPIWQNJSPXFNHNYHSQNTGKRVKPRABQWTAXCDWOAKDKYWPTVG9BGXNVNKTLEJGESAVXIKIZ9999", "insertTime":1599620082000, "transferType":0, "confirmTimes":"1/1" } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "capital/deposit/hisrec", True, data=params ) def get_withdraw_history(self, **params): """Fetch withdraw history. https://developers.binance.com/docs/wallet/capital/withdraw-history :param coin: optional :type coin: str :type status: 0(0:Email Sent,1:Cancelled 2:Awaiting Approval 3:Rejected 4:Processing 5:Failure 6Completed) optional :type status: int :param offset: optional - default:0 :type offset: int :param limit: optional :type limit: int :param startTime: optional - Default: 90 days from current timestamp :type startTime: int :param endTime: optional - Default: present timestamp :type endTime: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python [ { "address": "0x94df8b352de7f46f64b01d3666bf6e936e44ce60", "amount": "8.91000000", "applyTime": "2019-10-12 11:12:02", "coin": "USDT", "id": "b6ae22b3aa844210a7041aee7589627c", "withdrawOrderId": "WITHDRAWtest123", // will not be returned if there's no withdrawOrderId for this withdraw. "network": "ETH", "transferType": 0, // 1 for internal transfer, 0 for external transfer "status": 6, "txId": "0xb5ef8c13b968a406cc62a93a8bd80f9e9a906ef1b3fcf20a2e48573c17659268" }, { "address": "1FZdVHtiBqMrWdjPyRPULCUceZPJ2WLCsB", "amount": "0.00150000", "applyTime": "2019-09-24 12:43:45", "coin": "BTC", "id": "156ec387f49b41df8724fa744fa82719", "network": "BTC", "status": 6, "txId": "60fd9007ebfddc753455f95fafa808c4302c836e4d1eebc5a132c36c1d8ac354" } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "capital/withdraw/history", True, data=params ) def get_withdraw_history_id(self, withdraw_id, **params): """Fetch withdraw history. https://binance-docs.github.io/apidocs/spot/en/#withdraw-history-supporting-network-user_data :param withdraw_id: required :type withdraw_id: str :param asset: optional :type asset: str :type status: 0(0:Email Sent,1:Cancelled 2:Awaiting Approval 3:Rejected 4:Processing 5:Failure 6Completed) optional :type status: int :param startTime: optional :type startTime: long :param endTime: optional :type endTime: long :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "id":"7213fea8e94b4a5593d507237e5a555b", "withdrawOrderId": None, "amount": 0.99, "transactionFee": 0.01, "address": "0x6915f16f8791d0a1cc2bf47c13a6b2a92000504b", "asset": "ETH", "txId": "0xdf33b22bdb2b28b1f75ccd201a4a4m6e7g83jy5fc5d5a9d1340961598cfcb0a1", "applyTime": 1508198532000, "status": 4 } :raises: BinanceRequestException, BinanceAPIException """ result = self.get_withdraw_history(**params) for entry in result: if "id" in entry and entry["id"] == withdraw_id: return entry raise Exception("There is no entry with withdraw id", result) def get_deposit_address(self, coin: str, network: Optional[str] = None, **params): """Fetch a deposit address for a symbol https://developers.binance.com/docs/wallet/capital/deposite-address :param coin: required :type coin: str :param network: optional :type network: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "address": "1HPn8Rx2y6nNSfagQBKy27GB99Vbzg89wv", "coin": "BTC", "tag": "", "url": "https://btc.com/1HPn8Rx2y6nNSfagQBKy27GB99Vbzg89wv" } :raises: BinanceRequestException, BinanceAPIException """ params["coin"] = coin if network: params["network"] = network return self._request_margin_api( "get", "capital/deposit/address", True, data=params ) # User Stream Endpoints def stream_get_listen_key(self): """Start a new user data stream and return the listen key If a stream already exists it should return the same key. If the stream becomes invalid a new key is returned. Can be used to keep the user stream alive. https://binance-docs.github.io/apidocs/spot/en/#listen-key-spot :returns: API response .. code-block:: python { "listenKey": "pqia91ma19a5s61cv6a81va65sdf19v8a65a1a5s61cv6a81va65sdf19v8a65a1" } :raises: BinanceRequestException, BinanceAPIException """ res = self._post( "userDataStream", False, data={} ) return res["listenKey"] def stream_keepalive(self, listenKey): """PING a user data stream to prevent a time out. https://binance-docs.github.io/apidocs/spot/en/#listen-key-spot :param listenKey: required :type listenKey: str :returns: API response .. code-block:: python {} :raises: BinanceRequestException, BinanceAPIException """ params = {"listenKey": listenKey} return self._put( "userDataStream", False, data=params ) def stream_close(self, listenKey): """Close out a user data stream. https://binance-docs.github.io/apidocs/spot/en/#listen-key-spot :param listenKey: required :type listenKey: str :returns: API response .. code-block:: python {} :raises: BinanceRequestException, BinanceAPIException """ params = {"listenKey": listenKey} return self._delete( "userDataStream", False, data=params, version=self.PRIVATE_API_VERSION ) # Margin Trading Endpoints def get_margin_account(self, **params): """Query cross-margin account details https://developers.binance.com/docs/margin_trading/account/Query-Cross-Margin-Account-Details :returns: API response .. code-block:: python { "borrowEnabled": true, "marginLevel": "11.64405625", "totalAssetOfBtc": "6.82728457", "totalLiabilityOfBtc": "0.58633215", "totalNetAssetOfBtc": "6.24095242", "tradeEnabled": true, "transferEnabled": true, "userAssets": [ { "asset": "BTC", "borrowed": "0.00000000", "free": "0.00499500", "interest": "0.00000000", "locked": "0.00000000", "netAsset": "0.00499500" }, { "asset": "BNB", "borrowed": "201.66666672", "free": "2346.50000000", "interest": "0.00000000", "locked": "0.00000000", "netAsset": "2144.83333328" }, { "asset": "ETH", "borrowed": "0.00000000", "free": "0.00000000", "interest": "0.00000000", "locked": "0.00000000", "netAsset": "0.00000000" }, { "asset": "USDT", "borrowed": "0.00000000", "free": "0.00000000", "interest": "0.00000000", "locked": "0.00000000", "netAsset": "0.00000000" } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("get", "margin/account", True, data=params) def get_isolated_margin_account(self, **params): """Query isolated margin account details https://developers.binance.com/docs/margin_trading/account/Query-Isolated-Margin-Account-Info :param symbols: optional up to 5 margin pairs as a comma separated string :type asset: str .. code:: python account_info = client.get_isolated_margin_account() account_info = client.get_isolated_margin_account(symbols="BTCUSDT,ETHUSDT") :returns: API response .. code-block:: python If "symbols" is not sent: { "assets":[ { "baseAsset": { "asset": "BTC", "borrowEnabled": true, "borrowed": "0.00000000", "free": "0.00000000", "interest": "0.00000000", "locked": "0.00000000", "netAsset": "0.00000000", "netAssetOfBtc": "0.00000000", "repayEnabled": true, "totalAsset": "0.00000000" }, "quoteAsset": { "asset": "USDT", "borrowEnabled": true, "borrowed": "0.00000000", "free": "0.00000000", "interest": "0.00000000", "locked": "0.00000000", "netAsset": "0.00000000", "netAssetOfBtc": "0.00000000", "repayEnabled": true, "totalAsset": "0.00000000" }, "symbol": "BTCUSDT" "isolatedCreated": true, "marginLevel": "0.00000000", "marginLevelStatus": "EXCESSIVE", // "EXCESSIVE", "NORMAL", "MARGIN_CALL", "PRE_LIQUIDATION", "FORCE_LIQUIDATION" "marginRatio": "0.00000000", "indexPrice": "10000.00000000" "liquidatePrice": "1000.00000000", "liquidateRate": "1.00000000" "tradeEnabled": true } ], "totalAssetOfBtc": "0.00000000", "totalLiabilityOfBtc": "0.00000000", "totalNetAssetOfBtc": "0.00000000" } If "symbols" is sent: { "assets":[ { "baseAsset": { "asset": "BTC", "borrowEnabled": true, "borrowed": "0.00000000", "free": "0.00000000", "interest": "0.00000000", "locked": "0.00000000", "netAsset": "0.00000000", "netAssetOfBtc": "0.00000000", "repayEnabled": true, "totalAsset": "0.00000000" }, "quoteAsset": { "asset": "USDT", "borrowEnabled": true, "borrowed": "0.00000000", "free": "0.00000000", "interest": "0.00000000", "locked": "0.00000000", "netAsset": "0.00000000", "netAssetOfBtc": "0.00000000", "repayEnabled": true, "totalAsset": "0.00000000" }, "symbol": "BTCUSDT" "isolatedCreated": true, "marginLevel": "0.00000000", "marginLevelStatus": "EXCESSIVE", // "EXCESSIVE", "NORMAL", "MARGIN_CALL", "PRE_LIQUIDATION", "FORCE_LIQUIDATION" "marginRatio": "0.00000000", "indexPrice": "10000.00000000" "liquidatePrice": "1000.00000000", "liquidateRate": "1.00000000" "tradeEnabled": true } ] } """ return self._request_margin_api( "get", "margin/isolated/account", True, data=params ) def enable_isolated_margin_account(self, **params): """Enable isolated margin account for a specific symbol. https://developers.binance.com/docs/margin_trading/account/Enable-Isolated-Margin-Account :param symbol: :type asset: str :returns: API response .. code-block:: python { "success": true, "symbol": "BTCUSDT" } """ return self._request_margin_api( "post", "margin/isolated/account", True, data=params ) def disable_isolated_margin_account(self, **params): """Disable isolated margin account for a specific symbol. Each trading pair can only be deactivated once every 24 hours. https://developers.binance.com/docs/margin_trading/account/Disable-Isolated-Margin-Account :param symbol: :type asset: str :returns: API response .. code-block:: python { "success": true, "symbol": "BTCUSDT" } """ return self._request_margin_api( "delete", "margin/isolated/account", True, data=params ) def get_enabled_isolated_margin_account_limit(self, **params): """Query enabled isolated margin account limit. https://developers.binance.com/docs/margin_trading/account/Query-Enabled-Isolated-Margin-Account-Limit :returns: API response .. code-block:: python { "enabledAccount": 5, "maxAccount": 20 } """ return self._request_margin_api( "get", "margin/isolated/accountLimit", True, data=params ) def get_margin_dustlog(self, **params): """ Query the historical information of user's margin account small-value asset conversion BNB. https://binance-docs.github.io/apidocs/spot/en/#margin-dustlog-user_data :param startTime: optional :type startTime: long :param endTime: optional :type endTime: long :returns: API response .. code-block:: python { "total": 8, //Total counts of exchange "userAssetDribblets": [ { "operateTime": 1615985535000, "totalTransferedAmount": "0.00132256", // Total transfered BNB amount for this exchange. "totalServiceChargeAmount": "0.00002699", //Total service charge amount for this exchange. "transId": 45178372831, "userAssetDribbletDetails": [ //Details of this exchange. { "transId": 4359321, "serviceChargeAmount": "0.000009", "amount": "0.0009", "operateTime": 1615985535000, "transferedAmount": "0.000441", "fromAsset": "USDT" }, { "transId": 4359321, "serviceChargeAmount": "0.00001799", "amount": "0.0009", "operateTime": 1615985535000, "transferedAmount": "0.00088156", "fromAsset": "ETH" } ] }, { "operateTime":1616203180000, "totalTransferedAmount": "0.00058795", "totalServiceChargeAmount": "0.000012", "transId": 4357015, "userAssetDribbletDetails": [ { "transId": 4357015, "serviceChargeAmount": "0.00001", "amount": "0.001", "operateTime": 1616203180000, "transferedAmount": "0.00049", "fromAsset": "USDT" }, { "transId": 4357015, "serviceChargeAmount": "0.000002", "amount": "0.0001", "operateTime": 1616203180000, "transferedAmount": "0.00009795", "fromAsset": "ETH" } ] } ] } """ return self._request_margin_api("get", "margin/dribblet", True, data=params) def get_margin_dust_assets(self, **params): """Get margin assets that can be converted into BNB. https://binance-docs.github.io/apidocs/spot/en/#margin-dustlog-user_data :returns: API response .. code-block:: python { "details": [ { "asset": "ADA", "assetFullName": "ADA", "amountFree": "6.21", "toBTC": "0.00016848", "toBNB": "0.01777302", "toBNBOffExchange": "0.01741756", "exchange": "0.00035546" } ], "totalTransferBtc": "0.00016848", "totalTransferBNB": "0.01777302", "dribbletPercentage": "0.02" } """ return self._request_margin_api("get", "margin/dust", True, data=params) def transfer_margin_dust(self, **params): """Convert dust assets to BNB. https://binance-docs.github.io/apidocs/spot/en/#dust-transfer-trade :returns: API response .. code-block:: python { "totalServiceCharge":"0.02102542", "totalTransfered":"1.05127099", "transferResult":[ { "amount":"0.03000000", "fromAsset":"ETH", "operateTime":1563368549307, "serviceChargeAmount":"0.00500000", "tranId":2970932918, "transferedAmount":"0.25000000" }, { "amount":"0.09000000", "fromAsset":"LTC", "operateTime":1563368549404, "serviceChargeAmount":"0.01548000", "tranId":2970932918, "transferedAmount":"0.77400000" } ] } """ return self._request_margin_api("post", "margin/dust", True, data=params) def get_cross_margin_collateral_ratio(self, **params): """ https://developers.binance.com/docs/margin_trading/market-data :param none :returns: API response .. code-block:: python [ { "collaterals": [ { "minUsdValue": "0", "maxUsdValue": "13000000", "discountRate": "1" }, { "minUsdValue": "13000000", "maxUsdValue": "20000000", "discountRate": "0.975" }, { "minUsdValue": "20000000", "discountRate": "0" } ], "assetNames": [ "BNX" ] }, { "collaterals": [ { "minUsdValue": "0", "discountRate": "1" } ], "assetNames": [ "BTC", "BUSD", "ETH", "USDT" ] } ] """ return self._request_margin_api( "get", "margin/crossMarginCollateralRatio", True, data=params ) def get_small_liability_exchange_assets(self, **params): """Query the coins which can be small liability exchange https://developers.binance.com/docs/margin_trading/trade/Get-Small-Liability-Exchange-Coin-List :returns: API response .. code-block:: python [ { "asset": "ETH", "interest": "0.00083334", "principal": "0.001", "liabilityAsset": "USDT", "liabilityQty": 0.3552 } ] """ return self._request_margin_api( "get", "margin/exchange-small-liability", True, data=params ) def exchange_small_liability_assets(self, **params): """Cross Margin Small Liability Exchange https://developers.binance.com/docs/margin_trading/trade/Small-Liability-Exchange :param assetNames: The assets list of small liability exchange :type assetNames: array :returns: API response .. code-block:: python none """ return self._request_margin_api( "post", "margin/exchange-small-liability", True, data=params ) def get_small_liability_exchange_history(self, **params): """Get Small liability Exchange History https://developers.binance.com/docs/margin_trading/trade/Get-Small-Liability-Exchange-History :param current: Currently querying page. Start from 1. Default:1 :type current: int :param size: Default:10, Max:100 :type size: int :param startTime: Default: 30 days from current timestamp :type startTime: long :param endTime: Default: present timestamp :type endTIme: long :returns: API response .. code-block:: python { "total": 1, "rows": [ { "asset": "ETH", "amount": "0.00083434", "targetAsset": "BUSD", "targetAmount": "1.37576819", "bizType": "EXCHANGE_SMALL_LIABILITY", "timestamp": 1672801339253 } ] } """ return self._request_margin_api( "get", "margin/exchange-small-liability-history", True, data=params ) def get_future_hourly_interest_rate(self, **params): """Get user the next hourly estimate interest https://developers.binance.com/docs/margin_trading/borrow-and-repay :param assets: List of assets, separated by commas, up to 20 :type assets: str :param isIsolated: for isolated margin or not, "TRUE", "FALSE" :type isIsolated: bool :returns: API response .. code-block:: python [ { "asset": "BTC", "nextHourlyInterestRate": "0.00000571" }, { "asset": "ETH", "nextHourlyInterestRate": "0.00000578" } ] """ return self._request_margin_api( "get", "margin/next-hourly-interest-rate", True, data=params ) def get_margin_capital_flow(self, **params): """Get cross or isolated margin capital flow https://developers.binance.com/docs/margin_trading/account/Query-Cross-Isolated-Margin-Capital-Flow :param asset: optional :type asset: str :param symbol: Required when querying isolated data :type symbol: str :param type: optional :type type: string :param startTime: Only supports querying the data of the last 90 days :type startTime: long :param endTime: optional :type endTime: long :param formId: If fromId is set, the data with id > fromId will be returned. Otherwise the latest data will be returned :type formId: long :param limit: The number of data items returned each time is limited. Default 500; Max 1000. :type limit: long :returns: API response .. code-block:: python [ { "id": 123456, "tranId": 123123, "timestamp": 1691116657000, "asset": "USDT, "symbol": "BTCUSDT", "type": "BORROW", "amount": "101" }, { "id": 123457, "tranId": 123124, "timestamp": 1691116658000, "asset": "BTC", "symbol": "BTCUSDT", "type": "REPAY", "amount": "10" } ] """ return self._request_margin_api("get", "margin/capital-flow", True, data=params) def get_margin_asset(self, **params): """Query cross-margin asset https://binance-docs.github.io/apidocs/spot/en/#query-margin-asset-market_data :param asset: name of the asset :type asset: str .. code-block:: python asset_details = client.get_margin_asset(asset='BNB') :returns: API response .. code-block:: python { "assetFullName": "Binance Coin", "assetName": "BNB", "isBorrowable": false, "isMortgageable": true, "userMinBorrow": "0.00000000", "userMinRepay": "0.00000000" } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("get", "margin/asset", data=params) def get_margin_symbol(self, **params): """Query cross-margin symbol info https://binance-docs.github.io/apidocs/spot/en/#query-cross-margin-pair-market_data :param symbol: name of the symbol pair :type symbol: str .. code:: python pair_details = client.get_margin_symbol(symbol='BTCUSDT') :returns: API response .. code-block:: python { "id":323355778339572400, "symbol":"BTCUSDT", "base":"BTC", "quote":"USDT", "isMarginTrade":true, "isBuyAllowed":true, "isSellAllowed":true } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("get", "margin/pair", data=params) def get_margin_all_assets(self, **params): """Get All Margin Assets (MARKET_DATA) https://developers.binance.com/docs/margin_trading/market-data/Get-All-Margin-Assets .. code:: python margin_assets = client.get_margin_all_assets() :returns: API response .. code-block:: python [ { "assetFullName": "USD coin", "assetName": "USDC", "isBorrowable": true, "isMortgageable": true, "userMinBorrow": "0.00000000", "userMinRepay": "0.00000000" }, { "assetFullName": "BNB-coin", "assetName": "BNB", "isBorrowable": true, "isMortgageable": true, "userMinBorrow": "1.00000000", "userMinRepay": "0.00000000" } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("get", "margin/allAssets", data=params) def get_margin_all_pairs(self, **params): """Get All Cross Margin Pairs (MARKET_DATA) https://developers.binance.com/docs/margin_trading/market-data/Get-All-Cross-Margin-Pairs .. code:: python margin_pairs = client.get_margin_all_pairs() :returns: API response .. code-block:: python [ { "base": "BNB", "id": 351637150141315861, "isBuyAllowed": true, "isMarginTrade": true, "isSellAllowed": true, "quote": "BTC", "symbol": "BNBBTC" }, { "base": "TRX", "id": 351637923235429141, "isBuyAllowed": true, "isMarginTrade": true, "isSellAllowed": true, "quote": "BTC", "symbol": "TRXBTC" } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("get", "margin/allPairs", data=params) def create_isolated_margin_account(self, **params): """Create isolated margin account for symbol https://binance-docs.github.io/apidocs/spot/en/#create-isolated-margin-account-margin :param base: Base asset of symbol :type base: str :param quote: Quote asset of symbol :type quote: str .. code:: python pair_details = client.create_isolated_margin_account(base='USDT', quote='BTC') :returns: API response .. code-block:: python { "success": true, "symbol": "BTCUSDT" } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "margin/isolated/create", signed=True, data=params ) def get_isolated_margin_symbol(self, **params): """Query isolated margin symbol info https://binance-docs.github.io/apidocs/spot/en/#query-isolated-margin-symbol-user_data :param symbol: name of the symbol pair :type symbol: str .. code:: python pair_details = client.get_isolated_margin_symbol(symbol='BTCUSDT') :returns: API response .. code-block:: python { "symbol":"BTCUSDT", "base":"BTC", "quote":"USDT", "isMarginTrade":true, "isBuyAllowed":true, "isSellAllowed":true } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "margin/isolated/pair", signed=True, data=params ) def get_all_isolated_margin_symbols(self, **params): """Query isolated margin symbol info for all pairs https://developers.binance.com/docs/margin_trading/market-data/Get-All-Isolated-Margin-Symbol .. code:: python pair_details = client.get_all_isolated_margin_symbols() :returns: API response .. code-block:: python [ { "base": "BNB", "isBuyAllowed": true, "isMarginTrade": true, "isSellAllowed": true, "quote": "BTC", "symbol": "BNBBTC" }, { "base": "TRX", "isBuyAllowed": true, "isMarginTrade": true, "isSellAllowed": true, "quote": "BTC", "symbol": "TRXBTC" } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "margin/isolated/allPairs", signed=True, data=params ) def get_isolated_margin_fee_data(self, **params): """Get isolated margin fee data collection with any vip level or user's current specific data as https://www.binance.com/en/margin-fee https://developers.binance.com/docs/margin_trading/account/Query-Isolated-Margin-Fee-Data :param vipLevel: User's current specific margin data will be returned if vipLevel is omitted :type vipLevel: int :param symbol: optional :type symbol: str :returns: API response .. code-block:: python [ { "vipLevel": 0, "symbol": "BTCUSDT", "leverage": "10", "data": [ { "coin": "BTC", "dailyInterest": "0.00026125", "borrowLimit": "270" }, { "coin": "USDT", "dailyInterest": "0.000475", "borrowLimit": "2100000" } ] } ] """ return self._request_margin_api( "get", "margin/isolatedMarginData", True, data=params ) def get_isolated_margin_tier_data(self, **params): """Get isolated margin tier data collection with any tier as https://www.binance.com/en/margin-data https://developers.binance.com/docs/margin_trading/market-data/Query-Isolated-Margin-Tier-Data :param symbol: required :type symbol: str :param tier: All margin tier data will be returned if tier is omitted :type tier: int :param recvWindow: optional: No more than 60000 :type recvWindow: :returns: API response .. code-block:: python [ { "symbol": "BTCUSDT", "tier": 1, "effectiveMultiple": "10", "initialRiskRatio": "1.111", "liquidationRiskRatio": "1.05", "baseAssetMaxBorrowable": "9", "quoteAssetMaxBorrowable": "70000" } ] """ return self._request_margin_api( "get", "margin/isolatedMarginTier", True, data=params ) def margin_manual_liquidation(self, **params): """ https://developers.binance.com/docs/margin_trading/trade/Margin-Manual-Liquidation :param type: required :type symbol: str: When type selected is "ISOLATED", symbol must be filled in :returns: API response [ { "asset": "ETH", "interest": "0.00083334", "principal": "0.001", "liabilityAsset": "USDT", "liabilityQty": 0.3552 } ] """ return self._request_margin_api( "post", "margin/manual-liquidation", True, data=params ) def toggle_bnb_burn_spot_margin(self, **params): """Toggle BNB Burn On Spot Trade And Margin Interest https://developers.binance.com/docs/wallet/asset/Toggle-BNB-Burn-On-Spot-Trade-And-Margin-Interest :param spotBNBBurn: Determines whether to use BNB to pay for trading fees on SPOT :type spotBNBBurn: bool :param interestBNBBurn: Determines whether to use BNB to pay for margin loan's interest :type interestBNBBurn: bool .. code:: python response = client.toggle_bnb_burn_spot_margin() :returns: API response .. code-block:: python { "spotBNBBurn":true, "interestBNBBurn": false } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("post", "bnbBurn", signed=True, data=params) def get_bnb_burn_spot_margin(self, **params): """Get BNB Burn Status https://developers.binance.com/docs/margin_trading/account/Get-BNB-Burn-Status .. code:: python status = client.get_bnb_burn_spot_margin() :returns: API response .. code-block:: python { "spotBNBBurn":true, "interestBNBBurn": false } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("get", "bnbBurn", signed=True, data=params) def get_margin_price_index(self, **params): """Query margin priceIndex https://developers.binance.com/docs/margin_trading/market-data/Query-Margin-PriceIndex :param symbol: name of the symbol pair :type symbol: str .. code:: python price_index_details = client.get_margin_price_index(symbol='BTCUSDT') :returns: API response .. code-block:: python { "calcTime": 1562046418000, "price": "0.00333930", "symbol": "BNBBTC" } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("get", "margin/priceIndex", data=params) def transfer_margin_to_spot(self, **params): """Execute transfer between cross-margin account and spot account. https://binance-docs.github.io/apidocs/spot/en/#cross-margin-account-transfer-margin :param asset: name of the asset :type asset: str :param amount: amount to transfer :type amount: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int .. code-block:: python transfer = client.transfer_margin_to_spot(asset='BTC', amount='1.1') :returns: API response .. code-block:: python { "tranId": 100000001 } :raises: BinanceRequestException, BinanceAPIException """ params["type"] = 2 return self._request_margin_api( "post", "margin/transfer", signed=True, data=params ) def transfer_spot_to_margin(self, **params): """Execute transfer between spot account and cross-margin account. https://binance-docs.github.io/apidocs/spot/en/#cross-margin-account-transfer-margin :param asset: name of the asset :type asset: str :param amount: amount to transfer :type amount: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int .. code-block:: python transfer = client.transfer_spot_to_margin(asset='BTC', amount='1.1') :returns: API response .. code-block:: python { "tranId": 100000001 } :raises: BinanceRequestException, BinanceAPIException """ params["type"] = 1 return self._request_margin_api( "post", "margin/transfer", signed=True, data=params ) def transfer_isolated_margin_to_spot(self, **params): """Execute transfer between isolated margin account and spot account. https://binance-docs.github.io/apidocs/spot/en/#isolated-margin-account-transfer-margin :param asset: name of the asset :type asset: str :param symbol: pair symbol :type symbol: str :param amount: amount to transfer :type amount: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int .. code-block:: python transfer = client.transfer_isolated_margin_to_spot(asset='BTC', symbol='ETHBTC', amount='1.1') :returns: API response .. code-block:: python { "tranId": 100000001 } :raises: BinanceRequestException, BinanceAPIException """ params["transFrom"] = "ISOLATED_MARGIN" params["transTo"] = "SPOT" return self._request_margin_api( "post", "margin/isolated/transfer", signed=True, data=params ) def transfer_spot_to_isolated_margin(self, **params): """Execute transfer between spot account and isolated margin account. https://binance-docs.github.io/apidocs/spot/en/#isolated-margin-account-transfer-margin :param asset: name of the asset :type asset: str :param symbol: pair symbol :type symbol: str :param amount: amount to transfer :type amount: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int .. code-block:: python transfer = client.transfer_spot_to_isolated_margin(asset='BTC', symbol='ETHBTC', amount='1.1') :returns: API response .. code-block:: python { "tranId": 100000001 } :raises: BinanceRequestException, BinanceAPIException """ params["transFrom"] = "SPOT" params["transTo"] = "ISOLATED_MARGIN" return self._request_margin_api( "post", "margin/isolated/transfer", signed=True, data=params ) def get_isolated_margin_tranfer_history(self, **params): """Get transfers to isolated margin account. https://binance-docs.github.io/apidocs/spot/en/#get-isolated-margin-transfer-history-user_data :param asset: name of the asset :type asset: str :param symbol: pair required :type symbol: str :param transFrom: optional SPOT, ISOLATED_MARGIN :param transFrom: str SPOT, ISOLATED_MARGIN :param transTo: optional :param transTo: str :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param current: Currently querying page. Start from 1. Default:1 :type current: str :param size: Default:10 Max:100 :type size: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int .. code-block:: python transfer = client.transfer_spot_to_isolated_margin(symbol='ETHBTC') :returns: API response .. code-block:: python { "rows": [ { "amount": "0.10000000", "asset": "BNB", "status": "CONFIRMED", "timestamp": 1566898617000, "txId": 5240372201, "transFrom": "SPOT", "transTo": "ISOLATED_MARGIN" }, { "amount": "5.00000000", "asset": "USDT", "status": "CONFIRMED", "timestamp": 1566888436123, "txId": 5239810406, "transFrom": "ISOLATED_MARGIN", "transTo": "SPOT" } ], "total": 2 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "margin/isolated/transfer", signed=True, data=params ) def create_margin_loan(self, **params): """Apply for a loan in cross-margin or isolated-margin account. https://binance-docs.github.io/apidocs/spot/en/#margin-account-borrow-margin :param asset: name of the asset :type asset: str :param amount: amount to transfer :type amount: str :param isIsolated: set to 'TRUE' for isolated margin (default 'FALSE') :type isIsolated: str :param symbol: Isolated margin symbol (default blank for cross-margin) :type symbol: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int .. code-block:: python transaction = client.margin_create_loan(asset='BTC', amount='1.1') transaction = client.margin_create_loan(asset='BTC', amount='1.1', isIsolated='TRUE', symbol='ETHBTC') :returns: API response .. code-block:: python { "tranId": 100000001 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("post", "margin/loan", signed=True, data=params) def repay_margin_loan(self, **params): """Repay loan in cross-margin or isolated-margin account. If amount is more than the amount borrowed, the full loan will be repaid. https://binance-docs.github.io/apidocs/spot/en/#margin-account-repay-margin :param asset: name of the asset :type asset: str :param amount: amount to transfer :type amount: str :param isIsolated: set to 'TRUE' for isolated margin (default 'FALSE') :type isIsolated: str :param symbol: Isolated margin symbol (default blank for cross-margin) :type symbol: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int .. code-block:: python transaction = client.margin_repay_loan(asset='BTC', amount='1.1') transaction = client.margin_repay_loan(asset='BTC', amount='1.1', isIsolated='TRUE', symbol='ETHBTC') :returns: API response .. code-block:: python { "tranId": 100000001 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "margin/repay", signed=True, data=params ) def create_margin_order(self, **params): """Post a new order for margin account. https://developers.binance.com/docs/margin_trading/trade/Margin-Account-New-Order :param symbol: required :type symbol: str :param isIsolated: set to 'TRUE' for isolated margin (default 'FALSE') :type isIsolated: str :param side: required :type side: str :param type: required :type type: str :param quantity: required :type quantity: decimal :param price: required :type price: str :param stopPrice: Used with STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, and TAKE_PROFIT_LIMIT orders. :type stopPrice: str :param timeInForce: required if limit order GTC,IOC,FOK :type timeInForce: str :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param icebergQty: Used with LIMIT, STOP_LOSS_LIMIT, and TAKE_PROFIT_LIMIT to create an iceberg order. :type icebergQty: str :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; MARKET and LIMIT order types default to FULL, all other orders default to ACK. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response Response ACK: .. code-block:: python { "symbol": "BTCUSDT", "orderId": 28, "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP", "transactTime": 1507725176595 } Response RESULT: .. code-block:: python { "symbol": "BTCUSDT", "orderId": 28, "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP", "transactTime": 1507725176595, "price": "1.00000000", "origQty": "10.00000000", "executedQty": "10.00000000", "cummulativeQuoteQty": "10.00000000", "status": "FILLED", "timeInForce": "GTC", "type": "MARKET", "side": "SELL" } Response FULL: .. code-block:: python { "symbol": "BTCUSDT", "orderId": 28, "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP", "transactTime": 1507725176595, "price": "1.00000000", "origQty": "10.00000000", "executedQty": "10.00000000", "cummulativeQuoteQty": "10.00000000", "status": "FILLED", "timeInForce": "GTC", "type": "MARKET", "side": "SELL", "fills": [ { "price": "4000.00000000", "qty": "1.00000000", "commission": "4.00000000", "commissionAsset": "USDT" }, { "price": "3999.00000000", "qty": "5.00000000", "commission": "19.99500000", "commissionAsset": "USDT" }, { "price": "3998.00000000", "qty": "2.00000000", "commission": "7.99600000", "commissionAsset": "USDT" }, { "price": "3997.00000000", "qty": "1.00000000", "commission": "3.99700000", "commissionAsset": "USDT" }, { "price": "3995.00000000", "qty": "1.00000000", "commission": "3.99500000", "commissionAsset": "USDT" } ] } :raises: BinanceRequestException, BinanceAPIException, BinanceOrderException, BinanceOrderMinAmountException, BinanceOrderMinPriceException, BinanceOrderMinTotalException, BinanceOrderUnknownSymbolException, BinanceOrderInactiveSymbolException """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.SPOT_ORDER_PREFIX + self.uuid22() return self._request_margin_api( "post", "margin/order", signed=True, data=params ) def cancel_margin_order(self, **params): """Cancel an active order for margin account. Either orderId or origClientOrderId must be sent. https://developers.binance.com/docs/margin_trading/trade/Margin-Account-Cancel-Order :param symbol: required :type symbol: str :param isIsolated: set to 'TRUE' for isolated margin (default 'FALSE') :type isIsolated: str :param orderId: :type orderId: str :param origClientOrderId: :type origClientOrderId: str :param newClientOrderId: Used to uniquely identify this cancel. Automatically generated by default. :type newClientOrderId: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response { "symbol": "LTCBTC", "orderId": 28, "origClientOrderId": "myOrder1", "clientOrderId": "cancelMyOrder1", "transactTime": 1507725176595, "price": "1.00000000", "origQty": "10.00000000", "executedQty": "8.00000000", "cummulativeQuoteQty": "8.00000000", "status": "CANCELED", "timeInForce": "GTC", "type": "LIMIT", "side": "SELL" } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "delete", "margin/order", signed=True, data=params ) def cancel_all_open_margin_orders(self, **params): """ Cancels all active orders on a symbol for margin account. https://developers.binance.com/docs/margin_trading/trade/Margin-Account-Cancel-All-Open-Orders :param symbol: required :type symbol: str :param isIsolated: set to 'TRUE' for isolated margin (default 'FALSE') :type isIsolated: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "delete", "margin/openOrders", signed=True, data=params ) def set_margin_max_leverage(self, **params): """Adjust cross margin max leverage https://developers.binance.com/docs/margin_trading/account :param maxLeverage: required Can only adjust 3 or 5,Example: maxLeverage=3 :type maxLeverage: int :returns: API response { "success": true } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "margin/max-leverage", signed=True, data=params ) def get_margin_transfer_history(self, **params): """Query margin transfer history https://developers.binance.com/docs/margin_trading/transfer :param asset: optional :type asset: str :param type: optional Transfer Type: ROLL_IN, ROLL_OUT :type type: str :param archived: optional Default: false. Set to true for archived data from 6 months ago :type archived: str :param startTime: earliest timestamp to filter transactions :type startTime: str :param endTime: Used to uniquely identify this cancel. Automatically generated by default. :type endTime: str :param current: Currently querying page. Start from 1. Default:1 :type current: str :param size: Default:10 Max:100 :type size: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response { "rows": [ { "amount": "0.10000000", "asset": "BNB", "status": "CONFIRMED", "timestamp": 1566898617, "txId": 5240372201, "type": "ROLL_IN" }, { "amount": "5.00000000", "asset": "USDT", "status": "CONFIRMED", "timestamp": 1566888436, "txId": 5239810406, "type": "ROLL_OUT" }, { "amount": "1.00000000", "asset": "EOS", "status": "CONFIRMED", "timestamp": 1566888403, "txId": 5239808703, "type": "ROLL_IN" } ], "total": 3 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "margin/transfer", signed=True, data=params ) def get_margin_loan_details(self, **params): """Query loan record txId or startTime must be sent. txId takes precedence. https://binance-docs.github.io/apidocs/spot/en/#query-loan-record-user_data :param asset: required :type asset: str :param isolatedSymbol: isolated symbol (if querying isolated margin) :type isolatedSymbol: str :param txId: the tranId in of the created loan :type txId: str :param startTime: earliest timestamp to filter transactions :type startTime: str :param endTime: Used to uniquely identify this cancel. Automatically generated by default. :type endTime: str :param current: Currently querying page. Start from 1. Default:1 :type current: str :param size: Default:10 Max:100 :type size: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response { "rows": [ { "asset": "BNB", "principal": "0.84624403", "timestamp": 1555056425000, //one of PENDING (pending to execution), CONFIRMED (successfully loaned), FAILED (execution failed, nothing happened to your account); "status": "CONFIRMED" } ], "total": 1 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("get", "margin/loan", signed=True, data=params) def get_margin_repay_details(self, **params): """Query repay record txId or startTime must be sent. txId takes precedence. https://binance-docs.github.io/apidocs/spot/en/#query-repay-record-user_data :param asset: required :type asset: str :param isolatedSymbol: isolated symbol (if querying isolated margin) :type isolatedSymbol: str :param txId: the tranId in of the created loan :type txId: str :param startTime: :type startTime: str :param endTime: Used to uniquely identify this cancel. Automatically generated by default. :type endTime: str :param current: Currently querying page. Start from 1. Default:1 :type current: str :param size: Default:10 Max:100 :type size: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response { "rows": [ { //Total amount repaid "amount": "14.00000000", "asset": "BNB", //Interest repaid "interest": "0.01866667", //Principal repaid "principal": "13.98133333", //one of PENDING (pending to execution), CONFIRMED (successfully loaned), FAILED (execution failed, nothing happened to your account); "status": "CONFIRMED", "timestamp": 1563438204000, "txId": 2970933056 } ], "total": 1 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("get", "margin/repay", signed=True, data=params) def get_cross_margin_data(self, **params): """Query Cross Margin Fee Data (USER_DATA) https://developers.binance.com/docs/margin_trading/account/Query-Cross-Margin-Fee-Data :param vipLevel: User's current specific margin data will be returned if vipLevel is omitted :type vipLevel: int :param coin :type coin: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response (example): [ { "vipLevel": 0, "coin": "BTC", "transferIn": true, "borrowable": true, "dailyInterest": "0.00026125", "yearlyInterest": "0.0953", "borrowLimit": "180", "marginablePairs": [ "BNBBTC", "TRXBTC", "ETHBTC", "BTCUSDT" ] } ] """ return self._request_margin_api( "get", "margin/crossMarginData", signed=True, data=params ) def get_margin_interest_history(self, **params): """Get Interest History (USER_DATA) https://developers.binance.com/docs/margin_trading/borrow-and-repay/Get-Interest-History :param asset: :type asset: str :param isolatedSymbol: isolated symbol (if querying isolated margin) :type isolatedSymbol: str :param startTime: :type startTime: str :param endTime: :type endTime: str :param current: Currently querying page. Start from 1. Default:1 :type current: str :param size: Default:10 Max:100 :type size: int :param archived: Default: false. Set to true for archived data from 6 months ago :type archived: bool :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response { "rows":[ { "isolatedSymbol": "BNBUSDT", // isolated symbol, will not be returned for crossed margin "asset": "BNB", "interest": "0.02414667", "interestAccuredTime": 1566813600000, "interestRate": "0.01600000", "principal": "36.22000000", "type": "ON_BORROW" } ], "total": 1 } """ return self._request_margin_api( "get", "margin/interestHistory", signed=True, data=params ) def get_margin_force_liquidation_rec(self, **params): """Get Force Liquidation Record (USER_DATA) https://developers.binance.com/docs/margin_trading/trade :param startTime: :type startTime: str :param endTime: :type endTime: str :param isolatedSymbol: isolated symbol (if querying isolated margin) :type isolatedSymbol: str :param current: Currently querying page. Start from 1. Default:1 :type current: str :param size: Default:10 Max:100 :type size: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response { "rows": [ { "avgPrice": "0.00388359", "executedQty": "31.39000000", "orderId": 180015097, "price": "0.00388110", "qty": "31.39000000", "side": "SELL", "symbol": "BNBBTC", "timeInForce": "GTC", "isIsolated": true, "updatedTime": 1558941374745 } ], "total": 1 } """ return self._request_margin_api( "get", "margin/forceLiquidationRec", signed=True, data=params ) def get_margin_order(self, **params): """Query margin accounts order Either orderId or origClientOrderId must be sent. For some historical orders cummulativeQuoteQty will be < 0, meaning the data is not available at this time. https://developers.binance.com/docs/margin_trading/trade/Query-Margin-Account-Order :param symbol: required :type symbol: str :param isIsolated: set to 'TRUE' for isolated margin (default 'FALSE') :type isIsolated: str :param orderId: :type orderId: str :param origClientOrderId: :type origClientOrderId: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response { "clientOrderId": "ZwfQzuDIGpceVhKW5DvCmO", "cummulativeQuoteQty": "0.00000000", "executedQty": "0.00000000", "icebergQty": "0.00000000", "isWorking": true, "orderId": 213205622, "origQty": "0.30000000", "price": "0.00493630", "side": "SELL", "status": "NEW", "stopPrice": "0.00000000", "symbol": "BNBBTC", "time": 1562133008725, "timeInForce": "GTC", "type": "LIMIT", "updateTime": 1562133008725 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("get", "margin/order", signed=True, data=params) def get_open_margin_orders(self, **params): """Query margin accounts open orders If the symbol is not sent, orders for all symbols will be returned in an array (cross-margin only). If querying isolated margin orders, both the isIsolated='TRUE' and symbol=symbol_name must be set. When all symbols are returned, the number of requests counted against the rate limiter is equal to the number of symbols currently trading on the exchange. https://developers.binance.com/docs/margin_trading/trade/Query-Margin-Account-Open-Orders :param symbol: optional :type symbol: str :param isIsolated: set to 'TRUE' for isolated margin (default 'FALSE') :type isIsolated: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response [ { "clientOrderId": "qhcZw71gAkCCTv0t0k8LUK", "cummulativeQuoteQty": "0.00000000", "executedQty": "0.00000000", "icebergQty": "0.00000000", "isWorking": true, "orderId": 211842552, "origQty": "0.30000000", "price": "0.00475010", "side": "SELL", "status": "NEW", "stopPrice": "0.00000000", "symbol": "BNBBTC", "time": 1562040170089, "timeInForce": "GTC", "type": "LIMIT", "updateTime": 1562040170089 } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "margin/openOrders", signed=True, data=params ) def get_all_margin_orders(self, **params): """Query all margin accounts orders If orderId is set, it will get orders >= that orderId. Otherwise most recent orders are returned. For some historical orders cummulativeQuoteQty will be < 0, meaning the data is not available at this time. https://developers.binance.com/docs/margin_trading/trade/Query-Margin-Account-All-Orders :param symbol: required :type symbol: str :param isIsolated: set to 'TRUE' for isolated margin (default 'FALSE') :type isIsolated: str :param orderId: optional :type orderId: str :param startTime: optional :type startTime: str :param endTime: optional :type endTime: str :param limit: Default 500; max 1000 :type limit: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response [ { "id": 43123876, "price": "0.00395740", "qty": "4.06000000", "quoteQty": "0.01606704", "symbol": "BNBBTC", "time": 1556089977693 }, { "id": 43123877, "price": "0.00395740", "qty": "0.77000000", "quoteQty": "0.00304719", "symbol": "BNBBTC", "time": 1556089977693 }, { "id": 43253549, "price": "0.00428930", "qty": "23.30000000", "quoteQty": "0.09994069", "symbol": "BNBBTC", "time": 1556163963504 } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "margin/allOrders", signed=True, data=params ) def get_margin_trades(self, **params): """Query margin accounts trades If fromId is set, it will get orders >= that fromId. Otherwise most recent orders are returned. https://developers.binance.com/docs/margin_trading/trade/Query-Margin-Account-Trade-List :param symbol: required :type symbol: str :param isIsolated: set to 'TRUE' for isolated margin (default 'FALSE') :type isIsolated: str :param fromId: optional :type fromId: str :param startTime: optional :type startTime: str :param endTime: optional :type endTime: str :param limit: Default 500; max 1000 :type limit: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response [ { "commission": "0.00006000", "commissionAsset": "BTC", "id": 34, "isBestMatch": true, "isBuyer": false, "isMaker": false, "orderId": 39324, "price": "0.02000000", "qty": "3.00000000", "symbol": "BNBBTC", "time": 1561973357171 }, { "commission": "0.00002950", "commissionAsset": "BTC", "id": 32, "isBestMatch": true, "isBuyer": false, "isMaker": true, "orderId": 39319, "price": "0.00590000", "qty": "5.00000000", "symbol": "BNBBTC", "time": 1561964645345 } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "margin/myTrades", signed=True, data=params ) def get_max_margin_loan(self, **params): """Query max borrow amount for an asset https://binance-docs.github.io/apidocs/spot/en/#query-max-borrow-user_data :param asset: required :type asset: str :param isolatedSymbol: isolated symbol (if querying isolated margin) :type isolatedSymbol: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response { "amount": "1.69248805" } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "margin/maxBorrowable", signed=True, data=params ) def get_max_margin_transfer(self, **params): """Query max transfer-out amount https://developers.binance.com/docs/margin_trading/transfer/Query-Max-Transfer-Out-Amount :param asset: required :type asset: str :param isolatedSymbol: isolated symbol (if querying isolated margin) :type isolatedSymbol: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response { "amount": "3.59498107" } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "margin/maxTransferable", signed=True, data=params ) def get_margin_delist_schedule(self, **params): """Get tokens or symbols delist schedule for cross margin and isolated margin https://developers.binance.com/docs/margin_trading/market-data/Get-Delist-Schedule :param recvWindow: optional - the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python [ { "delistTime": 1686161202000, "crossMarginAssets": [ "BTC", "USDT" ], "isolatedMarginSymbols": [ "ADAUSDT", "BNBUSDT" ] }, { "delistTime": 1686222232000, "crossMarginAssets": [ "ADA" ], "isolatedMarginSymbols": [] } ] """ return self._request_margin_api( "get", "/margin/delist-schedule", signed=True, data=params ) # Margin OCO def create_margin_oco_order(self, **params): """Post a new OCO trade for margin account. https://developers.binance.com/docs/margin_trading/trade/Margin-Account-New-OCO :param symbol: required :type symbol: str :param isIsolated: for isolated margin or not, "TRUE", "FALSE",default "FALSE" :type symbol: str :param listClientOrderId: A unique id for the list order. Automatically generated if not sent. :type listClientOrderId: str :param side: required :type side: str :param quantity: required :type quantity: decimal :param limitClientOrderId: A unique id for the limit order. Automatically generated if not sent. :type limitClientOrderId: str :param price: required :type price: str :param limitIcebergQty: Used to make the LIMIT_MAKER leg an iceberg order. :type limitIcebergQty: decimal :param stopClientOrderId: A unique Id for the stop loss/stop loss limit leg. Automatically generated if not sent. :type stopClientOrderId: str :param stopPrice: required :type stopPrice: str :param stopLimitPrice: If provided, stopLimitTimeInForce is required. :type stopLimitPrice: str :param stopIcebergQty: Used with STOP_LOSS_LIMIT leg to make an iceberg order. :type stopIcebergQty: decimal :param stopLimitTimeInForce: Valid values are GTC/FOK/IOC. :type stopLimitTimeInForce: str :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param sideEffectType: NO_SIDE_EFFECT, MARGIN_BUY, AUTO_REPAY; default NO_SIDE_EFFECT. :type sideEffectType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "orderListId": 0, "contingencyType": "OCO", "listStatusType": "EXEC_STARTED", "listOrderStatus": "EXECUTING", "listClientOrderId": "JYVpp3F0f5CAG15DhtrqLp", "transactionTime": 1563417480525, "symbol": "LTCBTC", "marginBuyBorrowAmount": "5", // will not return if no margin trade happens "marginBuyBorrowAsset": "BTC", // will not return if no margin trade happens "isIsolated": false, // if isolated margin "orders": [ { "symbol": "LTCBTC", "orderId": 2, "clientOrderId": "Kk7sqHb9J6mJWTMDVW7Vos" }, { "symbol": "LTCBTC", "orderId": 3, "clientOrderId": "xTXKaGYd4bluPVp78IVRvl" } ], "orderReports": [ { "symbol": "LTCBTC", "orderId": 2, "orderListId": 0, "clientOrderId": "Kk7sqHb9J6mJWTMDVW7Vos", "transactTime": 1563417480525, "price": "0.000000", "origQty": "0.624363", "executedQty": "0.000000", "cummulativeQuoteQty": "0.000000", "status": "NEW", "timeInForce": "GTC", "type": "STOP_LOSS", "side": "BUY", "stopPrice": "0.960664" }, { "symbol": "LTCBTC", "orderId": 3, "orderListId": 0, "clientOrderId": "xTXKaGYd4bluPVp78IVRvl", "transactTime": 1563417480525, "price": "0.036435", "origQty": "0.624363", "executedQty": "0.000000", "cummulativeQuoteQty": "0.000000", "status": "NEW", "timeInForce": "GTC", "type": "LIMIT_MAKER", "side": "BUY" } ] } :raises: BinanceRequestException, BinanceAPIException, BinanceOrderException, BinanceOrderMinAmountException, BinanceOrderMinPriceException, BinanceOrderMinTotalException, BinanceOrderUnknownSymbolException, BinanceOrderInactiveSymbolException """ return self._request_margin_api( "post", "margin/order/oco", signed=True, data=params ) def cancel_margin_oco_order(self, **params): """Cancel an entire Order List for a margin account. https://developers.binance.com/docs/margin_trading/trade/Margin-Account-Cancel-OCO :param symbol: required :type symbol: str :param isIsolated: for isolated margin or not, "TRUE", "FALSE",default "FALSE" :type symbol: str :param orderListId: Either orderListId or listClientOrderId must be provided :type orderListId: int :param listClientOrderId: Either orderListId or listClientOrderId must be provided :type listClientOrderId: str :param newClientOrderId: Used to uniquely identify this cancel. Automatically generated by default. :type newClientOrderId: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "orderListId": 0, "contingencyType": "OCO", "listStatusType": "ALL_DONE", "listOrderStatus": "ALL_DONE", "listClientOrderId": "C3wyj4WVEktd7u9aVBRXcN", "transactionTime": 1574040868128, "symbol": "LTCBTC", "isIsolated": false, // if isolated margin "orders": [ { "symbol": "LTCBTC", "orderId": 2, "clientOrderId": "pO9ufTiFGg3nw2fOdgeOXa" }, { "symbol": "LTCBTC", "orderId": 3, "clientOrderId": "TXOvglzXuaubXAaENpaRCB" } ], "orderReports": [ { "symbol": "LTCBTC", "origClientOrderId": "pO9ufTiFGg3nw2fOdgeOXa", "orderId": 2, "orderListId": 0, "clientOrderId": "unfWT8ig8i0uj6lPuYLez6", "price": "1.00000000", "origQty": "10.00000000", "executedQty": "0.00000000", "cummulativeQuoteQty": "0.00000000", "status": "CANCELED", "timeInForce": "GTC", "type": "STOP_LOSS_LIMIT", "side": "SELL", "stopPrice": "1.00000000" }, { "symbol": "LTCBTC", "origClientOrderId": "TXOvglzXuaubXAaENpaRCB", "orderId": 3, "orderListId": 0, "clientOrderId": "unfWT8ig8i0uj6lPuYLez6", "price": "3.00000000", "origQty": "10.00000000", "executedQty": "0.00000000", "cummulativeQuoteQty": "0.00000000", "status": "CANCELED", "timeInForce": "GTC", "type": "LIMIT_MAKER", "side": "SELL" } ] } """ return self._request_margin_api( "delete", "margin/orderList", signed=True, data=params ) def get_margin_oco_order(self, **params): """Retrieves a specific OCO based on provided optional parameters https://developers.binance.com/docs/margin_trading/trade/Query-Margin-Account-OCO :param isIsolated: for isolated margin or not, "TRUE", "FALSE",default "FALSE" :type symbol: str :param symbol: mandatory for isolated margin, not supported for cross margin :type symbol: str :param orderListId: Either orderListId or listClientOrderId must be provided :type orderListId: int :param listClientOrderId: Either orderListId or listClientOrderId must be provided :type listClientOrderId: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response { "orderListId": 27, "contingencyType": "OCO", "listStatusType": "EXEC_STARTED", "listOrderStatus": "EXECUTING", "listClientOrderId": "h2USkA5YQpaXHPIrkd96xE", "transactionTime": 1565245656253, "symbol": "LTCBTC", "isIsolated": false, // if isolated margin "orders": [ { "symbol": "LTCBTC", "orderId": 4, "clientOrderId": "qD1gy3kc3Gx0rihm9Y3xwS" }, { "symbol": "LTCBTC", "orderId": 5, "clientOrderId": "ARzZ9I00CPM8i3NhmU9Ega" } ] } """ return self._request_margin_api( "get", "margin/orderList", signed=True, data=params ) def get_open_margin_oco_orders(self, **params): """Retrieves open OCO trades https://developers.binance.com/docs/margin_trading/trade/Query-Margin-Account-Open-OCO :param isIsolated: for isolated margin or not, "TRUE", "FALSE",default "FALSE" :type symbol: str :param symbol: mandatory for isolated margin, not supported for cross margin :type symbol: str :param fromId: If supplied, neither startTime or endTime can be provided :type fromId: int :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param limit: optional Default Value: 500; Max Value: 1000 :type limit: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response [ { "orderListId": 29, "contingencyType": "OCO", "listStatusType": "EXEC_STARTED", "listOrderStatus": "EXECUTING", "listClientOrderId": "amEEAXryFzFwYF1FeRpUoZ", "transactionTime": 1565245913483, "symbol": "LTCBTC", "isIsolated": true, // if isolated margin "orders": [ { "symbol": "LTCBTC", "orderId": 4, "clientOrderId": "oD7aesZqjEGlZrbtRpy5zB" }, { "symbol": "LTCBTC", "orderId": 5, "clientOrderId": "Jr1h6xirOxgeJOUuYQS7V3" } ] }, { "orderListId": 28, "contingencyType": "OCO", "listStatusType": "EXEC_STARTED", "listOrderStatus": "EXECUTING", "listClientOrderId": "hG7hFNxJV6cZy3Ze4AUT4d", "transactionTime": 1565245913407, "symbol": "LTCBTC", "orders": [ { "symbol": "LTCBTC", "orderId": 2, "clientOrderId": "j6lFOfbmFMRjTYA7rRJ0LP" }, { "symbol": "LTCBTC", "orderId": 3, "clientOrderId": "z0KCjOdditiLS5ekAFtK81" } ] } ] """ return self._request_margin_api( "get", "margin/openOrderList", signed=True, data=params ) # Cross-margin def margin_stream_get_listen_key(self): """Start a new cross-margin data stream and return the listen key If a stream already exists it should return the same key. If the stream becomes invalid a new key is returned. Can be used to keep the stream alive. https://developers.binance.com/docs/margin_trading/trade-data-stream/Start-Margin-User-Data-Stream :returns: API response .. code-block:: python { "listenKey": "pqia91ma19a5s61cv6a81va65sdf19v8a65a1a5s61cv6a81va65sdf19v8a65a1" } :raises: BinanceRequestException, BinanceAPIException """ warnings.warn( "POST /sapi/v1/userDataStream is deprecated and will be removed on 2026-02-20. " "Use the WebSocket API subscription method instead (create listenToken via POST /sapi/v1/userListenToken, " "then subscribe with userDataStream.subscribe.listenToken). " "The margin_socket() method now uses WebSocket API by default.", DeprecationWarning, stacklevel=2 ) res = self._request_margin_api("post", "userDataStream", signed=False, data={}) return res["listenKey"] def margin_stream_keepalive(self, listenKey): """PING a cross-margin data stream to prevent a time out. https://developers.binance.com/docs/margin_trading/trade-data-stream/Keepalive-Margin-User-Data-Stream :param listenKey: required :type listenKey: str :returns: API response .. code-block:: python {} :raises: BinanceRequestException, BinanceAPIException """ warnings.warn( "PUT /sapi/v1/userDataStream is deprecated and will be removed on 2026-02-20. " "Use the WebSocket API subscription method instead (create listenToken via POST /sapi/v1/userListenToken, " "then subscribe with userDataStream.subscribe.listenToken). " "The margin_socket() method now uses WebSocket API by default.", DeprecationWarning, stacklevel=2 ) params = {"listenKey": listenKey} return self._request_margin_api( "put", "userDataStream", signed=False, data=params ) def margin_stream_close(self, listenKey): """Close out a cross-margin data stream. https://developers.binance.com/docs/margin_trading/trade-data-stream/Close-Margin-User-Data-Stream :param listenKey: required :type listenKey: str :returns: API response .. code-block:: python {} :raises: BinanceRequestException, BinanceAPIException """ warnings.warn( "DELETE /sapi/v1/userDataStream is deprecated and will be removed on 2026-02-20. " "Use the WebSocket API subscription method instead (create listenToken via POST /sapi/v1/userListenToken, " "then subscribe with userDataStream.subscribe.listenToken). " "The margin_socket() method now uses WebSocket API by default.", DeprecationWarning, stacklevel=2 ) params = {"listenKey": listenKey} return self._request_margin_api( "delete", "userDataStream", signed=False, data=params ) def margin_create_listen_token(self, symbol: Optional[str] = None, is_isolated: bool = False, validity: Optional[int] = None): """Create a listenToken for margin account user data stream https://developers.binance.com/docs/margin_trading/trade-data-stream/Create-Margin-Account-listenToken :param symbol: Trading pair symbol (required when is_isolated=True) :type symbol: str :param is_isolated: Whether it is isolated margin (default: False for cross-margin) :type is_isolated: bool :param validity: Validity in milliseconds (default: 24 hours, max: 24 hours) :type validity: int :returns: API response with token and expirationTime .. code-block:: python { "token": "6xXxePXwZRjVSHKhzUCCGnmN3fkvMTXru+pYJS8RwijXk9Vcyr3rkwfVOTcP2OkONqciYA", "expirationTime": 1758792204196 } :raises: BinanceRequestException, BinanceAPIException """ params = {} if is_isolated: if not symbol: raise ValueError("symbol is required when is_isolated=True") params["symbol"] = symbol params["isIsolated"] = "true" if validity is not None: params["validity"] = validity return self._request_margin_api( "post", "userListenToken", signed=True, data=params ) # Isolated margin def isolated_margin_stream_get_listen_key(self, symbol): """Start a new isolated margin data stream and return the listen key If a stream already exists it should return the same key. If the stream becomes invalid a new key is returned. Can be used to keep the stream alive. https://developers.binance.com/docs/margin_trading/trade-data-stream/Start-Isolated-Margin-User-Data-Stream :param symbol: required - symbol for the isolated margin account :type symbol: str :returns: API response .. code-block:: python { "listenKey": "T3ee22BIYuWqmvne0HNq2A2WsFlEtLhvWCtItw6ffhhdmjifQ2tRbuKkTHhr" } :raises: BinanceRequestException, BinanceAPIException """ warnings.warn( "POST /sapi/v1/userDataStream/isolated is deprecated and will be removed on 2026-02-20. " "Use the WebSocket API subscription method instead (create listenToken via POST /sapi/v1/userListenToken " "with isIsolated=true, then subscribe with userDataStream.subscribe.listenToken). " "The isolated_margin_socket() method now uses WebSocket API by default.", DeprecationWarning, stacklevel=2 ) params = {"symbol": symbol} res = self._request_margin_api( "post", "userDataStream/isolated", signed=False, data=params ) return res["listenKey"] def isolated_margin_stream_keepalive(self, symbol, listenKey): """PING an isolated margin data stream to prevent a time out. https://developers.binance.com/docs/margin_trading/trade-data-stream/Keepalive-Isolated-Margin-User-Data-Stream :param symbol: required - symbol for the isolated margin account :type symbol: str :param listenKey: required :type listenKey: str :returns: API response .. code-block:: python {} :raises: BinanceRequestException, BinanceAPIException """ warnings.warn( "PUT /sapi/v1/userDataStream/isolated is deprecated and will be removed on 2026-02-20. " "Use the WebSocket API subscription method instead (create listenToken via POST /sapi/v1/userListenToken " "with isIsolated=true, then subscribe with userDataStream.subscribe.listenToken). " "The isolated_margin_socket() method now uses WebSocket API by default.", DeprecationWarning, stacklevel=2 ) params = {"symbol": symbol, "listenKey": listenKey} return self._request_margin_api( "put", "userDataStream/isolated", signed=False, data=params ) def isolated_margin_stream_close(self, symbol, listenKey): """Close out an isolated margin data stream. https://developers.binance.com/docs/margin_trading/trade-data-stream/Close-Isolated-Margin-User-Data-Stream :param symbol: required - symbol for the isolated margin account :type symbol: str :param listenKey: required :type listenKey: str :returns: API response .. code-block:: python {} :raises: BinanceRequestException, BinanceAPIException """ warnings.warn( "DELETE /sapi/v1/userDataStream/isolated is deprecated and will be removed on 2026-02-20. " "Use the WebSocket API subscription method instead (create listenToken via POST /sapi/v1/userListenToken " "with isIsolated=true, then subscribe with userDataStream.subscribe.listenToken). " "The isolated_margin_socket() method now uses WebSocket API by default.", DeprecationWarning, stacklevel=2 ) params = {"symbol": symbol, "listenKey": listenKey} return self._request_margin_api( "delete", "userDataStream/isolated", signed=False, data=params ) # Simple Earn Endpoints def get_simple_earn_flexible_product_list(self, **params): """Get available Simple Earn flexible product list https://binance-docs.github.io/apidocs/spot/en/#get-simple-earn-flexible-product-list-user_data :param asset: optional :type asset: str :param current: optional - Currently querying page. Start from 1. Default:1 :type current: int :param size: optional - Default:10, Max:100 :type size: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "rows":[ { "asset": "BTC", "latestAnnualPercentageRate": "0.05000000", "tierAnnualPercentageRate": { "0-5BTC": 0.05, "5-10BTC": 0.03 }, "airDropPercentageRate": "0.05000000", "canPurchase": true, "canRedeem": true, "isSoldOut": true, "hot": true, "minPurchaseAmount": "0.01000000", "productId": "BTC001", "subscriptionStartTime": "1646182276000", "status": "PURCHASING" } ], "total": 1 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "simple-earn/flexible/list", signed=True, data=params ) def get_simple_earn_locked_product_list(self, **params): """Get available Simple Earn flexible product list https://binance-docs.github.io/apidocs/spot/en/#get-simple-earn-locked-product-list-user_data :param asset: optional :type asset: str :param current: optional - Currently querying page. Start from 1. Default:1 :type current: int :param size: optional - Default:10, Max:100 :type size: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "rows": [ { "projectId": "Axs*90", "detail": { "asset": "AXS", "rewardAsset": "AXS", "duration": 90, "renewable": true, "isSoldOut": true, "apr": "1.2069", "status": "CREATED", "subscriptionStartTime": "1646182276000", "extraRewardAsset": "BNB", "extraRewardAPR": "0.23" }, "quota": { "totalPersonalQuota": "2", "minimum": "0.001" } } ], "total": 1 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "simple-earn/locked/list", signed=True, data=params ) def subscribe_simple_earn_flexible_product(self, **params): """Subscribe to a simple earn flexible product https://binance-docs.github.io/apidocs/spot/en/#subscribe-locked-product-trade :param productId: required :type productId: str :param amount: required :type amount: str :param autoSubscribe: optional - Default True :type autoSubscribe: bool :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "purchaseId": 40607, "success": true } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "simple-earn/flexible/subscribe", signed=True, data=params ) def subscribe_simple_earn_locked_product(self, **params): """Subscribe to a simple earn locked product https://binance-docs.github.io/apidocs/spot/en/#subscribe-locked-product-trade :param productId: required :type productId: str :param amount: required :type amount: str :param autoSubscribe: optional - Default True :type autoSubscribe: bool :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "purchaseId": 40607, "positionId": "12345", "success": true } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "simple-earn/locked/subscribe", signed=True, data=params ) def redeem_simple_earn_flexible_product(self, **params): """Redeem a simple earn flexible product https://binance-docs.github.io/apidocs/spot/en/#redeem-flexible-product-trade :param productId: required :type productId: str :param amount: optional :type amount: str :param redeemAll: optional - Default False :type redeemAll: bool :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "redeemId": 40607, "success": true } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "simple-earn/flexible/redeem", signed=True, data=params ) def redeem_simple_earn_locked_product(self, **params): """Redeem a simple earn locked product https://binance-docs.github.io/apidocs/spot/en/#redeem-locked-product-trade :param productId: required :type productId: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "redeemId": 40607, "success": true } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "simple-earn/locked/redeem", signed=True, data=params ) def get_simple_earn_flexible_product_position(self, **params): """ https://binance-docs.github.io/apidocs/spot/en/#get-flexible-product-position-user_data :param asset: optional :type asset: str :param current: optional - Currently querying page. Start from 1. Default:1 :type current: int :param size: optional - Default:10, Max:100 :type size: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "rows":[ { "totalAmount": "75.46000000", "tierAnnualPercentageRate": { "0-5BTC": 0.05, "5-10BTC": 0.03 }, "latestAnnualPercentageRate": "0.02599895", "yesterdayAirdropPercentageRate": "0.02599895", "asset": "USDT", "airDropAsset": "BETH", "canRedeem": true, "collateralAmount": "232.23123213", "productId": "USDT001", "yesterdayRealTimeRewards": "0.10293829", "cumulativeBonusRewards": "0.22759183", "cumulativeRealTimeRewards": "0.22759183", "cumulativeTotalRewards": "0.45459183", "autoSubscribe": true } ], "total": 1 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "simple-earn/flexible/position", signed=True, data=params ) def get_simple_earn_locked_product_position(self, **params): """ https://binance-docs.github.io/apidocs/spot/en/#get-locked-product-position-user_data :param asset: optional :type asset: str :param current: optional - Currently querying page. Start from 1. Default:1 :type current: int :param size: optional - Default:10, Max:100 :type size: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "rows":[ { "positionId": "123123", "projectId": "Axs*90", "asset": "AXS", "amount": "122.09202928", "purchaseTime": "1646182276000", "duration": "60", "accrualDays": "4", "rewardAsset": "AXS", "APY": "0.23", "isRenewable": true, "isAutoRenew": true, "redeemDate": "1732182276000" } ], "total": 1 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "simple-earn/locked/position", signed=True, data=params ) def get_simple_earn_account(self, **params): """ https://binance-docs.github.io/apidocs/spot/en/#simple-account-user_data :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "totalAmountInBTC": "0.01067982", "totalAmountInUSDT": "77.13289230", "totalFlexibleAmountInBTC": "0.00000000", "totalFlexibleAmountInUSDT": "0.00000000", "totalLockedInBTC": "0.01067982", "totalLockedInUSDT": "77.13289230" } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "simple-earn/account", signed=True, data=params ) # Lending Endpoints def get_fixed_activity_project_list(self, **params): """Get Fixed and Activity Project List https://binance-docs.github.io/apidocs/spot/en/#get-fixed-and-activity-project-list-user_data :param asset: optional :type asset: str :param type: required - "ACTIVITY", "CUSTOMIZED_FIXED" :type type: str :param status: optional - "ALL", "SUBSCRIBABLE", "UNSUBSCRIBABLE"; default "ALL" :type status: str :param sortBy: optional - "START_TIME", "LOT_SIZE", "INTEREST_RATE", "DURATION"; default "START_TIME" :type sortBy: str :param current: optional - Currently querying page. Start from 1. Default:1 :type current: int :param size: optional - Default:10, Max:100 :type size: int :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python [ { "asset": "USDT", "displayPriority": 1, "duration": 90, "interestPerLot": "1.35810000", "interestRate": "0.05510000", "lotSize": "100.00000000", "lotsLowLimit": 1, "lotsPurchased": 74155, "lotsUpLimit": 80000, "maxLotsPerUser": 2000, "needKyc": False, "projectId": "CUSDT90DAYSS001", "projectName": "USDT", "status": "PURCHASING", "type": "CUSTOMIZED_FIXED", "withAreaLimitation": False } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "lending/project/list", signed=True, data=params ) def change_fixed_activity_to_daily_position(self, **params): """Change Fixed/Activity Position to Daily Position https://binance-docs.github.io/apidocs/spot/en/#change-fixed-activity-position-to-daily-position-user_data """ return self._request_margin_api( "post", "lending/positionChanged", signed=True, data=params ) # Staking Endpoints def get_staking_product_list(self, **params): """Get Staking Product List https://binance-docs.github.io/apidocs/spot/en/#get-staking-product-list-user_data """ return self._request_margin_api( "get", "staking/productList", signed=True, data=params ) def purchase_staking_product(self, **params): """Purchase Staking Product https://binance-docs.github.io/apidocs/spot/en/#purchase-staking-product-user_data """ return self._request_margin_api( "post", "staking/purchase", signed=True, data=params ) def redeem_staking_product(self, **params): """Redeem Staking Product https://binance-docs.github.io/apidocs/spot/en/#redeem-staking-product-user_data """ return self._request_margin_api( "post", "staking/redeem", signed=True, data=params ) def get_staking_position(self, **params): """Get Staking Product Position https://binance-docs.github.io/apidocs/spot/en/#get-staking-product-position-user_data """ return self._request_margin_api( "get", "staking/position", signed=True, data=params ) def get_staking_purchase_history(self, **params): """Get Staking Purchase History https://binance-docs.github.io/apidocs/spot/en/#get-staking-history-user_data """ return self._request_margin_api( "get", "staking/purchaseRecord", signed=True, data=params ) def set_auto_staking(self, **params): """Set Auto Staking on Locked Staking or Locked DeFi Staking https://binance-docs.github.io/apidocs/spot/en/#set-auto-staking-user_data """ return self._request_margin_api( "post", "staking/setAutoStaking", signed=True, data=params ) def get_personal_left_quota(self, **params): """Get Personal Left Quota of Staking Product https://binance-docs.github.io/apidocs/spot/en/#get-personal-left-quota-of-staking-product-user_data """ return self._request_margin_api( "get", "staking/personalLeftQuota", signed=True, data=params ) # US Staking Endpoints def get_staking_asset_us(self, **params): """Get staking information for a supported asset (or assets) https://docs.binance.us/#get-staking-asset-information :raises BinanceRegionException: If client is not configured for binance.us """ self._require_tld("us", "get_staking_asset_us") return self._request_margin_api("get", "staking/asset", True, data=params) def stake_asset_us(self, **params): """Stake a supported asset. https://docs.binance.us/#stake-asset :raises BinanceRegionException: If client is not configured for binance.us """ self._require_tld("us", "stake_asset_us") return self._request_margin_api("post", "staking/stake", True, data=params) def unstake_asset_us(self, **params): """Unstake a staked asset https://docs.binance.us/#unstake-asset :raises BinanceRegionException: If client is not configured for binance.us """ self._require_tld("us", "unstake_asset_us") return self._request_margin_api("post", "staking/unstake", True, data=params) def get_staking_balance_us(self, **params): """Get staking balance https://docs.binance.us/#get-staking-balance :raises BinanceRegionException: If client is not configured for binance.us """ self._require_tld("us", "get_staking_balance_us") return self._request_margin_api( "get", "staking/stakingBalance", True, data=params ) def get_staking_history_us(self, **params): """Get staking history https://docs.binance.us/#get-staking-history :raises BinanceRegionException: If client is not configured for binance.us """ self._require_tld("us", "get_staking_history_us") return self._request_margin_api("get", "staking/history", True, data=params) def get_staking_rewards_history_us(self, **params): """Get staking rewards history for an asset(or assets) within a given time range. https://docs.binance.us/#get-staking-rewards-history :raises BinanceRegionException: If client is not configured for binance.us """ self._require_tld("us", "get_staking_rewards_history_us") return self._request_margin_api( "get", "staking/stakingRewardsHistory", True, data=params ) # Sub Accounts def get_sub_account_list(self, **params): """Query Sub-account List. https://developers.binance.com/docs/sub_account/account-management/Query-Sub-account-List :param email: optional - Sub-account email :type email: str :param isFreeze: optional :type isFreeze: str :param page: optional - Default value: 1 :type page: int :param limit: optional - Default value: 1, Max value: 200 :type limit: int :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "subAccounts":[ { "email":"testsub@gmail.com", "isFreeze":false, "createTime":1544433328000 }, { "email":"virtual@oxebmvfonoemail.com", "isFreeze":false, "createTime":1544433328000 } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("get", "sub-account/list", True, data=params) def get_sub_account_transfer_history(self, **params): """Query Sub-account Transfer History. https://developers.binance.com/docs/sub_account/asset-management/Query-Sub-account-Spot-Asset-Transfer-History :param fromEmail: optional :type fromEmail: str :param toEmail: optional :type toEmail: str :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param page: optional - Default value: 1 :type page: int :param limit: optional - Default value: 500 :type limit: int :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python [ { "from":"aaa@test.com", "to":"bbb@test.com", "asset":"BTC", "qty":"10", "status": "SUCCESS", "tranId": 6489943656, "time":1544433328000 }, { "from":"bbb@test.com", "to":"ccc@test.com", "asset":"ETH", "qty":"2", "status": "SUCCESS", "tranId": 6489938713, "time":1544433328000 } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "sub-account/sub/transfer/history", True, data=params ) def get_sub_account_futures_transfer_history(self, **params): """Query Sub-account Futures Transfer History. https://developers.binance.com/docs/sub_account/asset-management/Query-Sub-account-Futures-Asset-Transfer-History :param email: required :type email: str :param futuresType: required :type futuresType: int :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param page: optional :type page: int :param limit: optional :type limit: int :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "success":true, "futuresType": 2, "transfers":[ { "from":"aaa@test.com", "to":"bbb@test.com", "asset":"BTC", "qty":"1", "time":1544433328000 }, { "from":"bbb@test.com", "to":"ccc@test.com", "asset":"ETH", "qty":"2", "time":1544433328000 } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "sub-account/futures/internalTransfer", True, data=params ) def create_sub_account_futures_transfer(self, **params): """Execute sub-account Futures transfer https://developers.binance.com/docs/sub_account/asset-management/Sub-account-Futures-Asset-Transfer :param fromEmail: required - Sender email :type fromEmail: str :param toEmail: required - Recipient email :type toEmail: str :param futuresType: required :type futuresType: int :param asset: required :type asset: str :param amount: required :type amount: decimal :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "success":true, "txnId":"2934662589" } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "sub-account/futures/internalTransfer", True, data=params ) def get_sub_account_assets(self, **params): """Fetch sub-account assets https://developers.binance.com/docs/sub_account/asset-management/Query-Sub-account-Assets-V4 :param email: required :type email: str :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "balances":[ { "asset":"ADA", "free":10000, "locked":0 }, { "asset":"BNB", "free":10003, "locked":0 }, { "asset":"BTC", "free":11467.6399, "locked":0 }, { "asset":"ETH", "free":10004.995, "locked":0 }, { "asset":"USDT", "free":11652.14213, "locked":0 } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "sub-account/assets", True, data=params, version=4 ) def query_subaccount_spot_summary(self, **params): """Query Sub-account Spot Assets Summary (For Master Account) https://developers.binance.com/docs/sub_account/asset-management/Query-Sub-account-Spot-Assets-Summary :param email: optional - Sub account email :type email: str :param page: optional - default 1 :type page: int :param size: optional - default 10, max 20 :type size: int :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "totalCount":2, "masterAccountTotalAsset": "0.23231201", "spotSubUserAssetBtcVoList":[ { "email":"sub123@test.com", "totalAsset":"9999.00000000" }, { "email":"test456@test.com", "totalAsset":"0.00000000" } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "sub-account/spotSummary", True, data=params ) def get_subaccount_deposit_address(self, **params): """Get Sub-account Deposit Address (For Master Account) https://developers.binance.com/docs/sub_account/asset-management/Get-Sub-account-Deposit-Address :param email: required - Sub account email :type email: str :param coin: required :type coin: str :param network: optional :type network: str :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "address":"TDunhSa7jkTNuKrusUTU1MUHtqXoBPKETV", "coin":"USDT", "tag":"", "url":"https://tronscan.org/#/address/TDunhSa7jkTNuKrusUTU1MUHtqXoBPKETV" } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "capital/deposit/subAddress", True, data=params ) def get_subaccount_deposit_history(self, **params): """Get Sub-account Deposit History (For Master Account) https://developers.binance.com/docs/sub_account/asset-management/Get-Sub-account-Deposit-History :param email: required - Sub account email :type email: str :param coin: optional :type coin: str :param status: optional - (0:pending,6: credited but cannot withdraw, 1:success) :type status: int :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param limit: optional :type limit: int :param offset: optional - default:0 :type offset: int :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python [ { "amount":"0.00999800", "coin":"PAXG", "network":"ETH", "status":1, "address":"0x788cabe9236ce061e5a892e1a59395a81fc8d62c", "addressTag":"", "txId":"0xaad4654a3234aa6118af9b4b335f5ae81c360b2394721c019b5d1e75328b09f3", "insertTime":1599621997000, "transferType":0, "confirmTimes":"12/12" }, { "amount":"0.50000000", "coin":"IOTA", "network":"IOTA", "status":1, "address":"SIZ9VLMHWATXKV99LH99CIGFJFUMLEHGWVZVNNZXRJJVWBPHYWPPBOSDORZ9EQSHCZAMPVAPGFYQAUUV9DROOXJLNW", "addressTag":"", "txId":"ESBFVQUTPIWQNJSPXFNHNYHSQNTGKRVKPRABQWTAXCDWOAKDKYWPTVG9BGXNVNKTLEJGESAVXIKIZ9999", "insertTime":1599620082000, "transferType":0, "confirmTimes":"1/1" } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "capital/deposit/subHisrec", True, data=params ) def get_subaccount_futures_margin_status(self, **params): """Get Sub-account's Status on Margin/Futures (For Master Account) https://developers.binance.com/docs/sub_account/account-management/Get-Sub-accounts-Status-on-Margin-Or-Futures :param email: optional - Sub account email :type email: str :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python [ { "email":"123@test.com", // user email "isSubUserEnabled": true, // true or false "isUserActive": true, // true or false "insertTime": 1570791523523 // sub account create time "isMarginEnabled": true, // true or false for margin "isFutureEnabled": true // true or false for futures. "mobile": 1570791523523 // user mobile number } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("get", "sub-account/status", True, data=params) def enable_subaccount_margin(self, **params): """Enable Margin for Sub-account (For Master Account) https://binance-docs.github.io/apidocs/spot/en/#enable-margin-for-sub-account-for-master-account :param email: required - Sub account email :type email: str :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "email":"123@test.com", "isMarginEnabled": true } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "sub-account/margin/enable", True, data=params ) def get_subaccount_margin_details(self, **params): """Get Detail on Sub-account's Margin Account (For Master Account) https://developers.binance.com/docs/sub_account/asset-management/Get-Detail-on-Sub-accounts-Margin-Account :param email: required - Sub account email :type email: str :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "email":"123@test.com", "marginLevel": "11.64405625", "totalAssetOfBtc": "6.82728457", "totalLiabilityOfBtc": "0.58633215", "totalNetAssetOfBtc": "6.24095242", "marginTradeCoeffVo": { "forceLiquidationBar": "1.10000000", // Liquidation margin ratio "marginCallBar": "1.50000000", // Margin call margin ratio "normalBar": "2.00000000" // Initial margin ratio }, "marginUserAssetVoList": [ { "asset": "BTC", "borrowed": "0.00000000", "free": "0.00499500", "interest": "0.00000000", "locked": "0.00000000", "netAsset": "0.00499500" }, { "asset": "BNB", "borrowed": "201.66666672", "free": "2346.50000000", "interest": "0.00000000", "locked": "0.00000000", "netAsset": "2144.83333328" }, { "asset": "ETH", "borrowed": "0.00000000", "free": "0.00000000", "interest": "0.00000000", "locked": "0.00000000", "netAsset": "0.00000000" }, { "asset": "USDT", "borrowed": "0.00000000", "free": "0.00000000", "interest": "0.00000000", "locked": "0.00000000", "netAsset": "0.00000000" } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "sub-account/margin/account", True, data=params ) def get_subaccount_margin_summary(self, **params): """Get Summary of Sub-account's Margin Account (For Master Account) https://developers.binance.com/docs/sub_account/asset-management/Get-Summary-of-Sub-accounts-Margin-Account :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "totalAssetOfBtc": "4.33333333", "totalLiabilityOfBtc": "2.11111112", "totalNetAssetOfBtc": "2.22222221", "subAccountList":[ { "email":"123@test.com", "totalAssetOfBtc": "2.11111111", "totalLiabilityOfBtc": "1.11111111", "totalNetAssetOfBtc": "1.00000000" }, { "email":"345@test.com", "totalAssetOfBtc": "2.22222222", "totalLiabilityOfBtc": "1.00000001", "totalNetAssetOfBtc": "1.22222221" } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "sub-account/margin/accountSummary", True, data=params ) def enable_subaccount_futures(self, **params): """Enable Futures for Sub-account (For Master Account) https://developers.binance.com/docs/sub_account/account-management/Enable-Futures-for-Sub-account :param email: required - Sub account email :type email: str :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "email":"123@test.com", "isFuturesEnabled": true // true or false } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "sub-account/futures/enable", True, data=params ) def get_subaccount_futures_details(self, **params): """Get Detail on Sub-account's Futures Account (For Master Account) https://developers.binance.com/docs/sub_account/asset-management/Get-Detail-on-Sub-accounts-Futures-Account :param email: required - Sub account email :type email: str :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "email": "abc@test.com", "asset": "USDT", "assets":[ { "asset": "USDT", "initialMargin": "0.00000000", "maintenanceMargin": "0.00000000", "marginBalance": "0.88308000", "maxWithdrawAmount": "0.88308000", "openOrderInitialMargin": "0.00000000", "positionInitialMargin": "0.00000000", "unrealizedProfit": "0.00000000", "walletBalance": "0.88308000" } ], "canDeposit": true, "canTrade": true, "canWithdraw": true, "feeTier": 2, "maxWithdrawAmount": "0.88308000", "totalInitialMargin": "0.00000000", "totalMaintenanceMargin": "0.00000000", "totalMarginBalance": "0.88308000", "totalOpenOrderInitialMargin": "0.00000000", "totalPositionInitialMargin": "0.00000000", "totalUnrealizedProfit": "0.00000000", "totalWalletBalance": "0.88308000", "updateTime": 1576756674610 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "sub-account/futures/account", True, data=params, version=2 ) def get_subaccount_futures_summary(self, **params): """Get Summary of Sub-account's Futures Account (For Master Account) https://developers.binance.com/docs/sub_account/asset-management/Get-Summary-of-Sub-accounts-Futures-Account-V2 :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "totalInitialMargin": "9.83137400", "totalMaintenanceMargin": "0.41568700", "totalMarginBalance": "23.03235621", "totalOpenOrderInitialMargin": "9.00000000", "totalPositionInitialMargin": "0.83137400", "totalUnrealizedProfit": "0.03219710", "totalWalletBalance": "22.15879444", "asset": "USDT", "subAccountList":[ { "email": "123@test.com", "totalInitialMargin": "9.00000000", "totalMaintenanceMargin": "0.00000000", "totalMarginBalance": "22.12659734", "totalOpenOrderInitialMargin": "9.00000000", "totalPositionInitialMargin": "0.00000000", "totalUnrealizedProfit": "0.00000000", "totalWalletBalance": "22.12659734", "asset": "USDT" }, { "email": "345@test.com", "totalInitialMargin": "0.83137400", "totalMaintenanceMargin": "0.41568700", "totalMarginBalance": "0.90575887", "totalOpenOrderInitialMargin": "0.00000000", "totalPositionInitialMargin": "0.83137400", "totalUnrealizedProfit": "0.03219710", "totalWalletBalance": "0.87356177", "asset": "USDT" } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "sub-account/futures/accountSummary", True, data=params, version=2 ) def get_subaccount_futures_positionrisk(self, **params): """Get Futures Position-Risk of Sub-account (For Master Account) https://developers.binance.com/docs/sub_account/account-management/Get-Futures-Position-Risk-of-Sub-account-V2 :param email: required - Sub account email :type email: str :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python [ { "entryPrice": "9975.12000", "leverage": "50", // current initial leverage "maxNotional": "1000000", // notional value limit of current initial leverage "liquidationPrice": "7963.54", "markPrice": "9973.50770517", "positionAmount": "0.010", "symbol": "BTCUSDT", "unrealizedProfit": "-0.01612295" } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "sub-account/futures/positionRisk", True, data=params, version=2 ) def make_subaccount_futures_transfer(self, **params): """Futures Transfer for Sub-account (For Master Account) https://developers.binance.com/docs/sub_account/asset-management :param email: required - Sub account email :type email: str :param asset: required - The asset being transferred, e.g., USDT :type asset: str :param amount: required - The amount to be transferred :type amount: float :param type: required - 1: transfer from subaccount's spot account to its USDT-margined futures account 2: transfer from subaccount's USDT-margined futures account to its spot account 3: transfer from subaccount's spot account to its COIN-margined futures account 4: transfer from subaccount's COIN-margined futures account to its spot account :type type: int :returns: API response .. code-block:: python { "txnId":"2966662589" } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "sub-account/futures/transfer", True, data=params ) def make_subaccount_margin_transfer(self, **params): """Margin Transfer for Sub-account (For Master Account) https://developers.binance.com/docs/sub_account/asset-management/Margin-Transfer-for-Sub-account :param email: required - Sub account email :type email: str :param asset: required - The asset being transferred, e.g., USDT :type asset: str :param amount: required - The amount to be transferred :type amount: float :param type: required - 1: transfer from subaccount's spot account to margin account 2: transfer from subaccount's margin account to its spot account :type type: int :returns: API response .. code-block:: python { "txnId":"2966662589" } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "sub-account/margin/transfer", True, data=params ) def make_subaccount_to_subaccount_transfer(self, **params): """Transfer to Sub-account of Same Master (For Sub-account) https://developers.binance.com/docs/sub_account/asset-management/Transfer-to-Sub-account-of-Same-Master :param toEmail: required - Sub account email :type toEmail: str :param asset: required - The asset being transferred, e.g., USDT :type asset: str :param amount: required - The amount to be transferred :type amount: float :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "txnId":"2966662589" } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "sub-account/transfer/subToSub", True, data=params ) def make_subaccount_to_master_transfer(self, **params): """Transfer to Master (For Sub-account) https://developers.binance.com/docs/sub_account/asset-management/Transfer-to-Master :param asset: required - The asset being transferred, e.g., USDT :type asset: str :param amount: required - The amount to be transferred :type amount: float :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "txnId":"2966662589" } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "sub-account/transfer/subToMaster", True, data=params ) def get_subaccount_transfer_history(self, **params): """Sub-account Transfer History (For Sub-account) https://developers.binance.com/docs/sub_account/asset-management/Sub-account-Transfer-History :param asset: required - The asset being transferred, e.g., USDT :type asset: str :param type: optional - 1: transfer in, 2: transfer out :type type: int :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param limit: optional - Default 500 :type limit: int :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python [ { "counterParty":"master", "email":"master@test.com", "type":1, // 1 for transfer in, 2 for transfer out "asset":"BTC", "qty":"1", "status":"SUCCESS", "tranId":11798835829, "time":1544433325000 }, { "counterParty":"subAccount", "email":"sub2@test.com", "type":2, "asset":"ETH", "qty":"2", "status":"SUCCESS", "tranId":11798829519, "time":1544433326000 } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "sub-account/transfer/subUserHistory", True, data=params ) def make_subaccount_universal_transfer(self, **params): """Universal Transfer (For Master Account) https://developers.binance.com/docs/sub_account/asset-management/Universal-Transfer :param fromEmail: optional :type fromEmail: str :param toEmail: optional :type toEmail: str :param fromAccountType: required - "SPOT","USDT_FUTURE","COIN_FUTURE" :type fromAccountType: str :param toAccountType: required - "SPOT","USDT_FUTURE","COIN_FUTURE" :type toAccountType: str :param asset: required - The asset being transferred, e.g., USDT :type asset: str :param amount: required :type amount: float :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "tranId":11945860693 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "sub-account/universalTransfer", True, data=params ) def get_universal_transfer_history(self, **params): """Universal Transfer (For Master Account) https://developers.binance.com/docs/sub_account/asset-management/Query-Universal-Transfer-History :param fromEmail: optional :type fromEmail: str :param toEmail: optional :type toEmail: str :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param page: optional :type page: int :param limit: optional :type limit: int :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python [ { "tranId":11945860693, "fromEmail":"master@test.com", "toEmail":"subaccount1@test.com", "asset":"BTC", "amount":"0.1", "fromAccountType":"SPOT", "toAccountType":"COIN_FUTURE", "status":"SUCCESS", "createTimeStamp":1544433325000 }, { "tranId":11945857955, "fromEmail":"master@test.com", "toEmail":"subaccount2@test.com", "asset":"ETH", "amount":"0.2", "fromAccountType":"SPOT", "toAccountType":"USDT_FUTURE", "status":"SUCCESS", "createTimeStamp":1544433326000 } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "sub-account/universalTransfer", True, data=params ) # Futures API def futures_ping(self): """Test connectivity to the Rest API https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api """ return self._request_futures_api("get", "ping") def futures_time(self): """Test connectivity to the Rest API and get the current server time. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Check-Server-Time """ return self._request_futures_api("get", "time") def futures_exchange_info(self): """Current exchange trading rules and symbol information https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Exchange-Information """ return self._request_futures_api("get", "exchangeInfo") def futures_order_book(self, **params): """Get the Order Book for the market https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Order-Book """ return self._request_futures_api("get", "depth", data=params) def futures_rpi_depth(self, **params): """Get RPI Order Book with Retail Price Improvement orders https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/RPI-Order-Book :param symbol: required :type symbol: str :param limit: Default 1000; Valid limits:[1000] :type limit: int :returns: API response .. code-block:: python { "lastUpdateId": 1027024, "E": 1589436922972, // Message output time "T": 1589436922959, // Transaction time "bids": [ [ "4.00000000", // PRICE "431.00000000" // QTY ] ], "asks": [ [ "4.00000200", "12.00000000" ] ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_futures_api("get", "rpiDepth", data=params) def futures_recent_trades(self, **params): """Get recent trades (up to last 500). https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Recent-Trades-List """ return self._request_futures_api("get", "trades", data=params) def futures_historical_trades(self, **params): """Get older market historical trades. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Old-Trades-Lookup """ return self._request_futures_api("get", "historicalTrades", data=params) def futures_aggregate_trades(self, **params): """Get compressed, aggregate trades. Trades that fill at the time, from the same order, with the same price will have the quantity aggregated. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Compressed-Aggregate-Trades-List """ return self._request_futures_api("get", "aggTrades", data=params) def futures_klines(self, **params): """Kline/candlestick bars for a symbol. Klines are uniquely identified by their open time. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Kline-Candlestick-Data """ return self._request_futures_api("get", "klines", data=params) def futures_mark_price_klines(self, **params): """Kline/candlestick bars for the mark price of a symbol. Klines are uniquely identified by their open time. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Mark-Price-Kline-Candlestick-Data """ return self._request_futures_api("get", "markPriceKlines", data=params) def futures_index_price_klines(self, **params): """Kline/candlestick bars for the index price of a symbol. Klines are uniquely identified by their open time. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Index-Price-Kline-Candlestick-Data """ return self._request_futures_api("get", "indexPriceKlines", data=params) def futures_premium_index_klines(self, **params): """Premium index kline bars of a symbol.l. Klines are uniquely identified by their open time. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Premium-Index-Kline-Data """ return self._request_futures_api("get", "premiumIndexKlines", data=params) def futures_continuous_klines(self, **params): """Kline/candlestick bars for a specific contract type. Klines are uniquely identified by their open time. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Continuous-Contract-Kline-Candlestick-Data """ return self._request_futures_api("get", "continuousKlines", data=params) def futures_historical_klines( self, symbol: str, interval :str, start_str, end_str=None, limit=None ): """Get historical futures klines from Binance :param symbol: Name of symbol pair e.g. BNBBTC :type symbol: str :param interval: Binance Kline interval :type interval: str :param start_str: Start date string in UTC format or timestamp in milliseconds :type start_str: str|int :param end_str: optional - end date string in UTC format or timestamp in milliseconds (default will fetch everything up to now) :type end_str: str|int :param limit: Default None (fetches full range in batches of max 1000 per request). To limit the number of rows, pass an integer. :type limit: int :return: list of OHLCV values (Open time, Open, High, Low, Close, Volume, Close time, Quote asset volume, Number of trades, Taker buy base asset volume, Taker buy quote asset volume, Ignore) """ return self._historical_klines( symbol, interval, start_str, end_str=end_str, limit=limit, klines_type=HistoricalKlinesType.FUTURES, ) def futures_historical_mark_price_klines( self, symbol: str, interval: str, start_str, end_str=None, limit=None ): """Get historical futures mark price klines from Binance :param symbol: Name of symbol pair e.g. BNBBTC :type symbol: str :param interval: Binance Kline interval :type interval: str :param start_str: Start date string in UTC format or timestamp in milliseconds :type start_str: str|int :param end_str: optional - end date string in UTC format or timestamp in milliseconds (default will fetch everything up to now) :type end_str: str|int :param limit: Default None (fetches full range in batches of max 1000 per request). To limit the number of rows, pass an integer. :type limit: int :return: list of OHLCV values (Open time, Open, High, Low, Close, Volume, Close time, Quote asset volume, Number of trades, Taker buy base asset volume, Taker buy quote asset volume, Ignore) """ return self._historical_klines( symbol, interval, start_str, end_str=end_str, limit=limit, klines_type=HistoricalKlinesType.FUTURES_MARK_PRICE, ) def futures_historical_klines_generator( self, symbol, interval, start_str, end_str=None ): """Get historical futures klines generator from Binance :param symbol: Name of symbol pair e.g. BNBBTC :type symbol: str :param interval: Binance Kline interval :type interval: str :param start_str: Start date string in UTC format or timestamp in milliseconds :type start_str: str|int :param end_str: optional - end date string in UTC format or timestamp in milliseconds (default will fetch everything up to now) :type end_str: str|int :return: generator of OHLCV values """ return self._historical_klines_generator( symbol, interval, start_str, end_str=end_str, klines_type=HistoricalKlinesType.FUTURES, ) def futures_mark_price(self, **params): """Get Mark Price and Funding Rate https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Mark-Price """ return self._request_futures_api("get", "premiumIndex", data=params) def futures_funding_rate(self, **params): """Get funding rate history https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Get-Funding-Rate-History """ return self._request_futures_api("get", "fundingRate", data=params) def futures_top_longshort_account_ratio(self, **params): """Get present long to short ratio for top accounts of a specific symbol. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Top-Long-Short-Account-Ratio """ return self._request_futures_data_api( "get", "topLongShortAccountRatio", data=params ) def futures_top_longshort_position_ratio(self, **params): """Get present long to short ratio for top positions of a specific symbol. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Top-Trader-Long-Short-Ratio """ return self._request_futures_data_api( "get", "topLongShortPositionRatio", data=params ) def futures_global_longshort_ratio(self, **params): """Get present global long to short ratio of a specific symbol. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Long-Short-Ratio """ return self._request_futures_data_api( "get", "globalLongShortAccountRatio", data=params ) def futures_taker_longshort_ratio(self, **params): """Get taker buy to sell volume ratio of a specific symbol https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Taker-BuySell-Volume """ return self._request_futures_data_api( "get", "takerlongshortRatio", data=params ) def futures_basis(self, **params): """Get future basis of a specific symbol https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Basis """ return self._request_futures_data_api( "get", "basis", data=params ) def futures_ticker(self, **params): """24 hour rolling window price change statistics. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/24hr-Ticker-Price-Change-Statistics """ return self._request_futures_api("get", "ticker/24hr", data=params) def futures_symbol_ticker(self, **params): """Latest price for a symbol or symbols. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Symbol-Price-Ticker-v2 """ return self._request_futures_api("get", "ticker/price", version=2, data=params) def futures_orderbook_ticker(self, **params): """Best price/qty on the order book for a symbol or symbols. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Symbol-Order-Book-Ticker """ return self._request_futures_api("get", "ticker/bookTicker", data=params) def futures_delivery_price(self, **params): """Get latest price for a symbol or symbols https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Delivery-Price """ return self._request_futures_data_api("get", "delivery-price", data=params) def futures_index_price_constituents(self, **params): """Get index price constituents https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Index-Constituents """ return self._request_futures_api("get", "constituents", data=params) def futures_insurance_fund_balance_snapshot(self, **params): """Get Insurance Fund Balance Snapshot https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Insurance-Fund-Balance """ return self._request_futures_api("get", "insuranceBalance", data=params) def futures_liquidation_orders(self, **params): """Get all liquidation orders https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Users-Force-Orders """ return self._request_futures_api("get", "forceOrders", signed=True, data=params) def futures_api_trading_status(self, **params): """Get quantitative trading rules for order placement, such as Unfilled Ratio (UFR), Good-Til-Canceled Ratio (GCR), Immediate-or-Cancel (IOC) & Fill-or-Kill (FOK) Expire Ratio (IFER), among others. https://www.binance.com/en/support/faq/binance-futures-trading-quantitative-rules-4f462ebe6ff445d4a170be7d9e897272 https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Futures-Trading-Quantitative-Rules-Indicators :param symbol: optional :type symbol: str :returns: API response .. code-block:: python { "indicators": { // indicator: quantitative rules indicators, value: user's indicators value, triggerValue: trigger indicator value threshold of quantitative rules. "BTCUSDT": [ { "isLocked": true, "plannedRecoverTime": 1545741270000, "indicator": "UFR", // Unfilled Ratio (UFR) "value": 0.05, // Current value "triggerValue": 0.995 // Trigger value }, { "isLocked": true, "plannedRecoverTime": 1545741270000, "indicator": "IFER", // IOC/FOK Expiration Ratio (IFER) "value": 0.99, // Current value "triggerValue": 0.99 // Trigger value }, { "isLocked": true, "plannedRecoverTime": 1545741270000, "indicator": "GCR", // GTC Cancellation Ratio (GCR) "value": 0.99, // Current value "triggerValue": 0.99 // Trigger value }, { "isLocked": true, "plannedRecoverTime": 1545741270000, "indicator": "DR", // Dust Ratio (DR) "value": 0.99, // Current value "triggerValue": 0.99 // Trigger value } ], "ETHUSDT": [ { "isLocked": true, "plannedRecoverTime": 1545741270000, "indicator": "UFR", "value": 0.05, "triggerValue": 0.995 }, { "isLocked": true, "plannedRecoverTime": 1545741270000, "indicator": "IFER", "value": 0.99, "triggerValue": 0.99 }, { "isLocked": true, "plannedRecoverTime": 1545741270000, "indicator": "GCR", "value": 0.99, "triggerValue": 0.99 } { "isLocked": true, "plannedRecoverTime": 1545741270000, "indicator": "DR", "value": 0.99, "triggerValue": 0.99 } ] }, "updateTime": 1545741270000 } :raises: BinanceRequestException, BinanceAPIException """ return self._request_futures_api( "get", "apiTradingStatus", signed=True, data=params ) def futures_commission_rate(self, **params): """Get Futures commission rate https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/User-Commission-Rate :param symbol: required :type symbol: str :returns: API response .. code-block:: python { "symbol": "BTCUSDT", "makerCommissionRate": "0.0002", // 0.02% "takerCommissionRate": "0.0004" // 0.04% } :raises: BinanceRequestException, BinanceAPIException """ return self._request_futures_api( "get", "commissionRate", signed=True, data=params ) def futures_adl_quantile_estimate(self, **params): """Get Position ADL Quantile Estimate https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Position-ADL-Quantile-Estimation """ return self._request_futures_api("get", "adlQuantile", signed=True, data=params) def futures_open_interest(self, **params): """Get present open interest of a specific symbol. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Open-Interest """ return self._request_futures_api("get", "openInterest", data=params) def futures_index_info(self, **params): """Get index_info https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Composite-Index-Symbol-Information """ return self._request_futures_api("get", "indexInfo", data=params) def futures_open_interest_hist(self, **params): """Get open interest statistics of a specific symbol. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Open-Interest-Statistics """ return self._request_futures_data_api("get", "openInterestHist", data=params) def futures_leverage_bracket(self, **params): """Notional and Leverage Brackets https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Notional-and-Leverage-Brackets """ return self._request_futures_api("get", "leverageBracket", True, data=params) def futures_account_transfer(self, **params): """Execute transfer between spot account and futures account. https://binance-docs.github.io/apidocs/futures/en/#new-future-account-transfer """ return self._request_margin_api("post", "futures/transfer", True, data=params) def transfer_history(self, **params): """Get future account transaction history list https://binance-docs.github.io/apidocs/futures/en/#get-future-account-transaction-history-list-user_data """ return self._request_margin_api("get", "futures/transfer", True, data=params) def futures_loan_borrow_history(self, **params): return self._request_margin_api( "get", "futures/loan/borrow/history", True, data=params ) def futures_loan_repay_history(self, **params): return self._request_margin_api( "get", "futures/loan/repay/history", True, data=params ) def futures_loan_wallet(self, **params): return self._request_margin_api( "get", "futures/loan/wallet", True, data=params, version=2 ) def futures_cross_collateral_adjust_history(self, **params): return self._request_margin_api( "get", "futures/loan/adjustCollateral/history", True, data=params ) def futures_cross_collateral_liquidation_history(self, **params): return self._request_margin_api( "get", "futures/loan/liquidationHistory", True, data=params ) def futures_loan_interest_history(self, **params): return self._request_margin_api( "get", "futures/loan/interestHistory", True, data=params ) def futures_create_order(self, **params): """Send in a new order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api Note: After 2025-12-09, conditional order types (STOP, STOP_MARKET, TAKE_PROFIT, TAKE_PROFIT_MARKET, TRAILING_STOP_MARKET) are automatically routed to the algo order endpoint. """ # Check if this is a conditional order type that needs to use algo endpoint order_type = params.get("type", "").upper() conditional_types = [ "STOP", "STOP_MARKET", "TAKE_PROFIT", "TAKE_PROFIT_MARKET", "TRAILING_STOP_MARKET", ] if order_type in conditional_types: # Route to algo order endpoint if "clientAlgoId" not in params: params["clientAlgoId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() # Remove newClientOrderId if it was added by default params.pop("newClientOrderId", None) params["algoType"] = "CONDITIONAL" # Convert stopPrice to triggerPrice for algo orders (camelCase per API docs) if "stopPrice" in params and "triggerPrice" not in params: params["triggerPrice"] = params.pop("stopPrice") return self._request_futures_api("post", "algoOrder", True, data=params) else: # Use regular order endpoint if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return self._request_futures_api("post", "order", True, data=params) def futures_limit_order(self, **params): """Send in a new futures limit order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() params["type"] = "LIMIT" return self._request_futures_api("post", "order", True, data=params) def futures_market_order(self, **params): """Send in a new futures market order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() params["type"] = "MARKET" return self._request_futures_api("post", "order", True, data=params) def futures_limit_buy_order(self, **params): """Send in a new futures limit buy order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() params["side"] = "BUY" params["type"] = "LIMIT" return self._request_futures_api("post", "order", True, data=params) def futures_limit_sell_order(self, **params): """Send in a new futures limit sell order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() params["side"] = "SELL" params["type"] = "LIMIT" return self._request_futures_api("post", "order", True, data=params) def futures_market_buy_order(self, **params): """Send in a new futures market buy order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() params["side"] = "BUY" params["type"] = "MARKET" return self._request_futures_api("post", "order", True, data=params) def futures_market_sell_order(self, **params): """Send in a new futures market sell order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() params["side"] = "SELL" params["type"] = "MARKET" return self._request_futures_api("post", "order", True, data=params) def futures_modify_order(self, **params): """Modify an existing order. Currently only LIMIT order modification is supported. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Modify-Order """ return self._request_futures_api("put", "order", True, data=params) def futures_create_test_order(self, **params): """Testing order request, this order will not be submitted to matching engine https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/New-Order-Test """ return self._request_futures_api("post", "order/test", True, data=params) def futures_place_batch_order(self, **params): """Send in new orders. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Place-Multiple-Orders To avoid modifying the existing signature generation and parameter order logic, the url encoding is done on the special query param, batchOrders, in the early stage. """ for order in params["batchOrders"]: if "newClientOrderId" not in order: order["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() query_string = urlencode(params) query_string = query_string.replace("%27", "%22") params["batchOrders"] = query_string[12:] return self._request_futures_api( "post", "batchOrders", True, data=params, force_params=True ) def futures_get_order(self, **params): """Check an order's status. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Query-Order :param conditional: optional - Set to True to query algo/conditional order :type conditional: bool :param algoId: optional - Algo order ID (for conditional orders) :type algoId: int :param clientAlgoId: optional - Client algo order ID (for conditional orders) :type clientAlgoId: str """ # Check if this is a request for a conditional/algo order is_conditional = params.pop("conditional", False) # Also check if algoId or clientAlgoId is provided if "algoId" in params or "clientAlgoId" in params: is_conditional = True if is_conditional: return self._request_futures_api("get", "algoOrder", True, data=params) else: return self._request_futures_api("get", "order", True, data=params) def futures_get_open_orders(self, **params): """Get all open orders on a symbol. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Current-All-Open-Orders :param conditional: optional - Set to True to query algo/conditional orders :type conditional: bool """ is_conditional = params.pop("conditional", False) if is_conditional: return self._request_futures_api("get", "openAlgoOrders", True, data=params) else: return self._request_futures_api("get", "openOrders", True, data=params) def futures_get_all_orders(self, **params): """Get all futures account orders; active, canceled, or filled. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/All-Orders :param conditional: optional - Set to True to query algo/conditional orders :type conditional: bool """ is_conditional = params.pop("conditional", False) if is_conditional: return self._request_futures_api("get", "allAlgoOrders", True, data=params) else: return self._request_futures_api("get", "allOrders", True, data=params) def futures_cancel_order(self, **params): """Cancel an active futures order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Cancel-Order :param conditional: optional - Set to True to cancel algo/conditional order :type conditional: bool :param algoId: optional - Algo order ID (for conditional orders) :type algoId: int :param clientAlgoId: optional - Client algo order ID (for conditional orders) :type clientAlgoId: str """ # Check if this is a request for a conditional/algo order is_conditional = params.pop("conditional", False) # Also check if algoId or clientAlgoId is provided if "algoId" in params or "clientAlgoId" in params: is_conditional = True if is_conditional: return self._request_futures_api("delete", "algoOrder", True, data=params) else: return self._request_futures_api("delete", "order", True, data=params) def futures_cancel_all_open_orders(self, **params): """Cancel all open futures orders https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Cancel-All-Open-Orders :param conditional: optional - Set to True to cancel algo/conditional orders :type conditional: bool """ is_conditional = params.pop("conditional", False) if is_conditional: return self._request_futures_api( "delete", "algoOpenOrders", True, data=params ) else: return self._request_futures_api("delete", "allOpenOrders", True, data=params) def futures_cancel_orders(self, **params): """Cancel multiple futures orders https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Cancel-Multiple-Orders """ if params.get("orderidlist"): params["orderidlist"] = quote( convert_list_to_json_array(params["orderidlist"]) ) if params.get("origclientorderidlist"): params["origclientorderidlist"] = quote( convert_list_to_json_array(params["origclientorderidlist"]) ) return self._request_futures_api( "delete", "batchOrders", True, force_params=True, data=params ) def futures_countdown_cancel_all(self, **params): """Cancel all open orders of the specified symbol at the end of the specified countdown. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Auto-Cancel-All-Open-Orders :param symbol: required :type symbol: str :param countdownTime: required :type countdownTime: int :param recvWindow: optional - the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "symbol": "BTCUSDT", "countdownTime": "100000" } """ return self._request_futures_api( "post", "countdownCancelAll", True, data=params ) # Algo Orders (Conditional Orders) def futures_create_algo_order(self, **params): """Send in a new algo order (conditional order). https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/New-Algo-Order :param algoType: required - Only support CONDITIONAL :type algoType: str :param symbol: required :type symbol: str :param side: required - BUY or SELL :type side: str :param positionSide: optional - Default BOTH for One-way Mode; LONG or SHORT for Hedge Mode :type positionSide: str :param type: required - STOP_MARKET/TAKE_PROFIT_MARKET/STOP/TAKE_PROFIT/TRAILING_STOP_MARKET :type type: str :param timeInForce: optional - IOC or GTC or FOK or GTX, default GTC :type timeInForce: str :param quantity: optional - Cannot be sent with closePosition=true :type quantity: decimal :param price: optional :type price: decimal :param triggerPrice: optional - Used with STOP, STOP_MARKET, TAKE_PROFIT, TAKE_PROFIT_MARKET :type triggerPrice: decimal :param workingType: optional - triggerPrice triggered by: MARK_PRICE, CONTRACT_PRICE. Default CONTRACT_PRICE :type workingType: str :param priceMatch: optional - only available for LIMIT/STOP/TAKE_PROFIT order :type priceMatch: str :param closePosition: optional - true, false; Close-All, used with STOP_MARKET or TAKE_PROFIT_MARKET :type closePosition: str :param priceProtect: optional - "TRUE" or "FALSE", default "FALSE" :type priceProtect: str :param reduceOnly: optional - "true" or "false", default "false" :type reduceOnly: str :param activatePrice: optional - Used with TRAILING_STOP_MARKET orders :type activatePrice: decimal :param callbackRate: optional - Used with TRAILING_STOP_MARKET orders, min 0.1, max 10 :type callbackRate: decimal :param clientAlgoId: optional - A unique id among open orders :type clientAlgoId: str :param newOrderRespType: optional - "ACK", "RESULT", default "ACK" :type newOrderRespType: str :param selfTradePreventionMode: optional - EXPIRE_TAKER, EXPIRE_MAKER, EXPIRE_BOTH, default NONE :type selfTradePreventionMode: str :param goodTillDate: optional - order cancel time for timeInForce GTD :type goodTillDate: long :param recvWindow: optional - the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python result = client.futures_create_algo_order( algoType='CONDITIONAL', symbol='BNBUSDT', side='SELL', type='TAKE_PROFIT', quantity='0.01', price='750.000', triggerPrice='750.000', timeInForce='GTC' ) """ if "clientAlgoId" not in params: params["clientAlgoId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() if "algoType" not in params: params["algoType"] = "CONDITIONAL" return self._request_futures_api("post", "algoOrder", True, data=params) def futures_cancel_algo_order(self, **params): """Cancel an active algo order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Cancel-Algo-Order :param symbol: required :type symbol: str :param algoId: optional - Either algoId or clientAlgoId must be sent :type algoId: int :param clientAlgoId: optional - Either algoId or clientAlgoId must be sent :type clientAlgoId: str :param recvWindow: optional - the number of milliseconds the request is valid for :type recvWindow: int :returns: API response """ return self._request_futures_api("delete", "algoOrder", True, data=params) def futures_cancel_all_algo_open_orders(self, **params): """Cancel all open algo orders https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Cancel-All-Algo-Open-Orders :param symbol: required :type symbol: str :param recvWindow: optional - the number of milliseconds the request is valid for :type recvWindow: int :returns: API response """ return self._request_futures_api( "delete", "algoOpenOrders", True, data=params ) def futures_get_algo_order(self, **params): """Check an algo order's status. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Query-Algo-Order :param symbol: required :type symbol: str :param algoId: optional - Either algoId or clientAlgoId must be sent :type algoId: int :param clientAlgoId: optional - Either algoId or clientAlgoId must be sent :type clientAlgoId: str :param recvWindow: optional - the number of milliseconds the request is valid for :type recvWindow: int :returns: API response """ return self._request_futures_api("get", "algoOrder", True, data=params) def futures_get_open_algo_orders(self, **params): """Get all open algo orders on a symbol. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Current-All-Algo-Open-Orders :param symbol: optional :type symbol: str :param recvWindow: optional - the number of milliseconds the request is valid for :type recvWindow: int :returns: API response """ return self._request_futures_api("get", "openAlgoOrders", True, data=params) def futures_get_all_algo_orders(self, **params): """Get all algo account orders; active, canceled, or filled. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Query-All-Algo-Orders :param symbol: required :type symbol: str :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param limit: optional - Default 100; max 100 :type limit: int :param recvWindow: optional - the number of milliseconds the request is valid for :type recvWindow: int :returns: API response """ return self._request_futures_api("get", "allAlgoOrders", True, data=params) def futures_account_balance(self, **params): """Get futures account balance https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Futures-Account-Balance-V3 """ return self._request_futures_api("get", "balance", True, 3, data=params) def futures_account(self, **params): """Get current account information. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Account-Information-V2 """ return self._request_futures_api("get", "account", True, 2, data=params) def futures_symbol_adl_risk(self, **params): """Query the symbol-level ADL (Auto-Deleveraging) risk rating The ADL risk rating measures the likelihood of ADL during liquidation. Rating can be: high, medium, low. Updated every 30 minutes. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Query-ADL-Risk-Rating :param symbol: optional - if not provided, returns ADL risk for all symbols :type symbol: str :returns: API response .. code-block:: python # Single symbol { "symbol": "BTCUSDT", "adlRisk": "low", "updateTime": 1597370495002 } # All symbols (when symbol not provided) [ { "symbol": "BTCUSDT", "adlRisk": "low", "updateTime": 1597370495002 }, { "symbol": "ETHUSDT", "adlRisk": "high", "updateTime": 1597370495004 } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_futures_api("get", "symbolAdlRisk", True, data=params) def futures_change_leverage(self, **params): """Change user's initial leverage of specific symbol market https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Change-Initial-Leverage """ return self._request_futures_api("post", "leverage", True, data=params) def futures_change_margin_type(self, **params): """Change the margin type for a symbol https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Change-Margin-Type """ return self._request_futures_api("post", "marginType", True, data=params) def futures_change_position_margin(self, **params): """Change the position margin for a symbol https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Modify-Isolated-Position-Margin """ return self._request_futures_api("post", "positionMargin", True, data=params) def futures_position_margin_history(self, **params): """Get position margin change history https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Get-Position-Margin-Change-History """ return self._request_futures_api( "get", "positionMargin/history", True, data=params ) def futures_position_information(self, **params): """Get position information https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Position-Information-V3 """ return self._request_futures_api("get", "positionRisk", True, 3, data=params) def futures_account_trades(self, **params): """Get trades for the authenticated account and symbol. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Account-Trade-List """ return self._request_futures_api("get", "userTrades", True, data=params) def futures_income_history(self, **params): """Get income history for authenticated account https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Get-Income-History """ return self._request_futures_api("get", "income", True, data=params) def futures_change_position_mode(self, **params): """Change position mode for authenticated account https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Change-Position-Mode """ return self._request_futures_api("post", "positionSide/dual", True, data=params) def futures_get_position_mode(self, **params): """Get position mode for authenticated account https://binance-docs.github.io/apidocs/futures/en/#get-current-position-mode-user_data """ return self._request_futures_api("get", "positionSide/dual", True, data=params) def futures_change_multi_assets_mode(self, multiAssetsMargin: bool): """Change user's Multi-Assets mode (Multi-Assets Mode or Single-Asset Mode) on Every symbol https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Change-Multi-Assets-Mode """ params = {"multiAssetsMargin": "true" if multiAssetsMargin else "false"} return self._request_futures_api("post", "multiAssetsMargin", True, data=params) def futures_get_multi_assets_mode(self): """Get user's Multi-Assets mode (Multi-Assets Mode or Single-Asset Mode) on Every symbol https://binance-docs.github.io/apidocs/futures/en/#get-current-multi-assets-mode-user_data """ return self._request_futures_api("get", "multiAssetsMargin", True, data={}) def futures_stream_get_listen_key(self): res = self._request_futures_api("post", "listenKey", signed=False, data={}) return res["listenKey"] def futures_stream_keepalive(self, listenKey): params = {"listenKey": listenKey} return self._request_futures_api("put", "listenKey", signed=False, data=params) def futures_stream_close(self, listenKey): params = {"listenKey": listenKey} return self._request_futures_api( "delete", "listenKey", signed=False, data=params ) # new methods def futures_account_config(self, **params): """Get futures account configuration https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Account-Config """ return self._request_futures_api( "get", "accountConfig", signed=True, version=1, data=params ) def futures_symbol_config(self, **params): """Get current account symbol configuration https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Symbol-Config """ return self._request_futures_api( "get", "symbolConfig", signed=True, version=1, data=params ) # COIN Futures API def futures_coin_ping(self): """Test connectivity to the Rest API https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api """ return self._request_futures_coin_api("get", "ping") def futures_coin_time(self): """Test connectivity to the Rest API and get the current server time. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Check-Server-time """ return self._request_futures_coin_api("get", "time") def futures_coin_exchange_info(self): """Current exchange trading rules and symbol information https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Exchange-Information """ return self._request_futures_coin_api("get", "exchangeInfo") def futures_coin_order_book(self, **params): """Get the Order Book for the market https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Order-Book """ return self._request_futures_coin_api("get", "depth", data=params) def futures_coin_recent_trades(self, **params): """Get recent trades (up to last 500). https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Recent-Trades-List """ return self._request_futures_coin_api("get", "trades", data=params) def futures_coin_historical_trades(self, **params): """Get older market historical trades. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Old-Trades-Lookup """ return self._request_futures_coin_api("get", "historicalTrades", data=params) def futures_coin_aggregate_trades(self, **params): """Get compressed, aggregate trades. Trades that fill at the time, from the same order, with the same price will have the quantity aggregated. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Compressed-Aggregate-Trades-List """ return self._request_futures_coin_api("get", "aggTrades", data=params) def futures_coin_klines(self, **params): """Kline/candlestick bars for a symbol. Klines are uniquely identified by their open time. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Kline-Candlestick-Data """ return self._request_futures_coin_api("get", "klines", data=params) def futures_coin_continous_klines(self, **params): """Kline/candlestick bars for a specific contract type. Klines are uniquely identified by their open time. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Continuous-Contract-Kline-Candlestick-Data """ return self._request_futures_coin_api("get", "continuousKlines", data=params) def futures_coin_index_price_klines(self, **params): """Kline/candlestick bars for the index price of a pair.. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Index-Price-Kline-Candlestick-Data """ return self._request_futures_coin_api("get", "indexPriceKlines", data=params) def futures_coin_premium_index_klines(self, **params): """Kline/candlestick bars for the index price of a pair.. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Premium-Index-Kline-Data """ return self._request_futures_coin_api("get", "premiumIndexKlines", data=params) def futures_coin_mark_price_klines(self, **params): """Kline/candlestick bars for the index price of a pair.. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Mark-Price-Kline-Candlestick-Data """ return self._request_futures_coin_api("get", "markPriceKlines", data=params) def futures_coin_mark_price(self, **params): """Get Mark Price and Funding Rate https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Index-Price-and-Mark-Price """ return self._request_futures_coin_api("get", "premiumIndex", data=params) def futures_coin_funding_rate(self, **params): """Get funding rate history https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Get-Funding-Rate-History-of-Perpetual-Futures """ return self._request_futures_coin_api("get", "fundingRate", data=params) def futures_coin_ticker(self, **params): """24 hour rolling window price change statistics. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/24hr-Ticker-Price-Change-Statistics """ return self._request_futures_coin_api("get", "ticker/24hr", data=params) def futures_coin_symbol_ticker(self, **params): """Latest price for a symbol or symbols. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Symbol-Price-Ticker """ return self._request_futures_coin_api("get", "ticker/price", data=params) def futures_coin_orderbook_ticker(self, **params): """Best price/qty on the order book for a symbol or symbols. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Symbol-Order-Book-Ticker """ return self._request_futures_coin_api("get", "ticker/bookTicker", data=params) def futures_coin_top_longshort_position_ratio(self, **params): """Get present long to short ratio for top positions of a specific symbol. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Top-Trader-Long-Short-Ratio """ return self._request_futures_coin_data_api("get", "topLongShortPositionRatio", data=params) def futures_coin_top_longshort_account_ratio(self, **params): """Get present long to short ratio for top positions of a specific symbol. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Top-Long-Short-Account-Ratio """ return self._request_futures_coin_data_api("get", "topLongShortAccountRatio", data=params) def futures_coin_global_longshort_ratio(self, **params): """Get present long to short ratio for top positions of a specific symbol. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Long-Short-Ratio """ return self._request_futures_coin_data_api("get", "globalLongShortAccountRatio", data=params) def futures_coin_taker_buy_sell_volume(self, **params): """Get present long to short ratio for top positions of a specific symbol. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Taker-Buy-Sell-Volume """ return self._request_futures_coin_data_api("get", "takerBuySellVol", data=params) def futures_coin_basis(self, **params): """Get future basis of a specific symbol https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Basis """ return self._request_futures_coin_data_api("get", "basis", data=params) def futures_coin_index_price_constituents(self, **params): """Get index price constituents https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Index-Constituents """ return self._request_futures_coin_api("get", "constituents", data=params) def futures_coin_liquidation_orders(self, **params): """Get all liquidation orders https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Users-Force-Orders """ return self._request_futures_coin_api( "get", "forceOrders", signed=True, data=params ) def futures_coin_open_interest(self, **params): """Get present open interest of a specific symbol. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Open-Interest """ return self._request_futures_coin_api("get", "openInterest", data=params) def futures_coin_open_interest_hist(self, **params): """Get open interest statistics of a specific symbol. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Open-Interest-Statistics """ return self._request_futures_coin_data_api( "get", "openInterestHist", data=params ) def futures_coin_leverage_bracket(self, **params): """Notional and Leverage Brackets https://developers.binance.com/docs/derivatives/coin-margined-futures/account/rest-api/Notional-Bracket-for-Symbol """ return self._request_futures_coin_api( "get", "leverageBracket", version=2, signed=True, data=params ) def new_transfer_history(self, **params): """Get future account transaction history list https://developers.binance.com/docs/wallet/asset/query-user-universal-transfer """ return self._request_margin_api("get", "asset/transfer", True, data=params) def funding_wallet(self, **params): """ Query Funding Wallet https://developers.binance.com/docs/wallet/asset/funding-wallet """ return self._request_margin_api( "post", "asset/get-funding-asset", True, data=params ) def get_user_asset(self, **params): """ Get user assets, just for positive data https://developers.binance.com/docs/wallet/asset/user-assets """ return self._request_margin_api( "post", "asset/getUserAsset", True, data=params, version=3 ) def universal_transfer(self, **params): """Unviversal transfer api accross different binance account types https://developers.binance.com/docs/wallet/asset/user-universal-transfer """ return self._request_margin_api( "post", "asset/transfer", signed=True, data=params ) def futures_coin_create_order(self, **params): """Send in a new order. https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return self._request_futures_coin_api("post", "order", True, data=params) def futures_coin_place_batch_order(self, **params): """Send in new orders. https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Place-Multiple-Orders To avoid modifying the existing signature generation and parameter order logic, the url encoding is done on the special query param, batchOrders, in the early stage. """ for order in params["batchOrders"]: if "newClientOrderId" not in order: order["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() query_string = urlencode(params) query_string = query_string.replace("%27", "%22") params["batchOrders"] = query_string[12:] return self._request_futures_coin_api("post", "batchOrders", True, data=params) def futures_coin_modify_order(self, **params): """Modify an existing order. Currently only LIMIT order modification is supported. https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Modify-Order """ return self._request_futures_coin_api("put", "order", True, data=params) def futures_coin_get_order(self, **params): """Check an order's status. https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Query-Order """ return self._request_futures_coin_api("get", "order", True, data=params) def futures_coin_get_open_orders(self, **params): """Get all open orders on a symbol. https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Current-All-Open-Orders """ return self._request_futures_coin_api("get", "openOrders", True, data=params) def futures_coin_get_all_orders(self, **params): """Get all futures account orders; active, canceled, or filled. https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/All-Orders """ return self._request_futures_coin_api( "get", "allOrders", signed=True, data=params ) def futures_coin_cancel_order(self, **params): """Cancel an active futures order. https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Cancel-Order """ return self._request_futures_coin_api( "delete", "order", signed=True, data=params ) def futures_coin_cancel_all_open_orders(self, **params): """Cancel all open futures orders https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Cancel-All-Open-Orders """ return self._request_futures_coin_api( "delete", "allOpenOrders", signed=True, force_params=True, data=params ) def futures_coin_cancel_orders(self, **params): """Cancel multiple futures orders https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Cancel-Multiple-Orders """ if params.get("orderidlist"): params["orderidlist"] = quote( convert_list_to_json_array(params["orderidlist"]) ) if params.get("origclientOrderidlist"): params["origclientorderidlist"] = quote( convert_list_to_json_array(params["origclientorderidlist"]) ) return self._request_futures_coin_api( "delete", "batchOrders", True, data=params ) def futures_coin_countdown_cancel_all(self, **params): """Cancel all open orders of the specified symbol at the end of the specified countdown. https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Auto-Cancel-All-Open-Orders :param symbol: required :type symbol: str :param countdownTime: required :type countdownTime: int :param recvWindow: optional - the number of milliseconds the request is valid for :type recvWindow: int :returns: API response .. code-block:: python { "symbol": "BTCUSDT", "countdownTime": "100000" } """ return self._request_futures_coin_api( "post", "countdownCancelAll", True, data=params ) def futures_coin_get_open_order(self, **params): """Get current open order. https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Query-Current-Open-Order """ return self._request_futures_coin_api( "get", "openOrder", signed=True, data=params ) def futures_coin_account_balance(self, **params): """Get futures account balance https://developers.binance.com/docs/derivatives/coin-margined-futures/account/rest-api/Futures-Account-Balance """ return self._request_futures_coin_api( "get", "balance", signed=True, data=params ) def futures_coin_account(self, **params): """Get current account information. https://developers.binance.com/docs/derivatives/coin-margined-futures/account/rest-api/Account-Information """ return self._request_futures_coin_api( "get", "account", signed=True, data=params ) def futures_coin_change_leverage(self, **params): """Change user's initial leverage of specific symbol market https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Change-Initial-Leverage """ return self._request_futures_coin_api( "post", "leverage", signed=True, data=params ) def futures_coin_change_margin_type(self, **params): """Change the margin type for a symbol https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Change-Margin-Type """ return self._request_futures_coin_api( "post", "marginType", signed=True, data=params ) def futures_coin_change_position_margin(self, **params): """Change the position margin for a symbol https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Modify-Isolated-Position-Margin """ return self._request_futures_coin_api( "post", "positionMargin", True, data=params ) def futures_coin_position_margin_history(self, **params): """Get position margin change history https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Get-Position-Margin-Change-History """ return self._request_futures_coin_api( "get", "positionMargin/history", True, data=params ) def futures_coin_position_information(self, **params): """Get position information https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Position-Information """ return self._request_futures_coin_api("get", "positionRisk", True, data=params) def futures_coin_account_trades(self, **params): """Get trades for the authenticated account and symbol. https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Account-Trade-List """ return self._request_futures_coin_api("get", "userTrades", True, data=params) def futures_coin_income_history(self, **params): """Get income history for authenticated account https://developers.binance.com/docs/derivatives/coin-margined-futures/account/rest-api/Get-Income-History """ return self._request_futures_coin_api("get", "income", True, data=params) def futures_coin_change_position_mode(self, **params): """Change user's position mode (Hedge Mode or One-way Mode ) on EVERY symbol https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Change-Position-Mode """ return self._request_futures_coin_api( "post", "positionSide/dual", True, data=params ) def futures_coin_get_position_mode(self, **params): """Get user's position mode (Hedge Mode or One-way Mode ) on EVERY symbol https://developers.binance.com/docs/derivatives/coin-margined-futures/account/rest-api/Get-Current-Position-Mode """ return self._request_futures_coin_api( "get", "positionSide/dual", True, data=params ) def futures_coin_stream_get_listen_key(self): res = self._request_futures_coin_api("post", "listenKey", signed=False, data={}) return res["listenKey"] def futures_coin_stream_keepalive(self, listenKey): params = {"listenKey": listenKey} return self._request_futures_coin_api( "put", "listenKey", signed=False, data=params ) def futures_coin_stream_close(self, listenKey): params = {"listenKey": listenKey} return self._request_futures_coin_api( "delete", "listenKey", signed=False, data=params ) def futures_coin_account_order_history_download(self, **params): """Get Download Id For Futures Order History https://developers.binance.com/docs/derivatives/coin-margined-futures/account/rest-api/Get-Download-Id-For-Futures-Order-History :param startTime: required - Start timestamp in ms :type startTime: int :param endTime: required - End timestamp in ms :type endTime: int :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "avgCostTimestampOfLast30d": 7241837, # Average time taken for data download in the past 30 days "downloadId": "546975389218332672" } Note: - Request Limitation is 10 times per month, shared by front end download page and rest api - The time between startTime and endTime can not be longer than 1 year :raises: BinanceRequestException, BinanceAPIException """ return self._request_futures_coin_api( "get", "order/asyn", signed=True, data=params ) def futures_coin_accout_order_history_download_link(self, **params): """Get futures order history download link by Id https://developers.binance.com/docs/derivatives/coin-margined-futures/account/rest-api/Get-Futures-Order-History-Download-Link-by-Id :param downloadId: required - Download ID obtained from futures_coin_download_id :type downloadId: str :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "downloadId": "545923594199212032", "status": "completed", # Enum:completed,processing "url": "www.binance.com", # The link is mapped to download id "notified": true, # ignore "expirationTimestamp": 1645009771000, # The link would expire after this timestamp "isExpired": null } # OR (Response when server is processing) { "downloadId": "545923594199212032", "status": "processing", "url": "", "notified": false, "expirationTimestamp": -1, "isExpired": null } Note: - Download link expiration: 24h :raises: BinanceRequestException, BinanceAPIException """ return self._request_futures_coin_api("get", "order/asyn/id", True, data=params) def futures_coin_account_trade_history_download(self, **params): """Get Download Id For Futures Trade History (USER_DATA) https://developers.binance.com/docs/derivatives/coin-margined-futures/account/rest-api/Get-Download-Id-For-Futures-Trade-History :param startTime: required - Start timestamp in ms :type startTime: int :param endTime: required - End timestamp in ms :type endTime: int :returns: API response .. code-block:: python { "avgCostTimestampOfLast30d": 7241837, # Average time taken for data download in the past 30 days "downloadId": "546975389218332672" } Note: - Request Limitation is 5 times per month, shared by front end download page and rest api - The time between startTime and endTime can not be longer than 1 year :raises: BinanceRequestException, BinanceAPIException """ return self._request_futures_coin_api("get", "trade/asyn", True, data=params) def futures_coin_account_trade_history_download_link(self, **params): """Get futures trade download link by Id https://developers.binance.com/docs/derivatives/coin-margined-futures/account/rest-api/Get-Futures-Trade-Download-Link-by-Id :param downloadId: required - Download ID obtained from futures_coin_trade_download_id :type downloadId: str :returns: API response .. code-block:: python { "downloadId": "545923594199212032", "status": "completed", # Enum:completed,processing "url": "www.binance.com", # The link is mapped to download id "notified": true, # ignore "expirationTimestamp": 1645009771000, # The link would expire after this timestamp "isExpired": null } # OR (Response when server is processing) { "downloadId": "545923594199212032", "status": "processing", "url": "", "notified": false, "expirationTimestamp": -1, "isExpired": null } Note: - Download link expiration: 24h :raises: BinanceRequestException, BinanceAPIException """ return self._request_futures_coin_api("get", "trade/asyn/id", True, data=params) def get_all_coins_info(self, **params): """Get information of coins (available for deposit and withdraw) for user. https://developers.binance.com/docs/wallet/capital :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "coin": "BTC", "depositAllEnable": true, "withdrawAllEnable": true, "name": "Bitcoin", "free": "0", "locked": "0", "freeze": "0", "withdrawing": "0", "ipoing": "0", "ipoable": "0", "storage": "0", "isLegalMoney": false, "trading": true, "networkList": [ { "network": "BNB", "coin": "BTC", "withdrawIntegerMultiple": "0.00000001", "isDefault": false, "depositEnable": true, "withdrawEnable": true, "depositDesc": "", "withdrawDesc": "", "specialTips": "Both a MEMO and an Address are required to successfully deposit your BEP2-BTCB tokens to Binance.", "name": "BEP2", "resetAddressStatus": false, "addressRegex": "^(bnb1)[0-9a-z]{38}$", "memoRegex": "^[0-9A-Za-z-_]{1,120}$", "withdrawFee": "0.0000026", "withdrawMin": "0.0000052", "withdrawMax": "0", "minConfirm": 1, "unLockConfirm": 0 }, { "network": "BTC", "coin": "BTC", "withdrawIntegerMultiple": "0.00000001", "isDefault": true, "depositEnable": true, "withdrawEnable": true, "depositDesc": "", "withdrawDesc": "", "specialTips": "", "name": "BTC", "resetAddressStatus": false, "addressRegex": "^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^(bc1)[0-9A-Za-z]{39,59}$", "memoRegex": "", "withdrawFee": "0.0005", "withdrawMin": "0.001", "withdrawMax": "0", "minConfirm": 1, "unLockConfirm": 2 } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "get", "capital/config/getall", True, data=params ) def get_account_snapshot(self, **params): """Get daily account snapshot of specific type. https://developers.binance.com/docs/wallet/account/daily-account-snapshoot :param type: required. Valid values are SPOT/MARGIN/FUTURES. :type type: string :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param limit: optional :type limit: int :param recvWindow: optional :type recvWindow: int :returns: API response .. code-block:: python { "code":200, // 200 for success; others are error codes "msg":"", // error message "snapshotVos":[ { "data":{ "balances":[ { "asset":"BTC", "free":"0.09905021", "locked":"0.00000000" }, { "asset":"USDT", "free":"1.89109409", "locked":"0.00000000" } ], "totalAssetOfBtc":"0.09942700" }, "type":"spot", "updateTime":1576281599000 } ] } OR .. code-block:: python { "code":200, // 200 for success; others are error codes "msg":"", // error message "snapshotVos":[ { "data":{ "marginLevel":"2748.02909813", "totalAssetOfBtc":"0.00274803", "totalLiabilityOfBtc":"0.00000100", "totalNetAssetOfBtc":"0.00274750", "userAssets":[ { "asset":"XRP", "borrowed":"0.00000000", "free":"1.00000000", "interest":"0.00000000", "locked":"0.00000000", "netAsset":"1.00000000" } ] }, "type":"margin", "updateTime":1576281599000 } ] } OR .. code-block:: python { "code":200, // 200 for success; others are error codes "msg":"", // error message "snapshotVos":[ { "data":{ "assets":[ { "asset":"USDT", "marginBalance":"118.99782335", "walletBalance":"120.23811389" } ], "position":[ { "entryPrice":"7130.41000000", "markPrice":"7257.66239673", "positionAmt":"0.01000000", "symbol":"BTCUSDT", "unRealizedProfit":"1.24029054" } ] }, "type":"futures", "updateTime":1576281599000 } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api("get", "accountSnapshot", True, data=params) def disable_fast_withdraw_switch(self, **params): """Disable Fast Withdraw Switch https://binance-docs.github.io/apidocs/spot/en/#disable-fast-withdraw-switch-user_data :param recvWindow: optional :type recvWindow: int :returns: API response :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "disableFastWithdrawSwitch", True, data=params ) def enable_fast_withdraw_switch(self, **params): """Enable Fast Withdraw Switch https://binance-docs.github.io/apidocs/spot/en/#enable-fast-withdraw-switch-user_data :param recvWindow: optional :type recvWindow: int :returns: API response :raises: BinanceRequestException, BinanceAPIException """ return self._request_margin_api( "post", "enableFastWithdrawSwitch", True, data=params ) """ ==================================================================================================================== Options API ==================================================================================================================== """ # Quoting interface endpoints def options_ping(self): """Test connectivity https://developers.binance.com/docs/derivatives/option/market-data/Test-Connectivity """ return self._request_options_api("get", "ping") def options_time(self): """Get server time https://developers.binance.com/docs/derivatives/option/market-data """ return self._request_options_api("get", "time") def options_info(self): """Get current trading pair info https://binance-docs.github.io/apidocs/voptions/en/#get-current-trading-pair-info """ return self._request_options_api("get", "optionInfo") def options_exchange_info(self): """Get current limit info and trading pair info https://developers.binance.com/docs/derivatives/option/market-data/Exchange-Information """ return self._request_options_api("get", "exchangeInfo") def options_index_price(self, **params): """Get the spot index price https://developers.binance.com/docs/derivatives/option/market-data/Symbol-Price-Ticker :param underlying: required - Spot pair(Option contract underlying asset)- BTCUSDT :type underlying: str """ return self._request_options_api("get", "index", data=params) def options_price(self, **params): """Get the latest price https://developers.binance.com/docs/derivatives/option/market-data/24hr-Ticker-Price-Change-Statistics :param symbol: optional - Option trading pair - BTC-200730-9000-C :type symbol: str """ return self._request_options_api("get", "ticker", data=params) def options_mark_price(self, **params): """Get the latest mark price https://developers.binance.com/docs/derivatives/option/market-data/Option-Mark-Price :param symbol: optional - Option trading pair - BTC-200730-9000-C :type symbol: str """ return self._request_options_api("get", "mark", data=params) def options_order_book(self, **params): """Depth information https://developers.binance.com/docs/derivatives/option/market-data/Order-Book :param symbol: required - Option trading pair - BTC-200730-9000-C :type symbol: str :param limit: optional - Default:100 Max:1000.Optional value:[10, 20, 50, 100, 500, 1000] - 100 :type limit: int """ return self._request_options_api("get", "depth", data=params) def options_klines(self, **params): """Candle data https://developers.binance.com/docs/derivatives/option/market-data/Kline-Candlestick-Data :param symbol: required - Option trading pair - BTC-200730-9000-C :type symbol: str :param interval: required - Time interval - 5m :type interval: str :param startTime: optional - Start Time - 1592317127349 :type startTime: int :param endTime: optional - End Time - 1592317127349 :type endTime: int :param limit: optional - Number of records Default:500 Max:1500 - 500 :type limit: int """ return self._request_options_api("get", "klines", data=params) def options_recent_trades(self, **params): """Recently completed Option trades https://developers.binance.com/docs/derivatives/option/market-data/Recent-Trades-List :param symbol: required - Option trading pair - BTC-200730-9000-C :type symbol: str :param limit: optional - Number of records Default:100 Max:500 - 100 :type limit: int """ return self._request_options_api("get", "trades", data=params) def options_historical_trades(self, **params): """Query trade history https://developers.binance.com/docs/derivatives/option/market-data/Old-Trades-Lookup :param symbol: required - Option trading pair - BTC-200730-9000-C :type symbol: str :param fromId: optional - The deal ID from which to return. The latest deal record is returned by default - 1592317127349 :type fromId: int :param limit: optional - Number of records Default:100 Max:500 - 100 :type limit: int """ return self._request_options_api("get", "historicalTrades", data=params) # Account and trading interface endpoints def options_account_info(self, **params): """Account asset info (USER_DATA) https://developers.binance.com/docs/derivatives/option/account :param recvWindow: optional :type recvWindow: int """ return self._request_options_api("get", "account", signed=True, data=params) def options_get_bill(self, **params): """Get account funding flows https://developers.binance.com/docs/derivatives/option/account/Account-Funding-Flow :param currency: required :type currency: str :param recordId: optional :type recordId: int :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param limit: optional :type limit: int :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_options_api("get", "bill", signed=True, data=params) def options_funds_transfer(self, **params): """Funds transfer (USER_DATA) https://binance-docs.github.io/apidocs/voptions/en/#funds-transfer-user_data :param currency: required - Asset type - USDT :type currency: str :param type: required - IN: Transfer from spot account to option account OUT: Transfer from option account to spot account - IN :type type: str (ENUM) :param amount: required - Amount - 10000 :type amount: float :param recvWindow: optional :type recvWindow: int """ return self._request_options_api("post", "transfer", signed=True, data=params) def options_positions(self, **params): """Option holdings info (USER_DATA) https://developers.binance.com/docs/derivatives/option/trade/Option-Position-Information :param symbol: optional - Option trading pair - BTC-200730-9000-C :type symbol: str :param recvWindow: optional :type recvWindow: int """ return self._request_options_api("get", "position", signed=True, data=params) def options_exercise_record(self, **params): """ Get account exercise records. https://developers.binance.com/docs/derivatives/option/trade/User-Exercise-Record :param symbol: optional :type symbol: str :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param limit: optional :type limit: int :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_options_api("get", "exerciseRecord", signed=True, data=params) def options_bill(self, **params): """Account funding flow (USER_DATA) https://binance-docs.github.io/apidocs/voptions/en/#account-funding-flow-user_data :param currency: required - Asset type - USDT :type currency: str :param recordId: optional - Return the recordId and subsequent data, the latest data is returned by default - 100000 :type recordId: int :param startTime: optional - Start Time - 1593511200000 :type startTime: int :param endTime: optional - End Time - 1593511200000 :type endTime: int :param limit: optional - Number of result sets returned Default:100 Max:1000 - 100 :type limit: int :param recvWindow: optional :type recvWindow: int """ return self._request_options_api("post", "bill", signed=True, data=params) def options_place_order(self, **params): """Option order (TRADE) https://developers.binance.com/docs/derivatives/option/trade :param symbol: required - Option trading pair - BTC-200730-9000-C :type symbol: str :param side: required - Buy/sell direction: SELL, BUY - BUY :type side: str (ENUM) :param type: required - Order Type: LIMIT, MARKET - LIMIT :type type: str (ENUM) :param quantity: required - Order Quantity - 3 :type quantity: float :param price: optional - Order Price - 1000 :type price: float :param timeInForce: optional - Time in force method(Default GTC) - GTC :type timeInForce: str (ENUM) :param reduceOnly: optional - Reduce Only (Default false) - false :type reduceOnly: bool :param postOnly: optional - Post Only (Default false) - false :type postOnly: bool :param newOrderRespType: optional - "ACK", "RESULT", Default "ACK" - ACK :type newOrderRespType: str (ENUM) :param clientOrderId: optional - User-defined order ID cannot be repeated in pending orders - 10000 :type clientOrderId: str :param recvWindow: optional :type recvWindow: int """ if "clientOrderId" not in params: params["clientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return self._request_options_api("post", "order", signed=True, data=params) def options_place_batch_order(self, **params): """Place Multiple Option orders (TRADE) https://developers.binance.com/docs/derivatives/option/trade/Place-Multiple-Orders :param orders: required - order list. Max 5 orders - [{"symbol":"BTC-210115-35000-C","price":"100","quantity":"0.0001","side":"BUY","type":"LIMIT"}] :type orders: list :param recvWindow: optional :type recvWindow: int """ for order in params["batchOrders"]: if "newClientOrderId" not in order: order["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return self._request_options_api( "post", "batchOrders", signed=True, data=params ) def options_cancel_order(self, **params): """Cancel Option order (TRADE) https://developers.binance.com/docs/derivatives/option/trade/Cancel-Option-Order :param symbol: required - Option trading pair - BTC-200730-9000-C :type symbol: str :param orderId: optional - Order ID - 4611875134427365377 :type orderId: str :param clientOrderId: optional - User-defined order ID - 10000 :type clientOrderId: str :param recvWindow: optional :type recvWindow: int """ return self._request_options_api("delete", "order", signed=True, data=params) def options_cancel_batch_order(self, **params): """Cancel Multiple Option orders (TRADE) https://developers.binance.com/docs/derivatives/option/trade/Cancel-Multiple-Option-Orders :param symbol: required - Option trading pair - BTC-200730-9000-C :type symbol: str :param orderIds: optional - Order ID - [4611875134427365377,4611875134427365378] :type orderId: list :param clientOrderIds: optional - User-defined order ID - ["my_id_1","my_id_2"] :type clientOrderIds: list :param recvWindow: optional :type recvWindow: int """ return self._request_options_api( "delete", "batchOrders", signed=True, data=params ) def options_cancel_all_orders(self, **params): """Cancel all Option orders (TRADE) https://developers.binance.com/docs/derivatives/option/trade/Cancel-all-Option-orders-on-specific-symbol :param symbol: required - Option trading pair - BTC-200730-9000-C :type symbol: str :param recvWindow: optional :type recvWindow: int """ return self._request_options_api( "delete", "allOpenOrders", signed=True, data=params ) def options_query_order(self, **params): """Query Option order (TRADE) https://developers.binance.com/docs/derivatives/option/trade/Query-Single-Order :param symbol: required - Option trading pair - BTC-200730-9000-C :type symbol: str :param orderId: optional - Order ID - 4611875134427365377 :type orderId: str :param clientOrderId: optional - User-defined order ID - 10000 :type clientOrderId: str :param recvWindow: optional :type recvWindow: int """ return self._request_options_api("get", "order", signed=True, data=params) def options_query_pending_orders(self, **params): """Query current pending Option orders (TRADE) https://developers.binance.com/docs/derivatives/option/trade/Query-Current-Open-Option-Orders :param symbol: required - Option trading pair - BTC-200730-9000-C :type symbol: str :param orderId: optional - Returns the orderId and subsequent orders, the most recent order is returned by default - 100000 :type orderId: str :param startTime: optional - Start Time - 1593511200000 :type startTime: int :param endTime: optional - End Time - 1593511200000 :type endTime: int :param limit: optional - Number of result sets returned Default:100 Max:1000 - 100 :type limit: int :param recvWindow: optional :type recvWindow: int """ return self._request_options_api("get", "openOrders", signed=True, data=params) def options_query_order_history(self, **params): """Query Option order history (TRADE) https://developers.binance.com/docs/derivatives/option/trade/Query-Option-Order-History :param symbol: required - Option trading pair - BTC-200730-9000-C :type symbol: str :param orderId: optional - Returns the orderId and subsequent orders, the most recent order is returned by default - 100000 :type orderId: str :param startTime: optional - Start Time - 1593511200000 :type startTime: int :param endTime: optional - End Time - 1593511200000 :type endTime: int :param limit: optional - Number of result sets returned Default:100 Max:1000 - 100 :type limit: int :param recvWindow: optional :type recvWindow: int """ return self._request_options_api( "get", "historyOrders", signed=True, data=params ) def options_user_trades(self, **params): """Option Trade List (USER_DATA) https://developers.binance.com/docs/derivatives/option/trade/Account-Trade-List :param symbol: required - Option trading pair - BTC-200730-9000-C :type symbol: str :param fromId: optional - Trade id to fetch from. Default gets most recent trades. - 4611875134427365376 :type fromId: int :param startTime: optional - Start Time - 1593511200000 :type startTime: int :param endTime: optional - End Time - 1593511200000 :type endTime: int :param limit: optional - Number of result sets returned Default:100 Max:1000 - 100 :type limit: int :param recvWindow: optional :type recvWindow: int """ return self._request_options_api("get", "userTrades", signed=True, data=params) #################################################### # Options - Market Maker Block Trade #################################################### def options_create_block_trade_order(self, **params): """New Block Trade Order (TRADE) https://developers.binance.com/docs/derivatives/option/market-maker-block-trade :param liquidity: required - Taker or Maker :type liquidity: str :param symbol: required - Option trading pair, e.g BTC-200730-9000-C :type symbol: str :param side: required - BUY or SELL :type side: str :param price: required - Order Price :type price: float :param quantity: required - Order Quantity :type quantity: float :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: API response .. code-block:: python { "blockTradeSettlementKey": "3668822b8-1baa-6a2f-adb8-d3de6289b361", "expireTime": 1730171888109, "liquidity": "TAKER", "status": "RECEIVED", "legs": [ { "symbol": "BNB-241101-700-C", "side": "BUY", "quantity": "1.2", "price": "2.8" } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_options_api( "post", "block/order/create", signed=True, data=params ) def options_cancel_block_trade_order(self, **params): """Cancel Block Trade Order (TRADE) https://developers.binance.com/docs/derivatives/option/market-maker-block-trade/Cancel-Block-Trade-Order :param blockOrderMatchingKey: required - Block Order Matching Key :type blockOrderMatchingKey: str :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: API response .. code-block:: python {} :raises: BinanceRequestException, BinanceAPIException """ return self._request_options_api( "delete", "block/order/create", signed=True, data=params ) def options_extend_block_trade_order(self, **params): """Extend Block Trade Order (TRADE) Extends a block trade expire time by 30 mins from the current time. https://developers.binance.com/docs/derivatives/option/market-maker-block-trade/Extend-Block-Trade-Order :param blockOrderMatchingKey: required - Block Order Matching Key :type blockOrderMatchingKey: str :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: API response .. code-block:: python { "blockTradeSettlementKey": "3668822b8-1baa-6a2f-adb8-d3de6289b361", "expireTime": 1730172007000, "liquidity": "TAKER", "status": "RECEIVED", "createTime": 1730170088111, "legs": [ { "symbol": "BNB-241101-700-C", "side": "BUY", "quantity": "1.2", "price": "2.8" } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_options_api( "put", "block/order/create", signed=True, data=params ) def options_get_block_trade_orders(self, **params): """Query Block Trade Order (TRADE) Check block trade order status. https://developers.binance.com/docs/derivatives/option/market-maker-block-trade/Query-Block-Trade-Order :param blockOrderMatchingKey: optional - Returns specific block trade for this key :type blockOrderMatchingKey: str :param endTime: optional :type endTime: int :param startTime: optional :type startTime: int :param underlying: optional :type underlying: str :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: API response .. code-block:: python [ { "blockTradeSettlementKey": "7d046e6e-a429-4335-ab9d-6a681febcde5", "expireTime": 1730172115801, "liquidity": "TAKER", "status": "RECEIVED", "createTime": 1730170315803, "legs": [ { "symbol": "BNB-241101-700-C", "side": "BUY", "quantity": "1.2", "price": "2.8" } ] } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_options_api( "get", "block/order/orders", signed=True, data=params ) def options_accept_block_trade_order(self, **params): """Accept Block Trade Order (TRADE) Accept a block trade order. https://developers.binance.com/docs/derivatives/option/market-maker-block-trade/Accept-Block-Trade-Order :param blockOrderMatchingKey: required - Block Order Matching Key :type blockOrderMatchingKey: str :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: API response .. code-block:: python { "blockTradeSettlementKey": "7d046e6e-a429-4335-ab9d-6a681febcde5", "expireTime": 1730172115801, "liquidity": "MAKER", "status": "ACCEPTED", "createTime": 1730170315803, "legs": [ { "symbol": "BNB-241101-700-C", "side": "SELL", "quantity": "1.2", "price": "2.8" } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_options_api( "post", "block/order/execute", signed=True, data=params ) def options_get_block_trade_order(self, **params): """Query Block Trade Details (USER_DATA) Query block trade details; returns block trade details from counterparty's perspective. https://developers.binance.com/docs/derivatives/option/market-maker-block-trade/Query-Block-Trade-Detail :param blockOrderMatchingKey: required - Block Order Matching Key :type blockOrderMatchingKey: str :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: API response .. code-block:: python { "blockTradeSettlementKey": "12b96c28-ba05-8906-c89t-703215cfb2e6", "expireTime": 1730171860460, "liquidity": "MAKER", "status": "RECEIVED", "createTime": 1730170060462, "legs": [ { "symbol": "BNB-241101-700-C", "side": "SELL", "quantity": "1.66", "price": "20" } ] } :raises: BinanceRequestException, BinanceAPIException """ return self._request_options_api( "get", "block/order/execute", signed=True, data=params ) def options_account_get_block_trades(self, **params): """Account Block Trade List (USER_DATA) Gets block trades for a specific account. https://developers.binance.com/docs/derivatives/option/market-maker-block-trade/Account-Block-Trade-List :param endTime: optional :type endTime: int :param startTime: optional :type startTime: int :param underlying: optional :type underlying: str :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: API response .. code-block:: python [ { "parentOrderId": "4675011431944499201", "crossType": "USER_BLOCK", "legs": [ { "createTime": 1730170445600, "updateTime": 1730170445600, "symbol": "BNB-241101-700-C", "orderId": "4675011431944499203", "orderPrice": 2.8, "orderQuantity": 1.2, "orderStatus": "FILLED", "executedQty": 1.2, "executedAmount": 3.36, "fee": 0.336, "orderType": "PREV_QUOTED", "orderSide": "BUY", "id": "1125899906900937837", "tradeId": 1, "tradePrice": 2.8, "tradeQty": 1.2, "tradeTime": 1730170445600, "liquidity": "TAKER", "commission": 0.336 } ], "blockTradeSettlementKey": "7d085e6e-a229-2335-ab9d-6a581febcd25" } ] :raises: BinanceRequestException, BinanceAPIException """ return self._request_options_api( "get", "block/user-trades", signed=True, data=params ) # Fiat Endpoints def get_fiat_deposit_withdraw_history(self, **params): """Get Fiat Deposit/Withdraw History https://binance-docs.github.io/apidocs/spot/en/#get-fiat-deposit-withdraw-history-user_data :param transactionType: required - 0-deposit,1-withdraw :type transactionType: str :param beginTime: optional :type beginTime: int :param endTime: optional :type endTime: int :param page: optional - default 1 :type page: int :param rows: optional - default 100, max 500 :type rows: int :param recvWindow: optional :type recvWindow: int """ return self._request_margin_api("get", "fiat/orders", signed=True, data=params) def get_fiat_payments_history(self, **params): """Get Fiat Payments History https://binance-docs.github.io/apidocs/spot/en/#get-fiat-payments-history-user_data :param transactionType: required - 0-buy,1-sell :type transactionType: str :param beginTime: optional :type beginTime: int :param endTime: optional :type endTime: int :param page: optional - default 1 :type page: int :param rows: optional - default 100, max 500 :type rows: int :param recvWindow: optional :type recvWindow: int """ return self._request_margin_api( "get", "fiat/payments", signed=True, data=params ) # C2C Endpoints def get_c2c_trade_history(self, **params): """Get C2C Trade History https://binance-docs.github.io/apidocs/spot/en/#get-c2c-trade-history-user_data :param tradeType: required - BUY, SELL :type tradeType: str :param startTimestamp: optional :type startTime: int :param endTimestamp: optional :type endTimestamp: int :param page: optional - default 1 :type page: int :param rows: optional - default 100, max 100 :type rows: int :param recvWindow: optional :type recvWindow: int :returns: API response { "code": "000000", "message": "success", "data": [ { "orderNumber":"20219644646554779648", "advNo": "11218246497340923904", "tradeType": "SELL", "asset": "BUSD", "fiat": "CNY", "fiatSymbol": "¥", "amount": "5000.00000000", // Quantity (in Crypto) "totalPrice": "33400.00000000", "unitPrice": "6.68", // Unit Price (in Fiat) "orderStatus": "COMPLETED", // PENDING, TRADING, BUYER_PAYED, DISTRIBUTING, COMPLETED, IN_APPEAL, CANCELLED, CANCELLED_BY_SYSTEM "createTime": 1619361369000, "commission": "0", // Transaction Fee (in Crypto) "counterPartNickName": "ab***", "advertisementRole": "TAKER" } ], "total": 1, "success": true } """ return self._request_margin_api( "get", "c2c/orderMatch/listUserOrderHistory", signed=True, data=params ) # Pay Endpoints def get_pay_trade_history(self, **params): """Get C2C Trade History https://binance-docs.github.io/apidocs/spot/en/#pay-endpoints :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param limit: optional - default 100, max 100 :type limit: int :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_margin_api( "get", "pay/transactions", signed=True, data=params ) # Convert Endpoints def get_convert_trade_history(self, **params): """Get C2C Trade History https://developers.binance.com/docs/convert/trade/Get-Convert-Trade-History :param startTime: required - Start Time - 1593511200000 :type startTime: int :param endTime: required - End Time - 1593511200000 :type endTime: int :param limit: optional - default 100, max 100 :type limit: int :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_margin_api( "get", "convert/tradeFlow", signed=True, data=params ) def convert_request_quote(self, **params): """Request a quote for the requested token pairs https://developers.binance.com/docs/convert/trade :param fromAsset: required - Asset to convert from - BUSD :type fromAsset: str :param toAsset: required - Asset to convert to - BTC :type toAsset: str :param fromAmount: EITHER - When specified, it is the amount you will be debited after the conversion :type fromAmount: decimal :param toAmount: EITHER - When specified, it is the amount you will be credited after the conversion :type toAmount: decimal :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_margin_api( "post", "convert/getQuote", signed=True, data=params ) def convert_accept_quote(self, **params): """Accept the offered quote by quote ID. https://developers.binance.com/docs/convert/trade/Accept-Quote :param quoteId: required - 457235734584567 :type quoteId: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_margin_api( "post", "convert/acceptQuote", signed=True, data=params ) """ ==================================================================================================================== PortfolioMargin API ==================================================================================================================== """ def papi_get_balance(self, **params): """Query account balance. https://developers.binance.com/docs/derivatives/portfolio-margin/account :param asset: required :type asset: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api("get", "balance", signed=True, data=params) def papi_get_rate_limit(self, **params): """Query User Rate Limit https://developers.binance.com/docs/derivatives/portfolio-margin/account/Query-User-Rate-Limit :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api("get", "rateLimit/order", signed=True, data=params) def papi_stream_get_listen_key(self): """Start a new user data stream for Portfolio Margin account. https://developers.binance.com/docs/derivatives/portfolio-margin/user-data-streams/Start-User-Data-Stream :returns: API response { "listenKey": "pM_XXXXXXX" } The stream will close after 60 minutes unless a keepalive is sent. If the account has an active listenKey, that listenKey will be returned and its validity will be extended for 60 minutes. Weight: 1 """ res = self._request_papi_api("post", "listenKey", signed=False, data={}) return res["listenKey"] def papi_stream_keepalive(self, listenKey): """Keepalive a user data stream to prevent a time out. https://developers.binance.com/docs/derivatives/portfolio-margin/user-data-streams/Keepalive-User-Data-Stream :returns: API response {} User data streams will close after 60 minutes. It's recommended to send a ping about every 60 minutes. Weight: 1 """ params = {"listenKey": listenKey} return self._request_papi_api("put", "listenKey", signed=False, data=params) def papi_stream_close(self, listenKey): """Close out a user data stream. https://developers.binance.com/docs/derivatives/portfolio-margin/user-data-streams/Close-User-Data-Stream :returns: API response {} Weight: 1 """ params = {"listenKey": listenKey} return self._request_papi_api("delete", "listenKey", signed=False, data=params) def papi_get_account(self, **params): """Query account information. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Account-Information :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api("get", "account", signed=True, data=params) def papi_get_margin_max_borrowable(self, **params): """Query margin max borrow. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Margin-Max-Borrow :param asset: required :type asset: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "margin/maxBorrowable", signed=True, data=params ) def papi_get_margin_max_withdraw(self, **params): """Query margin max borrow. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Query-Margin-Max-Withdraw :param asset: required :type asset: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "margin/maxWithdraw", signed=True, data=params ) def papi_get_um_position_risk(self, **params): """Query margin max borrow. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Query-UM-Position-Information :param symbol: required :type symbol: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "um/positionRisk", signed=True, data=params ) def papi_get_cm_position_risk(self, **params): """Query margin max borrow. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Query-CM-Position-Information :param asset: required :type asset: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "cm/positionRisk", signed=True, data=params ) def papi_set_um_leverage(self, **params): """Query margin max borrow. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Change-UM-Initial-Leverage :param asset: required :type asset: str :param leverage: required :type leverage: int :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api("post", "um/leverage", signed=True, data=params) def papi_set_cm_leverage(self, **params): """Query margin max borrow. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Change-CM-Initial-Leverage :param asset: required :type asset: str :param leverage: required :type leverage: int :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api("post", "cm/leverage", signed=True, data=params) def papi_change_um_position_side_dual(self, **params): """Change user's position mode (Hedge Mode or One-way Mode ) on EVERY symbol in UM. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Change-UM-Position-Mode :param dualSidePosition: required :type dualSidePosition: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "post", "um/positionSide/dual", signed=True, data=params ) def papi_change_cm_position_side_dual(self, **params): """Change user's position mode (Hedge Mode or One-way Mode ) on EVERY symbol in CM. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Change-CM-Position-Mode :param dualSidePosition: required :type dualSidePosition: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "post", "cm/positionSide/dual", signed=True, data=params ) def papi_get_um_position_side_dual(self, **params): """Get user's position mode (Hedge Mode or One-way Mode ) on EVERY symbol in UM. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-UM-Current-Position-Mode :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "um/positionSide/dual", signed=True, data=params ) def papi_get_cm_position_side_dual(self, **params): """Get user's position mode (Hedge Mode or One-way Mode ) on EVERY symbol in CM. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-CM-Current-Position-Mode :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "cm/positionSide/dual", signed=True, data=params ) def papi_get_um_leverage_bracket(self, **params): """Query UM notional and leverage brackets. https://developers.binance.com/docs/derivatives/portfolio-margin/account/UM-Notional-and-Leverage-Brackets :param symbol: optional :type symbol: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "um/leverageBracket", signed=True, data=params ) def papi_get_cm_leverage_bracket(self, **params): """Query CM notional and leverage brackets. https://developers.binance.com/docs/derivatives/portfolio-margin/account/CM-Notional-and-Leverage-Brackets :param symbol: optional :type symbol: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "cm/leverageBracket", signed=True, data=params ) def papi_get_um_api_trading_status(self, **params): """Portfolio Margin UM Trading Quantitative Rules Indicators. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Portfolio-Margin-UM-Trading-Quantitative-Rules-Indicators :param symbol: optional :type symbol: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "um/apiTradingStatus", signed=True, data=params ) def papi_get_um_comission_rate(self, **params): """Get User Commission Rate for UM. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-User-Commission-Rate-for-UM :param symbol: required :type symbol: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "um/commissionRate", signed=True, data=params ) def papi_get_cm_comission_rate(self, **params): """Get User Commission Rate for CM. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-User-Commission-Rate-for-CM :param symbol: required :type symbol: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "cm/commissionRate", signed=True, data=params ) def papi_get_margin_margin_loan(self, **params): """Query margin loan record. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Query-Margin-Loan-Record :param asset: required :type asset: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "margin/marginLoan", signed=True, data=params ) def papi_get_margin_repay_loan(self, **params): """Query margin repay record. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Query-Margin-repay-Record :param asset: required :type asset: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "margin/repayLoan", signed=True, data=params ) def papi_get_repay_futures_switch(self, **params): """Query Auto-repay-futures Status. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-Auto-repay-futures-Status :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "repay-futures-switch", signed=True, data=params ) def papi_repay_futures_switch(self, **params): """Change Auto-repay-futures Status. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Change-Auto-repay-futures-Status :param autoRepay: required :type autoRepay: str :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "post", "repay-futures-switch", signed=True, data=params ) def papi_get_margin_interest_history(self, **params): """Get Margin Borrow/Loan Interest History. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-Margin-BorrowLoan-Interest-History :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "margin/marginInterestHistory", signed=True, data=params ) def papi_repay_futures_negative_balance(self, **params): """Repay futures Negative Balance. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Repay-futures-Negative-Balance :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "post", "repay-futures-negative-balance", signed=True, data=params ) def papi_get_portfolio_interest_history(self, **params): """Query interest history of negative balance for portfolio margin. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Query-Portfolio-Margin-Negative-Balance-Interest-History :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "portfolio/interest-history", signed=True, data=params ) def papi_get_portfolio_negative_balance_exchange_record(self, **params): """Query user negative balance auto exchange record. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Query-User-Negative-Balance-Auto-Exchange-Record :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "portfolio/negative-balance-exchange-record", signed=True, data=params ) def papi_fund_auto_collection(self, **params): """Fund collection for Portfolio Margin. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Fund-Auto-collection :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "post", "auto-collection", signed=True, data=params ) def papi_fund_asset_collection(self, **params): """Transfers specific asset from Futures Account to Margin account. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Fund-Collection-by-Asset :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "post", "asset-collection", signed=True, data=params ) def papi_bnb_transfer(self, **params): """Transfer BNB in and out of UM. https://developers.binance.com/docs/derivatives/portfolio-margin/account/BNB-transfer :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api("post", "bnb-transfer", signed=True, data=params) def papi_get_um_income_history(self, **params): """Get UM Income History. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-UM-Income-History :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api("get", "um/income", signed=True, data=params) def papi_get_cm_income_history(self, **params): """Get CM Income History. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-CM-Income-History :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api("get", "cm/income", signed=True, data=params) def papi_get_um_account(self, **params): """Get current UM account asset and position information. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-UM-Account-Detail :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api("get", "um/account", signed=True, data=params) def papi_get_um_account_v2(self, **params): """Get current UM account asset and position information. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-UM-Account-Detail-V2 :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "um/account", version=2, signed=True, data=params ) def papi_get_cm_account(self, **params): """Get current CM account asset and position information. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-CM-Account-Detail :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api("get", "cm/account", signed=True, data=params) def papi_get_um_account_config(self, **params): """Query UM Futures account configuration. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-UM-Futures-Account-Config :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "um/accountConfig", signed=True, data=params ) def papi_get_um_symbol_config(self, **params): """Get current UM account symbol configuration. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-UM-Futures-Symbol-Config :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "um/symbolConfig", signed=True, data=params ) def papi_get_um_trade_asyn(self, **params): """Get download id for UM futures trade history. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-Download-Id-For-UM-Futures-Trade-History :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api("get", "um/trade/asyn", signed=True, data=params) def papi_get_um_trade_asyn_id(self, **params): """Get UM futures trade download link by Id. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-UM-Futures-Trade-Download-Link-by-Id :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "um/trade/asyn/id", signed=True, data=params ) def papi_get_um_order_asyn(self, **params): """Get download id for UM futures order history. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-Download-Id-For-UM-Futures-Order-History :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api("get", "um/order/asyn", signed=True, data=params) def papi_get_um_order_asyn_id(self, **params): """Get UM futures order download link by Id. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-UM-Futures-Order-Download-Link-by-Id :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "um/order/asyn/id", signed=True, data=params ) def papi_get_um_income_asyn(self, **params): """Get download id for UM futures transaction history. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-Download-Id-For-UM-Futures-Transaction-History :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api("get", "um/income/asyn", signed=True, data=params) def papi_get_um_income_asyn_id(self, **params): """Get UM futures Transaction download link by Id. https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-UM-Futures-Transaction-Download-Link-by-Id :param recvWindow: optional :type recvWindow: int :returns: API response """ return self._request_papi_api( "get", "um/income/asyn/id", signed=True, data=params ) # Public papi endpoints def papi_ping(self, **params): """Test connectivity to the Rest API. https://developers.binance.com/docs/derivatives/portfolio-margin/market-data :returns: API response """ return self._request_papi_api("get", "ping", signed=False, data=params) # Trade papi endpoints def papi_create_um_order(self, **params): """Place new UM order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade :returns: API response """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return self._request_papi_api("post", "um/order", signed=True, data=params) def papi_create_um_conditional_order(self, **params): """Place new UM Conditional order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/New-UM-Conditional-Order :returns: API response """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return self._request_papi_api( "post", "um/conditional/order", signed=True, data=params ) def papi_create_cm_order(self, **params): """Place new CM order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/New-CM-Order :returns: API response """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return self._request_papi_api("post", "cm/order", signed=True, data=params) def papi_create_cm_conditional_order(self, **params): """Place new CM Conditional order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/New-CM-Conditional-Order :returns: API response """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return self._request_papi_api( "post", "cm/conditional/order", signed=True, data=params ) def papi_create_margin_order(self, **params): """New Margin Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/New-Margin-Order :returns: API response """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return self._request_papi_api("post", "margin/order", signed=True, data=params) def papi_margin_loan(self, **params): """Apply for a margin loan. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Margin-Account-Borrow :returns: API response """ return self._request_papi_api("post", "marginLoan", signed=True, data=params) def papi_repay_loan(self, **params): """Repay for a margin loan. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Margin-Account-Repay :returns: API response """ return self._request_papi_api("post", "repayLoan", signed=True, data=params) def papi_margin_order_oco(self, **params): """Send in a new OCO for a margin account. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Margin-Account-New-OCO :returns: API response """ return self._request_papi_api( "post", "margin/order/oco", signed=True, data=params ) def papi_cancel_um_order(self, **params): """Cancel an active UM LIMIT order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-UM-Order :returns: API response """ return self._request_papi_api("delete", "um/order", signed=True, data=params) def papi_cancel_um_all_open_orders(self, **params): """Cancel an active UM LIMIT order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-All-UM-Open-Orders :returns: API response """ return self._request_papi_api( "delete", "um/allOpenOrders", signed=True, data=params ) def papi_cancel_um_conditional_order(self, **params): """Cancel UM Conditional Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-UM-Conditional-Order :returns: API response """ return self._request_papi_api( "delete", "um/conditional/order", signed=True, data=params ) def papi_cancel_um_conditional_all_open_orders(self, **params): """Cancel All UM Open Conditional Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-All-UM-Open-Conditional-Orders :returns: API response """ return self._request_papi_api( "delete", "um/conditional/allOpenOrders", signed=True, data=params ) def papi_cancel_cm_order(self, **params): """Cancel an active CM LIMIT order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-CM-Order :returns: API response """ return self._request_papi_api("delete", "cm/order", signed=True, data=params) def papi_cancel_cm_all_open_orders(self, **params): """Cancel an active CM LIMIT order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-All-CM-Open-Orders :returns: API response """ return self._request_papi_api( "delete", "cm/allOpenOrders", signed=True, data=params ) def papi_cancel_cm_conditional_order(self, **params): """Cancel CM Conditional Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-CM-Conditional-Order :returns: API response """ return self._request_papi_api( "delete", "cm/conditional/order", signed=True, data=params ) def papi_cancel_cm_conditional_all_open_orders(self, **params): """Cancel All CM Open Conditional Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-All-CM-Open-Conditional-Orders :returns: API response """ return self._request_papi_api( "delete", "cm/conditional/allOpenOrders", signed=True, data=params ) def papi_cancel_margin_order(self, **params): """Cancel Margin Account Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-Margin-Account-Order :returns: API response """ return self._request_papi_api( "delete", "margin/order", signed=True, data=params ) def papi_cancel_margin_order_list(self, **params): """Cancel Margin Account OCO Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-Margin-Account-OCO-Orders :returns: API response """ return self._request_papi_api( "delete", "margin/orderList", signed=True, data=params ) def papi_cancel_margin_all_open_orders(self, **params): """Cancel Margin Account All Open Orders on a Symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-Margin-Account-All-Open-Orders-on-a-Symbol :returns: API response """ return self._request_papi_api( "delete", "margin/allOpenOrders", signed=True, data=params ) def papi_modify_um_order(self, **params): """Order modify function, currently only LIMIT order modification is supported, modified orders will be reordered in the match queue. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Modify-UM-Order :returns: API response """ return self._request_papi_api("put", "um/order", signed=True, data=params) def papi_modify_cm_order(self, **params): """Order modify function, currently only LIMIT order modification is supported, modified orders will be reordered in the match queue. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Modify-CM-Order :returns: API response """ return self._request_papi_api("put", "cm/order", signed=True, data=params) def papi_get_um_order(self, **params): """Check an UM order's status. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-UM-Order :returns: API response """ return self._request_papi_api("get", "um/order", signed=True, data=params) def papi_get_um_all_orders(self, **params): """Get all account UM orders; active, canceled, or filled. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-UM-Orders :returns: API response """ return self._request_papi_api("get", "um/allOrders", signed=True, data=params) def papi_get_um_open_order(self, **params): """Query current UM open order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Current-UM-Open-Order :returns: API response """ return self._request_papi_api("get", "um/openOrder", signed=True, data=params) def papi_get_um_open_orders(self, **params): """Get all open orders on a symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-Current-UM-Open-Orders :returns: API response """ return self._request_papi_api("get", "um/openOrders", signed=True, data=params) def papi_get_um_conditional_all_orders(self, **params): """Query All UM Conditional Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-UM-Conditional-Orders :returns: API response """ return self._request_papi_api( "get", "um/conditional/allOrders", signed=True, data=params ) def papi_get_um_conditional_open_orders(self, **params): """Get all open conditional orders on a symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-Current-UM-Open-Conditional-Orders :returns: API response """ return self._request_papi_api( "get", "um/conditional/openOrders", signed=True, data=params ) def papi_get_um_conditional_open_order(self, **params): """Query Current UM Open Conditional Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Current-UM-Open-Conditional-Order :returns: API response """ return self._request_papi_api( "get", "um/conditional/openOrder", signed=True, data=params ) def papi_get_um_conditional_order_history(self, **params): """Get all open conditional orders on a symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-UM-Conditional-Order-History :returns: API response """ return self._request_papi_api( "get", "um/conditional/orderHistory", signed=True, data=params ) def papi_get_cm_order(self, **params): """Check an CM order's status. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-CM-Order :returns: API response """ return self._request_papi_api("get", "cm/order", signed=True, data=params) def papi_get_cm_all_orders(self, **params): """Get all account CM orders; active, canceled, or filled. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-CM-Orders :returns: API response """ return self._request_papi_api("get", "cm/allOrders", signed=True, data=params) def papi_get_cm_open_order(self, **params): """Query current CM open order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Current-CM-Open-Order :returns: API response """ return self._request_papi_api("get", "cm/openOrder", signed=True, data=params) def papi_get_cm_open_orders(self, **params): """Get all open orders on a symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-Current-CM-Open-Orders :returns: API response """ return self._request_papi_api("get", "cm/openOrders", signed=True, data=params) def papi_get_cm_conditional_all_orders(self, **params): """Query All CM Conditional Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-CM-Conditional-Orders :returns: API response """ return self._request_papi_api( "get", "cm/conditional/allOrders", signed=True, data=params ) def papi_get_cm_conditional_open_orders(self, **params): """Get all open conditional orders on a symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-Current-CM-Open-Conditional-Orders :returns: API response """ return self._request_papi_api( "get", "cm/conditional/openOrders", signed=True, data=params ) def papi_get_cm_conditional_open_order(self, **params): """Query Current UM Open Conditional Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Current-CM-Open-Conditional-Order :returns: API response """ return self._request_papi_api( "get", "cm/conditional/openOrder", signed=True, data=params ) def papi_get_cm_conditional_order_history(self, **params): """Get all open conditional orders on a symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-CM-Conditional-Order-History :returns: API response """ return self._request_papi_api( "get", "cm/conditional/orderHistory", signed=True, data=params ) def papi_get_um_force_orders(self, **params): """Query User's UM Force Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Users-UM-Force-Orders :returns: API response """ return self._request_papi_api("get", "um/forceOrders", signed=True, data=params) def papi_get_cm_force_orders(self, **params): """Query User's CM Force Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Users-CM-Force-Orders :returns: API response """ return self._request_papi_api("get", "cm/forceOrders", signed=True, data=params) def papi_get_um_order_amendment(self, **params): """Get order modification history. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-UM-Modify-Order-History :returns: API response """ return self._request_papi_api( "get", "um/orderAmendment", signed=True, data=params ) def papi_get_cm_order_amendment(self, **params): """Get order modification history. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-CM-Modify-Order-History :returns: API response """ return self._request_papi_api( "get", "cm/orderAmendment", signed=True, data=params ) def papi_get_margin_force_orders(self, **params): """Query user's margin force orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Users-Margin-Force-Orders :returns: API response """ return self._request_papi_api( "get", "margin/forceOrders", signed=True, data=params ) def papi_get_um_user_trades(self, **params): """Get trades for a specific account and UM symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/UM-Account-Trade-List :returns: API response """ return self._request_papi_api("get", "um/userTrades", signed=True, data=params) def papi_get_cm_user_trades(self, **params): """Get trades for a specific account and CM symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/CM-Account-Trade-List :returns: API response """ return self._request_papi_api("get", "cm/userTrades", signed=True, data=params) def papi_get_um_adl_quantile(self, **params): """Query UM Position ADL Quantile Estimation. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/UM-Position-ADL-Quantile-Estimation :returns: API response """ return self._request_papi_api("get", "um/adlQuantile", signed=True, data=params) def papi_get_cm_adl_quantile(self, **params): """Query CM Position ADL Quantile Estimation. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/CM-Position-ADL-Quantile-Estimation :returns: API response """ return self._request_papi_api("get", "cm/adlQuantile", signed=True, data=params) def papi_set_um_fee_burn(self, **params): """Change user's BNB Fee Discount for UM Futures (Fee Discount On or Fee Discount Off ) on EVERY symbol. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Toggle-BNB-Burn-On-UM-Futures-Trade :returns: API response """ return self._request_papi_api("post", "um/feeBurn", signed=True, data=params) def papi_get_um_fee_burn(self, **params): """Get user's BNB Fee Discount for UM Futures (Fee Discount On or Fee Discount Off). https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Get-UM-Futures-BNB-Burn-Status :returns: API response """ return self._request_papi_api("get", "um/feeBurn", signed=True, data=params) def papi_get_margin_order(self, **params): """Query Margin Account Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Margin-Account-Order :returns: API response """ return self._request_papi_api("get", "margin/order", signed=True, data=params) def papi_get_margin_open_orders(self, **params): """Query Current Margin Open Order. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Current-Margin-Open-Order :returns: API response """ return self._request_papi_api( "get", "margin/openOrders", signed=True, data=params ) def papi_get_margin_all_orders(self, **params): """Query All Margin Account Orders. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-All-Margin-Account-Orders :returns: API response """ return self._request_papi_api( "get", "margin/allOrders", signed=True, data=params ) def papi_get_margin_order_list(self, **params): """Retrieves a specific OCO based on provided optional parameters. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Margin-Account-OCO :returns: API response """ return self._request_papi_api( "get", "margin/orderList", signed=True, data=params ) def papi_get_margin_all_order_list(self, **params): """Query all OCO for a specific margin account based on provided optional parameters. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Margin-Account-all-OCO :returns: API response """ return self._request_papi_api( "get", "margin/allOrderList", signed=True, data=params ) def papi_get_margin_open_order_list(self, **params): """Query Margin Account's Open OCO. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Margin-Account-Open-OCO :returns: API response """ return self._request_papi_api( "get", "margin/openOrderList", signed=True, data=params ) def papi_get_margin_my_trades(self, **params): """Margin Account Trade List. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Margin-Account-Trade-List :returns: API response """ return self._request_papi_api( "get", "margin/myTrades", signed=True, data=params ) def papi_get_margin_repay_debt(self, **params): """Repay debt for a margin loan. https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Margin-Account-Repay-Debt :returns: API response """ return self._request_papi_api( "post", "margin/repay-debt", signed=True, data=params ) def close_connection(self): if self.session: self.session.close() def __del__(self): self.close_connection() ############################################################ # WebSocket API methods ############################################################ def ws_create_test_order(self, **params): """Test new order creation and signature/recvWindow long. Creates and validates a new order but does not send it into the matching engine. https://binance-docs.github.io/apidocs/websocket_api/en/#test-new-order-trade :param symbol: required :type symbol: str :param side: required :type side: str :param type: required :type type: str :param timeInForce: required if limit order :type timeInForce: str :param quantity: required :type quantity: decimal :param price: required :type price: str :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param icebergQty: Used with iceberg orders :type icebergQty: decimal :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: The number of milliseconds the request is valid for :type recvWindow: int :returns: WS response .. code-block:: python {} """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.SPOT_ORDER_PREFIX + self.uuid22() return self._ws_api_request_sync("order.test", True, params) def ws_create_order(self, **params): """Create an order via WebSocket. https://binance-docs.github.io/apidocs/websocket_api/en/#place-new-order-trade :param id: The request ID to be used. By default uuid22() is used. :param symbol: The symbol to create an order for :param side: BUY or SELL :param type: Order type (e.g., LIMIT, MARKET) :param quantity: The amount to buy or sell :param kwargs: Additional order parameters """ if "newClientOrderId" not in params: params["newClientOrderId"] = self.SPOT_ORDER_PREFIX + self.uuid22() return self._ws_api_request_sync("order.place", True, params) def ws_order_limit(self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params): """Send in a new limit order Any order with an icebergQty MUST have timeInForce set to GTC. :param symbol: required :type symbol: str :param side: required :type side: str :param quantity: required :type quantity: decimal :param price: required :type price: str :param timeInForce: default Good till cancelled :type timeInForce: str :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param icebergQty: Used with LIMIT, STOP_LOSS_LIMIT, and TAKE_PROFIT_LIMIT to create an iceberg order. :type icebergQty: decimal :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: WS response See order endpoint for full response options """ params.update({ "type": self.ORDER_TYPE_LIMIT, "timeInForce": timeInForce, }) return self.ws_create_order(**params) def ws_order_limit_buy(self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params): """Send in a new limit buy order Any order with an icebergQty MUST have timeInForce set to GTC. :param symbol: required :type symbol: str :param quantity: required :type quantity: decimal :param price: required :type price: str :param timeInForce: default Good till cancelled :type timeInForce: str :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param stopPrice: Used with stop orders :type stopPrice: decimal :param icebergQty: Used with iceberg orders :type icebergQty: decimal :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: WS response See order endpoint for full response options """ params.update({ "side": self.SIDE_BUY, }) return self.ws_order_limit(timeInForce=timeInForce, **params) def ws_order_limit_sell(self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params): """Send in a new limit sell order :param symbol: required :type symbol: str :param quantity: required :type quantity: decimal :param price: required :type price: str :param timeInForce: default Good till cancelled :type timeInForce: str :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param stopPrice: Used with stop orders :type stopPrice: decimal :param icebergQty: Used with iceberg orders :type icebergQty: decimal :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: WS response See order endpoint for full response options """ params.update({"side": self.SIDE_SELL}) return self.ws_order_limit(timeInForce=timeInForce, **params) def ws_order_market(self, **params): """Send in a new market order :param symbol: required :type symbol: str :param side: required :type side: str :param quantity: required :type quantity: decimal :param quoteOrderQty: amount the user wants to spend (when buying) or receive (when selling) of the quote asset :type quoteOrderQty: decimal :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: WS response See order endpoint for full response options """ params.update({"type": self.ORDER_TYPE_MARKET}) return self.ws_create_order(**params) def ws_order_market_buy(self, **params): """Send in a new market buy order :param symbol: required :type symbol: str :param quantity: required :type quantity: decimal :param quoteOrderQty: the amount the user wants to spend of the quote asset :type quoteOrderQty: decimal :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: WS response See order endpoint for full response options """ params.update({"side": self.SIDE_BUY}) return self.ws_order_market(**params) def ws_order_market_sell(self, **params): """Send in a new market sell order :param symbol: required :type symbol: str :param quantity: required :type quantity: decimal :param quoteOrderQty: the amount the user wants to receive of the quote asset :type quoteOrderQty: decimal :param newClientOrderId: A unique id for the order. Automatically generated if not sent. :type newClientOrderId: str :param newOrderRespType: Set the response JSON. ACK, RESULT, or FULL; default: RESULT. :type newOrderRespType: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int :returns: WS response See order endpoint for full response options """ params.update({"side": self.SIDE_SELL}) return self.ws_order_market(**params) def ws_get_order(self, **params): """Check an order's status. Either orderId or origClientOrderId must be sent. https://binance-docs.github.io/apidocs/websocket_api/en/#query-order-user_data :param symbol: required :type symbol: str :param orderId: The unique order id :type orderId: int :param origClientOrderId: optional :type origClientOrderId: str :param recvWindow: the number of milliseconds the request is valid for :type recvWindow: int """ return self._ws_api_request_sync("order.status", True, params) def ws_cancel_order(self, **params): """Cancel an active order. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#cancel-order-trade :param symbol: required - Trading symbol, e.g. 'BTCUSDT' :type symbol: str :param orderId: optional - The unique order id :type orderId: int :param origClientOrderId: optional - The original client order id :type origClientOrderId: str :param newClientOrderId: optional - Used to uniquely identify this cancel. Automatically generated if not sent :type newClientOrderId: str :param cancelRestrictions: optional - ONLY_NEW - Cancel will succeed if the order status is NEW. ONLY_PARTIALLY_FILLED - Cancel will succeed if order status is PARTIALLY_FILLED. :type cancelRestrictions: str :param recvWindow: optional - The number of milliseconds the request is valid for :type recvWindow: int Either orderId or origClientOrderId must be sent. Weight: 1 Returns: .. code-block:: python { "id": "5633b6a2-90a9-4192-83e7-925c90b6a2fd", "method": "order.cancel", "params": { "symbol": "BTCUSDT", "origClientOrderId": "4d96324ff9d44481926157", "apiKey": "vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A", "signature": "33d5b721f278ae17a52f004a82a6f68a70c68e7dd6776ed0be77a455ab855282", "timestamp": 1660801715830 } } """ return self._ws_api_request_sync("order.cancel", True, params) def ws_cancel_and_replace_order(self, **params): """Cancels an existing order and places a new order on the same symbol. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#cancel-and-replace-order-trade :param symbol: required - Trading symbol, e.g. 'BTCUSDT' :type symbol: str :param cancelReplaceMode: required - The mode of cancel-replace: STOP_ON_FAILURE - If the cancel request fails, new order placement will not be attempted. ALLOW_FAILURE - New order placement will be attempted even if cancel request fails :type cancelReplaceMode: str :param cancelOrderId: optional - The order ID to cancel :type cancelOrderId: int :param cancelOrigClientOrderId: optional - The original client order ID to cancel :type cancelOrigClientOrderId: str :param cancelNewClientOrderId: optional - Used to uniquely identify this cancel. Automatically generated if not sent :type cancelNewClientOrderId: str :param side: required - BUY or SELL :type side: str :param type: required - Order type, e.g. LIMIT, MARKET :type type: str :param timeInForce: optional - GTC, IOC, FOK :type timeInForce: str :param price: optional - Order price :type price: str :param quantity: optional - Order quantity :type quantity: str :param quoteOrderQty: optional - Quote quantity :type quoteOrderQty: str :param newClientOrderId: optional - Used to uniquely identify this new order :type newClientOrderId: str :param newOrderRespType: optional - ACK, RESULT, or FULL :type newOrderRespType: str :param stopPrice: optional - Used with STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, and TAKE_PROFIT_LIMIT orders :type stopPrice: str :param trailingDelta: optional - Used with TAKE_PROFIT, TAKE_PROFIT_LIMIT, STOP_LOSS, STOP_LOSS_LIMIT orders :type trailingDelta: int :param icebergQty: optional - Used with iceberg orders :type icebergQty: str :param strategyId: optional - Arbitrary numeric value identifying the order within an order strategy :type strategyId: int :param strategyType: optional - Arbitrary numeric value identifying the order strategy :type strategyType: int :param selfTradePreventionMode: optional - The allowed enums is dependent on what is configured on the symbol :type selfTradePreventionMode: str :param cancelRestrictions: optional - ONLY_NEW - Cancel will succeed if order status is NEW. ONLY_PARTIALLY_FILLED - Cancel will succeed if order status is PARTIALLY_FILLED :type cancelRestrictions: str :param recvWindow: optional - The number of milliseconds the request is valid for :type recvWindow: int Either cancelOrderId or cancelOrigClientOrderId must be provided. Price is required for LIMIT orders. Either quantity or quoteOrderQty must be provided. Weight: 1 Returns: .. code-block:: python { "id": "99de6b92-0eda-4154-9c8d-a51d93c6f92e", "status": 200, "result": { "cancelResult": "SUCCESS", "newOrderResult": "SUCCESS", "cancelResponse": { "symbol": "BTCUSDT", "origClientOrderId": "4d96324ff9d44481926157", "orderId": 12569099453, "orderListId": -1, "clientOrderId": "91fe37ce9e69c90d6358c0", "price": "23416.10000000", "origQty": "0.00847000", "executedQty": "0.00001000", "cummulativeQuoteQty": "0.23416100", "status": "CANCELED", "timeInForce": "GTC", "type": "LIMIT", "side": "SELL", "selfTradePreventionMode": "NONE" }, "newOrderResponse": { "symbol": "BTCUSDT", "orderId": 12569099454, "orderListId": -1, "clientOrderId": "bX5wROblo6YeDwa9iTLeyY", "transactTime": 1660801715639 } } } """ return self._ws_api_request_sync("order.cancelReplace", True, params) def ws_get_open_orders(self, **params): """Get all open orders on a symbol or all symbols. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#current-open-orders-user_data :param symbol: optional - Symbol to get open orders for :type symbol: str :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: API response Response format: [ { "symbol": "BTCUSDT", "orderId": 12569099453, "orderListId": -1, "clientOrderId": "4d96324ff9d44481926157", "price": "23416.10000000", "origQty": "0.00847000", "executedQty": "0.00720000", "cummulativeQuoteQty": "168.59532000", "status": "PARTIALLY_FILLED", "timeInForce": "GTC", "type": "LIMIT", "side": "SELL", "stopPrice": "0.00000000", "icebergQty": "0.00000000", "time": 1660801715639, "updateTime": 1660801717945, "isWorking": true, "workingTime": 1660801715639, "origQuoteOrderQty": "0.00000000", "selfTradePreventionMode": "NONE" } ] Weight: Adjusted based on parameters: - With symbol: 6 - Without symbol: 12 """ return self._ws_api_request_sync("openOrders.status", True, params) def ws_cancel_all_open_orders(self, **params): """Cancel all open orders on a symbol or all symbols. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#cancel-open-orders-trade :param symbol: optional - Symbol to cancel orders for :type symbol: str :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: Websocket message Response format: [ { "symbol": "BTCUSDT", "origClientOrderId": "4d96324ff9d44481926157", "orderId": 12569099453, "orderListId": -1, "clientOrderId": "91fe37ce9e69c90d6358c0", "price": "23416.10000000", "origQty": "0.00847000", "executedQty": "0.00847000", "cummulativeQuoteQty": "198.33521500", "status": "CANCELED", "timeInForce": "GTC", "type": "LIMIT", "side": "SELL", "stopPrice": "0.00000000", "trailingDelta": 0, "trailingTime": -1, "icebergQty": "0.00000000", "strategyId": 37463720, "strategyType": 1000000, "selfTradePreventionMode": "NONE" } ] Weight: 1 """ return self._ws_api_request_sync("openOrders.cancelAll", True, params) def ws_create_oco_order(self, **params): """Create a new OCO (One-Cancels-the-Other) order. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#place-new-order-list---oco-trade :param symbol: required - Trading symbol :type symbol: str :param side: required - BUY or SELL :type side: str :param quantity: required - Order quantity :type quantity: decimal :param price: required - Order price for limit leg :type price: decimal :param stopPrice: required - Stop trigger price for stop leg :type stopPrice: decimal :param stopLimitPrice: optional - Stop limit price for stop leg :type stopLimitPrice: decimal :param stopLimitTimeInForce: optional - Time in force for stop leg :type stopLimitTimeInForce: str :param listClientOrderId: optional - Unique ID for the entire orderList :type listClientOrderId: str :param limitClientOrderId: optional - Unique ID for the limit order :type limitClientOrderId: str :param stopClientOrderId: optional - Unique ID for the stop order :type stopClientOrderId: str :param limitStrategyId: optional - Arbitrary numeric value identifying the limit order within an order strategy :type limitStrategyId: int :param limitStrategyType: optional - Arbitrary numeric value identifying the limit order strategy :type limitStrategyType: int :param stopStrategyId: optional - Arbitrary numeric value identifying the stop order within an order strategy :type stopStrategyId: int :param stopStrategyType: optional - Arbitrary numeric value identifying the stop order strategy :type stopStrategyType: int :param limitIcebergQty: optional - Iceberg quantity for the limit leg :type limitIcebergQty: decimal :param stopIcebergQty: optional - Iceberg quantity for the stop leg :type stopIcebergQty: decimal :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: Websocket message Response format: .. code-block:: python { "id": "56374a46-3261-486b-a211-99ed972eb648", "status": 200, "result": { "orderListId": 2, "contingencyType": "OCO", "listStatusType": "EXEC_STARTED", "listOrderStatus": "EXECUTING", "listClientOrderId": "cKPMnDCbcLQILtDYM4f4fX", "transactionTime": 1711062760648, "symbol": "LTCBNB", "orders": [ { "symbol": "LTCBNB", "orderId": 2, "clientOrderId": "0m6I4wfxvTUrOBSMUl0OPU" }, { "symbol": "LTCBNB", "orderId": 3, "clientOrderId": "Z2IMlR79XNY5LU0tOxrWyW" } ], "orderReports": [ { "symbol": "LTCBNB", "orderId": 2, "orderListId": 2, "clientOrderId": "0m6I4wfxvTUrOBSMUl0OPU", "transactTime": 1711062760648, "price": "1.50000000", "origQty": "1.000000", "executedQty": "0.000000", "origQuoteOrderQty": "0.000000", "cummulativeQuoteQty": "0.00000000", "status": "NEW", "timeInForce": "GTC", "type": "STOP_LOSS_LIMIT", "side": "BUY", "stopPrice": "1.50000001", "workingTime": -1, "selfTradePreventionMode": "NONE" }, { "symbol": "LTCBNB", "orderId": 3, "orderListId": 2, "clientOrderId": "Z2IMlR79XNY5LU0tOxrWyW", "transactTime": 1711062760648, "price": "1.49999999", "origQty": "1.000000", "executedQty": "0.000000", "origQuoteOrderQty": "0.000000", "cummulativeQuoteQty": "0.00000000", "status": "NEW", "timeInForce": "GTC", "type": "LIMIT_MAKER", "side": "BUY", "workingTime": 1711062760648, "selfTradePreventionMode": "NONE" } ] }, "rateLimits": [ { "rateLimitType": "ORDERS", "interval": "SECOND", "intervalNum": 10, "limit": 50, "count": 2 }, { "rateLimitType": "ORDERS", "interval": "DAY", "intervalNum": 1, "limit": 160000, "count": 2 }, { "rateLimitType": "REQUEST_WEIGHT", "interval": "MINUTE", "intervalNum": 1, "limit": 6000, "count": 1 } ] } Weight: 2 """ return self._ws_api_request_sync("orderList.place.oco", True, params) def ws_create_oto_order(self, **params): """Create a new OTO (One-Triggers-Other) order list. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#place-new-order-list---oto-trade An OTO order list consists of two orders: 1. Primary order that must be filled first 2. Secondary order that is placed only after the primary order is filled :param symbol: required - Trading symbol :type symbol: str :param orders: required - Array of order objects containing: [ { # Primary order "type": required - Order type (e.g. LIMIT, MARKET), "side": required - BUY or SELL, "price": required for LIMIT orders, "quantity": required - Order quantity, "timeInForce": required for LIMIT orders, "icebergQty": optional, "strategyId": optional, "strategyType": optional, "selfTradePreventionMode": optional }, { # Secondary order - same parameters as primary ... } ] :type orders: list :param listClientOrderId: optional - Unique ID for the entire order list :type listClientOrderId: str :param limitClientOrderId: optional - Client order ID for the LIMIT leg :type limitClientOrderId: str :param limitStrategyId: optional - Strategy ID for the LIMIT leg :type limitStrategyId: int :param limitStrategyType: optional - Strategy type for the LIMIT leg :type limitStrategyType: int :param stopClientOrderId: optional - Client order ID for the STOP_LOSS/STOP_LOSS_LIMIT leg :type stopClientOrderId: str :param stopStrategyId: optional - Strategy ID for the STOP_LOSS/STOP_LOSS_LIMIT leg :type stopStrategyId: int :param stopStrategyType: optional - Strategy type for the STOP_LOSS/STOP_LOSS_LIMIT leg :type stopStrategyType: int :param newOrderRespType: optional - Set the response JSON :type newOrderRespType: str Response example: .. code-block:: python { "id": "c5899911-d3f4-47ae-8835-97da553d27d0", "status": 200, "result": { "orderListId": 1, "contingencyType": "OTO", "listStatusType": "EXEC_STARTED", "listOrderStatus": "EXECUTING", "listClientOrderId": "C3wyRVh3aqKyI2RpBZYmFz", "transactionTime": 1669632210676, "symbol": "BTCUSDT", "orders": [ { "symbol": "BTCUSDT", "orderId": 12569099453, "clientOrderId": "bX5wROblo6YeDwa9iTLeyY" }, { "symbol": "BTCUSDT", "orderId": 12569099454, "clientOrderId": "Tnu2IP0J5Y4mxw3IxZYeFi" } ], "orderReports": [ { "symbol": "BTCUSDT", "orderId": 12569099453, "orderListId": 1, "clientOrderId": "bX5wROblo6YeDwa9iTLeyY", "transactTime": 1669632210676, "price": "23416.10000000", "origQty": "0.00847000", "executedQty": "0.00847000", "cummulativeQuoteQty": "198.33521500", "status": "FILLED", "timeInForce": "GTC", "type": "LIMIT", "side": "SELL", "stopPrice": "0.00000000", "workingTime": 1669632210676, "selfTradePreventionMode": "NONE" }, { "symbol": "BTCUSDT", "orderId": 12569099454, "orderListId": 1, "clientOrderId": "Tnu2IP0J5Y4mxw3IxZYeFi", "transactTime": 1669632210676, "price": "0.00000000", "origQty": "0.00847000", "executedQty": "0.00000000", "cummulativeQuoteQty": "0.00000000", "status": "NEW", "timeInForce": "GTC", "type": "MARKET", "side": "BUY", "stopPrice": "0.00000000", "workingTime": -1, "selfTradePreventionMode": "NONE" } ] }, "rateLimits": [ { "rateLimitType": "ORDERS", "interval": "SECOND", "intervalNum": 10, "limit": 50, "count": 1 }, { "rateLimitType": "ORDERS", "interval": "DAY", "intervalNum": 1, "limit": 160000, "count": 1 }, { "rateLimitType": "REQUEST_WEIGHT", "interval": "MINUTE", "intervalNum": 1, "limit": 6000, "count": 1 } ] } Weight: 1 """ return self._ws_api_request_sync("orderList.place.oto", True, params) def ws_create_otoco_order(self, **params): """ Returns: Websocket message .. code-block:: python { "id": "1712544408508", "status": 200, "result": { "orderListId": 629, "contingencyType": "OTO", "listStatusType": "EXEC_STARTED", "listOrderStatus": "EXECUTING", "listClientOrderId": "GaeJHjZPasPItFj4x7Mqm6", "transactionTime": 1712544408537, "symbol": "1712544378871", "orders": [ { "symbol": "1712544378871", "orderId": 23, "clientOrderId": "OVQOpKwfmPCfaBTD0n7e7H" }, { "symbol": "1712544378871", "orderId": 24, "clientOrderId": "YcCPKCDMQIjNvLtNswt82X" }, { "symbol": "1712544378871", "orderId": 25, "clientOrderId": "ilpIoShcFZ1ZGgSASKxMPt" } ], "orderReports": [ { "symbol": "LTCBNB", "orderId": 23, "orderListId": 629, "clientOrderId": "OVQOpKwfmPCfaBTD0n7e7H", "transactTime": 1712544408537, "price": "1.500000", "origQty": "1.000000", "executedQty": "0.000000", "origQuoteOrderQty": "0.000000", "cummulativeQuoteQty": "0.000000", "status": "NEW", "timeInForce": "GTC", "type": "LIMIT", "side": "BUY", "workingTime": 1712544408537, "selfTradePreventionMode": "NONE" }, { "symbol": "LTCBNB", "orderId": 24, "orderListId": 629, "clientOrderId": "YcCPKCDMQIjNvLtNswt82X", "transactTime": 1712544408537, "price": "0.000000", "origQty": "5.000000", "executedQty": "0.000000", "origQuoteOrderQty": "0.000000", "cummulativeQuoteQty": "0.000000", "status": "PENDING_NEW", "timeInForce": "GTC", "type": "STOP_LOSS", "side": "SELL", "stopPrice": "0.500000", "workingTime": -1, "selfTradePreventionMode": "NONE" }, { "symbol": "LTCBNB", "orderId": 25, "orderListId": 629, "clientOrderId": "ilpIoShcFZ1ZGgSASKxMPt", "transactTime": 1712544408537, "price": "5.000000", "origQty": "5.000000", "executedQty": "0.000000", "origQuoteOrderQty": "0.000000", "cummulativeQuoteQty": "0.000000", "status": "PENDING_NEW", "timeInForce": "GTC", "type": "LIMIT_MAKER", "side": "SELL", "workingTime": -1, "selfTradePreventionMode": "NONE" } ] }, "rateLimits": [ { "rateLimitType": "ORDERS", "interval": "MINUTE", "intervalNum": 1, "limit": 10000000, "count": 18 }, { "rateLimitType": "REQUEST_WEIGHT", "interval": "MINUTE", "intervalNum": 1, "limit": 1000, "count": 65 } ] } Weight: 1 """ return self._ws_api_request_sync("orderList.place.otoco", True, params) def ws_get_oco_order(self, **params): """Query information about a specific OCO order list. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#query-order-list-user_data :param orderListId: int - The identifier for the OCO order list (optional) :param origClientOrderId: str - The client-specified OCO order list ID (optional) :returns: API response containing OCO order list information including: .. code-block:: python { "id": "b53fd5ff-82c7-4a04-bd64-5f9dc42c2100", "status": 200, "result": { "orderListId": 1274512, "contingencyType": "OCO", "listStatusType": "EXEC_STARTED", "listOrderStatus": "EXECUTING", "listClientOrderId": "08985fedd9ea2cf6b28996", "transactionTime": 1660801713793, "symbol": "BTCUSDT", "orders": [ { "symbol": "BTCUSDT", "orderId": 12569138901, "clientOrderId": "BqtFCj5odMoWtSqGk2X9tU" }, { "symbol": "BTCUSDT", "orderId": 12569138902, "clientOrderId": "jLnZpj5enfMXTuhKB1d0us" } ] }, "rateLimits": [ { "rateLimitType": "REQUEST_WEIGHT", "interval": "MINUTE", "intervalNum": 1, "limit": 6000, "count": 4 } ] } Notes: - Either orderListId or origClientOrderId must be provided - Weight: 4 - Data Source: Database """ return self._ws_api_request_sync("orderList.status", True, params) def ws_cancel_oco_order(self, **params): """Cancel an OCO (One-Cancels-the-Other) order list. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#cancel-order-list-trade :param symbol: required - Trading symbol :type symbol: str :param orderListId: optional - The ID of the OCO order list to cancel :type orderListId: int :param listClientOrderId: optional - The client-specified ID of the OCO order list :type listClientOrderId: str :param newClientOrderId: optional - Client ID to identify the cancel request :type newClientOrderId: str :param apiKey: required - Your API key :type apiKey: str :param recvWindow: optional - Number of milliseconds the request is valid for :type recvWindow: int :param signature: required - HMAC SHA256 signature :type signature: str :param timestamp: required - Current timestamp in milliseconds :type timestamp: int **Notes**: - Either orderListId or listClientOrderId must be provided - newClientOrderId will be auto-generated if not provided Response example: .. code-block:: python { "id": "c5899911-d3f4-47ae-8835-97da553d27d0", "status": 200, "result": { "orderListId": 1274512, "contingencyType": "OCO", "listStatusType": "ALL_DONE", "listOrderStatus": "ALL_DONE", "listClientOrderId": "6023531d7edaad348f5aff", "transactionTime": 1660801720215, "symbol": "BTCUSDT", "orders": [ { "symbol": "BTCUSDT", "orderId": 12569138901, "clientOrderId": "BqtFCj5odMoWtSqGk2X9tU" }, { "symbol": "BTCUSDT", "orderId": 12569138902, "clientOrderId": "jLnZpj5enfMXTuhKB1d0us" } ], "orderReports": [ { "symbol": "BTCUSDT", "orderId": 12569138901, "orderListId": 1274512, "clientOrderId": "BqtFCj5odMoWtSqGk2X9tU", "transactTime": 1660801720215, "price": "23416.10000000", "origQty": "0.00847000", "executedQty": "0.00000000", "cummulativeQuoteQty": "0.00000000", "status": "CANCELED", "timeInForce": "GTC", "type": "STOP_LOSS_LIMIT", "side": "SELL", "stopPrice": "23416.10000000", "selfTradePreventionMode": "NONE" }, { "symbol": "BTCUSDT", "orderId": 12569138902, "orderListId": 1274512, "clientOrderId": "jLnZpj5enfMXTuhKB1d0us", "transactTime": 1660801720215, "price": "23416.10000000", "origQty": "0.00847000", "executedQty": "0.00000000", "cummulativeQuoteQty": "0.00000000", "status": "CANCELED", "timeInForce": "GTC", "type": "LIMIT_MAKER", "side": "SELL", "selfTradePreventionMode": "NONE" } ] }, "rateLimits": [ { "rateLimitType": "REQUEST_WEIGHT", "interval": "MINUTE", "intervalNum": 1, "limit": 6000, "count": 1 } ] } """ return self._ws_api_request_sync("orderList.cancel", True, params) def ws_get_oco_open_orders(self, **params): """Query current open OCO (One-Cancels-the-Other) order lists. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#current-open-order-lists-user_data :param recvWindow: optional - Number of milliseconds after timestamp the request is valid for. Default 5000, max 60000 :type recvWindow: int :param apiKey: required - Your API key :type apiKey: str :param signature: required - HMAC SHA256 signature :type signature: str :param timestamp: required - Current timestamp in milliseconds :type timestamp: int :returns: API response in JSON format with open OCO orders { "id": "c5899911-d3f5-47b3-9b67-4c1342f2a7e1", "status": 200, "result": [ { "orderListId": 1274512, "contingencyType": "OCO", "listStatusType": "EXEC_STARTED", "listOrderStatus": "EXECUTING", "listClientOrderId": "08985fedd9ea2cf6b28996", "transactionTime": 1660801713793, "symbol": "BTCUSDT", "orders": [ { "symbol": "BTCUSDT", "orderId": 12569138901, "clientOrderId": "BqtFCj5odMoWtSqGk2X9tU" }, { "symbol": "BTCUSDT", "orderId": 12569138902, "clientOrderId": "jLnZpj5enfMXTuhKB1d0us" } ] } ], "rateLimits": [ { "rateLimitType": "REQUEST_WEIGHT", "interval": "MINUTE", "intervalNum": 1, "limit": 6000, "count": 10 } ] } :raises: BinanceRequestException, BinanceAPIException Weight: 10 Data Source: Memory """ return self._ws_api_request_sync("openOrderLists.status", True, params) def ws_create_sor_order(self, **params): """Place a new order using Smart Order Routing (SOR). https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#place-new-order-using-sor-trade :param symbol: required - Trading symbol, e.g. BTCUSDT :type symbol: str :param side: required - Order side: BUY or SELL :type side: str :param type: required - Order type: LIMIT or MARKET :type type: str :param quantity: required - Order quantity :type quantity: float :param timeInForce: required for LIMIT orders - Time in force: GTC, IOC, FOK :type timeInForce: str :param price: required for LIMIT orders - Order price :type price: float :param newClientOrderId: optional - Unique order ID. Automatically generated if not sent :type newClientOrderId: str :param newOrderRespType: optional - Response format: ACK, RESULT, FULL. MARKET and LIMIT orders use FULL by default :type newOrderRespType: str :param strategyId: optional - Arbitrary numeric value identifying the order within an order strategy :type strategyId: int :param strategyType: optional - Arbitrary numeric value identifying the order strategy. Values < 1000000 are reserved :type strategyType: int :param selfTradePreventionMode: optional - Supported values depend on exchange configuration: EXPIRE_TAKER, EXPIRE_MAKER, EXPIRE_BOTH, NONE :type selfTradePreventionMode: str :param recvWindow: optional - Number of milliseconds after timestamp the request is valid for. Default 5000, max 60000 :type recvWindow: int :returns: Websocket message .. code-block:: python { "id": "3a4437e2-41a3-4c19-897c-9cadc5dce8b6", "status": 200, "result": [ { "symbol": "BTCUSDT", "orderId": 2, "orderListId": -1, "clientOrderId": "sBI1KM6nNtOfj5tccZSKly", "transactTime": 1689149087774, "price": "31000.00000000", "origQty": "0.50000000", "executedQty": "0.50000000", "cummulativeQuoteQty": "14000.00000000", "status": "FILLED", "timeInForce": "GTC", "type": "LIMIT", "side": "BUY", "workingTime": 1689149087774, "fills": [ { "matchType": "ONE_PARTY_TRADE_REPORT", "price": "28000.00000000", "qty": "0.50000000", "commission": "0.00000000", "commissionAsset": "BTC", "tradeId": -1, "allocId": 0 } ], "workingFloor": "SOR", "selfTradePreventionMode": "NONE", "usedSor": true } ], "rateLimits": [ { "rateLimitType": "REQUEST_WEIGHT", "interval": "MINUTE", "intervalNum": 1, "limit": 6000, "count": 1 } ] } Notes: - SOR only supports LIMIT and MARKET orders - quoteOrderQty is not supported - Weight: 1 - Data Source: Matching Engine """ return self._ws_api_request_sync("sor.order.place", True, params) def ws_create_test_sor_order(self, **params): """Test new order creation using Smart Order Routing (SOR). Creates and validates a new order but does not send it into the matching engine. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#test-new-order-using-sor-trade :param symbol: required - Trading symbol, e.g. BTCUSDT :type symbol: str :param side: required - Order side: BUY or SELL :type side: str :param type: required - Order type: LIMIT or MARKET :type type: str :param quantity: required - Order quantity :type quantity: float :param timeInForce: required for LIMIT orders - Time in force: GTC, IOC, FOK :type timeInForce: str :param price: required for LIMIT orders - Order price :type price: float :param newClientOrderId: optional - Unique order ID. Generated automatically if not sent :type newClientOrderId: str :param strategyId: optional - Arbitrary numeric value identifying the order within an order strategy :type strategyId: int :param strategyType: optional - Arbitrary numeric value identifying the order strategy. Values < 1000000 are reserved :type strategyType: int :param selfTradePreventionMode: optional - EXPIRE_TAKER, EXPIRE_MAKER, EXPIRE_BOTH, NONE :type selfTradePreventionMode: str :param computeCommissionRates: optional - Calculate commission rates. Default: False :type computeCommissionRates: bool :returns: Websocket message Without computeCommissionRates: .. code-block:: python { "id": "3a4437e2-41a3-4c19-897c-9cadc5dce8b6", "status": 200, "result": {}, "rateLimits": [ { "rateLimitType": "REQUEST_WEIGHT", "interval": "MINUTE", "intervalNum": 1, "limit": 6000, "count": 1 } ] } With computeCommissionRates: .. code-block:: python { "id": "3a4437e2-41a3-4c19-897c-9cadc5dce8b6", "status": 200, "result": { "standardCommissionForOrder": { "maker": "0.00000112", "taker": "0.00000114" }, "taxCommissionForOrder": { "maker": "0.00000112", "taker": "0.00000114" }, "discount": { "enabledForAccount": true, "enabledForSymbol": true, "discountAsset": "BNB", "discount": "0.25" } }, "rateLimits": [...] } Notes: - SOR only supports LIMIT and MARKET orders - quoteOrderQty is not supported - Weight: 1 (without computeCommissionRates), 20 (with computeCommissionRates) - Data Source: Memory """ return self._ws_api_request_sync("sor.order.test", True, params) def ws_get_account(self, **params): """Get current account information. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#account-information-user_data :param omitZeroBalances: optional - When set to true, emits only the non-zero balances of an account. Default: false :type omitZeroBalances: bool :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: Websocket message .. code-block:: python { "makerCommission": 15, "takerCommission": 15, "buyerCommission": 0, "sellerCommission": 0, "canTrade": true, "canWithdraw": true, "canDeposit": true, "commissionRates": { "maker": "0.00150000", "taker": "0.00150000", "buyer": "0.00000000", "seller": "0.00000000" }, "brokered": false, "requireSelfTradePrevention": false, "preventSor": false, "updateTime": 1660801833000, "accountType": "SPOT", "balances": [ { "asset": "BNB", "free": "0.00000000", "locked": "0.00000000" }, { "asset": "BTC", "free": "1.34471120", "locked": "0.08600000" } ], "permissions": [ "SPOT" ], "uid": 354937868 } Notes: - Weight: 20 - Data Source: Memory => Database """ return self._ws_api_request_sync("account.status", True, params) def ws_get_account_rate_limits_orders(self, **params): """Query your current unfilled order count for all intervals. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#account-unfilled-order-count-user_data :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: Websocket response .. code-block:: python { "result": [ { "rateLimitType": "ORDERS", "interval": "SECOND", "intervalNum": 10, "limit": 50, "count": 0 }, { "rateLimitType": "ORDERS", "interval": "DAY", "intervalNum": 1, "limit": 160000, "count": 0 } ], "id": "d3783d8d-f8d1-4d2c-b8a0-b7596af5a664" } :raises: BinanceRequestException, BinanceAPIException Notes: - Weight: 40 - Data Source: Memory """ return self._ws_api_request_sync("account.rateLimits.orders", True, params) def ws_get_all_orders(self, **params): """Query information about all your orders – active, canceled, filled – filtered by time range. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#account-order-history-user_data :param symbol: STRING - Required :type symbol: str :param orderId: optional - Order ID to begin at :type orderId: int :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param limit: optional - Default 500; max 1000 :type limit: int :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: Websocket response .. code-block:: python { "id": "734235c2-13d2-4574-be68-723e818c08f3", "status": 200, "result": [ { "symbol": "BTCUSDT", "orderId": 12569099453, "orderListId": -1, "clientOrderId": "4d96324ff9d44481926157", "price": "23416.10000000", "origQty": "0.00847000", "executedQty": "0.00847000", "cummulativeQuoteQty": "198.33521500", "status": "FILLED", "timeInForce": "GTC", "type": "LIMIT", "side": "SELL", "stopPrice": "0.00000000", "icebergQty": "0.00000000", "time": 1660801715639, "updateTime": 1660801717945, "isWorking": true, "workingTime": 1660801715639, "origQuoteOrderQty": "0.00000000", "selfTradePreventionMode": "NONE", "preventedMatchId": 0, // Only appears if order expired due to STP "preventedQuantity": "1.200000" // Only appears if order expired due to STP } ] } Notes: - Weight: 20 - Data Source: Database - If startTime and/or endTime are specified, orderId is ignored - Orders are filtered by time of the last execution status update - If orderId is specified, return orders with order ID >= orderId - If no condition is specified, the most recent orders are returned - For some historical orders the cummulativeQuoteQty response field may be negative - The time between startTime and endTime can't be longer than 24 hours """ return self._ws_api_request_sync("allOrders", True, params) def ws_get_my_trades(self, **params): """Query information about your trades, filtered by time range. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#account-trade-history-user_data :param symbol: STRING - Required :type symbol: str :param orderId: optional - Get trades for a specific order :type orderId: int :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param fromId: optional - Trade ID to fetch from :type fromId: int :param limit: optional - Default 500; max 1000 :type limit: int :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: Websocket response .. code-block:: python [ { "symbol": "BTCUSDT", "id": 1650422481, "orderId": 12569099453, "orderListId": -1, "price": "23416.10000000", "qty": "0.00635000", "quoteQty": "148.69223500", "commission": "0.00000000", "commissionAsset": "BNB", "time": 1660801715793, "isBuyer": false, "isMaker": true, "isBestMatch": true } ] Notes: - Weight: 20 - Data Source: Memory => Database - If fromId is specified, return trades with trade ID >= fromId - If startTime and/or endTime are specified, trades are filtered by execution time (time) - fromId cannot be used together with startTime and endTime - If orderId is specified, only trades related to that order are returned - startTime and endTime cannot be used together with orderId - If no condition is specified, the most recent trades are returned - The time between startTime and endTime can't be longer than 24 hours """ return self._ws_api_request_sync("myTrades", True, params) def ws_get_prevented_matches(self, **params): """Displays the list of orders that were expired due to STP (Self-Trade Prevention). https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#account-prevented-matches-user_data :param symbol: STRING - Required :type symbol: str :param preventedMatchId: optional - Get specific prevented match by ID :type preventedMatchId: int :param orderId: optional - Get prevented matches for specific order :type orderId: int :param fromPreventedMatchId: optional - Get prevented matches from this ID :type fromPreventedMatchId: int :param limit: optional - Default 500; max 1000 :type limit: int :param recvWindow: optional - The value cannot be greater than 60000 :type recvWindow: int :returns: Websocket response .. code-block:: python { "symbol": "BTCUSDT", # Trading pair "preventedMatchId": 1, # Unique ID for prevented match "takerOrderId": 5, # Order ID of the taker order "makerSymbol": "BTCUSDT", # Symbol of maker order "makerOrderId": 3, # Order ID of maker order "tradeGroupId": 1, # Trade group ID "selfTradePreventionMode": "EXPIRE_MAKER", # STP mode used "price": "1.100000", # Price level where match was prevented "makerPreventedQuantity": "1.300000", # Quantity that was prevented "transactTime": 1669101687094 # Time of prevention } Supported parameter combinations: - symbol + preventedMatchId - symbol + orderId - symbol + orderId + fromPreventedMatchId (limit defaults to 500) - symbol + orderId + fromPreventedMatchId + limit Weight: - 2 if symbol is invalid - 2 when querying by preventedMatchId - 20 when querying by orderId Data Source: Database """ return self._ws_api_request_sync("myPreventedMatches", True, params) def ws_get_allocations(self, **params): """Get information about orders that were expired due to STP (Self-Trade Prevention). https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#account-prevented-matches-user_data :param symbol: STRING - Required - Trading symbol :type symbol: str :param preventedMatchId: LONG - Optional - Get specific prevented match by ID :type preventedMatchId: int :param orderId: LONG - Optional - Get prevented matches for specific order :type orderId: int :param fromPreventedMatchId: LONG - Optional - Get prevented matches from this ID :type fromPreventedMatchId: int :param limit: INT - Optional - Default 500; max 1000 :type limit: int :param recvWindow: LONG - Optional - The value cannot be greater than 60000 :type recvWindow: int :param timestamp: LONG - Required :type timestamp: int :returns: API response .. code-block:: python { "symbol": "BTCUSDT", "preventedMatchId": 1, "takerOrderId": 5, "makerSymbol": "BTCUSDT", "makerOrderId": 3, "tradeGroupId": 1, "selfTradePreventionMode": "EXPIRE_MAKER", "price": "1.100000", "makerPreventedQuantity": "1.300000", "transactTime": 1669101687094 } Supported parameter combinations: - symbol + preventedMatchId - symbol + orderId - symbol + orderId + fromPreventedMatchId (limit defaults to 500) - symbol + orderId + fromPreventedMatchId + limit Weight: - 2 if symbol is invalid - 2 when querying by preventedMatchId - 20 when querying by orderId Data Source: Database """ return self._ws_api_request_sync("myAllocations", True, params) def ws_get_commission_rates(self, **params): """Get current account commission rates for a symbol. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#account-commission-rates-user_data :param symbol: STRING - Required - Trading symbol :type symbol: str :param recvWindow: LONG - Optional - The value cannot be greater than 60000 :type recvWindow: int :returns: API response dict with commission rates: { "symbol": "BTCUSDT", "standardCommission": { # Standard commission rates on trades "maker": "0.00000010", "taker": "0.00000020", "buyer": "0.00000030", "seller": "0.00000040" }, "taxCommission": { # Tax commission rates on trades "maker": "0.00000112", "taker": "0.00000114", "buyer": "0.00000118", "seller": "0.00000116" }, "discount": { # Discount on standard commissions when paying in BNB "enabledForAccount": true, "enabledForSymbol": true, "discountAsset": "BNB", "discount": "0.75000000" # Standard commission reduction rate when paying in BNB } } :raises: BinanceRequestException, BinanceAPIException Weight: 20 Data Source: Database """ return self._ws_api_request_sync("account.commission", True, params) def ws_get_order_book(self, **params): """Get current order book for a symbol. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#order-book Note that this request returns limited market depth. If you need to continuously monitor order book updates, consider using WebSocket Streams: - @depth - @depth You can use `depth` request together with `@depth` streams to maintain a local order book. :param symbol: STRING - Required - Trading symbol :type symbol: str :param limit: INT - Optional - Default 100; max 5000 :type limit: int :returns: Websocket message { "lastUpdateId": 2731179239, "bids": [ // Bid levels sorted from highest to lowest price [ "0.01379900", // Price level "3.43200000" // Quantity ], ... ], "asks": [ // Ask levels sorted from lowest to highest price [ "0.01380000", // Price level "5.91700000" // Quantity ], ... ] } Weight: Adjusted based on limit: - 1-100: 5 - 101-500: 25 - 501-1000: 50 - 1001-5000: 250 Data Source: Memory """ return self._ws_api_request_sync("depth", False, params) def ws_get_recent_trades(self, **params): """Get recent trades for a symbol. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#recent-trades If you need access to real-time trading activity, please consider using WebSocket Streams: - @trade :param symbol: STRING - Required - Trading symbol :type symbol: str :param limit: INT - Optional - Default 500; max 1000 :type limit: int :returns: API response .. code-block:: python { "id": "409a20bd-253d-41db-a6dd-687862a5882f", "status": 200, "result": [ { "id": 194686783, # Trade ID "price": "0.01361000", # Price "qty": "0.01400000", # Quantity "quoteQty": "0.00019054", # Quote quantity "time": 1660009530807, # Trade time "isBuyerMaker": true, # Was the buyer the maker? "isBestMatch": true # Was this the best price match? } ] } :raises: BinanceRequestException, BinanceAPIException Weight: 25 Data Source: Memory """ return self._ws_api_request_sync("trades.recent", False, params) def ws_get_historical_trades(self, **params): """Get historical trades. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#historical-trades :param symbol: STRING - Required - Trading symbol :type symbol: str :param fromId: INT - Optional - Trade ID to begin at :type fromId: int :param limit: INT - Optional - Default 500; max 1000 :type limit: int :returns: Websocket message .. code-block:: python { "id": "cffc9c7d-4efc-4ce0-b587-6b87448f052a", "result": [ { "id": 0, # Trade ID "price": "0.00005000", # Price "qty": "40.00000000", # Quantity "quoteQty": "0.00200000", # Quote quantity "time": 1500004800376, # Trade time "isBuyerMaker": true, # Was the buyer the maker? "isBestMatch": true # Was this the best price match? } ] } :raises: BinanceRequestException, BinanceAPIException Notes: - If fromId is not specified, the most recent trades are returned Weight: 25 Data Source: Database """ return self._ws_api_request_sync("trades.historical", False, params) def ws_get_aggregate_trades(self, **params): """Get aggregate trades. An aggregate trade represents one or more individual trades that fill at the same time, from the same taker order, with the same price. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#aggregate-trades :param symbol: STRING - Required - Trading symbol :type symbol: str :param fromId: INT - Optional - Aggregate trade ID to begin at :type fromId: int :param startTime: INT - Optional - Start time in milliseconds :type startTime: int :param endTime: INT - Optional - End time in milliseconds :type endTime: int :param limit: INT - Optional - Default 500; max 1000 :type limit: int :returns: API response .. code-block:: python { "id": "...", "status": 200, "result": [ { "a": 50000000, # Aggregate trade ID "p": "0.00274100", # Price "q": "57.19000000", # Quantity "f": 59120167, # First trade ID "l": 59120170, # Last trade ID "T": 1565877971222, # Timestamp "m": true, # Was the buyer the maker? "M": true # Was the trade the best price match? } ] } :raises: BinanceRequestException, BinanceAPIException Notes: - If fromId is specified, return aggtrades with aggregate trade ID >= fromId. Use fromId and limit to page through all aggtrades. - If startTime and/or endTime are specified, aggtrades are filtered by execution time (T). fromId cannot be used together with startTime and endTime. - If no condition is specified, the most recent aggregate trades are returned. - For real-time updates, consider using WebSocket Streams: @aggTrade - For historical data, consider using data.binance.vision Weight: 2 Data Source: Database """ return self._ws_api_request_sync("trades.aggregate", False, params) def ws_get_klines(self, **params): """Get klines (candlestick bars). Klines are uniquely identified by their open & close time. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#klines :param symbol: STRING - Required - Trading symbol :type symbol: str :param interval: ENUM - Required - Kline interval :type interval: str :param startTime: INT - Optional - Start time in milliseconds :type startTime: int :param endTime: INT - Optional - End time in milliseconds :type endTime: int :param timeZone: STRING - Optional - Default: 0 (UTC) :type timeZone: str :param limit: INT - Optional - Default 500; max 1000 :type limit: int Supported kline intervals: - seconds: 1s - minutes: 1m, 3m, 5m, 15m, 30m - hours: 1h, 2h, 4h, 6h, 8h, 12h - days: 1d, 3d - weeks: 1w - months: 1M Notes: - If startTime/endTime not specified, returns most recent klines - Supported timeZone values: - Hours and minutes (e.g. "-1:00", "05:45") - Only hours (e.g. "0", "8", "4") - Accepted range is strictly [-12:00 to +14:00] inclusive - If timeZone provided, kline intervals interpreted in that timezone instead of UTC - startTime and endTime always interpreted in UTC, regardless of timeZone - For real-time updates, consider using WebSocket Streams: @kline_ - For historical data, consider using data.binance.vision Weight: 2 Data Source: Database :returns: API response .. code-block:: python { "id": "1dbbeb56-8eea-466a-8f6e-86bdcfa2fc0b", "status": 200, "result": [ [ 1655971200000, # Kline open time "0.01086000", # Open price "0.01086600", # High price "0.01083600", # Low price "0.01083800", # Close price "2290.53800000", # Volume 1655974799999, # Kline close time "24.85074442", # Quote asset volume 2283, # Number of trades "1171.64000000", # Taker buy base asset volume "12.71225884", # Taker buy quote asset volume "0" # Unused field, ignore ] ] } :raises: BinanceRequestException, BinanceAPIException """ return self._ws_api_request_sync("klines", False, params) def ws_get_uiKlines(self, **params): """Get klines (candlestick bars) optimized for presentation. This request is similar to klines, having the same parameters and response. uiKlines return modified kline data, optimized for presentation of candlestick charts. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#ui-klines :param symbol: STRING - Required - Trading symbol :type symbol: str :param interval: ENUM - Required - Kline interval :type interval: str :param startTime: INT - Optional - Start time in milliseconds :type startTime: int :param endTime: INT - Optional - End time in milliseconds :type endTime: int :param timeZone: STRING - Optional - Default: 0 (UTC) :type timeZone: str :param limit: INT - Optional - Default 500; max 1000 :type limit: int Supported kline intervals: - seconds: 1s - minutes: 1m, 3m, 5m, 15m, 30m - hours: 1h, 2h, 4h, 6h, 8h, 12h - days: 1d, 3d - weeks: 1w - months: 1M Notes: - If startTime/endTime not specified, returns most recent klines - Supported timeZone values: - Hours and minutes (e.g. "-1:00", "05:45") - Only hours (e.g. "0", "8", "4") - Accepted range is strictly [-12:00 to +14:00] inclusive - If timeZone provided, kline intervals are interpreted in that timezone instead of UTC - startTime and endTime are always interpreted in UTC, regardless of timeZone :returns: API response .. code-block:: python { "id": "b137468a-fb20-4c06-bd6b-625148eec958", "result": [ [ 1655971200000, # Kline open time "0.01086000", # Open price "0.01086600", # High price "0.01083600", # Low price "0.01083800", # Close price "2290.53800000", # Volume 1655974799999, # Kline close time "24.85074442", # Quote asset volume 2283, # Number of trades "1171.64000000", # Taker buy base asset volume "12.71225884", # Taker buy quote asset volume "0" # Unused field, ignore ] ] } :raises: BinanceRequestException, BinanceAPIException """ return self._ws_api_request_sync("uiKlines", False, params) def ws_get_avg_price(self, **params): """Get current average price for a symbol. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#current-average-price :param symbol: STRING - Required - Trading symbol :type symbol: str :returns: Websocket message .. code-block:: python { "mins": 5, # Average price interval (in minutes) "price": "9.35751834", # Average price "closeTime": 1694061154503 # Last trade time } Weight: 2 """ return self._ws_api_request_sync("avgPrice", False, params) def ws_get_ticker(self, **params): """Get 24-hour rolling window price change statistics. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#24hr-ticker-price-change-statistics :param symbol: STRING - Optional - Query ticker for a single symbol :type symbol: str :param symbols: ARRAY of STRING - Optional - Query ticker for multiple symbols :type symbols: list :param type: ENUM - Optional - Ticker type: FULL (default) or MINI :type type: str Note: - symbol and symbols cannot be used together - If no symbol is specified, returns information about all symbols currently trading on the exchange Weight: Adjusted based on the number of requested symbols: - 1-20 symbols: 2 - 21-100 symbols: 40 - 101 or more symbols: 80 - all symbols: 80 :returns: Websocket message For a single symbol with type=FULL: .. code-block:: python { "symbol": "BNBBTC", "priceChange": "0.00013900", # Absolute price change "priceChangePercent": "1.020", # Relative price change in percent "weightedAvgPrice": "0.01382453", # Quote volume divided by volume "prevClosePrice": "0.01362800", # Previous day's close price "lastPrice": "0.01376700", # Latest price "lastQty": "1.78800000", # Latest quantity "bidPrice": "0.01376700", # Best bid price "bidQty": "4.64600000", # Best bid quantity "askPrice": "0.01376800", # Best ask price "askQty": "14.31400000", # Best ask quantity "openPrice": "0.01362800", # Open price 24 hours ago "highPrice": "0.01414900", # Highest price in the last 24 hours "lowPrice": "0.01346600", # Lowest price in the last 24 hours "volume": "69412.40500000", # Trading volume in base asset "quoteVolume": "959.59411487", # Trading volume in quote asset "openTime": 1660014164909, # Open time for 24hr rolling window "closeTime": 1660100564909, # Close time for 24hr rolling window "firstId": 194696115, # First trade ID "lastId": 194968287, # Last trade ID "count": 272173 # Number of trades } For a single symbol with type=MINI: .. code-block:: python { "symbol": "BNBBTC", "openPrice": "0.01362800", "highPrice": "0.01414900", "lowPrice": "0.01346600", "lastPrice": "0.01376700", "volume": "69412.40500000", "quoteVolume": "959.59411487", "openTime": 1660014164909, "closeTime": 1660100564909, "firstId": 194696115, "lastId": 194968287, "count": 272173 } """ return self._ws_api_request_sync("ticker.24hr", False, params) def ws_get_trading_day_ticker(self, **params): """Price change statistics for a trading day. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#trading-day-ticker :param symbol: STRING - Optional - Query ticker of a single symbol :type symbol: str :param symbols: ARRAY of STRING - Optional - Query ticker for multiple symbols :type symbols: list :param timeZone: STRING - Optional - Default: 0 (UTC) Supported values: - Hours and minutes (e.g. "-1:00", "05:45") - Only hours (e.g. "0", "8", "4") - Accepted range is strictly [-12:00 to +14:00] inclusive :type timeZone: str :param type: ENUM - Optional - FULL (default) or MINI :type type: str :returns: Websocket message Response FULL type example: { "symbol": "BTCUSDT", "priceChange": "-83.13000000", # Absolute price change "priceChangePercent": "-0.317", # Relative price change in percent "weightedAvgPrice": "26234.58803036", # quoteVolume / volume "openPrice": "26304.80000000", "highPrice": "26397.46000000", "lowPrice": "26088.34000000", "lastPrice": "26221.67000000", "volume": "18495.35066000", # Volume in base asset "quoteVolume": "485217905.04210480", "openTime": 1695686400000, "closeTime": 1695772799999, "firstId": 3220151555, "lastId": 3220849281, "count": 697727 } Response MINI type example: { "symbol": "BTCUSDT", "openPrice": "26304.80000000", "highPrice": "26397.46000000", "lowPrice": "26088.34000000", "lastPrice": "26221.67000000", "volume": "18495.35066000", # Volume in base asset "quoteVolume": "485217905.04210480", # Volume in quote asset "openTime": 1695686400000, "closeTime": 1695772799999, "firstId": 3220151555, # Trade ID of the first trade in the interval "lastId": 3220849281, # Trade ID of the last trade in the interval "count": 697727 # Number of trades in the interval } Weight: - 4 for each requested symbol - Weight caps at 200 once number of symbols > 50 """ return self._ws_api_request_sync("ticker.tradingDay", False, params) def ws_get_symbol_ticker_window(self, **params): """Get rolling window price change statistics. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#rolling-window-price-change-statistics :param symbol: STRING - Optional - Query ticker of a single symbol :type symbol: str :param symbols: ARRAY of STRING - Optional - Query ticker for multiple symbols :type symbols: list :param windowSize: STRING - Required - Supported windowSize values: - 1h, 2h, 4h, 6h, 12h - 1d, 2d, 3d, 4d, 5d, 6d, 7d, 14d, 30d :type windowSize: str :param type: ENUM - Optional - FULL (default) or MINI :type type: str :returns: Websocket message With symbol parameter: .. code-block:: python { "symbol": "BTCUSDT", "priceChange": "-83.13000000", # Absolute price change "priceChangePercent": "-0.317", # Relative price change in percent "weightedAvgPrice": "26234.58803036", # quoteVolume / volume "openPrice": "26304.80000000", "highPrice": "26397.46000000", "lowPrice": "26088.34000000", "lastPrice": "26221.67000000", "volume": "18495.35066000", # Volume in base asset "quoteVolume": "485217905.04210480", # Volume in quote asset "openTime": 1695686400000, "closeTime": 1695772799999, "firstId": 3220151555, # Trade ID of first trade in the interval "lastId": 3220849281, # Trade ID of last trade in the interval "count": 697727 # Number of trades in the interval } With symbols parameter: .. code-block:: python [ { # Same fields as above }, { # Same fields as above for next symbol } ] For MINI type response: .. code-block:: python { "symbol": "BTCUSDT", "openPrice": "26304.80000000", "highPrice": "26397.46000000", "lowPrice": "26088.34000000", "lastPrice": "26221.67000000", "volume": "18495.35066000", "quoteVolume": "485217905.04210480", "openTime": 1695686400000, "closeTime": 1695772799999, "firstId": 3220151555, "lastId": 3220849281, "count": 697727 } Weight: - 4 for each requested symbol - Weight caps at 200 once number of symbols > 50 """ return self._ws_api_request_sync("ticker", False, params) def ws_get_symbol_ticker(self, **params): """Get latest price for a symbol or symbols. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#symbol-price-ticker :param symbol: STRING - Optional - Query ticker of a single symbol :type symbol: str :param symbols: ARRAY of STRING - Optional - Query ticker for multiple symbols :type symbols: list :returns: Websocket message With symbol parameter: { "symbol": "BNBBTC", "price": "0.01361000" } With symbols parameter: [ { "symbol": "BNBBTC", "price": "0.01361000" }, { "symbol": "BTCUSDT", "price": "23440.91000000" } ] Weight: - 1 for a single symbol - 2 for up to 20 symbols - 40 for 21 to 100 symbols - 40 for all symbols """ return self._ws_api_request_sync("ticker.price", False, params) def ws_get_orderbook_ticker(self, **params): """Get the best price/quantity on the order book for a symbol or symbols. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#symbol-order-book-ticker :param symbol: STRING - Optional - Query ticker of a single symbol :type symbol: str :param symbols: ARRAY of STRING - Optional - Query ticker for multiple symbols :type symbols: list :returns: Websocket response With symbol parameter: { "symbol": "BNBBTC", "bidPrice": "0.01358000", "bidQty": "0.95200000", "askPrice": "0.01358100", "askQty": "11.91700000" } With symbols parameter: [ { "symbol": "BNBBTC", "bidPrice": "0.01358000", "bidQty": "0.95200000", "askPrice": "0.01358100", "askQty": "11.91700000" }, { "symbol": "BTCUSDT", "bidPrice": "23440.90000000", "bidQty": "0.00200000", "askPrice": "23440.91000000", "askQty": "0.00200000" } ] Weight: - 2 for a single symbol - 4 for up to 100 symbols - 40 for 101 or more symbols """ return self._ws_api_request_sync("ticker.book", False, params) def ws_ping(self, **params): """Test connectivity to the WebSocket API. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#test-connectivity :returns: API response { "id": "922bcc6e-9de8-440d-9e84-7c80933a8d0d", "status": 200, "result": {}, "rateLimits": [ { "rateLimitType": "REQUEST_WEIGHT", "interval": "MINUTE", "intervalNum": 1, "limit": 6000, "count": 1 } ] } Weight: 1 """ return self._ws_api_request_sync("ping", False, params) def ws_get_time(self, **params): """Test connectivity to the WebSocket API and get the current server time. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#check-server-time :returns: API response with server time { "id": "187d3cb2-942d-484c-8271-4e2141bbadb1", "status": 200, "result": { "serverTime": 1656400526260 }, "rateLimits": [ { "rateLimitType": "REQUEST_WEIGHT", "interval": "MINUTE", "intervalNum": 1, "limit": 6000, "count": 1 } ] } Weight: 1 Data Source: Memory """ return self._ws_api_request_sync("time", False, params) def ws_get_exchange_info(self, **params): """Query current exchange trading rules, rate limits, and symbol information. https://developers.binance.com/docs/binance-spot-api-docs/testnet/web-socket-api/public-api-requests#exchange-information :param symbol: str - Filter by single symbol (optional) :param symbols: list - Filter by multiple symbols (optional) :param permissions: list or str - Filter symbols by permissions (optional) :returns: API response containing exchange information including: - Rate limits - Exchange filters - Symbol information including: - Status - Base/quote assets - Order types allowed - Filters (price, lot size, etc) - Trading permissions - Self-trade prevention modes Example response: { "timezone": "UTC", "serverTime": 1655969291181, "rateLimits": [ { "rateLimitType": "REQUEST_WEIGHT", "interval": "MINUTE", "intervalNum": 1, "limit": 6000 }, ... ], "exchangeFilters": [], "symbols": [ { "symbol": "BTCUSDT", "status": "TRADING", "baseAsset": "BTC", "baseAssetPrecision": 8, ... } ] } :raises: BinanceRequestException, BinanceAPIException Notes: - Only one of symbol, symbols, permissions parameters can be specified - Without parameters, displays all symbols with ["SPOT", "MARGIN", "LEVERAGED"] permissions - To list all active symbols, explicitly request all permissions - Permissions accepts either a list or single permission name (e.g. "SPOT") Weight: 20 Data Source: Memory """ return self._ws_api_request_sync("exchangeInfo", False, params) #################################################### # WS Futures Endpoints #################################################### def ws_futures_get_order_book(self, **params): """ Get the order book for a symbol https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/websocket-api """ return self._ws_futures_api_request_sync("depth", False, params) def ws_futures_get_all_tickers(self, **params): """ Latest price for a symbol or symbols https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/websocket-api/Symbol-Price-Ticker """ return self._ws_futures_api_request_sync("ticker.price", False, params) def ws_futures_get_order_book_ticker(self, **params): """ Best price/qty on the order book for a symbol or symbols. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/websocket-api/Symbol-Order-Book-Ticker """ return self._ws_futures_api_request_sync("ticker.book", False, params) def ws_futures_create_order(self, **params): """ Send in a new order https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api """ # Check if this is a conditional order type that needs to use algo endpoint order_type = params.get("type", "").upper() conditional_types = [ "STOP", "STOP_MARKET", "TAKE_PROFIT", "TAKE_PROFIT_MARKET", "TRAILING_STOP_MARKET", ] if order_type in conditional_types: # Route to algo order endpoint if "clientAlgoId" not in params: params["clientAlgoId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() # Remove newClientOrderId if it was added by default params.pop("newClientOrderId", None) if "algoType" not in params: params["algoType"] = "CONDITIONAL" # Convert stopPrice to triggerPrice for algo orders if "stopPrice" in params and "triggerPrice" not in params: params["triggerPrice"] = params.pop("stopPrice") return self._ws_futures_api_request_sync("algoOrder.place", True, params) else: # Use regular order endpoint if "newClientOrderId" not in params: params["newClientOrderId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return self._ws_futures_api_request_sync("order.place", True, params) def ws_futures_edit_order(self, **params): """ Edit an order https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Modify-Order """ return self._ws_futures_api_request_sync("order.modify", True, params) def ws_futures_cancel_order(self, **params): """ cancel an order https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Cancel-Order """ is_conditional = False if "algoId" in params or "clientAlgoId" in params: is_conditional = True if is_conditional: return self._ws_futures_api_request_sync("algoOrder.cancel", True, params) else: return self._ws_futures_api_request_sync("order.cancel", True, params) def ws_futures_get_order(self, **params): """ Get an order https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Query-Order Note: Algo/conditional orders cannot be queried via websocket API """ return self._ws_futures_api_request_sync("order.status", True, params) def ws_futures_v2_account_position(self, **params): """ Get current position information(only symbol that has position or open orders will be returned). https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Position-Info-V2 """ return self._ws_futures_api_request_sync("v2/account.position", True, params) def ws_futures_account_position(self, **params): """ Get current position information. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api/Position-Information """ return self._ws_futures_api_request_sync("account.position", True, params) def ws_futures_v2_account_balance(self, **params): """ Get current account information. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/websocket-api#api-description """ return self._ws_futures_api_request_sync("v2/account.balance", True, params) def ws_futures_account_balance(self, **params): """ Get current account information. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/websocket-api/Futures-Account-Balance """ return self._ws_futures_api_request_sync("account.balance", True, params) def ws_futures_v2_account_status(self, **params): """ Get current account information. User in single-asset/ multi-assets mode will see different value, see comments in response section for detail. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/websocket-api/Account-Information-V2 """ return self._ws_futures_api_request_sync("v2/account.status", True, params) def ws_futures_account_status(self, **params): """ Get current account information. User in single-asset/ multi-assets mode will see different value, see comments in response section for detail. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/websocket-api/Account-Information """ return self._ws_futures_api_request_sync("account.status", True, params) def ws_futures_create_algo_order(self, **params): """ Send in a new algo order (conditional order). https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api :param symbol: required :type symbol: str :param side: required - BUY or SELL :type side: str :param type: required - STOP, TAKE_PROFIT, STOP_MARKET, TAKE_PROFIT_MARKET, TRAILING_STOP_MARKET :type type: str :param algoType: required - Only support CONDITIONAL :type algoType: str :param positionSide: optional - Default BOTH for One-way Mode; LONG or SHORT for Hedge Mode :type positionSide: str :param timeInForce: optional - IOC or GTC or FOK, default GTC :type timeInForce: str :param quantity: optional - Cannot be sent with closePosition=true :type quantity: decimal :param price: optional :type price: decimal :param triggerPrice: optional - Used with STOP, STOP_MARKET, TAKE_PROFIT, TAKE_PROFIT_MARKET :type triggerPrice: decimal :param workingType: optional - triggerPrice triggered by: MARK_PRICE, CONTRACT_PRICE. Default CONTRACT_PRICE :type workingType: str :param priceMatch: optional - only available for LIMIT/STOP/TAKE_PROFIT order :type priceMatch: str :param closePosition: optional - true or false; Close-All, used with STOP_MARKET or TAKE_PROFIT_MARKET :type closePosition: bool :param priceProtect: optional - "TRUE" or "FALSE", default "FALSE" :type priceProtect: str :param reduceOnly: optional - "true" or "false", default "false" :type reduceOnly: str :param activationPrice: optional - Used with TRAILING_STOP_MARKET orders :type activationPrice: decimal :param callbackRate: optional - Used with TRAILING_STOP_MARKET orders, min 0.1, max 10 :type callbackRate: decimal :param clientAlgoId: optional - A unique id among open orders :type clientAlgoId: str :param selfTradePreventionMode: optional - EXPIRE_TAKER, EXPIRE_MAKER, EXPIRE_BOTH; default NONE :type selfTradePreventionMode: str :param goodTillDate: optional - order cancel time for timeInForce GTD :type goodTillDate: int :param newOrderRespType: optional - "ACK", "RESULT", default "ACK" :type newOrderRespType: str :param recvWindow: optional - the number of milliseconds the request is valid for :type recvWindow: int :returns: WS response """ if "clientAlgoId" not in params: params["clientAlgoId"] = self.CONTRACT_ORDER_PREFIX + self.uuid22() return self._ws_futures_api_request_sync("algoOrder.place", True, params) def ws_futures_cancel_algo_order(self, **params): """ Cancel an active algo order. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/websocket-api :param symbol: required :type symbol: str :param algoId: optional - Either algoId or clientAlgoId must be sent :type algoId: int :param clientAlgoId: optional - Either algoId or clientAlgoId must be sent :type clientAlgoId: str :param recvWindow: optional - the number of milliseconds the request is valid for :type recvWindow: int :returns: WS response """ return self._ws_futures_api_request_sync("algoOrder.cancel", True, params) ############################################### ### Gift card api ############################################### def gift_card_fetch_token_limit(self, **params): """Verify which tokens are available for you to create Stablecoin-Denominated gift cards https://developers.binance.com/docs/gift_card/market-data/Fetch-Token-Limit :param baseToken: The token you want to pay, example: BUSD :type baseToken: str :return: api response .. code-block:: python { "code": "000000", "message": "success", "data": [ { "coin": "BNB", "fromMin": "0.01", "fromMax": "1" } ], "success": true } """ return self._request_margin_api( "get", "giftcard/buyCode/token-limit", signed=True, data=params ) def gift_card_fetch_rsa_public_key(self, **params): """This API is for fetching the RSA Public Key. This RSA Public key will be used to encrypt the card code. Important Note: The RSA Public key fetched is valid only for the current day. https://developers.binance.com/docs/gift_card/market-data/Fetch-RSA-Public-Key :param recvWindow: The receive window for the request in milliseconds (optional) :type recvWindow: int :return: api response .. code-block:: python { "code": "000000", "message": "success", "data": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCXBBVKLAc1GQ5FsIFFqOHrPTox5noBONIKr+IAedTR9FkVxq6e65updEbfdhRNkMOeYIO2i0UylrjGC0X8YSoIszmrVHeV0l06Zh1oJuZos1+7N+WLuz9JvlPaawof3GUakTxYWWCa9+8KIbLKsoKMdfS96VT+8iOXO3quMGKUmQIDAQAB", "success": true } """ return self._request_margin_api( "get", "giftcard/cryptography/rsa-public-key", signed=True, data=params ) def gift_card_verify(self, **params): """This API is for verifying whether the Binance Gift Card is valid or not by entering Gift Card Number. Important Note: If you enter the wrong Gift Card Number 5 times within an hour, you will no longer be able to verify any Gift Card Number for that hour. https://developers.binance.com/docs/gift_card/market-data/Verify-Binance-Gift-Card-by-Gift-Card-Number :param referenceNo: Enter the Gift Card Number :type referenceNo: str :return: api response .. code-block:: python { "code": "000000", "message": "success", "data": { "valid": true, "token": "BNB", # coin "amount": "0.00000001" # amount }, "success": true } """ return self._request_margin_api( "get", "giftcard/verify", signed=True, data=params ) def gift_card_redeem(self, **params): """This API is for redeeming a Binance Gift Card. Once redeemed, the coins will be deposited in your funding wallet. Important Note: If you enter the wrong redemption code 5 times within 24 hours, you will no longer be able to redeem any Binance Gift Cards that day. Code Format Options: - Plaintext - Encrypted (Recommended for better security) For encrypted format: 1. Fetch RSA public key from the RSA public key endpoint 2. Encrypt the code using algorithm: RSA/ECB/OAEPWithSHA-256AndMGF1Padding https://developers.binance.com/docs/gift_card/market-data/Redeem-a-Binance-Gift-Card :param code: Redemption code of Binance Gift Card to be redeemed, supports both Plaintext & Encrypted code :type code: str :param externalUid: External unique ID representing a user on the partner platform. Helps identify redemption behavior and control risks/limits. Max 400 characters. (optional) :type externalUid: str :param recvWindow: The receive window for the request in milliseconds (optional) :type recvWindow: int :return: api response .. code-block:: python { "code": "000000", "message": "success", "data": { "referenceNo": "0033002328060227", "identityNo": "10317392647411060736", "token": "BNB", "amount": "0.00000001" }, "success": true } """ return self._request_margin_api( "post", "giftcard/redeemCode", signed=True, data=params ) def gift_card_create(self, **params): """ This API is for creating a Binance Gift Card. To get started with, please make sure: - You have a Binance account - You have passed KYB - You have a sufficient balance(Gift Card amount and fee amount) in your Binance funding wallet - You need Enable Withdrawals for the API Key which requests this endpoint. https://developers.binance.com/docs/gift_card/market-data :param token: The token type contained in the Binance Gift Card :type token: str :param amount: The amount of the token contained in the Binance Gift Card :type amount: float :return: api response .. code-block:: python { "code": "000000", "message": "success", "data": { "referenceNo": "0033002144060553", "code": "6H9EKF5ECCWFBHGE", "expiredTime": 1727417154000 }, "success": true } """ return self._request_margin_api( "post", "giftcard/createCode", signed=True, data=params ) def gift_card_create_dual_token(self, **params): """This API is for creating a dual-token ( stablecoin-denominated) Binance Gift Card. You may create a gift card using USDT as baseToken, that is redeemable to another designated token (faceToken). For example, you can create a fixed-value BTC gift card and pay with 100 USDT plus 1 USDT fee. This gift card can keep the value fixed at 100 USDT before redemption, and will be redeemable to BTC equivalent to 100 USDT upon redemption. Once successfully created, the amount of baseToken (e.g. USDT) in the fixed-value gift card along with the fee would be deducted from your funding wallet. To get started with, please make sure: - You have a Binance account - You have passed KYB - You have a sufficient balance(Gift Card amount and fee amount) in your Binance funding wallet - You need Enable Withdrawals for the API Key which requests this endpoint. https://developers.binance.com/docs/gift_card/market-data/Create-a-dual-token-gift-card :param baseToken: The token you want to pay, example: BUSD :type baseToken: str :param faceToken: The token you want to buy, example: BNB. If faceToken = baseToken, it's the same as createCode endpoint. :type faceToken: str :param discount: Stablecoin-denominated card discount percentage, Example: 1 for 1% discount. Scale should be less than 6. :type discount: float :return: api response .. code-block:: python { "code": "000000", "message": "success", "data": { "referenceNo": "0033002144060553", "code": "6H9EKF5ECCWFBHGE", "expiredTime": 1727417154000 }, "success": true } """ return self._request_margin_api( "post", "giftcard/buyCode", signed=True, data=params ) #################################################### # Borrow and repay Endpoints #################################################### def margin_next_hourly_interest_rate(self, **params): """Get future hourly interest rate (USER_DATA) https://developers.binance.com/docs/margin_trading/borrow-and-repay :param assets: required - List of assets, separated by commas, up to 20 :type assets: str :param isIsolated: required - for isolated margin or not, "TRUE", "FALSE" :type isIsolated: bool :returns: API response .. code-block:: python [ { "asset": "BTC", "nextHourlyInterestRate": "0.00000571" }, { "asset": "ETH", "nextHourlyInterestRate": "0.00000578" } ] """ return self._request_margin_api( "get", "margin/next-hourly-interest-rate", signed=True, data=params ) def margin_interest_history(self, **params): """Get Interest History (USER_DATA) https://developers.binance.com/docs/margin_trading/borrow-and-repay/Get-Interest-History :param asset: optional :type asset: str :param isolatedSymbol: optional - isolated symbol :type isolatedSymbol: str :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param current: optional - Currently querying page. Start from 1. Default:1 :type current: int :param size: optional - Default:10 Max:100 :type size: int :returns: API response .. code-block:: python { "rows": [ { "txId": 1352286576452864727, "interestAccuredTime": 1672160400000, "asset": "USDT", "rawAsset": “USDT”, // will not be returned for isolated margin "principal": "45.3313", "interest": "0.00024995", "interestRate": "0.00013233", "type": "ON_BORROW", "isolatedSymbol": "BNBUSDT" // isolated symbol, will not be returned for crossed margin } ], "total": 1 } """ return self._request_margin_api( "get", "margin/interestHistory", signed=True, data=params ) def margin_borrow_repay(self, **params): """Margin Account Borrow/Repay (MARGIN) https://developers.binance.com/docs/margin_trading/borrow-and-repay/Margin-Account-Borrow-Repay :param asset: required :type asset: str :param amount: required :type amount: float :param isIsolated: optional - for isolated margin or not, "TRUE", "FALSE", default "FALSE" :type isIsolated: str :param symbol: optional - isolated symbol :type symbol: str :param type: str :type type: str - BORROW or REPAY :returns: API response .. code-block:: python { //transaction id "tranId": 100000001 } """ return self._request_margin_api( "post", "margin/borrow-repay", signed=True, data=params ) def margin_get_borrow_repay_records(self, **params): """Query Query borrow/repay records in Margin account (USER_DATA) https://developers.binance.com/docs/margin_trading/borrow-and-repay/Query-Borrow-Repay :param asset: required :type asset: str :param isolatedSymbol: optional - isolated symbol :type isolatedSymbol: str :param txId: optional - the tranId in POST /sapi/v1/margin/loan :type txId: int :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :param current: optional - Currently querying page. Start from 1. Default:1 :type current: int :param size: optional - Default:10 Max:100 :type size: int :returns: API response .. code-block:: python { "rows": [ { "type": "AUTO", // AUTO,MANUAL for Cross Margin Borrow; MANUAL,AUTO,BNB_AUTO_REPAY,POINT_AUTO_REPAY for Cross Margin Repay; AUTO,MANUAL for Isolated Margin Borrow/Repay; "isolatedSymbol": "BNBUSDT", // isolated symbol, will not be returned for crossed margin "amount": "14.00000000", // Total amount borrowed/repaid "asset": "BNB", "interest": "0.01866667", // Interest repaid "principal": "13.98133333", // Principal repaid "status": "CONFIRMED", //one of PENDING (pending execution), CONFIRMED (successfully execution), FAILED (execution failed, nothing happened to your account); "timestamp": 1563438204000, "txId": 2970933056 } ], "total": 1 } """ return self._request_margin_api( "get", "margin/borrow-repay", signed=True, data=params ) def margin_interest_rate_history(self, **params): """Query Margin Interest Rate History (USER_DATA) https://developers.binance.com/docs/margin_trading/borrow-and-repay/Query-Margin-Interest-Rate-History :param asset: required :type asset: str :param vipLevel: optional :type vipLevel: int :param startTime: optional :type startTime: int :param endTime: optional :type endTime: int :returns: API response .. code-block:: python [ { "asset": "BTC", "dailyInterestRate": "0.00025000", "timestamp": 1611544731000, "vipLevel": 1 }, { "asset": "BTC", "dailyInterestRate": "0.00035000", "timestamp": 1610248118000, "vipLevel": 1 } ] """ return self._request_margin_api( "get", "margin/interestRateHistory", signed=True, data=params ) def margin_max_borrowable(self, **params): """Query Max Borrow (USER_DATA) https://developers.binance.com/docs/margin_trading/borrow-and-repay/Query-Max-Borrow :param asset: required :type asset: str :param isolatedSymbol: optional - isolated symbol :type isolatedSymbol: str :returns: API response .. code-block:: python { "amount": "1.69248805", // account's currently max borrowable amount with sufficient system availability "borrowLimit": "60" // max borrowable amount limited by the account level } """ return self._request_margin_api( "get", "margin/maxBorrowable", signed=True, data=params ) #################################################### # Futures Data #################################################### def futures_historical_data_link(self, **params): """Get Future TickLevel Orderbook Historical Data Download Link. https://developers.binance.com/docs/derivatives/futures-data/market-data :param symbol: STRING - Required - Symbol name, e.g. BTCUSDT or BTCUSD_PERP :type symbol: str :param dataType: ENUM - Required - Data type: - T_DEPTH for ticklevel orderbook data - S_DEPTH for orderbook snapshot data :type dataType: str :param startTime: LONG - Required - Start time in milliseconds :type startTime: int :param endTime: LONG - Required - End time in milliseconds :type endTime: int :param recvWindow: LONG - Optional - Number of milliseconds after timestamp the request is valid for :type recvWindow: int :param timestamp: LONG - Required - Current timestamp in milliseconds :type timestamp: int :returns: API response .. code-block:: python { "data": [ { "day": "2023-06-30", "url": "" } ] } :raises: BinanceRequestException, BinanceAPIException Notes: - The span between startTime and endTime can't be more than 7 days - The download link will be valid for 1 day - Only VIP users can query this endpoint - Weight: 200 """ return self._request_margin_api("get", "futures/data/histDataLink", signed=True, data=params) def margin_v1_get_loan_vip_ongoing_orders(self, **params): """ Placeholder function for GET /sapi/v1/loan/vip/ongoing/orders. Note: This function was auto-generated. Any issue please open an issue on GitHub. GET /sapi/v1/loan/vip/ongoing/orders :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/vip/ongoing/orders", signed=True, data=params, version=1) def margin_v1_get_mining_payment_other(self, **params): """ Placeholder function for GET /sapi/v1/mining/payment/other. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/mining/rest-api/Extra-Bonus-List :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "mining/payment/other", signed=True, data=params, version=1) def futures_coin_v1_get_income_asyn_id(self, **params): """ Placeholder function for GET /dapi/v1/income/asyn/id. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/coin-margined-futures/account/rest-api/Get-Futures-Transaction-History-Download-Link-by-Id :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_coin_api("get", "income/asyn/id", signed=True, data=params, version=1) def margin_v1_get_simple_earn_flexible_history_subscription_record(self, **params): """ Placeholder function for GET /sapi/v1/simple-earn/flexible/history/subscriptionRecord. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/simple_earn/history :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "simple-earn/flexible/history/subscriptionRecord", signed=True, data=params, version=1) def margin_v1_post_lending_auto_invest_one_off(self, **params): """ Placeholder function for POST /sapi/v1/lending/auto-invest/one-off. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "lending/auto-invest/one-off", signed=True, data=params, version=1) def margin_v1_post_broker_sub_account_api_commission_coin_futures(self, **params): """ Placeholder function for POST /sapi/v1/broker/subAccountApi/commission/coinFutures. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/fee/Change-Sub-Account-CM-Futures-Commission :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/subAccountApi/commission/coinFutures", signed=True, data=params, version=1) def v3_post_order_list_otoco(self, **params): """ Placeholder function for POST /api/v3/orderList/otoco. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_api("post", "orderList/otoco", signed=True, data=params, version="v3") def futures_v1_get_order_asyn(self, **params): """ Placeholder function for GET /fapi/v1/order/asyn. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Get-Download-Id-For-Futures-Order-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "order/asyn", signed=True, data=params, version=1) def margin_v1_get_asset_custody_transfer_history(self, **params): """ Placeholder function for GET /sapi/v1/asset/custody/transfer-history. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/asset/query-user-delegation :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "asset/custody/transfer-history", signed=True, data=params, version=1) def margin_v1_post_broker_sub_account_blvt(self, **params): """ Placeholder function for POST /sapi/v1/broker/subAccount/blvt. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/subAccount/blvt", signed=True, data=params, version=1) def margin_v1_post_sol_staking_sol_redeem(self, **params): """ Placeholder function for POST /sapi/v1/sol-staking/sol/redeem. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/sol-staking/staking/Redeem-SOL :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "sol-staking/sol/redeem", signed=True, data=params, version=1) def options_v1_get_countdown_cancel_all(self, **params): """ Placeholder function for GET /eapi/v1/countdownCancelAll. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/option/market-maker-endpoints/Get-Auto-Cancel-All-Open-Orders-Config :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_options_api("get", "countdownCancelAll", signed=True, data=params) def margin_v1_get_margin_trade_coeff(self, **params): """ Placeholder function for GET /sapi/v1/margin/tradeCoeff. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/margin_trading/account/Get-Summary-Of-Margin-Account :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "margin/tradeCoeff", signed=True, data=params, version=1) def futures_coin_v1_get_order_amendment(self, **params): """ Placeholder function for GET /dapi/v1/orderAmendment. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Get-Order-Modify-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_coin_api("get", "orderAmendment", signed=True, data=params, version=1) def margin_v1_get_margin_available_inventory(self, **params): """ Placeholder function for GET /sapi/v1/margin/available-inventory. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/margin_trading/market-data/Query-margin-avaliable-inventory :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "margin/available-inventory", signed=True, data=params, version=1) def margin_v1_post_account_api_restrictions_ip_restriction_ip_list(self, **params): """ Placeholder function for POST /sapi/v1/account/apiRestrictions/ipRestriction/ipList. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "account/apiRestrictions/ipRestriction/ipList", signed=True, data=params, version=1) def margin_v2_get_eth_staking_account(self, **params): """ Placeholder function for GET /sapi/v2/eth-staking/account. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/eth-staking/account :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "eth-staking/account", signed=True, data=params, version=2) def margin_v1_get_loan_income(self, **params): """ Placeholder function for GET /sapi/v1/loan/income. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/crypto_loan/stable-rate/market-data :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/income", signed=True, data=params, version=1) def futures_coin_v1_get_pm_account_info(self, **params): """ Placeholder function for GET /dapi/v1/pmAccountInfo. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/coin-margined-futures/portfolio-margin-endpoints :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_coin_api("get", "pmAccountInfo", signed=True, data=params, version=1) def margin_v1_get_managed_subaccount_query_trans_log_for_investor(self, **params): """ Placeholder function for GET /sapi/v1/managed-subaccount/queryTransLogForInvestor. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/managed-sub-account/Query-Managed-Sub-Account-Transfer-Log-Investor :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "managed-subaccount/queryTransLogForInvestor", signed=True, data=params, version=1) def margin_v1_post_dci_product_auto_compound_edit_status(self, **params): """ Placeholder function for POST /sapi/v1/dci/product/auto_compound/edit-status. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/dual_investment/trade/Change-Auto-Compound-status :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "dci/product/auto_compound/edit-status", signed=True, data=params, version=1) def futures_v1_get_trade_asyn(self, **params): """ Placeholder function for GET /fapi/v1/trade/asyn. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Get-Download-Id-For-Futures-Trade-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "trade/asyn", signed=True, data=params, version=1) def margin_v1_get_loan_vip_request_interest_rate(self, **params): """ Placeholder function for GET /sapi/v1/loan/vip/request/interestRate. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/vip_loan/market-data :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/vip/request/interestRate", signed=True, data=params, version=1) def futures_v1_get_funding_info(self, **params): """ Placeholder function for GET /fapi/v1/fundingInfo. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Get-Funding-Rate-Info :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "fundingInfo", signed=False, data=params, version=1) def margin_v2_get_loan_flexible_repay_rate(self, **params): """ Placeholder function for GET /sapi/v2/loan/flexible/repay/rate. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/crypto_loan/flexible-rate/user-information/Check-Collateral-Repay-Rate :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/flexible/repay/rate", signed=True, data=params, version=2) def margin_v1_get_lending_auto_invest_plan_id(self, **params): """ Placeholder function for GET /sapi/v1/lending/auto-invest/plan/id. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "lending/auto-invest/plan/id", signed=True, data=params, version=1) def margin_v1_post_loan_adjust_ltv(self, **params): """ Placeholder function for POST /sapi/v1/loan/adjust/ltv. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "loan/adjust/ltv", signed=True, data=params, version=1) def margin_v1_get_mining_statistics_user_status(self, **params): """ Placeholder function for GET /sapi/v1/mining/statistics/user/status. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/mining/rest-api/Statistic-List :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "mining/statistics/user/status", signed=True, data=params, version=1) def margin_v1_get_broker_transfer_futures(self, **params): """ Placeholder function for GET /sapi/v1/broker/transfer/futures. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/asset/Query-Sub-Account-Transfer-History-Futures :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/transfer/futures", signed=True, data=params, version=1) def margin_v1_post_algo_spot_new_order_twap(self, **params): """ Placeholder function for POST /sapi/v1/algo/spot/newOrderTwap. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/algo/spot-algo/Time-Weighted-Average-Price-New-Order :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "algo/spot/newOrderTwap", signed=True, data=params, version=1) def margin_v1_get_lending_auto_invest_target_asset_list(self, **params): """ Placeholder function for GET /sapi/v1/lending/auto-invest/target-asset/list. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "lending/auto-invest/target-asset/list", signed=True, data=params, version=1) def margin_v1_get_capital_deposit_address_list(self, **params): """ Placeholder function for GET /sapi/v1/capital/deposit/address/list. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/capital/deposite-address :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "capital/deposit/address/list", signed=True, data=params, version=1) def margin_v1_post_broker_sub_account_bnb_burn_margin_interest(self, **params): """ Placeholder function for POST /sapi/v1/broker/subAccount/bnbBurn/marginInterest. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/account/Enable-Or-Disable-BNB-Burn-for-Sub-Account-Margin-Interest :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/subAccount/bnbBurn/marginInterest", signed=True, data=params, version=1) def margin_v2_post_loan_flexible_repay(self, **params): """ Placeholder function for POST /sapi/v2/loan/flexible/repay. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/crypto_loan/flexible-rate/trade/Flexible-Loan-Repay :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "loan/flexible/repay", signed=True, data=params, version=2) def margin_v2_get_loan_flexible_loanable_data(self, **params): """ Placeholder function for GET /sapi/v2/loan/flexible/loanable/data. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/crypto_loan/flexible-rate/market-data/Get-Flexible-Loan-Assets-Data :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/flexible/loanable/data", signed=True, data=params, version=2) def margin_v1_post_broker_sub_account_api_permission(self, **params): """ Placeholder function for POST /sapi/v1/broker/subAccountApi/permission. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/account/Change-Sub-Account-Api-Permission :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/subAccountApi/permission", signed=True, data=params, version=1) def margin_v1_post_broker_sub_account_api(self, **params): """ Placeholder function for POST /sapi/v1/broker/subAccountApi. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/account/Create-Api-Key-for-Sub-Account :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/subAccountApi", signed=True, data=params, version=1) def margin_v1_get_dci_product_positions(self, **params): """ Placeholder function for GET /sapi/v1/dci/product/positions. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/dual_investment/trade/Get-Dual-Investment-positions :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "dci/product/positions", signed=True, data=params, version=1) def margin_v1_post_convert_limit_cancel_order(self, **params): """ Placeholder function for POST /sapi/v1/convert/limit/cancelOrder. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/convert/trade/Cancel-Order :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "convert/limit/cancelOrder", signed=True, data=params, version=1) def v3_post_order_list_oto(self, **params): """ Placeholder function for POST /api/v3/orderList/oto. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_api("post", "orderList/oto", signed=True, data=params, version="v3") def margin_v1_get_mining_hash_transfer_config_details_list(self, **params): """ Placeholder function for GET /sapi/v1/mining/hash-transfer/config/details/list. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/mining/rest-api/Hashrate-Resale-List :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "mining/hash-transfer/config/details/list", signed=True, data=params, version=1) def margin_v1_get_mining_hash_transfer_profit_details(self, **params): """ Placeholder function for GET /sapi/v1/mining/hash-transfer/profit/details. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/mining/rest-api/Hashrate-Resale-Detail :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "mining/hash-transfer/profit/details", signed=True, data=params, version=1) def margin_v1_get_broker_sub_account(self, **params): """ Placeholder function for GET /sapi/v1/broker/subAccount. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/account/Query-Sub-Account :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/subAccount", signed=True, data=params, version=1) def margin_v1_get_portfolio_balance(self, **params): """ Placeholder function for GET /sapi/v1/portfolio/balance. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/portfolio-margin-pro/account/Get-Classic-Portfolio-Margin-Balance-Info :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "portfolio/balance", signed=True, data=params, version=1) def margin_v1_post_sub_account_eoptions_enable(self, **params): """ Placeholder function for POST /sapi/v1/sub-account/eoptions/enable. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/account-management/Enable-Options-for-Sub-account :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "sub-account/eoptions/enable", signed=True, data=params, version=1) def papi_v1_post_ping(self, **params): """ Placeholder function for POST /papi/v1/ping. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_papi_api("post", "ping", signed=True, data=params, version=1) def margin_v1_get_loan_loanable_data(self, **params): """ Placeholder function for GET /sapi/v1/loan/loanable/data. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/loanable/data", signed=True, data=params, version=1) def margin_v1_post_eth_staking_wbeth_unwrap(self, **params): """ Placeholder function for POST /sapi/v1/eth-staking/wbeth/unwrap. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "eth-staking/wbeth/unwrap", signed=True, data=params, version=1) def margin_v1_get_eth_staking_eth_history_staking_history(self, **params): """ Placeholder function for GET /sapi/v1/eth-staking/eth/history/stakingHistory. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/eth-staking/history :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "eth-staking/eth/history/stakingHistory", signed=True, data=params, version=1) def margin_v1_get_staking_staking_record(self, **params): """ Placeholder function for GET /sapi/v1/staking/stakingRecord. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "staking/stakingRecord", signed=True, data=params, version=1) def margin_v1_get_broker_rebate_recent_record(self, **params): """ Placeholder function for GET /sapi/v1/broker/rebate/recentRecord. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/fee/Query-Spot-Commission-Rebate-Recent-Record :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/rebate/recentRecord", signed=True, data=params, version=1) def margin_v1_get_loan_vip_collateral_account(self, **params): """ Placeholder function for GET /sapi/v1/loan/vip/collateral/account. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/vip_loan/user-information/Check-Locked-Value-of-VIP-Collateral-Account :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/vip/collateral/account", signed=True, data=params, version=1) def margin_v1_get_algo_spot_open_orders(self, **params): """ Placeholder function for GET /sapi/v1/algo/spot/openOrders. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/algo/spot-algo/Query-Current-Algo-Open-Orders :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "algo/spot/openOrders", signed=True, data=params, version=1) def margin_v1_post_loan_repay(self, **params): """ Placeholder function for POST /sapi/v1/loan/repay. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "loan/repay", signed=True, data=params, version=1) def futures_coin_v1_get_funding_info(self, **params): """ Placeholder function for GET /dapi/v1/fundingInfo. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Get-Funding-Info :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_coin_api("get", "fundingInfo", signed=False, data=params, version=1) def margin_v1_get_margin_leverage_bracket(self, **params): """ Placeholder function for GET /sapi/v1/margin/leverageBracket. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/margin_trading/market-data/Query-Liability-Coin-Leverage-Bracket-in-Cross-Margin-Pro-Mode :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "margin/leverageBracket", signed=True, data=params, version=1) def margin_v2_get_portfolio_collateral_rate(self, **params): """ Placeholder function for GET /sapi/v2/portfolio/collateralRate. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/portfolio-margin-pro/market-data/Portfolio-Margin-Pro-Tiered-Collateral-Rate :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "portfolio/collateralRate", signed=True, data=params, version=2) def margin_v2_post_loan_flexible_adjust_ltv(self, **params): """ Placeholder function for POST /sapi/v2/loan/flexible/adjust/ltv. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/crypto_loan/flexible-rate/trade/Flexible-Loan-Adjust-LTV :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "loan/flexible/adjust/ltv", signed=True, data=params, version=2) def margin_v1_get_convert_order_status(self, **params): """ Placeholder function for GET /sapi/v1/convert/orderStatus. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/convert/trade/Order-Status :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "convert/orderStatus", signed=True, data=params, version=1) def margin_v1_get_broker_sub_account_api_ip_restriction(self, **params): """ Placeholder function for GET /sapi/v1/broker/subAccountApi/ipRestriction. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/account/Get-IPRestriction-for-Sub-Account-Api-Key :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/subAccountApi/ipRestriction", signed=True, data=params, version=1) def margin_v1_post_dci_product_subscribe(self, **params): """ Placeholder function for POST /sapi/v1/dci/product/subscribe. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/dual_investment/trade :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "dci/product/subscribe", signed=True, data=params, version=1) def futures_v1_get_income_asyn_id(self, **params): """ Placeholder function for GET /fapi/v1/income/asyn/id. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Get-Futures-Transaction-History-Download-Link-by-Id :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "income/asyn/id", signed=True, data=params, version=1) def options_v1_post_countdown_cancel_all(self, **params): """ Placeholder function for POST /eapi/v1/countdownCancelAll. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/option/market-maker-endpoints/Set-Auto-Cancel-All-Open-Orders-Config :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_options_api("post", "countdownCancelAll", signed=True, data=params) def margin_v1_post_mining_hash_transfer_config_cancel(self, **params): """ Placeholder function for POST /sapi/v1/mining/hash-transfer/config/cancel. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/mining/rest-api/Cancel-hashrate-resale-configuration :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "mining/hash-transfer/config/cancel", signed=True, data=params, version=1) def margin_v1_get_broker_sub_account_deposit_hist(self, **params): """ Placeholder function for GET /sapi/v1/broker/subAccount/depositHist. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/asset/Get-Sub-Account-Deposit-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/subAccount/depositHist", signed=True, data=params, version=1) def margin_v1_get_mining_payment_list(self, **params): """ Placeholder function for GET /sapi/v1/mining/payment/list. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/mining/rest-api/Earnings-List :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "mining/payment/list", signed=True, data=params, version=1) def futures_v1_get_pm_account_info(self, **params): """ Placeholder function for GET /fapi/v1/pmAccountInfo. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/portfolio-margin-endpoints :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "pmAccountInfo", signed=True, data=params, version=1) def futures_coin_v1_get_adl_quantile(self, **params): """ Placeholder function for GET /dapi/v1/adlQuantile. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Position-ADL-Quantile-Estimation :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_coin_api("get", "adlQuantile", signed=True, data=params, version=1) def options_v1_get_income_asyn_id(self, **params): """ Placeholder function for GET /eapi/v1/income/asyn/id. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/option/account/Get-Option-Transaction-History-Download-Link-by-Id :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_options_api("get", "income/asyn/id", signed=True, data=params) def v3_post_cancel_replace(self, **params): """ Placeholder function for POST /api/v3/cancelReplace. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_api("post", "cancelReplace", signed=True, data=params, version="v3") def margin_v1_post_account_enable_fast_withdraw_switch(self, **params): """ Placeholder function for POST /sapi/v1/account/enableFastWithdrawSwitch. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/account/enable-fast-withdraw-switch :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "account/enableFastWithdrawSwitch", signed=True, data=params, version=1) def margin_v1_post_broker_transfer_futures(self, **params): """ Placeholder function for POST /sapi/v1/broker/transfer/futures. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/asset/Sub-Account-Transfer-Futures :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/transfer/futures", signed=True, data=params, version=1) def margin_v1_post_sol_staking_sol_stake(self, **params): """ Placeholder function for POST /sapi/v1/sol-staking/sol/stake. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/sol-staking/staking :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "sol-staking/sol/stake", signed=True, data=params, version=1) def margin_v1_post_loan_borrow(self, **params): """ Placeholder function for POST /sapi/v1/loan/borrow. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "loan/borrow", signed=True, data=params, version=1) def margin_v1_get_managed_subaccount_info(self, **params): """ Placeholder function for GET /sapi/v1/managed-subaccount/info. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/managed-sub-account/Query-Managed-Sub-account-List :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "managed-subaccount/info", signed=True, data=params, version=1) def margin_v1_post_lending_auto_invest_plan_edit_status(self, **params): """ Placeholder function for POST /sapi/v1/lending/auto-invest/plan/edit-status. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "lending/auto-invest/plan/edit-status", signed=True, data=params, version=1) def margin_v1_get_sol_staking_sol_history_unclaimed_rewards(self, **params): """ Placeholder function for GET /sapi/v1/sol-staking/sol/history/unclaimedRewards. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/sol-staking/history/Get-Unclaimed-rewards :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "sol-staking/sol/history/unclaimedRewards", signed=True, data=params, version=1) def margin_v1_post_asset_convert_transfer_query_by_page(self, **params): """ Placeholder function for POST /sapi/v1/asset/convert-transfer/queryByPage. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "asset/convert-transfer/queryByPage", signed=True, data=params, version=1) def margin_v1_get_sol_staking_sol_history_boost_rewards_history(self, **params): """ Placeholder function for GET /sapi/v1/sol-staking/sol/history/boostRewardsHistory. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/sol-staking/history/Get-Boost-rewards-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "sol-staking/sol/history/boostRewardsHistory", signed=True, data=params, version=1) def margin_v1_get_lending_auto_invest_one_off_status(self, **params): """ Placeholder function for GET /sapi/v1/lending/auto-invest/one-off/status. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "lending/auto-invest/one-off/status", signed=True, data=params, version=1) def margin_v1_post_broker_sub_account(self, **params): """ Placeholder function for POST /sapi/v1/broker/subAccount. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/account :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/subAccount", signed=True, data=params, version=1) def margin_v1_get_asset_ledger_transfer_cloud_mining_query_by_page(self, **params): """ Placeholder function for GET /sapi/v1/asset/ledger-transfer/cloud-mining/queryByPage. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/asset/cloud-mining-payment-and-refund-history :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "asset/ledger-transfer/cloud-mining/queryByPage", signed=True, data=params, version=1) def margin_v1_get_mining_pub_coin_list(self, **params): """ Placeholder function for GET /sapi/v1/mining/pub/coinList. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/mining/rest-api/Acquiring-CoinName :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "mining/pub/coinList", signed=True, data=params, version=1) def margin_v2_get_loan_flexible_repay_history(self, **params): """ Placeholder function for GET /sapi/v2/loan/flexible/repay/history. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/crypto_loan/flexible-rate/user-information/Get-Flexible-Loan-Repayment-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/flexible/repay/history", signed=True, data=params, version=2) def v3_post_sor_order(self, **params): """ Placeholder function for POST /api/v3/sor/order. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_api("post", "sor/order", signed=True, data=params, version="v3") def margin_v1_post_capital_deposit_credit_apply(self, **params): """ Placeholder function for POST /sapi/v1/capital/deposit/credit-apply. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/capital/one-click-arrival-deposite-apply :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "capital/deposit/credit-apply", signed=True, data=params, version=1) def futures_v1_put_batch_order(self, **params): """ Placeholder function for PUT /fapi/v1/batchOrder. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("put", "batchOrder", signed=True, data=params, version=1) def margin_v1_get_mining_statistics_user_list(self, **params): """ Placeholder function for GET /sapi/v1/mining/statistics/user/list. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/mining/rest-api/Account-List :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "mining/statistics/user/list", signed=True, data=params, version=1) def futures_v1_post_batch_order(self, **params): """ Placeholder function for POST /fapi/v1/batchOrder. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("post", "batchOrder", signed=True, data=params, version=1) def v3_get_ticker_trading_day(self, **params): """ Placeholder function for GET /api/v3/ticker/tradingDay. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_api("get", "ticker/tradingDay", signed=False, data=params, version="v3") def margin_v1_get_mining_worker_detail(self, **params): """ Placeholder function for GET /sapi/v1/mining/worker/detail. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/mining/rest-api/Request-for-Detail-Miner-List :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "mining/worker/detail", signed=True, data=params, version=1) def margin_v1_get_managed_subaccount_fetch_future_asset(self, **params): """ Placeholder function for GET /sapi/v1/managed-subaccount/fetch-future-asset. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/managed-sub-account/Query-Managed-Sub-account-Futures-Asset-Details :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "managed-subaccount/fetch-future-asset", signed=True, data=params, version=1) def margin_v1_get_margin_rate_limit_order(self, **params): """ Placeholder function for GET /sapi/v1/margin/rateLimit/order. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/margin_trading/trade/Query-Current-Margin-Order-Count-Usage :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "margin/rateLimit/order", signed=True, data=params, version=1) def margin_v1_get_localentity_vasp(self, **params): """ Placeholder function for GET /sapi/v1/localentity/vasp. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/travel-rule/onboarded-vasp-list :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "localentity/vasp", signed=True, data=params, version=1) def margin_v1_get_sol_staking_sol_history_rate_history(self, **params): """ Placeholder function for GET /sapi/v1/sol-staking/sol/history/rateHistory. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/sol-staking/history/Get-BNSOL-Rate-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "sol-staking/sol/history/rateHistory", signed=True, data=params, version=1) def margin_v1_post_broker_sub_account_api_ip_restriction(self, **params): """ Placeholder function for POST /sapi/v1/broker/subAccountApi/ipRestriction. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/subAccountApi/ipRestriction", signed=True, data=params, version=1) def margin_v1_get_broker_transfer(self, **params): """ Placeholder function for GET /sapi/v1/broker/transfer. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/asset/Query-Sub-Account-Transfer-History-Spot :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/transfer", signed=True, data=params, version=1) def margin_v1_get_sol_staking_account(self, **params): """ Placeholder function for GET /sapi/v1/sol-staking/account. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/sol-staking/account :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "sol-staking/account", signed=True, data=params, version=1) def margin_v1_get_account_info(self, **params): """ Placeholder function for GET /sapi/v1/account/info. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/account :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "account/info", signed=True, data=params, version=1) def margin_v1_post_portfolio_repay_futures_switch(self, **params): """ Placeholder function for POST /sapi/v1/portfolio/repay-futures-switch. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/portfolio-margin-pro/account/Change-Auto-repay-futures-Status :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "portfolio/repay-futures-switch", signed=True, data=params, version=1) def margin_v1_post_loan_vip_borrow(self, **params): """ Placeholder function for POST /sapi/v1/loan/vip/borrow. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "loan/vip/borrow", signed=True, data=params, version=1) def margin_v2_get_loan_flexible_ltv_adjustment_history(self, **params): """ Placeholder function for GET /sapi/v2/loan/flexible/ltv/adjustment/history. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/crypto_loan/flexible-rate/user-information :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/flexible/ltv/adjustment/history", signed=True, data=params, version=2) def options_v1_delete_all_open_orders_by_underlying(self, **params): """ Placeholder function for DELETE /eapi/v1/allOpenOrdersByUnderlying. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/option/trade/Cancel-All-Option-Orders-By-Underlying :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_options_api("delete", "allOpenOrdersByUnderlying", signed=True, data=params) def margin_v1_get_broker_sub_account_futures_summary(self, **params): """ Placeholder function for GET /sapi/v1/broker/subAccount/futuresSummary. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/subAccount/futuresSummary", signed=True, data=params, version=1) def margin_v1_get_broker_sub_account_spot_summary(self, **params): """ Placeholder function for GET /sapi/v1/broker/subAccount/spotSummary. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/asset/Query-Sub-Account-Spot-Asset-Info :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/subAccount/spotSummary", signed=True, data=params, version=1) def margin_v1_post_sub_account_blvt_enable(self, **params): """ Placeholder function for POST /sapi/v1/sub-account/blvt/enable. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "sub-account/blvt/enable", signed=True, data=params, version=1) def margin_v1_get_algo_spot_historical_orders(self, **params): """ Placeholder function for GET /sapi/v1/algo/spot/historicalOrders. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/algo/spot-algo/Query-Historical-Algo-Orders :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "algo/spot/historicalOrders", signed=True, data=params, version=1) def margin_v1_get_loan_vip_repay_history(self, **params): """ Placeholder function for GET /sapi/v1/loan/vip/repay/history. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/vip_loan/user-information/Get-VIP-Loan-Repayment-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/vip/repay/history", signed=True, data=params, version=1) def margin_v1_get_loan_borrow_history(self, **params): """ Placeholder function for GET /sapi/v1/loan/borrow/history. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/crypto_loan/stable-rate/user-information :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/borrow/history", signed=True, data=params, version=1) def margin_v1_post_lending_auto_invest_redeem(self, **params): """ Placeholder function for POST /sapi/v1/lending/auto-invest/redeem. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "lending/auto-invest/redeem", signed=True, data=params, version=1) def futures_coin_v1_get_income_asyn(self, **params): """ Placeholder function for GET /dapi/v1/income/asyn. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/coin-margined-futures/account/rest-api/Get-Download-Id-For-Futures-Transaction-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_coin_api("get", "income/asyn", signed=True, data=params, version=1) def margin_v1_post_managed_subaccount_deposit(self, **params): """ Placeholder function for POST /sapi/v1/managed-subaccount/deposit. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/managed-sub-account :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "managed-subaccount/deposit", signed=True, data=params, version=1) def margin_v1_post_lending_daily_purchase(self, **params): """ Placeholder function for POST /sapi/v1/lending/daily/purchase. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "lending/daily/purchase", signed=True, data=params, version=1) def futures_v1_get_trade_asyn_id(self, **params): """ Placeholder function for GET /fapi/v1/trade/asyn/id. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Get-Futures-Trade-Download-Link-by-Id :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "trade/asyn/id", signed=True, data=params, version=1) def margin_v1_delete_sub_account_sub_account_api_ip_restriction_ip_list(self, **params): """ Placeholder function for DELETE /sapi/v1/sub-account/subAccountApi/ipRestriction/ipList. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/api-management/Delete-IP-List-For-a-Sub-account-API-Key :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("delete", "sub-account/subAccountApi/ipRestriction/ipList", signed=True, data=params, version=1) def margin_v1_get_copy_trading_futures_user_status(self, **params): """ Placeholder function for GET /sapi/v1/copyTrading/futures/userStatus. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/copy_trading/future-copy-trading :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "copyTrading/futures/userStatus", signed=True, data=params, version=1) def options_v1_get_margin_account(self, **params): """ Placeholder function for GET /eapi/v1/marginAccount. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/option/market-maker-endpoints :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_options_api("get", "marginAccount", signed=True, data=params) def options_get_market_maker_protection_config(self, **params): """ Get config for MMP. https://developers.binance.com/docs/derivatives/option/market-maker-endpoints/Get-Market-Maker-Protection-Config :param underlying: required :type underlying: str :param recvWindow: optional :type recvWindow: int """ return self._request_options_api("get", "mmp", signed=True, data=params) def options_post_market_maker_protection_config(self, **params): """ Set config for MMP. https://developers.binance.com/docs/derivatives/option/market-maker-endpoints/Set-Market-Maker-Protection-Config :param underlying: required :type underlying: str :param windowTimeInMilliseconds: required :type windowTimeInMilliseconds: int :param frozenTimeInMilliseconds: required :type frozenTimeInMilliseconds: int :param qtyLimit: required :type qtyLimit: decimal :param deltaLimit: required :type deltaLimit: decimal :param recvWindow: optional :type recvWindow: int """ return self._request_options_api("post", "mmpSet", signed=True, data=params) def options_reset_market_maker_protection_config(self, **params): """ Reset MMP, start MMP order again. https://developers.binance.com/docs/derivatives/option/market-maker-endpoints/Reset-Market-Maker-Protection-Config :param underlying: required :type underlying: str :param recvWindow: optional :type recvWindow: int """ return self._request_options_api("post", "mmpReset", signed=True, data=params) def margin_v1_post_localentity_withdraw_apply(self, **params): """ Placeholder function for POST /sapi/v1/localentity/withdraw/apply. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/travel-rule/withdraw :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "localentity/withdraw/apply", signed=True, data=params, version=1) def margin_v1_get_asset_wallet_balance(self, **params): """ Placeholder function for GET /sapi/v1/asset/wallet/balance. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/asset/query-user-wallet-balance :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "asset/wallet/balance", signed=True, data=params, version=1) def margin_v1_post_broker_transfer(self, **params): """ Placeholder function for POST /sapi/v1/broker/transfer. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/asset :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/transfer", signed=True, data=params, version=1) def margin_v1_post_lending_customized_fixed_purchase(self, **params): """ Placeholder function for POST /sapi/v1/lending/customizedFixed/purchase. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "lending/customizedFixed/purchase", signed=True, data=params, version=1) def margin_v1_post_algo_futures_new_order_twap(self, **params): """ Placeholder function for POST /sapi/v1/algo/futures/newOrderTwap. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/algo/future-algo/Time-Weighted-Average-Price-New-Order :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "algo/futures/newOrderTwap", signed=True, data=params, version=1) def margin_v2_post_eth_staking_eth_stake(self, **params): """ Placeholder function for POST /sapi/v2/eth-staking/eth/stake. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/eth-staking/staking :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "eth-staking/eth/stake", signed=True, data=params, version=2) def margin_v1_post_loan_flexible_repay_history(self, **params): """ Placeholder function for POST /sapi/v1/loan/flexible/repay/history. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "loan/flexible/repay/history", signed=True, data=params, version=1) def margin_v1_get_lending_auto_invest_index_info(self, **params): """ Placeholder function for GET /sapi/v1/lending/auto-invest/index/info. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "lending/auto-invest/index/info", signed=True, data=params, version=1) def margin_v1_get_sol_staking_sol_history_redemption_history(self, **params): """ Placeholder function for GET /sapi/v1/sol-staking/sol/history/redemptionHistory. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/sol-staking/history/Get-SOL-redemption-history :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "sol-staking/sol/history/redemptionHistory", signed=True, data=params, version=1) def margin_v1_get_broker_rebate_futures_recent_record(self, **params): """ Placeholder function for GET /sapi/v1/broker/rebate/futures/recentRecord. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/fee/Query-Futures-Commission-Rebate-Record :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/rebate/futures/recentRecord", signed=True, data=params, version=1) def margin_v3_get_broker_sub_account_futures_summary(self, **params): """ Placeholder function for GET /sapi/v3/broker/subAccount/futuresSummary. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/asset/Query-Sub-Account-Futures-Asset-Info :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/subAccount/futuresSummary", signed=True, data=params, version=3) def margin_v1_get_lending_auto_invest_target_asset_roi_list(self, **params): """ Placeholder function for GET /sapi/v1/lending/auto-invest/target-asset/roi/list. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "lending/auto-invest/target-asset/roi/list", signed=True, data=params, version=1) def margin_v1_get_broker_universal_transfer(self, **params): """ Placeholder function for GET /sapi/v1/broker/universalTransfer. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/asset/Query-Universal-Transfer-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/universalTransfer", signed=True, data=params, version=1) def futures_v1_put_batch_orders(self, **params): """ Placeholder function for PUT /fapi/v1/batchOrders. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Modify-Multiple-Orders :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("put", "batchOrders", signed=True, data=params, version=1) def options_v1_post_countdown_cancel_all_heart_beat(self, **params): """ Placeholder function for POST /eapi/v1/countdownCancelAllHeartBeat. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/option/market-maker-endpoints/Auto-Cancel-All-Open-Orders-Heartbeat :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_options_api("post", "countdownCancelAllHeartBeat", signed=True, data=params) def margin_v1_get_loan_collateral_data(self, **params): """ Placeholder function for GET /sapi/v1/loan/collateral/data. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/collateral/data", signed=True, data=params, version=1) def margin_v1_get_loan_repay_history(self, **params): """ Placeholder function for GET /sapi/v1/loan/repay/history. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/crypto_loan/stable-rate/user-information/Get-Loan-Repayment-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/repay/history", signed=True, data=params, version=1) def margin_v1_post_convert_limit_place_order(self, **params): """ Placeholder function for POST /sapi/v1/convert/limit/placeOrder. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/convert/trade/Place-Order :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "convert/limit/placeOrder", signed=True, data=params, version=1) def futures_v1_get_convert_exchange_info(self, **params): """ Placeholder function for GET /fapi/v1/convert/exchangeInfo. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/convert :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "convert/exchangeInfo", signed=False, data=params, version=1) def v3_get_all_order_list(self, **params): """ Placeholder function for GET /api/v3/allOrderList. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_api("get", "allOrderList", signed=True, data=params, version="v3") def margin_v1_delete_broker_sub_account_api_ip_restriction_ip_list(self, **params): """ Placeholder function for DELETE /sapi/v1/broker/subAccountApi/ipRestriction/ipList. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/account/Delete-IPRestriction-for-Sub-Account-Api-Key :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("delete", "broker/subAccountApi/ipRestriction/ipList", signed=True, data=params, version=1) def margin_v1_post_sub_account_virtual_sub_account(self, **params): """ Placeholder function for POST /sapi/v1/sub-account/virtualSubAccount. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/account-management :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "sub-account/virtualSubAccount", signed=True, data=params, version=1) def margin_v1_put_localentity_deposit_provide_info(self, **params): """ Placeholder function for PUT /sapi/v1/localentity/deposit/provide-info. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/travel-rule/deposit-provide-info :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("put", "localentity/deposit/provide-info", signed=True, data=params, version=1) def margin_v1_post_portfolio_mint(self, **params): """ Placeholder function for POST /sapi/v1/portfolio/mint. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/portfolio-margin-pro/account/Mint-BFUSD-Portfolio-Margin :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "portfolio/mint", signed=True, data=params, version=1) def futures_v1_get_order_amendment(self, **params): """ Placeholder function for GET /fapi/v1/orderAmendment. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Get-Order-Modify-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "orderAmendment", signed=True, data=params, version=1) def margin_v1_post_sol_staking_sol_claim(self, **params): """ Placeholder function for POST /sapi/v1/sol-staking/sol/claim. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/sol-staking/staking/Claim-Boost-rewards :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "sol-staking/sol/claim", signed=True, data=params, version=1) def margin_v1_post_lending_daily_redeem(self, **params): """ Placeholder function for POST /sapi/v1/lending/daily/redeem. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "lending/daily/redeem", signed=True, data=params, version=1) def margin_v1_post_mining_hash_transfer_config(self, **params): """ Placeholder function for POST /sapi/v1/mining/hash-transfer/config. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/mining/rest-api/Hashrate-Resale-Request :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "mining/hash-transfer/config", signed=True, data=params, version=1) def margin_v1_get_lending_auto_invest_rebalance_history(self, **params): """ Placeholder function for GET /sapi/v1/lending/auto-invest/rebalance/history. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "lending/auto-invest/rebalance/history", signed=True, data=params, version=1) def margin_v1_get_loan_repay_collateral_rate(self, **params): """ Placeholder function for GET /sapi/v1/loan/repay/collateral/rate. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/repay/collateral/rate", signed=True, data=params, version=1) def futures_v1_get_income_asyn(self, **params): """ Placeholder function for GET /fapi/v1/income/asyn. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Get-Download-Id-For-Futures-Transaction-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "income/asyn", signed=True, data=params, version=1) def margin_v1_get_mining_payment_uid(self, **params): """ Placeholder function for GET /sapi/v1/mining/payment/uid. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/mining/rest-api/Mining-Account-Earning :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "mining/payment/uid", signed=True, data=params, version=1) def margin_v2_get_loan_flexible_borrow_history(self, **params): """ Placeholder function for GET /sapi/v2/loan/flexible/borrow/history. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/crypto_loan/flexible-rate/user-information/Get-Flexible-Loan-Borrow-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/flexible/borrow/history", signed=True, data=params, version=2) def margin_v1_get_capital_contract_convertible_coins(self, **params): """ Placeholder function for GET /sapi/v1/capital/contract/convertible-coins. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "capital/contract/convertible-coins", signed=True, data=params, version=1) def margin_v1_post_broker_sub_account_api_permission_vanilla_options(self, **params): """ Placeholder function for POST /sapi/v1/broker/subAccountApi/permission/vanillaOptions. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/subAccountApi/permission/vanillaOptions", signed=True, data=params, version=1) def margin_v1_get_lending_auto_invest_redeem_history(self, **params): """ Placeholder function for GET /sapi/v1/lending/auto-invest/redeem/history. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/travel-rule/withdraw-history :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "lending/auto-invest/redeem/history", signed=True, data=params, version=1) def margin_v2_get_localentity_withdraw_history(self, **params): """ Placeholder function for GET /sapi/v2/localentity/withdraw/history. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/travel-rule/withdraw-history-v2 :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "localentity/withdraw/history", signed=True, data=params, version=2) def margin_v1_get_eth_staking_eth_history_redemption_history(self, **params): """ Placeholder function for GET /sapi/v1/eth-staking/eth/history/redemptionHistory. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/eth-staking/history/Get-ETH-redemption-history :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "eth-staking/eth/history/redemptionHistory", signed=True, data=params, version=1) def futures_v1_get_fee_burn(self, **params): """ Placeholder function for GET /fapi/v1/feeBurn. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Get-BNB-Burn-Status :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "feeBurn", signed=True, data=params, version=1) def margin_v1_get_lending_auto_invest_index_user_summary(self, **params): """ Placeholder function for GET /sapi/v1/lending/auto-invest/index/user-summary. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "lending/auto-invest/index/user-summary", signed=True, data=params, version=1) def margin_v2_post_loan_flexible_borrow(self, **params): """ Placeholder function for POST /sapi/v2/loan/flexible/borrow. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/crypto_loan/flexible-rate/trade :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "loan/flexible/borrow", signed=True, data=params, version=2) def margin_v1_post_loan_vip_repay(self, **params): """ Placeholder function for POST /sapi/v1/loan/vip/repay. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/vip_loan/trade/VIP-Loan-Repay :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "loan/vip/repay", signed=True, data=params, version=1) def futures_coin_v1_get_commission_rate(self, **params): """ Placeholder function for GET /dapi/v1/commissionRate. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/coin-margined-futures/account/rest-api/User-Commission-Rate :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_coin_api("get", "commissionRate", signed=True, data=params, version=1) def margin_v1_get_convert_asset_info(self, **params): """ Placeholder function for GET /sapi/v1/convert/assetInfo. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/convert/market-data/Query-order-quantity-precision-per-asset :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "convert/assetInfo", signed=True, data=params, version=1) def v3_post_sor_order_test(self, **params): """ Placeholder function for POST /api/v3/sor/order/test. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_api("post", "sor/order/test", signed=True, data=params, version="v3") def margin_v1_post_broker_universal_transfer(self, **params): """ Placeholder function for POST /sapi/v1/broker/universalTransfer. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/asset/Universal-Transfer :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/universalTransfer", signed=True, data=params, version=1) def margin_v1_post_account_disable_fast_withdraw_switch(self, **params): """ Placeholder function for POST /sapi/v1/account/disableFastWithdrawSwitch. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/account/disable-fast-withdraw-switch :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "account/disableFastWithdrawSwitch", signed=True, data=params, version=1) def futures_v1_get_asset_index(self, **params): """ Placeholder function for GET /fapi/v1/assetIndex. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Multi-Assets-Mode-Asset-Index :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "assetIndex", signed=False, data=params, version=1) def margin_v1_get_account_api_restrictions_ip_restriction(self, **params): """ Placeholder function for GET /sapi/v1/account/apiRestrictions/ipRestriction. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "account/apiRestrictions/ipRestriction", signed=True, data=params, version=1) def margin_v1_post_broker_sub_account_bnb_burn_spot(self, **params): """ Placeholder function for POST /sapi/v1/broker/subAccount/bnbBurn/spot. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/account/Enable-Or-Disable-BNB-Burn-for-Sub-Account-Spot-Margin :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/subAccount/bnbBurn/spot", signed=True, data=params, version=1) def futures_coin_v1_put_order(self, **params): """ Placeholder function for PUT /dapi/v1/order. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Modify-Order :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_coin_api("put", "order", signed=True, data=params, version=1) def futures_coin_v1_put_batch_orders(self, **params): """ Placeholder function for PUT /dapi/v1/batchOrders. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Modify-Multiple-Orders :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_coin_api("put", "batchOrders", signed=True, data=params, version=1) def margin_v1_get_margin_delist_schedule(self, **params): """ Placeholder function for GET /sapi/v1/margin/delist-schedule. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "margin/delist-schedule", signed=True, data=params, version=1) def margin_v1_post_broker_sub_account_api_permission_universal_transfer(self, **params): """ Placeholder function for POST /sapi/v1/broker/subAccountApi/permission/universalTransfer. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/account/Enable-Universal-Transfer-Permission-For-SubAccount-Api-Key :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/subAccountApi/permission/universalTransfer", signed=True, data=params, version=1) def margin_v1_get_loan_ltv_adjustment_history(self, **params): """ Placeholder function for GET /sapi/v1/loan/ltv/adjustment/history. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/crypto_loan/stable-rate/user-information/Get-Loan-LTV-Adjustment-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/ltv/adjustment/history", signed=True, data=params, version=1) def margin_v1_get_localentity_withdraw_history(self, **params): """ Placeholder function for GET /sapi/v1/localentity/withdraw/history. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "localentity/withdraw/history", signed=True, data=params, version=1) def margin_v2_post_sub_account_sub_account_api_ip_restriction(self, **params): """ Placeholder function for POST /sapi/v2/sub-account/subAccountApi/ipRestriction. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/api-management/Add-IP-Restriction-for-Sub-Account-API-key :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "sub-account/subAccountApi/ipRestriction", signed=True, data=params, version=2) def futures_v1_get_rate_limit_order(self, **params): """ Placeholder function for GET /fapi/v1/rateLimit/order. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Query-Rate-Limit :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "rateLimit/order", signed=True, data=params, version=1) def margin_v1_get_broker_sub_account_api_commission_futures(self, **params): """ Placeholder function for GET /sapi/v1/broker/subAccountApi/commission/futures. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/fee/Query-Sub-Account-UM-Futures-Commission :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/subAccountApi/commission/futures", signed=True, data=params, version=1) def margin_v1_get_sol_staking_sol_history_staking_history(self, **params): """ Placeholder function for GET /sapi/v1/sol-staking/sol/history/stakingHistory. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/sol-staking/history :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "sol-staking/sol/history/stakingHistory", signed=True, data=params, version=1) def futures_v1_get_open_order(self, **params): """ Placeholder function for GET /fapi/v1/openOrder. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Query-Current-Open-Order :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "openOrder", signed=True, data=params, version=1) def margin_v1_delete_algo_spot_order(self, **params): """ Placeholder function for DELETE /sapi/v1/algo/spot/order. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/algo/spot-algo/Cancel-Algo-Order :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("delete", "algo/spot/order", signed=True, data=params, version=1) def margin_v1_delete_account_api_restrictions_ip_restriction_ip_list(self, **params): """ Placeholder function for DELETE /sapi/v1/account/apiRestrictions/ipRestriction/ipList. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("delete", "account/apiRestrictions/ipRestriction/ipList", signed=True, data=params, version=1) def margin_v1_post_capital_contract_convertible_coins(self, **params): """ Placeholder function for POST /sapi/v1/capital/contract/convertible-coins. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "capital/contract/convertible-coins", signed=True, data=params, version=1) def margin_v1_get_managed_subaccount_margin_asset(self, **params): """ Placeholder function for GET /sapi/v1/managed-subaccount/marginAsset. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/managed-sub-account/Query-Managed-Sub-account-Margin-Asset-Details :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "managed-subaccount/marginAsset", signed=True, data=params, version=1) def v3_delete_order_list(self, **params): """ Placeholder function for DELETE /api/v3/orderList. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_api("delete", "orderList", signed=True, data=params, version="v3") def margin_v1_post_sub_account_sub_account_api_ip_restriction_ip_list(self, **params): """ Placeholder function for POST /sapi/v1/sub-account/subAccountApi/ipRestriction/ipList. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "sub-account/subAccountApi/ipRestriction/ipList", signed=True, data=params, version=1) def margin_v1_post_broker_sub_account_api_commission(self, **params): """ Placeholder function for POST /sapi/v1/broker/subAccountApi/commission. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/fee :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/subAccountApi/commission", signed=True, data=params, version=1) def futures_v1_post_fee_burn(self, **params): """ Placeholder function for POST /fapi/v1/feeBurn. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Toggle-BNB-Burn-On-Futures-Trade :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("post", "feeBurn", signed=True, data=params, version=1) def margin_v1_get_broker_sub_account_margin_summary(self, **params): """ Placeholder function for GET /sapi/v1/broker/subAccount/marginSummary. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/asset/Query-Sub-Account-Margin-Asset-Info :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/subAccount/marginSummary", signed=True, data=params, version=1) def margin_v1_get_lending_auto_invest_plan_list(self, **params): """ Placeholder function for GET /sapi/v1/lending/auto-invest/plan/list. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "lending/auto-invest/plan/list", signed=True, data=params, version=1) def margin_v1_get_loan_vip_loanable_data(self, **params): """ Placeholder function for GET /sapi/v1/loan/vip/loanable/data. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/vip_loan/market-data/Get-Loanable-Assets-Data :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/vip/loanable/data", signed=True, data=params, version=1) def margin_v2_get_loan_flexible_collateral_data(self, **params): """ Placeholder function for GET /sapi/v2/loan/flexible/collateral/data. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/crypto_loan/flexible-rate/market-data :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/flexible/collateral/data", signed=True, data=params, version=2) def margin_v1_delete_broker_sub_account_api(self, **params): """ Placeholder function for DELETE /sapi/v1/broker/subAccountApi. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/account/Delete-Sub-Account-Api-Key :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("delete", "broker/subAccountApi", signed=True, data=params, version=1) def margin_v1_get_sol_staking_sol_history_bnsol_rewards_history(self, **params): """ Placeholder function for GET /sapi/v1/sol-staking/sol/history/bnsolRewardsHistory. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/sol-staking/history/Get-BNSOL-rewards-history :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "sol-staking/sol/history/bnsolRewardsHistory", signed=True, data=params, version=1) def margin_v1_get_convert_limit_query_open_orders(self, **params): """ Placeholder function for GET /sapi/v1/convert/limit/queryOpenOrders. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/convert/trade/Query-Order :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "convert/limit/queryOpenOrders", signed=True, data=params, version=1) def v3_get_account_commission(self, **params): """ Placeholder function for GET /api/v3/account/commission. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_api("get", "account/commission", signed=True, data=params, version="v3") def margin_v1_get_managed_subaccount_query_trans_log(self, **params): """ Placeholder function for GET /sapi/v1/managed-subaccount/query-trans-log. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/managed-sub-account/Query-Managed-Sub-Account-Transfer-Log-Trading-Team-Sub :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "managed-subaccount/query-trans-log", signed=True, data=params, version=1) def margin_v2_post_broker_sub_account_api_ip_restriction(self, **params): """ Placeholder function for POST /sapi/v2/broker/subAccountApi/ipRestriction. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/account/Update-IP-Restriction-for-Sub-Account-API-key-For-Master-Account :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/subAccountApi/ipRestriction", signed=True, data=params, version=2) def margin_v1_get_lending_auto_invest_all_asset(self, **params): """ Placeholder function for GET /sapi/v1/lending/auto-invest/all/asset. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "lending/auto-invest/all/asset", signed=True, data=params, version=1) def futures_v1_post_convert_accept_quote(self, **params): """ Placeholder function for POST /fapi/v1/convert/acceptQuote. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/convert/Accept-Quote :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("post", "convert/acceptQuote", signed=True, data=params, version=1) def margin_v1_get_spot_delist_schedule(self, **params): """ Placeholder function for GET /sapi/v1/spot/delist-schedule. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/asset/spot-delist-schedule :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "spot/delist-schedule", signed=True, data=params, version=1) def margin_v1_post_account_api_restrictions_ip_restriction(self, **params): """ Placeholder function for POST /sapi/v1/account/apiRestrictions/ipRestriction. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "account/apiRestrictions/ipRestriction", signed=True, data=params, version=1) def margin_v1_get_dci_product_accounts(self, **params): """ Placeholder function for GET /sapi/v1/dci/product/accounts. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/dual_investment/trade/Check-Dual-Investment-accounts :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "dci/product/accounts", signed=True, data=params, version=1) def margin_v1_get_sub_account_sub_account_api_ip_restriction(self, **params): """ Placeholder function for GET /sapi/v1/sub-account/subAccountApi/ipRestriction. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/api-management :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "sub-account/subAccountApi/ipRestriction", signed=True, data=params, version=1) def margin_v1_get_sub_account_transaction_statistics(self, **params): """ Placeholder function for GET /sapi/v1/sub-account/transaction-statistics. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/account-management/Query-Sub-account-Transaction-Statistics :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "sub-account/transaction-statistics", signed=True, data=params, version=1) def margin_v1_get_managed_subaccount_deposit_address(self, **params): """ Placeholder function for GET /sapi/v1/managed-subaccount/deposit/address. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/managed-sub-account/Get-Managed-Sub-account-Deposit-Address :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "managed-subaccount/deposit/address", signed=True, data=params, version=1) def margin_v2_get_portfolio_account(self, **params): """ Placeholder function for GET /sapi/v2/portfolio/account. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/portfolio-margin-pro/account/Get-Classic-Portfolio-Margin-Account-Info-V2 :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "portfolio/account", signed=True, data=params, version=2) def margin_v1_get_simple_earn_locked_history_redemption_record(self, **params): """ Placeholder function for GET /sapi/v1/simple-earn/locked/history/redemptionRecord. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/simple_earn/history/Get-Locked-Redemption-Record :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "simple-earn/locked/history/redemptionRecord", signed=True, data=params, version=1) def futures_v1_get_order_asyn_id(self, **params): """ Placeholder function for GET /fapi/v1/order/asyn/id. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Get-Futures-Order-History-Download-Link-by-Id :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "order/asyn/id", signed=True, data=params, version=1) def margin_v1_post_managed_subaccount_withdraw(self, **params): """ Placeholder function for POST /sapi/v1/managed-subaccount/withdraw. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/managed-sub-account/Withdrawl-Assets-From-The-Managed-Sub-account :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "managed-subaccount/withdraw", signed=True, data=params, version=1) def margin_v1_get_localentity_deposit_history(self, **params): """ Placeholder function for GET /sapi/v1/localentity/deposit/history. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/wallet/travel-rule/deposit-history :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "localentity/deposit/history", signed=True, data=params, version=1) def margin_v1_post_eth_staking_wbeth_wrap(self, **params): """ Placeholder function for POST /sapi/v1/eth-staking/wbeth/wrap. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/eth-staking/staking/Wrap-BETH :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "eth-staking/wbeth/wrap", signed=True, data=params, version=1) def margin_v1_post_simple_earn_locked_set_redeem_option(self, **params): """ Placeholder function for POST /sapi/v1/simple-earn/locked/setRedeemOption. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/simple_earn/earn/Set-Locked-Redeem-Option :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "simple-earn/locked/setRedeemOption", signed=True, data=params, version=1) def margin_v1_post_broker_sub_account_api_ip_restriction_ip_list(self, **params): """ Placeholder function for POST /sapi/v1/broker/subAccountApi/ipRestriction/ipList. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/subAccountApi/ipRestriction/ipList", signed=True, data=params, version=1) def margin_v1_post_broker_sub_account_api_commission_futures(self, **params): """ Placeholder function for POST /sapi/v1/broker/subAccountApi/commission/futures. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/fee/Change-Sub-Account-UM-Futures-Commission :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "broker/subAccountApi/commission/futures", signed=True, data=params, version=1) def margin_v1_get_lending_auto_invest_history_list(self, **params): """ Placeholder function for GET /sapi/v1/lending/auto-invest/history/list. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "lending/auto-invest/history/list", signed=True, data=params, version=1) def margin_v1_post_loan_customize_margin_call(self, **params): """ Placeholder function for POST /sapi/v1/loan/customize/margin_call. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "loan/customize/margin_call", signed=True, data=params, version=1) def margin_v1_get_broker_sub_account_bnb_burn_status(self, **params): """ Placeholder function for GET /sapi/v1/broker/subAccount/bnbBurn/status. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/account/Get-BNB-Burn-Status-for-Sub-Account :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/subAccount/bnbBurn/status", signed=True, data=params, version=1) def margin_v1_get_managed_subaccount_account_snapshot(self, **params): """ Placeholder function for GET /sapi/v1/managed-subaccount/accountSnapshot. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/managed-sub-account/Query-Managed-Sub-account-Snapshot :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "managed-subaccount/accountSnapshot", signed=True, data=params, version=1) def margin_v1_post_asset_convert_transfer(self, **params): """ Placeholder function for POST /sapi/v1/asset/convert-transfer. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "asset/convert-transfer", signed=True, data=params, version=1) def options_v1_get_income_asyn(self, **params): """ Placeholder function for GET /eapi/v1/income/asyn. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/option/account/Get-Download-Id-For-Option-Transaction-History :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_options_api("get", "income/asyn", signed=True, data=params) def margin_v1_get_broker_sub_account_api_commission_coin_futures(self, **params): """ Placeholder function for GET /sapi/v1/broker/subAccountApi/commission/coinFutures. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/fee/Query-Sub-Account-CM-Futures-Commission :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/subAccountApi/commission/coinFutures", signed=True, data=params, version=1) def margin_v2_get_broker_sub_account_futures_summary(self, **params): """ Placeholder function for GET /sapi/v2/broker/subAccount/futuresSummary. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/subAccount/futuresSummary", signed=True, data=params, version=2) def margin_v1_get_loan_ongoing_orders(self, **params): """ Placeholder function for GET /sapi/v1/loan/ongoing/orders. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/ongoing/orders", signed=True, data=params, version=1) def margin_v2_get_loan_flexible_ongoing_orders(self, **params): """ Placeholder function for GET /sapi/v2/loan/flexible/ongoing/orders. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/crypto_loan/flexible-rate/user-information/Get-Flexible-Loan-Ongoing-Orders :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "loan/flexible/ongoing/orders", signed=True, data=params, version=2) def margin_v1_post_algo_futures_new_order_vp(self, **params): """ Placeholder function for POST /sapi/v1/algo/futures/newOrderVp. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/algo/future-algo :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "algo/futures/newOrderVp", signed=True, data=params, version=1) def futures_v1_post_convert_get_quote(self, **params): """ Placeholder function for POST /fapi/v1/convert/getQuote. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/convert/Send-quote-request :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("post", "convert/getQuote", signed=True, data=params, version=1) def margin_v1_get_algo_spot_sub_orders(self, **params): """ Placeholder function for GET /sapi/v1/algo/spot/subOrders. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/algo/spot-algo/Query-Sub-Orders :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "algo/spot/subOrders", signed=True, data=params, version=1) def margin_v1_post_portfolio_redeem(self, **params): """ Placeholder function for POST /sapi/v1/portfolio/redeem. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/portfolio-margin-pro/account/Redeem-BFUSD-Portfolio-Margin :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "portfolio/redeem", signed=True, data=params, version=1) def margin_v1_post_lending_auto_invest_plan_add(self, **params): """ Placeholder function for POST /sapi/v1/lending/auto-invest/plan/add. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "lending/auto-invest/plan/add", signed=True, data=params, version=1) def v3_get_order_list(self, **params): """ Placeholder function for GET /api/v3/orderList. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_api("get", "orderList", signed=True, data=params, version="v3") def margin_v1_get_lending_auto_invest_source_asset_list(self, **params): """ Placeholder function for GET /sapi/v1/lending/auto-invest/source-asset/list. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "lending/auto-invest/source-asset/list", signed=True, data=params, version=1) def margin_v1_get_margin_all_order_list(self, **params): """ Placeholder function for GET /sapi/v1/margin/allOrderList. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/margin_trading/trade/Query-Margin-Account-All-OCO :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "margin/allOrderList", signed=True, data=params, version=1) def margin_v1_post_eth_staking_eth_redeem(self, **params): """ Placeholder function for POST /sapi/v1/eth-staking/eth/redeem. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/eth-staking/staking/Redeem-ETH :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "eth-staking/eth/redeem", signed=True, data=params, version=1) def margin_v1_get_broker_rebate_historical_record(self, **params): """ Placeholder function for GET /sapi/v1/broker/rebate/historicalRecord. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/rebate/historicalRecord", signed=True, data=params, version=1) def margin_v1_get_simple_earn_locked_history_subscription_record(self, **params): """ Placeholder function for GET /sapi/v1/simple-earn/locked/history/subscriptionRecord. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/simple_earn/history/Get-Locked-Subscription-Record :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "simple-earn/locked/history/subscriptionRecord", signed=True, data=params, version=1) def margin_v1_get_managed_subaccount_asset(self, **params): """ Placeholder function for GET /sapi/v1/managed-subaccount/asset. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/managed-sub-account/Query-Managed-Sub-account-Asset-Details :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "managed-subaccount/asset", signed=True, data=params, version=1) def margin_v1_get_sol_staking_sol_quota(self, **params): """ Placeholder function for GET /sapi/v1/sol-staking/sol/quota. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/sol-staking/account/Get-SOL-staking-quota-details :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "sol-staking/sol/quota", signed=True, data=params, version=1) def margin_v1_post_loan_vip_renew(self, **params): """ Placeholder function for POST /sapi/v1/loan/vip/renew. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "loan/vip/renew", signed=True, data=params, version=1) def margin_v1_get_managed_subaccount_query_trans_log_for_trade_parent(self, **params): """ Placeholder function for GET /sapi/v1/managed-subaccount/queryTransLogForTradeParent. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/sub_account/managed-sub-account/Query-Managed-Sub-Account-Transfer-Log-Trading-Team-Master :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "managed-subaccount/queryTransLogForTradeParent", signed=True, data=params, version=1) def margin_v1_post_sub_account_sub_account_api_ip_restriction(self, **params): """ Placeholder function for POST /sapi/v1/sub-account/subAccountApi/ipRestriction. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("post", "sub-account/subAccountApi/ipRestriction", signed=True, data=params, version=1) def margin_v1_get_simple_earn_flexible_history_redemption_record(self, **params): """ Placeholder function for GET /sapi/v1/simple-earn/flexible/history/redemptionRecord. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/simple_earn/history/Get-Flexible-Redemption-Record :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "simple-earn/flexible/history/redemptionRecord", signed=True, data=params, version=1) def margin_v1_get_broker_sub_account_api(self, **params): """ Placeholder function for GET /sapi/v1/broker/subAccountApi. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/binance_link/exchange-link/account/Query-Sub-Account-Api-Key :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "broker/subAccountApi", signed=True, data=params, version=1) def options_v1_get_exercise_history(self, **params): """ Placeholder function for GET /eapi/v1/exerciseHistory. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/option/market-data/Historical-Exercise-Records :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_options_api("get", "exerciseHistory", signed=False, data=params) def options_open_interest(self, **params): """Get present open interest specific underlying asset on specific expiration date. https://developers.binance.com/docs/derivatives/option/market-data/Open-Interest :param params: parameters required by the endpoint :type params: dict :param underlyingAsset: required :type underlyingAsset: str :param expiration: required (e.g '221225') :type expiration: str """ return self._request_options_api("get", "openInterest", data=params) def margin_v1_get_convert_exchange_info(self, **params): """ Placeholder function for GET /sapi/v1/convert/exchangeInfo. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/convert/market-data :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "convert/exchangeInfo", signed=False, data=params, version=1) def futures_v1_delete_batch_order(self, **params): """ Placeholder function for DELETE /fapi/v1/batchOrder. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("delete", "batchOrder", signed=True, data=params, version=1) def margin_v1_get_eth_staking_eth_history_wbeth_rewards_history(self, **params): """ Placeholder function for GET /sapi/v1/eth-staking/eth/history/wbethRewardsHistory. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/staking/eth-staking/history/Get-WBETH-rewards-history :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "eth-staking/eth/history/wbethRewardsHistory", signed=True, data=params, version=1) def margin_v1_get_mining_pub_algo_list(self, **params): """ Placeholder function for GET /sapi/v1/mining/pub/algoList. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/mining/rest-api :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "mining/pub/algoList", signed=True, data=params, version=1) def options_v1_get_block_trades(self, **params): """ Placeholder function for GET /eapi/v1/blockTrades. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/option/market-data/Recent-Block-Trade-List :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_options_api("get", "blockTrades", signed=False, data=params) def margin_v1_get_copy_trading_futures_lead_symbol(self, **params): """ Placeholder function for GET /sapi/v1/copyTrading/futures/leadSymbol. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/copy_trading/future-copy-trading/Get-Futures-Lead-Trading-Symbol-Whitelist :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "copyTrading/futures/leadSymbol", signed=True, data=params, version=1) def margin_v1_get_mining_worker_list(self, **params): """ Placeholder function for GET /sapi/v1/mining/worker/list. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/mining/rest-api/Request-for-Miner-List :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "mining/worker/list", signed=True, data=params, version=1) def margin_v1_get_dci_product_list(self, **params): """ Placeholder function for GET /sapi/v1/dci/product/list. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/dual_investment/market-data :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_margin_api("get", "dci/product/list", signed=True, data=params, version=1) def futures_v1_get_convert_order_status(self, **params): """ Placeholder function for GET /fapi/v1/convert/orderStatus. Note: This function was auto-generated. Any issue please open an issue on GitHub. https://developers.binance.com/docs/derivatives/usds-margined-futures/convert/Order-Status :param params: parameters required by the endpoint :type params: dict :returns: API response """ return self._request_futures_api("get", "convert/orderStatus", signed=True, data=params, version=1) ================================================ FILE: binance/enums.py ================================================ from enum import Enum SYMBOL_TYPE_SPOT = "SPOT" ORDER_STATUS_NEW = "NEW" ORDER_STATUS_PARTIALLY_FILLED = "PARTIALLY_FILLED" ORDER_STATUS_FILLED = "FILLED" ORDER_STATUS_CANCELED = "CANCELED" ORDER_STATUS_PENDING_CANCEL = "PENDING_CANCEL" ORDER_STATUS_REJECTED = "REJECTED" ORDER_STATUS_EXPIRED = "EXPIRED" ORDER_STATUS_ACCEPTED = "ACCEPTED" ORDER_STATUS_TRIGGERING = "TRIGGERING" ORDER_STATUS_TRIGGERED = "TRIGGERED" ORDER_STATUS_FINISHED = "FINISHED" KLINE_INTERVAL_1SECOND = "1s" KLINE_INTERVAL_1MINUTE = "1m" KLINE_INTERVAL_3MINUTE = "3m" KLINE_INTERVAL_5MINUTE = "5m" KLINE_INTERVAL_15MINUTE = "15m" KLINE_INTERVAL_30MINUTE = "30m" KLINE_INTERVAL_1HOUR = "1h" KLINE_INTERVAL_2HOUR = "2h" KLINE_INTERVAL_4HOUR = "4h" KLINE_INTERVAL_6HOUR = "6h" KLINE_INTERVAL_8HOUR = "8h" KLINE_INTERVAL_12HOUR = "12h" KLINE_INTERVAL_1DAY = "1d" KLINE_INTERVAL_3DAY = "3d" KLINE_INTERVAL_1WEEK = "1w" KLINE_INTERVAL_1MONTH = "1M" SIDE_BUY = "BUY" SIDE_SELL = "SELL" ORDER_TYPE_LIMIT = "LIMIT" ORDER_TYPE_MARKET = "MARKET" ORDER_TYPE_STOP_LOSS = "STOP_LOSS" ORDER_TYPE_STOP_LOSS_LIMIT = "STOP_LOSS_LIMIT" ORDER_TYPE_TAKE_PROFIT = "TAKE_PROFIT" ORDER_TYPE_TAKE_PROFIT_LIMIT = "TAKE_PROFIT_LIMIT" ORDER_TYPE_LIMIT_MAKER = "LIMIT_MAKER" FUTURE_ORDER_TYPE_LIMIT = "LIMIT" FUTURE_ORDER_TYPE_MARKET = "MARKET" FUTURE_ORDER_TYPE_STOP = "STOP" FUTURE_ORDER_TYPE_STOP_MARKET = "STOP_MARKET" FUTURE_ORDER_TYPE_TAKE_PROFIT = "TAKE_PROFIT" FUTURE_ORDER_TYPE_TAKE_PROFIT_MARKET = "TAKE_PROFIT_MARKET" FUTURE_ORDER_TYPE_LIMIT_MAKER = "LIMIT_MAKER" FUTURE_ORDER_TYPE_TRAILING_STOP_MARKET = "TRAILING_STOP_MARKET" TIME_IN_FORCE_GTC = "GTC" # Good till cancelled TIME_IN_FORCE_IOC = "IOC" # Immediate or cancel TIME_IN_FORCE_FOK = "FOK" # Fill or kill TIME_IN_FORCE_GTX = "GTX" # Post only order TIME_IN_FORCE_GTD = "GTD" # Good till date TIME_IN_FORCE_RPI = "RPI" # Retail Price Improvement ORDER_RESP_TYPE_ACK = "ACK" ORDER_RESP_TYPE_RESULT = "RESULT" ORDER_RESP_TYPE_FULL = "FULL" WEBSOCKET_DEPTH_5 = "5" WEBSOCKET_DEPTH_10 = "10" WEBSOCKET_DEPTH_20 = "20" NO_SIDE_EFFECT_TYPE = "NO_SIDE_EFFECT" MARGIN_BUY_TYPE = "MARGIN_BUY" AUTO_REPAY_TYPE = "AUTO_REPAY" class HistoricalKlinesType(Enum): SPOT = 1 FUTURES = 2 FUTURES_COIN = 3 FUTURES_MARK_PRICE = 4 FUTURES_INDEX_PRICE = 5 FUTURES_COIN_MARK_PRICE = 6 FUTURES_COIN_INDEX_PRICE = 7 class FuturesType(Enum): USD_M = 1 COIN_M = 2 class ContractType(Enum): PERPETUAL = "perpetual" CURRENT_QUARTER = "current_quarter" NEXT_QUARTER = "next_quarter" ================================================ FILE: binance/exceptions.py ================================================ # coding=utf-8 import json class BinanceAPIException(Exception): def __init__(self, response, status_code, text): self.code = 0 try: json_res = json.loads(text) except ValueError: self.message = "Invalid JSON error message from Binance: {}".format( response.text ) else: self.code = json_res.get("code") self.message = json_res.get("msg") self.status_code = status_code self.response = response self.request = getattr(response, "request", None) def __str__(self): # pragma: no cover return "APIError(code=%s): %s" % (self.code, self.message) class BinanceRequestException(Exception): def __init__(self, message): self.message = message def __str__(self): return "BinanceRequestException: %s" % self.message class BinanceOrderException(Exception): def __init__(self, code, message): self.code = code self.message = message def __str__(self): return "BinanceOrderException(code=%s): %s" % (self.code, self.message) class BinanceOrderMinAmountException(BinanceOrderException): def __init__(self, value): message = "Amount must be a multiple of %s" % value super().__init__(-1013, message) class BinanceOrderMinPriceException(BinanceOrderException): def __init__(self, value): message = "Price must be at least %s" % value super().__init__(-1013, message) class BinanceOrderMinTotalException(BinanceOrderException): def __init__(self, value): message = "Total must be at least %s" % value super().__init__(-1013, message) class BinanceOrderUnknownSymbolException(BinanceOrderException): def __init__(self, value): message = "Unknown symbol %s" % value super().__init__(-1013, message) class BinanceOrderInactiveSymbolException(BinanceOrderException): def __init__(self, value): message = "Attempting to trade an inactive symbol %s" % value super().__init__(-1013, message) class BinanceWebsocketUnableToConnect(Exception): pass class BinanceWebsocketQueueOverflow(Exception): """Raised when the websocket message queue exceeds its maximum size.""" pass class BinanceWebsocketClosed(Exception): """Raised when websocket connection is closed.""" pass class ReadLoopClosed(Exception): """Raised when trying to read from read loop but already closed""" pass class NotImplementedException(Exception): def __init__(self, value): message = f"Not implemented: {value}" super().__init__(message) class UnknownDateFormat(Exception): ... class BinanceRegionException(Exception): """Raised when using a region-specific endpoint with incompatible client.""" def __init__( self, required_tld: str, actual_tld: str, endpoint_name: str = "endpoint" ): self.required_tld = required_tld self.actual_tld = actual_tld self.endpoint_name = endpoint_name self.message = ( f"{endpoint_name} is only available on binance.{required_tld}, " f"but client is configured for binance.{actual_tld}" ) super().__init__(self.message) def __str__(self): return f"BinanceRegionException: {self.message}" ================================================ FILE: binance/helpers.py ================================================ import asyncio from decimal import Decimal import json from typing import Union, Optional, Dict import dateparser import pytz from datetime import datetime, timezone from binance.exceptions import UnknownDateFormat def date_to_milliseconds(date_str: str) -> int: """Convert UTC date to milliseconds If using offset strings add "UTC" to date string e.g. "now UTC", "11 hours ago UTC" See dateparse docs for formats http://dateparser.readthedocs.io/en/latest/ :param date_str: date in readable format, i.e. "January 01, 2018", "11 hours ago UTC", "now UTC" """ # get epoch value in UTC epoch: datetime = datetime.fromtimestamp(0,timezone.utc) # parse our date string d: Optional[datetime] = dateparser.parse(date_str, settings={"TIMEZONE": "UTC"}) if not d: raise UnknownDateFormat(date_str) # if the date is not timezone aware apply UTC timezone if d.tzinfo is None or d.tzinfo.utcoffset(d) is None: d = d.replace(tzinfo=pytz.utc) # return the difference in time return int((d - epoch).total_seconds() * 1000.0) def interval_to_milliseconds(interval: str) -> Optional[int]: """Convert a Binance interval string to milliseconds :param interval: Binance interval string, e.g.: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w :return: int value of interval in milliseconds None if interval prefix is not a decimal integer None if interval suffix is not one of m, h, d, w """ seconds_per_unit: Dict[str, int] = { "s": 1, "m": 60, "h": 60 * 60, "d": 24 * 60 * 60, "w": 7 * 24 * 60 * 60, } try: return int(interval[:-1]) * seconds_per_unit[interval[-1]] * 1000 except (ValueError, KeyError): return None def round_step_size( quantity: Union[float, Decimal], step_size: Union[float, Decimal] ) -> float: """Rounds a given quantity to a specific step size :param quantity: required :param step_size: required :return: decimal """ quantity = Decimal(str(quantity)) return float(quantity - quantity % Decimal(str(step_size))) def convert_ts_str(ts_str): if ts_str is None: return ts_str if isinstance(ts_str, int): return ts_str return date_to_milliseconds(ts_str) def convert_list_to_json_array(l): if l is None: return l res = json.dumps(l) return res.replace(" ", "") def get_loop(): """check if there is an event loop in the current thread, if not create one inspired by https://stackoverflow.com/questions/46727787/runtimeerror-there-is-no-current-event-loop-in-thread-in-async-apscheduler """ try: loop = asyncio.get_event_loop() return loop except RuntimeError as e: if str(e).startswith("There is no current event loop in thread"): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) return loop else: raise ================================================ FILE: binance/ws/__init__.py ================================================ ================================================ FILE: binance/ws/constants.py ================================================ from enum import Enum KEEPALIVE_TIMEOUT = 5 * 60 # 5 minutes class WSListenerState(Enum): INITIALISING = "Initialising" STREAMING = "Streaming" RECONNECTING = "Reconnecting" EXITING = "Exiting" ================================================ FILE: binance/ws/depthcache.py ================================================ import logging from operator import itemgetter import asyncio import time from typing import Optional, Dict, Callable from ..helpers import get_loop from .streams import BinanceSocketManager from .threaded_stream import ThreadedApiManager class DepthCache(object): def __init__(self, symbol, conv_type: Callable = float): """Initialise the DepthCache :param symbol: Symbol to create depth cache for :type symbol: string :param conv_type: Optional type to represent price, and amount, default is float. :type conv_type: function. """ self.symbol = symbol self._bids = {} self._asks = {} self.update_time = None self.conv_type: Callable = conv_type self._log = logging.getLogger(__name__) def add_bid(self, bid): """Add a bid to the cache :param bid: :return: """ self._bids[bid[0]] = self.conv_type(bid[1]) if bid[1] == "0.00000000": del self._bids[bid[0]] def add_ask(self, ask): """Add an ask to the cache :param ask: :return: """ self._asks[ask[0]] = self.conv_type(ask[1]) if ask[1] == "0.00000000": del self._asks[ask[0]] def get_bids(self): """Get the current bids :return: list of bids with price and quantity as conv_type .. code-block:: python [ [ 0.0001946, # Price 45.0 # Quantity ], [ 0.00019459, 2384.0 ], [ 0.00019158, 5219.0 ], [ 0.00019157, 1180.0 ], [ 0.00019082, 287.0 ] ] """ return DepthCache.sort_depth(self._bids, reverse=True, conv_type=self.conv_type) def get_asks(self): """Get the current asks :return: list of asks with price and quantity as conv_type. .. code-block:: python [ [ 0.0001955, # Price 57.0' # Quantity ], [ 0.00019699, 778.0 ], [ 0.000197, 64.0 ], [ 0.00019709, 1130.0 ], [ 0.0001971, 385.0 ] ] """ return DepthCache.sort_depth( self._asks, reverse=False, conv_type=self.conv_type ) @staticmethod def sort_depth(vals, reverse=False, conv_type: Callable = float): """Sort bids or asks by price""" if isinstance(vals, dict): lst = [ [conv_type(price), conv_type(quantity)] for price, quantity in vals.items() ] elif isinstance(vals, list): lst = [[conv_type(price), conv_type(quantity)] for price, quantity in vals] else: raise ValueError(f"Unknown order book depth data type: {type(vals)}") lst = sorted(lst, key=itemgetter(0), reverse=reverse) return lst DEFAULT_REFRESH = 60 * 30 # 30 minutes class BaseDepthCacheManager: TIMEOUT = 60 def __init__( self, client, symbol, loop=None, refresh_interval: Optional[int] = DEFAULT_REFRESH, bm=None, limit=10, conv_type=float, ): """Create a DepthCacheManager instance :param client: Binance API client :type client: binance.Client :param loop: :type loop: :param symbol: Symbol to create depth cache for :type symbol: string :param refresh_interval: Optional number of seconds between cache refresh, use 0 or None to disable :type refresh_interval: int :param bm: Optional BinanceSocketManager :type bm: BinanceSocketManager :param limit: Optional number of orders to get from orderbook :type limit: int :param conv_type: Optional type to represent price, and amount, default is float. :type conv_type: function. """ self._client = client self._depth_cache = None self._loop = loop or get_loop() self._symbol = symbol self._limit = limit self._last_update_id = None self._bm = bm or BinanceSocketManager(self._client) self._refresh_interval = refresh_interval self._conn_key = None self._conv_type = conv_type self._log = logging.getLogger(__name__) async def __aenter__(self): await asyncio.gather(self._init_cache(), self._start_socket()) await self._socket.__aenter__() return self async def __aexit__(self, *args, **kwargs): self._log.debug(f"Exiting depth cache manager for {self._symbol}") await self._socket.__aexit__(*args, **kwargs) async def recv(self): dc = None while not dc: try: res = await asyncio.wait_for(self._socket.recv(), timeout=self.TIMEOUT) self._log.debug(f"Received message: {res}") except Exception as e: self._log.warning(f"Exception recieving message: {e.__class__.__name__} (e) ") else: dc = await self._depth_event(res) return dc async def _init_cache(self): """Initialise the depth cache calling REST endpoint :return: """ self._log.debug(f"Initialising depth cache for {self._symbol}") # initialise or clear depth cache self._depth_cache = DepthCache(self._symbol, conv_type=self._conv_type) # set a time to refresh the depth cache if self._refresh_interval: self._refresh_time = int(time.time()) + self._refresh_interval async def _start_socket(self): """Start the depth cache socket :return: """ self._socket = self._get_socket() def _get_socket(self): raise NotImplementedError async def _depth_event(self, msg): """Handle a depth event :param msg: :return: """ self._log.debug(f"Received depth event: {msg}") if not msg: return None if "e" in msg and msg["e"] == "error": # notify user by return msg with error self._log.error(f"Error in depth event restarting cache: {msg}") return msg return await self._process_depth_message(msg) async def _process_depth_message(self, msg): """Process a depth event message. :param msg: Depth event message. :return: """ # add any bid or ask values self._apply_orders(msg) # call the callback with the updated depth cache res = self._depth_cache # after processing event see if we need to refresh the depth cache if self._refresh_interval and int(time.time()) > self._refresh_time: await self._init_cache() return res def _apply_orders(self, msg): assert self._depth_cache for bid in msg.get("b", []) + msg.get("bids", []): self._depth_cache.add_bid(bid) for ask in msg.get("a", []) + msg.get("asks", []): self._depth_cache.add_ask(ask) # keeping update time self._depth_cache.update_time = msg.get("E") or msg.get("lastUpdateId") def get_depth_cache(self): """Get the current depth cache :return: DepthCache object """ return self._depth_cache async def close(self): """Close the open socket for this manager :return: """ self._depth_cache = None def get_symbol(self): """Get the symbol :return: symbol """ return self._symbol class DepthCacheManager(BaseDepthCacheManager): def __init__( self, client, symbol, loop=None, refresh_interval: Optional[int] = None, bm=None, limit=500, conv_type=float, ws_interval=None, ): """Initialise the DepthCacheManager :param client: Binance API client :type client: binance.Client :param loop: asyncio loop :param symbol: Symbol to create depth cache for :type symbol: string :param refresh_interval: Optional number of seconds between cache refresh, use 0 or None to disable :type refresh_interval: int :param limit: Optional number of orders to get from orderbook :type limit: int :param conv_type: Optional type to represent price, and amount, default is float. :type conv_type: function. :param ws_interval: Optional interval for updates on websocket, default None. If not set, updates happen every second. Must be 0, None (1s) or 100 (100ms). :type ws_interval: int """ super().__init__(client, symbol, loop, refresh_interval, bm, limit, conv_type) self._ws_interval = ws_interval async def _init_cache(self): """Initialise the depth cache calling REST endpoint :return: """ self._last_update_id = None self._depth_message_buffer = [] res = await self._client.get_order_book(symbol=self._symbol, limit=self._limit) # initialise or clear depth cache await super()._init_cache() # process bid and asks from the order book self._apply_orders(res) assert self._depth_cache for bid in res["bids"]: self._depth_cache.add_bid(bid) for ask in res["asks"]: self._depth_cache.add_ask(ask) # set first update id self._last_update_id = res["lastUpdateId"] # Apply any updates from the websocket for msg in self._depth_message_buffer: await self._process_depth_message(msg) # clear the depth buffer self._depth_message_buffer = [] async def _start_socket(self): """Start the depth cache socket :return: """ if not getattr(self, "_depth_message_buffer", None): self._depth_message_buffer = [] await super()._start_socket() def _get_socket(self): return self._bm.depth_socket(self._symbol, interval=self._ws_interval) async def _process_depth_message(self, msg): """Process a depth event message. :param msg: Depth event message. :return: """ if self._last_update_id is None: # Initial depth snapshot fetch not yet performed, buffer messages self._depth_message_buffer.append(msg) return if msg["u"] <= self._last_update_id: # ignore any updates before the initial update id return elif msg["U"] != self._last_update_id + 1: # if not buffered check we get sequential updates # otherwise init cache again await self._init_cache() # add any bid or ask values self._apply_orders(msg) # call the callback with the updated depth cache res = self._depth_cache self._last_update_id = msg["u"] # after processing event see if we need to refresh the depth cache if self._refresh_interval and int(time.time()) > self._refresh_time: await self._init_cache() return res class FuturesDepthCacheManager(BaseDepthCacheManager): async def _process_depth_message(self, msg): """Process a depth event message. :param msg: Depth event message. :return: """ msg = msg.get("data") return await super()._process_depth_message(msg) def _apply_orders(self, msg): assert self._depth_cache self._depth_cache._bids = msg.get("b", []) self._depth_cache._asks = msg.get("a", []) # keeping update time self._depth_cache.update_time = msg.get("E") or msg.get("lastUpdateId") def _get_socket(self): sock = self._bm.futures_depth_socket(self._symbol) return sock class OptionsDepthCacheManager(BaseDepthCacheManager): def _get_socket(self): return self._bm.options_depth_socket(self._symbol) class ThreadedDepthCacheManager(ThreadedApiManager): def __init__( self, api_key: Optional[str] = None, api_secret: Optional[str] = None, requests_params: Optional[Dict[str, str]] = None, tld: str = "com", testnet: bool = False, ): super().__init__(api_key, api_secret, requests_params, tld, testnet) def _start_depth_cache( self, dcm_class, callback: Callable, symbol: str, refresh_interval=None, bm=None, limit=10, conv_type=float, **kwargs, ) -> str: while not self._client: time.sleep(0.01) dcm = dcm_class( client=self._client, symbol=symbol, loop=self._loop, refresh_interval=refresh_interval, bm=bm, limit=limit, conv_type=conv_type, **kwargs, ) path = symbol.lower() + "@depth" + str(limit) self._socket_running[path] = True self._loop.call_soon( asyncio.create_task, self.start_listener(dcm, path, callback) ) return path def start_depth_cache( self, callback: Callable, symbol: str, refresh_interval=None, bm=None, limit=10, conv_type=float, ws_interval=0, ) -> str: return self._start_depth_cache( dcm_class=DepthCacheManager, callback=callback, symbol=symbol, refresh_interval=refresh_interval, bm=bm, limit=limit, conv_type=conv_type, ws_interval=ws_interval, ) def start_futures_depth_socket( self, callback: Callable, symbol: str, refresh_interval=None, bm=None, limit=10, conv_type=float, ) -> str: return self._start_depth_cache( dcm_class=FuturesDepthCacheManager, callback=callback, symbol=symbol, refresh_interval=refresh_interval, bm=bm, limit=limit, conv_type=conv_type, ) def start_options_depth_socket( self, callback: Callable, symbol: str, refresh_interval=None, bm=None, limit=10, conv_type=float, ) -> str: return self._start_depth_cache( dcm_class=OptionsDepthCacheManager, callback=callback, symbol=symbol, refresh_interval=refresh_interval, bm=bm, limit=limit, conv_type=conv_type, ) ================================================ FILE: binance/ws/keepalive_websocket.py ================================================ import asyncio import uuid from binance.async_client import AsyncClient from binance.ws.reconnecting_websocket import ReconnectingWebsocket from binance.ws.constants import KEEPALIVE_TIMEOUT class KeepAliveWebsocket(ReconnectingWebsocket): def __init__( self, client: AsyncClient, url, keepalive_type, prefix="ws/", is_binary=False, exit_coro=None, user_timeout=None, **kwargs, ): super().__init__( path=None, url=url, prefix=prefix, is_binary=is_binary, exit_coro=exit_coro, **kwargs, ) self._keepalive_type = keepalive_type self._client = client self._user_timeout = user_timeout or KEEPALIVE_TIMEOUT self._timer = None self._subscription_id = None self._listen_key = None # Used for non spot stream types self._uses_ws_api_subscription = False # True when using ws_api self._listen_token_expiration = ( None # Expiration time for listenToken-based subscriptions ) async def __aexit__(self, *args, **kwargs): if self._timer: self._timer.cancel() self._timer = None # Clean up subscription if it exists if self._subscription_id is not None: # Unregister the queue from ws_api before unsubscribing if hasattr(self._client, "ws_api") and self._client.ws_api: self._client.ws_api.unregister_subscription_queue(self._subscription_id) await self._unsubscribe_from_user_data_stream() if self._uses_ws_api_subscription: # For ws_api subscriptions, we don't manage the connection return if not self._path: return await super().__aexit__(*args, **kwargs) def _build_path(self): self._path = self._listen_key time_unit = getattr(self._client, "TIME_UNIT", None) if time_unit: self._path = f"{self._listen_key}?timeUnit={time_unit}" async def _before_connect(self): if self._keepalive_type == "user": # Subscribe via ws_api and register our own queue for events self._subscription_id = await self._subscribe_to_user_data_stream() if self._subscription_id is None: raise ValueError( "Failed to subscribe to user data stream: no subscription ID returned" ) self._uses_ws_api_subscription = True # Register our queue with ws_api so events get routed to us self._client.ws_api.register_subscription_queue( self._subscription_id, self._queue ) self._path = f"user_subscription:{self._subscription_id}" return if self._keepalive_type == "margin": # Subscribe to cross-margin via ws_api self._subscription_id = await self._subscribe_to_margin_data_stream() if self._subscription_id is None: raise ValueError( "Failed to subscribe to margin data stream: no subscription ID returned" ) self._uses_ws_api_subscription = True # Register our queue with ws_api so events get routed to us self._client.ws_api.register_subscription_queue( self._subscription_id, self._queue ) self._path = f"margin_subscription:{self._subscription_id}" return # Check if this is isolated margin (when keepalive_type is a symbol string) if self._keepalive_type not in [ "user", "margin", "futures", "coin_futures", "portfolio_margin", ]: # This is isolated margin with symbol as keepalive_type self._subscription_id = ( await self._subscribe_to_isolated_margin_data_stream( self._keepalive_type ) ) if self._subscription_id is None: raise ValueError( f"Failed to subscribe to isolated margin data stream for {self._keepalive_type}: no subscription ID returned" ) self._uses_ws_api_subscription = True # Register our queue with ws_api so events get routed to us self._client.ws_api.register_subscription_queue( self._subscription_id, self._queue ) self._path = f"isolated_margin_subscription:{self._subscription_id}" return if not self._listen_key: self._listen_key = await self._get_listen_key() self._build_path() async def connect(self): """Override connect to handle ws_api subscriptions differently.""" # Check if this keepalive type uses ws_api subscription if self._keepalive_type in ["user", "margin"] or self._keepalive_type not in [ "futures", "coin_futures", "portfolio_margin", ]: # For sockets using ws_api subscription: # - Subscribe via ws_api (done in _before_connect) # - Don't create our own websocket connection # - Don't start a read loop (ws_api handles reading) await self._before_connect() # Check if ws_api subscription was actually used if self._uses_ws_api_subscription: await self._after_connect() return # For other keepalive types, use normal connection logic await super().connect() async def recv(self): """Override recv to work without a read loop for ws_api subscriptions.""" if self._uses_ws_api_subscription: # For ws_api subscriptions, just read from queue res = None while not res: try: res = await asyncio.wait_for( self._queue.get(), timeout=self.TIMEOUT ) except asyncio.TimeoutError: self._log.debug(f"no message in {self.TIMEOUT} seconds") return res return await super().recv() async def _after_connect(self): if self._timer is None: self._start_socket_timer() def _start_socket_timer(self): self._timer = self._loop.call_later( self._user_timeout, lambda: asyncio.create_task(self._keepalive_socket()) ) async def _subscribe_to_user_data_stream(self): """Subscribe to user data stream using WebSocket API""" params = { "id": str(uuid.uuid4()), } response = await self._client._ws_api_request( "userDataStream.subscribe.signature", signed=True, params=params ) return response.get("subscriptionId") async def _subscribe_to_margin_data_stream(self): """Subscribe to cross-margin data stream using WebSocket API with listenToken""" # Create listenToken for cross-margin token_response = await self._client.margin_create_listen_token( is_isolated=False ) listen_token = token_response["token"] self._listen_token_expiration = token_response.get("expirationTime") # Subscribe using listenToken params = { "id": str(uuid.uuid4()), "listenToken": listen_token, } response = await self._client._ws_api_request( "userDataStream.subscribe.listenToken", signed=False, params=params ) return response.get("subscriptionId") async def _subscribe_to_isolated_margin_data_stream(self, symbol: str): """Subscribe to isolated margin data stream using WebSocket API with listenToken""" # Create listenToken for isolated margin token_response = await self._client.margin_create_listen_token( symbol=symbol, is_isolated=True ) listen_token = token_response["token"] self._listen_token_expiration = token_response.get("expirationTime") # Subscribe using listenToken params = { "id": str(uuid.uuid4()), "listenToken": listen_token, } response = await self._client._ws_api_request( "userDataStream.subscribe.listenToken", signed=False, params=params ) return response.get("subscriptionId") async def _unsubscribe_from_user_data_stream(self): """Unsubscribe from user data stream using WebSocket API""" if self._subscription_id is not None: params = { "id": str(uuid.uuid4()), "subscriptionId": self._subscription_id, } await self._client._ws_api_request( "userDataStream.unsubscribe", signed=False, params=params ) self._subscription_id = None async def _get_listen_key(self): if self._keepalive_type == "user": listen_key = await self._client.stream_get_listen_key() elif self._keepalive_type == "margin": # cross-margin listen_key = await self._client.margin_stream_get_listen_key() elif self._keepalive_type == "futures": listen_key = await self._client.futures_stream_get_listen_key() elif self._keepalive_type == "coin_futures": listen_key = await self._client.futures_coin_stream_get_listen_key() elif self._keepalive_type == "portfolio_margin": listen_key = await self._client.papi_stream_get_listen_key() else: # isolated margin # Passing symbol for isolated margin listen_key = await self._client.isolated_margin_stream_get_listen_key( self._keepalive_type ) return listen_key async def _keepalive_socket(self): try: # Skip keepalive for ws_api subscriptions (user, margin, isolated margin) if self._uses_ws_api_subscription: return listen_key = await self._get_listen_key() if listen_key != self._listen_key: self._log.debug("listen key changed: reconnect") self._listen_key = listen_key self._build_path() self._reconnect() else: self._log.debug("listen key same: keepalive") if self._keepalive_type == "margin": # cross-margin await self._client.margin_stream_keepalive(self._listen_key) elif self._keepalive_type == "futures": await self._client.futures_stream_keepalive(self._listen_key) elif self._keepalive_type == "coin_futures": await self._client.futures_coin_stream_keepalive(self._listen_key) elif self._keepalive_type == "portfolio_margin": await self._client.papi_stream_keepalive(self._listen_key) else: # isolated margin # Passing symbol for isolated margin await self._client.isolated_margin_stream_keepalive( self._keepalive_type, self._listen_key ) except Exception as e: self._log.error(f"error in keepalive_socket: {e}") finally: if self._timer is not None: self._start_socket_timer() else: self._log.info("skip timer restart - web socket is exiting") ================================================ FILE: binance/ws/reconnecting_websocket.py ================================================ import asyncio import gzip import json import logging from socket import gaierror from typing import Optional from asyncio import sleep from random import random # load orjson if available, otherwise default to json orjson = None try: import orjson as orjson except ImportError: pass try: from websockets.exceptions import ConnectionClosedError, ConnectionClosedOK # type: ignore except ImportError: from websockets import ConnectionClosedError, ConnectionClosedOK # type: ignore Proxy = None proxy_connect = None try: from websockets_proxy import Proxy as w_Proxy, proxy_connect as w_proxy_connect Proxy = w_Proxy proxy_connect = w_proxy_connect except ImportError: pass import websockets as ws from binance.exceptions import ( BinanceWebsocketClosed, BinanceWebsocketUnableToConnect, BinanceWebsocketQueueOverflow, ReadLoopClosed, ) from binance.helpers import get_loop from binance.ws.constants import WSListenerState class ReconnectingWebsocket: MAX_RECONNECTS = 5 MAX_RECONNECT_SECONDS = 60 MIN_RECONNECT_WAIT = 0.1 TIMEOUT = 10 NO_MESSAGE_RECONNECT_TIMEOUT = 60 def __init__( self, url: str, path: Optional[str] = None, prefix: str = "ws/", is_binary: bool = False, exit_coro=None, https_proxy: Optional[str] = None, max_queue_size: int = 100, **kwargs, ): self._loop = get_loop() self._log = logging.getLogger(__name__) self._path = path self._url = url self._exit_coro = exit_coro self._prefix = prefix self._reconnects = 0 self._is_binary = is_binary self._conn = None self._socket = None self.ws: Optional[ws.WebSocketClientProtocol] = None # type: ignore self.ws_state = WSListenerState.INITIALISING self._queue = asyncio.Queue() self._handle_read_loop = None self._https_proxy = https_proxy self._ws_kwargs = kwargs self.max_queue_size = max_queue_size def json_dumps(self, msg) -> str: if orjson: return orjson.dumps(msg).decode("utf-8") return json.dumps(msg) def json_loads(self, msg): if orjson: return orjson.loads(msg) return json.loads(msg) async def __aenter__(self): await self.connect() return self async def close(self): await self.__aexit__(None, None, None) async def __aexit__(self, exc_type, exc_val, exc_tb): self._log.debug(f"Closing Websocket {self._url}{self._prefix}{self._path}") if self._handle_read_loop: await self._kill_read_loop() if self._exit_coro: await self._exit_coro(self._path) if self.ws: await self.ws.close() if self._conn and hasattr(self._conn, "protocol"): await self._conn.__aexit__(exc_type, exc_val, exc_tb) self.ws = None async def connect(self): self._log.debug("Establishing new WebSocket connection") self.ws_state = WSListenerState.RECONNECTING await self._before_connect() ws_url = ( f"{self._url}{getattr(self, '_prefix', '')}{getattr(self, '_path', '')}" ) # handle https_proxy if self._https_proxy: if not Proxy or not proxy_connect: raise ImportError( "websockets_proxy is not installed, please install it to use a websockets proxy (pip install websockets_proxy)" ) proxy = Proxy.from_url(self._https_proxy) # type: ignore self._conn = proxy_connect( ws_url, close_timeout=0.1, proxy=proxy, **self._ws_kwargs ) # type: ignore else: self._conn = ws.connect(ws_url, close_timeout=0.1, **self._ws_kwargs) # type: ignore try: self.ws = await self._conn.__aenter__() except Exception as e: # noqa self._log.error(f"Failed to connect to websocket: {e}") self.ws_state = WSListenerState.RECONNECTING raise e self.ws_state = WSListenerState.STREAMING self._reconnects = 0 await self._after_connect() if not self._handle_read_loop: self._handle_read_loop = self._loop.call_soon_threadsafe( asyncio.create_task, self._read_loop() ) async def _kill_read_loop(self): self.ws_state = WSListenerState.EXITING while self._handle_read_loop: await sleep(0.1) self._log.debug("Finished killing read_loop") async def _before_connect(self): pass async def _after_connect(self): pass def _handle_message(self, evt): if self._is_binary: try: evt = gzip.decompress(evt) except (ValueError, OSError) as e: self._log.error(f"Failed to decompress message: {(e)}") raise except Exception as e: self._log.error(f"Unexpected decompression error: {(e)}") raise try: return self.json_loads(evt) except ValueError as e: self._log.error(f"JSON Value Error parsing message: Error: {(e)}") raise except TypeError as e: self._log.error(f"JSON Type Error parsing message. Error: {(e)}") raise except Exception as e: self._log.error(f"Unexpected error parsing message. Error: {(e)}") raise async def _read_loop(self): try: while True: try: while self.ws_state == WSListenerState.RECONNECTING: await self._run_reconnect() if self.ws_state == WSListenerState.EXITING: self._log.debug( f"_read_loop {self._path} break for {self.ws_state}" ) break elif self.ws.state == ws.protocol.State.CLOSING: # type: ignore await asyncio.sleep(0.1) continue elif self.ws.state == ws.protocol.State.CLOSED: # type: ignore self._reconnect() raise BinanceWebsocketClosed( "Connection closed. Reconnecting..." ) elif self.ws_state == WSListenerState.STREAMING: assert self.ws res = await asyncio.wait_for( self.ws.recv(), timeout=self.TIMEOUT ) res = self._handle_message(res) self._log.debug(f"Received message: {res}") if res: if self._queue.qsize() < self.max_queue_size: await self._queue.put(res) else: raise BinanceWebsocketQueueOverflow( f"Message queue size {self._queue.qsize()} exceeded maximum {self.max_queue_size}" ) except asyncio.TimeoutError: self._log.debug(f"no message in {self.TIMEOUT} seconds") # _no_message_received_reconnect except asyncio.CancelledError as e: self._log.debug(f"_read_loop cancelled error {e}") await self._queue.put({ "e": "error", "type": f"{e.__class__.__name__}", "m": f"{e}", }) break except ( asyncio.IncompleteReadError, gaierror, ConnectionClosedError, ConnectionClosedOK, BinanceWebsocketClosed, ) as e: # reports errors and continue loop self._log.error(f"{e.__class__.__name__} ({e})") await self._queue.put({ "e": "error", "type": f"{e.__class__.__name__}", "m": f"{e}", }) except ( BinanceWebsocketUnableToConnect, BinanceWebsocketQueueOverflow, Exception, ) as e: # reports errors and break the loop self._log.error(f"Unknown exception: {e.__class__.__name__} ({e})") await self._queue.put({ "e": "error", "type": e.__class__.__name__, "m": f"{e}", }) break except Exception as e: self._log.error(f"Unknown exception: {e.__class__.__name__} ({e})") finally: self._handle_read_loop = None # Signal the coro is stopped self._reconnects = 0 async def _run_reconnect(self): await self.before_reconnect() if self._reconnects < self.MAX_RECONNECTS: reconnect_wait = self._get_reconnect_wait(self._reconnects) self._log.debug( f"websocket reconnecting. {self.MAX_RECONNECTS - self._reconnects} reconnects left - " f"waiting {reconnect_wait}" ) await asyncio.sleep(reconnect_wait) try: await self.connect() except Exception as e: pass else: self._log.error(f"Max reconnections {self.MAX_RECONNECTS} reached:") # Signal the error raise BinanceWebsocketUnableToConnect async def recv(self): res = None while not res: if not self._handle_read_loop: raise ReadLoopClosed( "Read loop has been closed, please reset the websocket connection and listen to the message error." ) try: res = await asyncio.wait_for(self._queue.get(), timeout=self.TIMEOUT) except asyncio.TimeoutError: self._log.debug(f"no message in {self.TIMEOUT} seconds") return res async def _wait_for_reconnect(self): while ( self.ws_state != WSListenerState.STREAMING and self.ws_state != WSListenerState.EXITING ): await sleep(0.1) def _get_reconnect_wait(self, attempts: int) -> int: expo = 2**attempts return round(random() * min(self.MAX_RECONNECT_SECONDS, expo - 1) + 1) async def before_reconnect(self): if self.ws: self.ws = None if self._conn and hasattr(self._conn, "protocol"): await self._conn.__aexit__(None, None, None) self._reconnects += 1 def _reconnect(self): self.ws_state = WSListenerState.RECONNECTING ================================================ FILE: binance/ws/streams.py ================================================ import asyncio import time from enum import Enum from typing import Optional, List, Dict, Callable, Any import logging from binance.ws.constants import KEEPALIVE_TIMEOUT from binance.ws.keepalive_websocket import KeepAliveWebsocket from binance.ws.reconnecting_websocket import ReconnectingWebsocket from binance.ws.threaded_stream import ThreadedApiManager from binance.async_client import AsyncClient from binance.enums import FuturesType from binance.enums import ContractType from binance.helpers import get_loop class BinanceSocketType(str, Enum): SPOT = "Spot" USD_M_FUTURES = "USD_M_Futures" COIN_M_FUTURES = "Coin_M_Futures" OPTIONS = "Vanilla_Options" ACCOUNT = "Account" class BinanceSocketManager: STREAM_URL = "wss://stream.binance.{}:9443/" STREAM_TESTNET_URL = "wss://stream.testnet.binance.vision/" STREAM_DEMO_URL = "wss://demo-stream.binance.com/" FSTREAM_URL = "wss://fstream.binance.{}/" FSTREAM_TESTNET_URL = "wss://stream.binancefuture.com/" FSTREAM_DEMO_URL = "wss://fstream.binancefuture.com/" DSTREAM_URL = "wss://dstream.binance.{}/" DSTREAM_TESTNET_URL = "wss://dstream.binancefuture.com/" DSTREAM_DEMO_URL = "wss://dstream.binancefuture.com/" OPTIONS_URL = "wss://nbstream.binance.{}/eoptions/" WEBSOCKET_DEPTH_5 = "5" WEBSOCKET_DEPTH_10 = "10" WEBSOCKET_DEPTH_20 = "20" def __init__( self, client: AsyncClient, user_timeout=KEEPALIVE_TIMEOUT, max_queue_size: int = 100, verbose: bool = False, ): """Initialise the BinanceSocketManager :param client: Binance API client :type client: binance.AsyncClient :param user_timeout: Timeout for user socket in seconds :param max_queue_size: Max size of the websocket queue, defaults to 100 :type max_queue_size: int :param verbose: Enable verbose logging for WebSocket connections :type verbose: bool """ self.STREAM_URL = self.STREAM_URL.format(client.tld) self.FSTREAM_URL = self.FSTREAM_URL.format(client.tld) self.DSTREAM_URL = self.DSTREAM_URL.format(client.tld) self.OPTIONS_URL = self.OPTIONS_URL.format(client.tld) self._conns = {} self._loop = get_loop() self._client = client self._user_timeout = user_timeout self.testnet = self._client.testnet self.demo = self._client.demo self._max_queue_size = max_queue_size self.verbose = verbose self.ws_kwargs = {} if verbose: logging.getLogger('binance.ws').setLevel(logging.DEBUG) def _get_stream_url(self, stream_url: Optional[str] = None): if stream_url: return stream_url stream_url = self.STREAM_URL if self.testnet: stream_url = self.STREAM_TESTNET_URL elif self.demo: stream_url = self.STREAM_DEMO_URL return stream_url def _get_socket( self, path: str, stream_url: Optional[str] = None, prefix: str = "ws/", is_binary: bool = False, socket_type: BinanceSocketType = BinanceSocketType.SPOT, ) -> ReconnectingWebsocket: conn_id = f"{socket_type}_{path}" time_unit = getattr(self._client, "TIME_UNIT", None) if time_unit: path = f"{path}?timeUnit={time_unit}" if conn_id not in self._conns: self._conns[conn_id] = ReconnectingWebsocket( path=path, url=self._get_stream_url(stream_url), prefix=prefix, exit_coro=lambda p: self._exit_socket(f"{socket_type}_{p}"), is_binary=is_binary, https_proxy=self._client.https_proxy, max_queue_size=self._max_queue_size, **self.ws_kwargs, ) return self._conns[conn_id] def _get_account_socket( self, path: str, stream_url: Optional[str] = None, prefix: str = "ws/", is_binary: bool = False, ) -> KeepAliveWebsocket: conn_id = f"{BinanceSocketType.ACCOUNT}_{path}" if conn_id not in self._conns: self._conns[conn_id] = KeepAliveWebsocket( client=self._client, url=self._get_stream_url(stream_url), keepalive_type=path, prefix=prefix, exit_coro=lambda p: self._exit_socket(conn_id), is_binary=is_binary, user_timeout=self._user_timeout, https_proxy=self._client.https_proxy, max_queue_size=self._max_queue_size, **self.ws_kwargs, ) return self._conns[conn_id] def _get_futures_socket( self, path: str, futures_type: FuturesType, prefix: str = "stream?streams=" ): socket_type: BinanceSocketType = BinanceSocketType.USD_M_FUTURES if futures_type == FuturesType.USD_M: stream_url = self.FSTREAM_URL if self.testnet: stream_url = self.FSTREAM_TESTNET_URL elif self.demo: stream_url = self.FSTREAM_DEMO_URL else: stream_url = self.DSTREAM_URL if self.testnet: stream_url = self.DSTREAM_TESTNET_URL elif self.demo: stream_url = self.DSTREAM_DEMO_URL return self._get_socket(path, stream_url, prefix, socket_type=socket_type) def _get_options_socket(self, path: str, prefix: str = "ws/"): stream_url = self.OPTIONS_URL return self._get_socket( path, stream_url, prefix, is_binary=False, socket_type=BinanceSocketType.OPTIONS, ) async def _exit_socket(self, path: str): await self._stop_socket(path) def depth_socket( self, symbol: str, depth: Optional[str] = None, interval: Optional[int] = None ): """Start a websocket for symbol market depth returning either a diff or a partial book https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#partial-book-depth-streams :param symbol: required :type symbol: str :param depth: optional Number of depth entries to return, default None. If passed returns a partial book instead of a diff :type depth: str :param interval: optional interval for updates, default None. If not set, updates happen every second. Must be 0, None (1s) or 100 (100ms) :type interval: int :returns: connection key string if successful, False otherwise Partial Message Format .. code-block:: python { "lastUpdateId": 160, # Last update ID "bids": [ # Bids to be updated [ "0.0024", # price level to be updated "10", # quantity [] # ignore ] ], "asks": [ # Asks to be updated [ "0.0026", # price level to be updated "100", # quantity [] # ignore ] ] } Diff Message Format .. code-block:: python { "e": "depthUpdate", # Event type "E": 123456789, # Event time "s": "BNBBTC", # Symbol "U": 157, # First update ID in event "u": 160, # Final update ID in event "b": [ # Bids to be updated [ "0.0024", # price level to be updated "10", # quantity [] # ignore ] ], "a": [ # Asks to be updated [ "0.0026", # price level to be updated "100", # quantity [] # ignore ] ] } """ socket_name = symbol.lower() + "@depth" if depth and depth != "1": socket_name = f"{socket_name}{depth}" if interval: if interval in [0, 100]: socket_name = f"{socket_name}@{interval}ms" else: raise ValueError( "Websocket interval value not allowed. Allowed values are [0, 100]" ) return self._get_socket(socket_name) def kline_socket(self, symbol: str, interval=AsyncClient.KLINE_INTERVAL_1MINUTE): """Start a websocket for symbol kline data https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#klinecandlestick-streams :param symbol: required :type symbol: str :param interval: Kline interval, default KLINE_INTERVAL_1MINUTE :type interval: str :returns: connection key string if successful, False otherwise Message Format .. code-block:: python { "e": "kline", # event type "E": 1499404907056, # event time "s": "ETHBTC", # symbol "k": { "t": 1499404860000, # start time of this bar "T": 1499404919999, # end time of this bar "s": "ETHBTC", # symbol "i": "1m", # interval "f": 77462, # first trade id "L": 77465, # last trade id "o": "0.10278577", # open "c": "0.10278645", # close "h": "0.10278712", # high "l": "0.10278518", # low "v": "17.47929838", # volume "n": 4, # number of trades "x": false, # whether this bar is final "q": "1.79662878", # quote volume "V": "2.34879839", # volume of active buy "Q": "0.24142166", # quote volume of active buy "B": "13279784.01349473" # can be ignored } } """ path = f"{symbol.lower()}@kline_{interval}" return self._get_socket(path) def kline_futures_socket( self, symbol: str, interval=AsyncClient.KLINE_INTERVAL_1MINUTE, futures_type: FuturesType = FuturesType.USD_M, contract_type: ContractType = ContractType.PERPETUAL, ): """Start a websocket for symbol kline data for the perpeual futures stream https://binance-docs.github.io/apidocs/futures/en/#continuous-contract-kline-candlestick-streams :param symbol: required :type symbol: str :param interval: Kline interval, default KLINE_INTERVAL_1MINUTE :type interval: str :param futures_type: use USD-M or COIN-M futures default USD-M :param contract_type: use PERPETUAL or CURRENT_QUARTER or NEXT_QUARTER default PERPETUAL :returns: connection key string if successful, False otherwise Message Format .. code-block:: python { "e":"continuous_kline", // Event type "E":1607443058651, // Event time "ps":"BTCUSDT", // Pair "ct":"PERPETUAL" // Contract type "k":{ "t":1607443020000, // Kline start time "T":1607443079999, // Kline close time "i":"1m", // Interval "f":116467658886, // First trade ID "L":116468012423, // Last trade ID "o":"18787.00", // Open price "c":"18804.04", // Close price "h":"18804.04", // High price "l":"18786.54", // Low price "v":"197.664", // volume "n": 543, // Number of trades "x":false, // Is this kline closed? "q":"3715253.19494", // Quote asset volume "V":"184.769", // Taker buy volume "Q":"3472925.84746", //Taker buy quote asset volume "B":"0" // Ignore } } _@continuousKline_ """ path = f"{symbol.lower()}_{contract_type.value}@continuousKline_{interval}" return self._get_futures_socket(path, prefix="ws/", futures_type=futures_type) def miniticker_socket(self, update_time: int = 1000): """Start a miniticker websocket for all trades This is not in the official Binance api docs, but this is what feeds the right column on a ticker page on Binance. :param update_time: time between callbacks in milliseconds, must be 1000 or greater :type update_time: int :returns: connection key string if successful, False otherwise Message Format .. code-block:: python [ { 'e': '24hrMiniTicker', # Event type 'E': 1515906156273, # Event time 's': 'QTUMETH', # Symbol 'c': '0.03836900', # close 'o': '0.03953500', # open 'h': '0.04400000', # high 'l': '0.03756000', # low 'v': '147435.80000000', # volume 'q': '5903.84338533' # quote volume } ] """ return self._get_socket(f"!miniTicker@arr@{update_time}ms") def trade_socket(self, symbol: str): """Start a websocket for symbol trade data https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#trade-streams :param symbol: required :type symbol: str :returns: connection key string if successful, False otherwise Message Format .. code-block:: python { "e": "trade", # Event type "E": 123456789, # Event time "s": "BNBBTC", # Symbol "t": 12345, # Trade ID "p": "0.001", # Price "q": "100", # Quantity "b": 88, # Buyer order Id "a": 50, # Seller order Id "T": 123456785, # Trade time "m": true, # Is the buyer the market maker? "M": true # Ignore. } """ return self._get_socket(symbol.lower() + "@trade") def aggtrade_socket(self, symbol: str): """Start a websocket for symbol trade data https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#aggregate-trade-streams :param symbol: required :type symbol: str :returns: connection key string if successful, False otherwise Message Format .. code-block:: python { "e": "aggTrade", # event type "E": 1499405254326, # event time "s": "ETHBTC", # symbol "a": 70232, # aggregated tradeid "p": "0.10281118", # price "q": "8.15632997", # quantity "f": 77489, # first breakdown trade id "l": 77489, # last breakdown trade id "T": 1499405254324, # trade time "m": false, # whether buyer is a maker "M": true # can be ignored } """ return self._get_socket(symbol.lower() + "@aggTrade") def aggtrade_futures_socket( self, symbol: str, futures_type: FuturesType = FuturesType.USD_M ): """Start a websocket for aggregate symbol trade data for the futures stream :param symbol: required :param futures_type: use USD-M or COIN-M futures default USD-M :returns: connection key string if successful, False otherwise Message Format .. code-block:: python { "e": "aggTrade", // Event type "E": 123456789, // Event time "s": "BTCUSDT", // Symbol "a": 5933014, // Aggregate trade ID "p": "0.001", // Price "q": "100", // Quantity "f": 100, // First trade ID "l": 105, // Last trade ID "T": 123456785, // Trade time "m": true, // Is the buyer the market maker? } """ return self._get_futures_socket( symbol.lower() + "@aggTrade", futures_type=futures_type ) def symbol_miniticker_socket(self, symbol: str): """Start a websocket for a symbol's miniTicker data https://binance-docs.github.io/apidocs/spot/en/#individual-symbol-mini-ticker-stream :param symbol: required :type symbol: str :returns: connection key string if successful, False otherwise Message Format .. code-block:: python { "e": "24hrMiniTicker", // Event type "E": 123456789, // Event time "s": "BNBBTC", // Symbol "c": "0.0025", // Close price "o": "0.0010", // Open price "h": "0.0025", // High price "l": "0.0010", // Low price "v": "10000", // Total traded base asset volume "q": "18" // Total traded quote asset volume } """ return self._get_socket(symbol.lower() + "@miniTicker") def symbol_ticker_socket(self, symbol: str): """Start a websocket for a symbol's ticker data https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#individual-symbol-ticker-streams :param symbol: required :type symbol: str :returns: connection key string if successful, False otherwise Message Format .. code-block:: python { "e": "24hrTicker", # Event type "E": 123456789, # Event time "s": "BNBBTC", # Symbol "p": "0.0015", # Price change "P": "250.00", # Price change percent "w": "0.0018", # Weighted average price "x": "0.0009", # Previous day's close price "c": "0.0025", # Current day's close price "Q": "10", # Close trade's quantity "b": "0.0024", # Best bid price "B": "10", # Bid bid quantity "a": "0.0026", # Best ask price "A": "100", # Best ask quantity "o": "0.0010", # Open price "h": "0.0025", # High price "l": "0.0010", # Low price "v": "10000", # Total traded base asset volume "q": "18", # Total traded quote asset volume "O": 0, # Statistics open time "C": 86400000, # Statistics close time "F": 0, # First trade ID "L": 18150, # Last trade Id "n": 18151 # Total number of trades } """ return self._get_socket(symbol.lower() + "@ticker") def ticker_socket(self): """Start a websocket for all ticker data By default all markets are included in an array. https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#all-market-tickers-stream :param coro: callback function to handle messages :type coro: function :returns: connection key string if successful, False otherwise Message Format .. code-block:: python [ { 'F': 278610, 'o': '0.07393000', 's': 'BCCBTC', 'C': 1509622420916, 'b': '0.07800800', 'l': '0.07160300', 'h': '0.08199900', 'L': 287722, 'P': '6.694', 'Q': '0.10000000', 'q': '1202.67106335', 'p': '0.00494900', 'O': 1509536020916, 'a': '0.07887800', 'n': 9113, 'B': '1.00000000', 'c': '0.07887900', 'x': '0.07399600', 'w': '0.07639068', 'A': '2.41900000', 'v': '15743.68900000' } ] """ return self._get_socket("!ticker@arr") def futures_ticker_socket(self): """Start a websocket for all ticker data By default all markets are included in an array. https://binance-docs.github.io/apidocs/futures/en/#all-market-tickers-streams :returns: connection key string if successful, False otherwise Message Format .. code-block:: python [ { "e": "24hrTicker", // Event type "E": 123456789, // Event time "s": "BTCUSDT", // Symbol "p": "0.0015", // Price change "P": "250.00", // Price change percent "w": "0.0018", // Weighted average price "c": "0.0025", // Last price "Q": "10", // Last quantity "o": "0.0010", // Open price "h": "0.0025", // High price "l": "0.0010", // Low price "v": "10000", // Total traded base asset volume "q": "18", // Total traded quote asset volume "O": 0, // Statistics open time "C": 86400000, // Statistics close time "F": 0, // First trade ID "L": 18150, // Last trade Id "n": 18151 // Total number of trades } ] """ return self._get_futures_socket("!ticker@arr", FuturesType.USD_M) def futures_coin_ticker_socket(self): """Start a websocket for all ticker data By default all markets are included in an array. https://binance-docs.github.io/apidocs/delivery/en/#all-market-tickers-streams :returns: connection key string if successful, False otherwise Message Format .. code-block:: python [ { "e": "24hrTicker", // Event type "E": 123456789, // Event time "s": "BTCUSDT", // Symbol "p": "0.0015", // Price change "P": "250.00", // Price change percent "w": "0.0018", // Weighted average price "c": "0.0025", // Last price "Q": "10", // Last quantity "o": "0.0010", // Open price "h": "0.0025", // High price "l": "0.0010", // Low price "v": "10000", // Total traded base asset volume "q": "18", // Total traded quote asset volume "O": 0, // Statistics open time "C": 86400000, // Statistics close time "F": 0, // First trade ID "L": 18150, // Last trade Id "n": 18151 // Total number of trades } ] """ return self._get_futures_socket("!ticker@arr", FuturesType.COIN_M) def index_price_socket(self, symbol: str, fast: bool = True): """Start a websocket for a symbol's futures mark price https://binance-docs.github.io/apidocs/delivery/en/#index-price-stream :param symbol: required :param fast: use faster or 1s default :returns: connection key string if successful, False otherwise Message Format .. code-block:: python { "e": "indexPriceUpdate", // Event type "E": 1591261236000, // Event time "i": "BTCUSD", // Pair "p": "9636.57860000", // Index Price } """ stream_name = "@indexPrice@1s" if fast else "@indexPrice" return self._get_futures_socket( symbol.lower() + stream_name, futures_type=FuturesType.COIN_M ) def symbol_mark_price_socket( self, symbol: str, fast: bool = True, futures_type: FuturesType = FuturesType.USD_M, ): """Start a websocket for a symbol's futures mark price https://binance-docs.github.io/apidocs/futures/en/#mark-price-stream :param symbol: required :param fast: use faster or 1s default :param futures_type: use USD-M or COIN-M futures default USD-M :returns: connection key string if successful, False otherwise Message Format .. code-block:: python { "e": "markPriceUpdate", // Event type "E": 1562305380000, // Event time "s": "BTCUSDT", // Symbol "p": "11185.87786614", // Mark price "r": "0.00030000", // Funding rate "T": 1562306400000 // Next funding time } """ stream_name = "@markPrice@1s" if fast else "@markPrice" return self._get_futures_socket( symbol.lower() + stream_name, futures_type=futures_type ) def all_mark_price_socket( self, fast: bool = True, futures_type: FuturesType = FuturesType.USD_M ): """Start a websocket for all futures mark price data By default all symbols are included in an array. https://binance-docs.github.io/apidocs/futures/en/#mark-price-stream-for-all-market :param fast: use faster or 1s default :param futures_type: use USD-M or COIN-M futures default USD-M :returns: connection key string if successful, False otherwise Message Format .. code-block:: python [ { "e": "markPriceUpdate", // Event type "E": 1562305380000, // Event time "s": "BTCUSDT", // Symbol "p": "11185.87786614", // Mark price "r": "0.00030000", // Funding rate "T": 1562306400000 // Next funding time } ] """ stream_name = "!markPrice@arr@1s" if fast else "!markPrice@arr" return self._get_futures_socket(stream_name, futures_type=futures_type) def symbol_ticker_futures_socket( self, symbol: str, futures_type: FuturesType = FuturesType.USD_M ): """Start a websocket for a symbol's ticker data By default all markets are included in an array. https://binance-docs.github.io/apidocs/futures/en/#individual-symbol-book-ticker-streams :param symbol: required :param futures_type: use USD-M or COIN-M futures default USD-M :returns: connection key string if successful, False otherwise .. code-block:: python [ { "u":400900217, // order book updateId "s":"BNBUSDT", // symbol "b":"25.35190000", // best bid price "B":"31.21000000", // best bid qty "a":"25.36520000", // best ask price "A":"40.66000000" // best ask qty } ] """ return self._get_futures_socket( symbol.lower() + "@bookTicker", futures_type=futures_type ) def individual_symbol_ticker_futures_socket( self, symbol: str, futures_type: FuturesType = FuturesType.USD_M ): """Start a futures websocket for a single symbol's ticker data https://binance-docs.github.io/apidocs/futures/en/#individual-symbol-ticker-streams :param symbol: required :type symbol: str :param futures_type: use USD-M or COIN-M futures default USD-M :returns: connection key string if successful, False otherwise .. code-block:: python { "e": "24hrTicker", // Event type "E": 123456789, // Event time "s": "BTCUSDT", // Symbol "p": "0.0015", // Price change } """ return self._get_futures_socket( symbol.lower() + "@ticker", futures_type=futures_type ) def all_ticker_futures_socket( self, channel: str = "!bookTicker", futures_type: FuturesType = FuturesType.USD_M, ): """Start a websocket for all ticker data By default all markets are included in an array. https://binance-docs.github.io/apidocs/futures/en/#all-book-tickers-stream https://binance-docs.github.io/apidocs/futures/en/#all-market-tickers-streams :param channel: optional channel type, default '!bookTicker', but '!ticker@arr' is also available :param: futures_type: use USD-M or COIN-M futures default USD-M :returns: connection key string if successful, False otherwise Message Format .. code-block:: python [ { "u":400900217, // order book updateId "s":"BNBUSDT", // symbol "b":"25.35190000", // best bid price "B":"31.21000000", // best bid qty "a":"25.36520000", // best ask price "A":"40.66000000" // best ask qty } ] """ return self._get_futures_socket(channel, futures_type=futures_type) def symbol_book_ticker_socket(self, symbol: str): """Start a websocket for the best bid or ask's price or quantity for a specified symbol. https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#individual-symbol-book-ticker-streams :param symbol: required :type symbol: str :returns: connection key string if successful, False otherwise Message Format .. code-block:: python { "u":400900217, // order book updateId "s":"BNBUSDT", // symbol "b":"25.35190000", // best bid price "B":"31.21000000", // best bid qty "a":"25.36520000", // best ask price "A":"40.66000000" // best ask qty } """ return self._get_socket(symbol.lower() + "@bookTicker") def book_ticker_socket(self): """Start a websocket for the best bid or ask's price or quantity for all symbols. https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#all-book-tickers-stream :returns: connection key string if successful, False otherwise Message Format .. code-block:: python { // Same as @bookTicker payload } """ return self._get_socket("!bookTicker") def multiplex_socket(self, streams: List[str]): """Start a multiplexed socket using a list of socket names. User stream sockets can not be included. Symbols in socket name must be lowercase i.e bnbbtc@aggTrade, neobtc@ticker Combined stream events are wrapped as follows: {"stream":"","data":} https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md :param streams: list of stream names in lower case :type streams: list :returns: connection key string if successful, False otherwise Message Format - see Binance API docs for all types """ path = f"streams={'/'.join(streams)}" return self._get_socket(path, prefix="stream?") def options_multiplex_socket(self, streams: List[str]): """Start a multiplexed socket using a list of socket names. https://developers.binance.com/docs/derivatives/option/websocket-market-streams """ stream_name = "/".join([s for s in streams]) stream_path = f"streams={stream_name}" return self._get_options_socket(stream_path, prefix="stream?") def futures_multiplex_socket( self, streams: List[str], futures_type: FuturesType = FuturesType.USD_M ): """Start a multiplexed socket using a list of socket names. User stream sockets can not be included. Symbols in socket name must be lowercase i.e bnbbtc@aggTrade, neobtc@ticker Combined stream events are wrapped as follows: {"stream":"","data":} https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md :param streams: list of stream names in lower case :param futures_type: use USD-M or COIN-M futures default USD-M :returns: connection key string if successful, False otherwise Message Format - see Binance API docs for all types """ path = f"streams={'/'.join(streams)}" return self._get_futures_socket( path, prefix="stream?", futures_type=futures_type ) def user_socket(self): """Start a websocket for user data https://github.com/binance-exchange/binance-official-api-docs/blob/master/user-data-stream.md https://binance-docs.github.io/apidocs/spot/en/#listen-key-spot :returns: connection key string if successful, False otherwise Message Format - see Binance API docs for all types """ stream_url = self.STREAM_URL if self.testnet: stream_url = self.STREAM_TESTNET_URL elif self.demo: stream_url = self.STREAM_DEMO_URL return self._get_account_socket("user", stream_url=stream_url) def futures_user_socket(self): """Start a websocket for futures user data https://binance-docs.github.io/apidocs/futures/en/#user-data-streams :returns: connection key string if successful, False otherwise Message Format - see Binanace API docs for all types """ stream_url = self.FSTREAM_URL if self.testnet: stream_url = self.FSTREAM_TESTNET_URL elif self.demo: stream_url = self.FSTREAM_DEMO_URL return self._get_account_socket("futures", stream_url=stream_url) def coin_futures_user_socket(self): """Start a websocket for coin futures user data https://binance-docs.github.io/apidocs/delivery/en/#user-data-streams :returns: connection key string if successful, False otherwise Message Format - see Binanace API docs for all types """ return self._get_account_socket("coin_futures", stream_url=self.DSTREAM_URL) def margin_socket(self): """Start a websocket for cross-margin data https://binance-docs.github.io/apidocs/spot/en/#listen-key-margin :returns: connection key string if successful, False otherwise Message Format - see Binance API docs for all types """ stream_url = self.STREAM_URL if self.testnet: stream_url = self.STREAM_TESTNET_URL elif self.demo: stream_url = self.STREAM_DEMO_URL return self._get_account_socket("margin", stream_url=stream_url) def futures_socket(self): """Start a websocket for futures data https://binance-docs.github.io/apidocs/futures/en/#websocket-market-streams :returns: connection key string if successful, False otherwise Message Format - see Binance API docs for all types """ stream_url = self.FSTREAM_URL if self.testnet: stream_url = self.FSTREAM_TESTNET_URL elif self.demo: stream_url = self.FSTREAM_DEMO_URL return self._get_account_socket("futures", stream_url=stream_url) def coin_futures_socket(self): """Start a websocket for coin futures data https://binance-docs.github.io/apidocs/delivery/en/#websocket-market-streams :returns: connection key string if successful, False otherwise Message Format - see Binance API docs for all types """ stream_url = self.DSTREAM_URL if self.testnet: stream_url = self.DSTREAM_TESTNET_URL elif self.demo: stream_url = self.DSTREAM_DEMO_URL return self._get_account_socket("coin_futures", stream_url=stream_url) def portfolio_margin_socket(self): """Start a websocket for portfolio margin user data https://developers.binance.com/docs/derivatives/portfolio-margin/user-data-streams :returns: connection key string if successful, False otherwise Message Format - see Binance API docs for all types """ stream_url = self.FSTREAM_URL if self.testnet: stream_url = self.FSTREAM_TESTNET_URL elif self.demo: stream_url = self.FSTREAM_DEMO_URL stream_url += "pm/" return self._get_account_socket("portfolio_margin", stream_url=stream_url) def isolated_margin_socket(self, symbol: str): """Start a websocket for isolated margin data https://binance-docs.github.io/apidocs/spot/en/#listen-key-isolated-margin :param symbol: required - symbol for the isolated margin account :type symbol: str :returns: connection key string if successful, False otherwise Message Format - see Binance API docs for all types """ stream_url = self.STREAM_URL if self.testnet: stream_url = self.STREAM_TESTNET_URL elif self.demo: stream_url = self.STREAM_DEMO_URL return self._get_account_socket(symbol, stream_url=stream_url) def options_ticker_socket(self, symbol: str): """Subscribe to a 24-hour ticker info stream for options trading. API Reference: https://developers.binance.com/docs/derivatives/option/websocket-market-streams/24-hour-TICKER Stream provides real-time 24hr ticker information for all symbols. Only symbols whose ticker info changed will be sent. Updates every 1000ms. :param symbol: The option symbol to subscribe to (e.g. "BTC-220930-18000-C") :type symbol: str """ return self._get_options_socket(symbol.upper() + "@ticker") def options_ticker_by_expiration_socket(self, symbol: str, expiration_date: str): """Subscribe to a 24-hour ticker info stream by underlying asset and expiration date. API Reference: https://developers.binance.com/docs/derivatives/option/websocket-market-streams/24-hour-TICKER-by-underlying-asset-and-expiration-data Stream provides real-time 24hr ticker information grouped by underlying asset and expiration date. Updates every 1000ms. :param symbol: The underlying asset (e.g., "ETH") :type symbol: str :param expiration_date: The expiration date (e.g., "220930" for Sept 30, 2022) :type expiration_date: str """ return self._get_options_socket(symbol.upper() + "@ticker@" + expiration_date) def options_recent_trades_socket(self, symbol: str): """Subscribe to a real-time trade information stream. API Reference: https://developers.binance.com/docs/derivatives/option/websocket-market-streams/Trade-Streams Stream pushes raw trade information for a specific symbol or underlying asset. Updates every 50ms. :param symbol: The option symbol or underlying asset (e.g., "BTC-200630-9000-P" or "BTC") :type symbol: str """ return self._get_options_socket(symbol.upper() + "@trade") def options_kline_socket( self, symbol: str, interval=AsyncClient.KLINE_INTERVAL_1MINUTE ): """Subscribe to a Kline/Candlestick data stream. API Reference: https://developers.binance.com/docs/derivatives/option/websocket-market-streams/Kline-Candlestick-Streams Stream pushes updates to the current klines/candlestick every 1000ms (if existing). Available intervals: - Minutes: "1m", "3m", "5m", "15m", "30m" - Hours: "1h", "2h", "4h", "6h", "12h" - Days: "1d", "3d" - Weeks: "1w" :param symbol: The option symbol (e.g., "BTC-200630-9000-P") :type symbol: str :param interval: Kline interval, default KLINE_INTERVAL_1MINUTE :type interval: str """ return self._get_options_socket(symbol.upper() + "@kline_" + interval) def options_depth_socket(self, symbol: str, depth: str = "10"): """Subscribe to partial book depth stream for options trading. API Reference: https://developers.binance.com/docs/derivatives/option/websocket-market-streams/Partial-Book-Depth-Streams Stream provides top N bids and asks from the order book. Default update speed is 500ms if not specified in the stream name. :param symbol: The option symbol (e.g., "BTC-200630-9000-P") :type symbol: str :param depth: Number of price levels. Valid values: "10", "20", "50", "100" :type depth: str """ return self._get_options_socket(symbol.upper() + "@depth" + str(depth)) def futures_depth_socket(self, symbol: str, depth: str = "10", futures_type=FuturesType.USD_M): """Subscribe to a futures depth data stream https://binance-docs.github.io/apidocs/futures/en/#partial-book-depth-streams :param symbol: required :type symbol: str :param depth: optional Number of depth entries to return, default 10. :type depth: str :param futures_type: use USD-M or COIN-M futures default USD-M """ return self._get_futures_socket( symbol.lower() + "@depth" + str(depth), futures_type=futures_type ) def futures_rpi_depth_socket(self, symbol: str, futures_type=FuturesType.USD_M): """Subscribe to a futures RPI (Retail Price Improvement) depth data stream RPI orders are included and aggregated in the stream. Crossed price levels are hidden. Updates every 500ms. https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/websocket-market-streams/RPI-Order-Book :param symbol: required :type symbol: str :param futures_type: use USD-M or COIN-M futures default USD-M """ return self._get_futures_socket( symbol.lower() + "@rpiDepth@500ms", futures_type=futures_type ) def options_new_symbol_socket(self): """Subscribe to a new symbol listing information stream. Stream provides real-time notifications when new option symbols are listed. Updates every 50ms. Stream name: option_pair API Reference: https://developers.binance.com/docs/derivatives/option/websocket-market-streams/New-Symbol-Info Response fields include: - Event type and timestamps - Underlying index (e.g., 'BTCUSDT') - Quotation asset (e.g., 'USDT') - Trading pair name (e.g., 'BTC-221116-21000-C') - Conversion ratio and minimum trade volume - Option type (CALL/PUT) - Strike price and expiration time """ return self._get_options_socket("option_pair") def options_open_interest_socket(self, symbol: str, expiration_date: str): """Subscribe to an options open interest stream. Stream provides open interest information for specific underlying asset on specific expiration date. Updates every 60 seconds. Stream name format: @openInterest@ API Reference: https://developers.binance.com/docs/derivatives/option/websocket-market-streams/Open-Interest Response fields include: - Event type and timestamps - Option symbol (e.g., 'ETH-221125-2700-C') - Open interest in contracts - Open interest in USDT :param symbol: The underlying asset (e.g., "ETH") :type symbol: str :param expiration_date: The expiration date (e.g., "221125" for Nov 25, 2022) :type expiration_date: str """ return self._get_options_socket(symbol.upper() + "@openInterest@" + expiration_date) def options_mark_price_socket(self, symbol: str): """Subscribe to an options mark price stream. Stream provides mark price information for all option symbols on specific underlying asset. Updates every 1000ms. Stream name format: @markPrice API Reference: https://developers.binance.com/docs/derivatives/option/websocket-market-streams/Mark-Price Response fields include: - Event type and timestamps - Option symbol (e.g., 'ETH-220930-1500-C') - Option mark price :param symbol: The underlying asset (e.g., "ETH") :type symbol: str """ return self._get_options_socket(symbol.upper() + "@markPrice") def options_index_price_socket(self, symbol: str): """Subscribe to an options index price stream. API Reference: https://developers.binance.com/docs/derivatives/option/websocket-market-streams/Index-Price-Streams Stream provides index price information for underlying assets (e.g., ETHUSDT). Updates every 1000ms. Response fields include: - Event type and timestamps - Underlying symbol (e.g., 'ETHUSDT') - Index price :param symbol: The underlying symbol (e.g., "ETHUSDT") :type symbol: str """ return self._get_options_socket(symbol.upper() + "@index") async def _stop_socket(self, conn_key): """Stop a websocket given the connection key :param conn_key: Socket connection key :type conn_key: string :returns: None """ if conn_key not in self._conns: return del self._conns[conn_key] class ThreadedWebsocketManager(ThreadedApiManager): def __init__( self, api_key: Optional[str] = None, api_secret: Optional[str] = None, requests_params: Optional[Dict[str, Any]] = None, tld: str = "com", testnet: bool = False, session_params: Optional[Dict[str, Any]] = None, https_proxy: Optional[str] = None, loop: Optional[asyncio.AbstractEventLoop] = None, max_queue_size: int = 100, ): super().__init__( api_key, api_secret, requests_params, tld, testnet, session_params, https_proxy, loop, ) self._bsm: Optional[BinanceSocketManager] = None self._max_queue_size = max_queue_size async def _before_socket_listener_start(self): assert self._client self._bsm = BinanceSocketManager( client=self._client, max_queue_size=self._max_queue_size ) def _start_async_socket( self, callback: Callable, socket_name: str, params: Dict[str, Any], path: Optional[str] = None, ) -> str: start_time = time.time() while not self._bsm: if time.time() - start_time > 5: raise RuntimeError("Binance Socket Manager failed to initialize after 5 seconds") time.sleep(0.1) socket = getattr(self._bsm, socket_name)(**params) socket_path: str = path or socket._path # noqa self._socket_running[socket_path] = True self._loop.call_soon_threadsafe( asyncio.create_task, self.start_listener(socket, socket_path, callback) ) return socket_path def start_depth_socket( self, callback: Callable, symbol: str, depth: Optional[str] = None, interval: Optional[int] = None, ) -> str: return self._start_async_socket( callback=callback, socket_name="depth_socket", params={ "symbol": symbol, "depth": depth, "interval": interval, }, ) def start_kline_socket( self, callback: Callable, symbol: str, interval=AsyncClient.KLINE_INTERVAL_1MINUTE, ) -> str: return self._start_async_socket( callback=callback, socket_name="kline_socket", params={ "symbol": symbol, "interval": interval, }, ) def start_kline_futures_socket( self, callback: Callable, symbol: str, interval=AsyncClient.KLINE_INTERVAL_1MINUTE, futures_type: FuturesType = FuturesType.USD_M, contract_type: ContractType = ContractType.PERPETUAL, ) -> str: return self._start_async_socket( callback=callback, socket_name="kline_futures_socket", params={ "symbol": symbol, "interval": interval, "futures_type": futures_type, "contract_type": contract_type, }, ) def start_miniticker_socket( self, callback: Callable, update_time: int = 1000 ) -> str: return self._start_async_socket( callback=callback, socket_name="miniticker_socket", params={ "update_time": update_time, }, ) def start_trade_socket(self, callback: Callable, symbol: str) -> str: return self._start_async_socket( callback=callback, socket_name="trade_socket", params={ "symbol": symbol, }, ) def start_aggtrade_socket(self, callback: Callable, symbol: str) -> str: return self._start_async_socket( callback=callback, socket_name="aggtrade_socket", params={ "symbol": symbol, }, ) def start_aggtrade_futures_socket( self, callback: Callable, symbol: str, futures_type: FuturesType = FuturesType.USD_M, ) -> str: return self._start_async_socket( callback=callback, socket_name="aggtrade_futures_socket", params={ "symbol": symbol, "futures_type": futures_type, }, ) def start_symbol_miniticker_socket(self, callback: Callable, symbol: str) -> str: return self._start_async_socket( callback=callback, socket_name="symbol_miniticker_socket", params={ "symbol": symbol, }, ) def start_symbol_ticker_socket(self, callback: Callable, symbol: str) -> str: return self._start_async_socket( callback=callback, socket_name="symbol_ticker_socket", params={ "symbol": symbol, }, ) def start_ticker_socket(self, callback: Callable) -> str: return self._start_async_socket( callback=callback, socket_name="ticker_socket", params={} ) def start_index_price_socket( self, callback: Callable, symbol: str, fast: bool = True ) -> str: return self._start_async_socket( callback=callback, socket_name="index_price_socket", params={"symbol": symbol, "fast": fast}, ) def start_symbol_mark_price_socket( self, callback: Callable, symbol: str, fast: bool = True, futures_type: FuturesType = FuturesType.USD_M, ) -> str: return self._start_async_socket( callback=callback, socket_name="symbol_mark_price_socket", params={"symbol": symbol, "fast": fast, "futures_type": futures_type}, ) def start_all_mark_price_socket( self, callback: Callable, fast: bool = True, futures_type: FuturesType = FuturesType.USD_M, ) -> str: return self._start_async_socket( callback=callback, socket_name="all_mark_price_socket", params={"fast": fast, "futures_type": futures_type}, ) def start_symbol_ticker_futures_socket( self, callback: Callable, symbol: str, futures_type: FuturesType = FuturesType.USD_M, ) -> str: return self._start_async_socket( callback=callback, socket_name="symbol_ticker_futures_socket", params={"symbol": symbol, "futures_type": futures_type}, ) def start_individual_symbol_ticker_futures_socket( self, callback: Callable, symbol: str, futures_type: FuturesType = FuturesType.USD_M, ) -> str: return self._start_async_socket( callback=callback, socket_name="individual_symbol_ticker_futures_socket", params={"symbol": symbol, "futures_type": futures_type}, ) def start_all_ticker_futures_socket( self, callback: Callable, futures_type: FuturesType = FuturesType.USD_M ) -> str: return self._start_async_socket( callback=callback, socket_name="all_ticker_futures_socket", params={"futures_type": futures_type}, ) def start_symbol_book_ticker_socket(self, callback: Callable, symbol: str) -> str: return self._start_async_socket( callback=callback, socket_name="symbol_book_ticker_socket", params={"symbol": symbol}, ) def start_book_ticker_socket(self, callback: Callable) -> str: return self._start_async_socket( callback=callback, socket_name="book_ticker_socket", params={} ) def start_multiplex_socket(self, callback: Callable, streams: List[str]) -> str: return self._start_async_socket( callback=callback, socket_name="multiplex_socket", params={"streams": streams}, ) def start_options_multiplex_socket( self, callback: Callable, streams: List[str] ) -> str: return self._start_async_socket( callback=callback, socket_name="options_multiplex_socket", params={"streams": streams}, ) def start_futures_multiplex_socket( self, callback: Callable, streams: List[str], futures_type: FuturesType = FuturesType.USD_M, ) -> str: return self._start_async_socket( callback=callback, socket_name="futures_multiplex_socket", params={"streams": streams, "futures_type": futures_type}, ) def start_user_socket(self, callback: Callable) -> str: return self._start_async_socket( callback=callback, socket_name="user_socket", params={} ) def start_futures_user_socket(self, callback: Callable) -> str: return self._start_async_socket( callback=callback, socket_name="futures_user_socket", params={} ) def start_coin_futures_user_socket(self, callback: Callable) -> str: return self._start_async_socket( callback=callback, socket_name="coin_futures_user_socket", params={} ) def start_margin_socket(self, callback: Callable) -> str: return self._start_async_socket( callback=callback, socket_name="margin_socket", params={} ) def start_futures_socket(self, callback: Callable) -> str: return self._start_async_socket( callback=callback, socket_name="futures_socket", params={} ) def start_coin_futures_socket(self, callback: Callable) -> str: return self._start_async_socket( callback=callback, socket_name="coin_futures_socket", params={} ) def start_isolated_margin_socket(self, callback: Callable, symbol: str) -> str: return self._start_async_socket( callback=callback, socket_name="isolated_margin_socket", params={"symbol": symbol}, ) def start_options_ticker_socket(self, callback: Callable, symbol: str) -> str: return self._start_async_socket( callback=callback, socket_name="options_ticker_socket", params={"symbol": symbol}, ) def start_options_ticker_by_expiration_socket( self, callback: Callable, symbol: str, expiration_date: str ) -> str: return self._start_async_socket( callback=callback, socket_name="options_ticker_by_expiration_socket", params={"symbol": symbol, "expiration_date": expiration_date}, ) def start_options_recent_trades_socket( self, callback: Callable, symbol: str ) -> str: return self._start_async_socket( callback=callback, socket_name="options_recent_trades_socket", params={"symbol": symbol}, ) def start_options_kline_socket( self, callback: Callable, symbol: str, interval=AsyncClient.KLINE_INTERVAL_1MINUTE, ) -> str: return self._start_async_socket( callback=callback, socket_name="options_kline_socket", params={"symbol": symbol, "interval": interval}, ) def start_options_depth_socket( self, callback: Callable, symbol: str, depth: str = "10" ) -> str: return self._start_async_socket( callback=callback, socket_name="options_depth_socket", params={"symbol": symbol, "depth": depth}, ) def start_futures_depth_socket( self, callback: Callable, symbol: str, depth: str = "10", futures_type=FuturesType.USD_M, ) -> str: return self._start_async_socket( callback=callback, socket_name="futures_depth_socket", params={"symbol": symbol, "depth": depth, "futures_type": futures_type}, ) ================================================ FILE: binance/ws/threaded_stream.py ================================================ import asyncio import logging import threading from typing import Optional, Dict, Any from binance.async_client import AsyncClient from binance.helpers import get_loop class ThreadedApiManager(threading.Thread): def __init__( self, api_key: Optional[str] = None, api_secret: Optional[str] = None, requests_params: Optional[Dict[str, Any]] = None, tld: str = "com", testnet: bool = False, session_params: Optional[Dict[str, Any]] = None, https_proxy: Optional[str] = None, _loop: Optional[asyncio.AbstractEventLoop] = None, verbose: bool = False, ): """Initialise the ThreadedApiManager :param api_key: Binance API key :param api_secret: Binance API secret :param requests_params: optional - Dictionary of requests params :param tld: optional - Top level domain, default is 'com' :param testnet: optional - Use testnet endpoint :param session_params: optional - Session params for aiohttp :param https_proxy: optional - Proxy URL :param _loop: optional - Event loop :param verbose: Enable verbose logging for WebSocket connections :type verbose: bool """ super().__init__() self._loop: asyncio.AbstractEventLoop = get_loop() if _loop is None else _loop self._client: Optional[AsyncClient] = None self._running: bool = True self._socket_running: Dict[str, bool] = {} self._log = logging.getLogger(__name__) self.verbose = verbose self._client_params = { "api_key": api_key, "api_secret": api_secret, "requests_params": requests_params, "tld": tld, "testnet": testnet, "session_params": session_params, "https_proxy": https_proxy, "verbose": verbose, } if verbose: logging.getLogger('binance.ws').setLevel(logging.DEBUG) async def _before_socket_listener_start(self): ... async def socket_listener(self): try: self._client = await AsyncClient.create(loop=self._loop, **self._client_params) await self._before_socket_listener_start() except Exception as e: self._log.error(f"Failed to create client: {e}") self.stop() while self._running: await asyncio.sleep(0.2) while self._socket_running: await asyncio.sleep(0.2) self._log.info("Socket listener stopped") async def start_listener(self, socket, path: str, callback): async with socket as s: while self._socket_running[path]: try: msg = await asyncio.wait_for(s.recv(), 3) except asyncio.TimeoutError: ... continue except Exception as e: self._log.error(f"Error receiving message: {e}") msg = { "e": "error", "type": e.__class__.__name__, "m": f"{e}", } if not msg: continue # Handle both async and sync callbacks if asyncio.iscoroutinefunction(callback): asyncio.create_task(callback(msg)) else: callback(msg) del self._socket_running[path] def run(self): self._loop.run_until_complete(self.socket_listener()) def stop_socket(self, socket_name): if socket_name in self._socket_running: self._socket_running[socket_name] = False async def stop_client(self): if not self._client: return await self._client.close_connection() def stop(self): self._log.debug("Stopping ThreadedApiManager") if not self._running: return self._running = False if self._client and self._loop and not self._loop.is_closed(): try: future = asyncio.run_coroutine_threadsafe( self.stop_client(), self._loop ) future.result(timeout=5) # Add timeout to prevent hanging except Exception as e: # Log the error but don't raise it self._log.error(f"Error stopping client: {e}") for socket_name in self._socket_running.keys(): self._socket_running[socket_name] = False ================================================ FILE: binance/ws/websocket_api.py ================================================ from typing import Dict, Optional import asyncio from websockets import WebSocketClientProtocol # type: ignore from .constants import WSListenerState from .reconnecting_websocket import ReconnectingWebsocket from binance.exceptions import BinanceAPIException, BinanceWebsocketUnableToConnect class WebsocketAPI(ReconnectingWebsocket): def __init__(self, url: str, tld: str = "com", testnet: bool = False, https_proxy: Optional[str] = None): self._tld = tld self._testnet = testnet self._responses: Dict[str, asyncio.Future] = {} self._connection_lock: Optional[asyncio.Lock] = None # Subscription queues for routing user data stream events self._subscription_queues: Dict[str, asyncio.Queue] = {} super().__init__(url=url, prefix="", path="", is_binary=False, https_proxy=https_proxy) def register_subscription_queue(self, subscription_id: str, queue: asyncio.Queue) -> None: """Register a queue to receive events for a specific subscription.""" self._subscription_queues[subscription_id] = queue def unregister_subscription_queue(self, subscription_id: str) -> None: """Unregister a subscription queue.""" self._subscription_queues.pop(subscription_id, None) @property def connection_lock(self) -> asyncio.Lock: if self._connection_lock is None: loop = asyncio.get_event_loop() self._connection_lock = asyncio.Lock() return self._connection_lock def _handle_message(self, msg): """Override message handling to support request-response""" parsed_msg = super()._handle_message(msg) self._log.debug(f"Received message: {parsed_msg}") if parsed_msg is None: return None # Check if this is a subscription event (user data stream, etc.) # These have 'subscriptionId' and 'event' fields instead of 'id' if "subscriptionId" in parsed_msg and "event" in parsed_msg: subscription_id = parsed_msg["subscriptionId"] event = parsed_msg["event"] # Route to the registered subscription queue if one exists if subscription_id in self._subscription_queues: queue = self._subscription_queues[subscription_id] try: queue.put_nowait(event) except asyncio.QueueFull: self._log.error(f"Subscription queue full for {subscription_id}, dropping event") except Exception as e: self._log.error(f"Error putting event in subscription queue for {subscription_id}: {e}") return None # Don't put in main queue else: # No registered queue, return event for main queue (backward compat) return event req_id, exception = None, None if "id" in parsed_msg: req_id = parsed_msg["id"] if "status" in parsed_msg: if parsed_msg["status"] != 200: exception = BinanceAPIException( parsed_msg, parsed_msg["status"], self.json_dumps(parsed_msg["error"]) ) if req_id is not None and req_id in self._responses: if exception is not None: self._responses[req_id].set_exception(exception) else: self._responses[req_id].set_result(parsed_msg) return None # Don't queue request-response messages elif exception is not None: raise exception else: self._log.warning(f"WS api receieved unknown message: {parsed_msg}") return None async def _ensure_ws_connection(self) -> None: """Ensure WebSocket connection is established and ready This function will: 1. Check if connection exists and is streaming 2. Attempt to connect if not 3. Wait for connection to be ready 4. Handle reconnection if needed """ async with self.connection_lock: try: if ( self.ws is None or (isinstance(self.ws, WebSocketClientProtocol) and self.ws.closed) or self.ws_state != WSListenerState.STREAMING ): await self.connect() # Wait for connection to be ready retries = 0 while ( self.ws_state != WSListenerState.STREAMING and retries < self.MAX_RECONNECTS ): if self.ws_state == WSListenerState.RECONNECTING: self._log.info("Connection is reconnecting, waiting...") await self._wait_for_reconnect() elif self.ws is None or self.ws.closed: self._log.info("Connection lost, reconnecting...") await self.connect() retries += 1 await asyncio.sleep(self.MIN_RECONNECT_WAIT) if self.ws_state != WSListenerState.STREAMING: raise BinanceWebsocketUnableToConnect( f"Failed to establish connection after {retries} attempts" ) self._log.debug("WebSocket connection established") except Exception as e: self._log.error(f"Error ensuring WebSocket connection: {e}") raise BinanceWebsocketUnableToConnect(f"Connection failed: {str(e)}") async def request(self, id: str, payload: dict) -> dict: """Send request and wait for response""" await self._ensure_ws_connection() # Create future for response future = asyncio.Future() self._responses[id] = future try: # Send request if self.ws is None: raise BinanceWebsocketUnableToConnect( "Trying to send request while WebSocket is not connected" ) await self.ws.send(self.json_dumps(payload)) # Wait for response response = await asyncio.wait_for(future, timeout=self.TIMEOUT) # Check for errors if "error" in response: raise BinanceWebsocketUnableToConnect(response["error"]) return response.get("result", response) except asyncio.TimeoutError: raise BinanceWebsocketUnableToConnect("Request timed out") except Exception as e: raise e finally: self._responses.pop(id, None) async def __aexit__(self, exc_type, exc_val, exc_tb): """Clean up responses before closing""" response_ids = list(self._responses.keys()) # Create a copy of keys for req_id in response_ids: future = self._responses.pop(req_id) # Remove and get the future if not future.done(): future.set_exception( BinanceWebsocketUnableToConnect("WebSocket closing") ) await super().__aexit__(exc_type, exc_val, exc_tb) ================================================ FILE: code-generator.py ================================================ import re import requests from bs4 import BeautifulSoup import os from binance.client import Client from binance.exceptions import BinanceAPIException URLS = [ 'https://developers.binance.com/docs/binance-spot-api-docs', 'https://developers.binance.com/docs/derivatives/change-log', 'https://developers.binance.com/docs/margin_trading/change-log', 'https://developers.binance.com/docs/algo/change-log', 'https://developers.binance.com/docs/wallet/change-log', 'https://developers.binance.com/docs/copy_trading/change-log', 'https://developers.binance.com/docs/convert/change-log', 'https://developers.binance.com/docs/sub_account/change-log', 'https://developers.binance.com/docs/binance_link/change-log', 'https://developers.binance.com/docs/auto_invest/change-log', 'https://developers.binance.com/docs/staking/change-log', 'https://developers.binance.com/docs/dual_investment/change-log', 'https://developers.binance.com/docs/mining/change-log', 'https://developers.binance.com/docs/crypto_loan/change-log', 'https://developers.binance.com/docs/vip_loan/change-log', 'https://developers.binance.com/docs/c2c/change-log', 'https://developers.binance.com/docs/fiat/change-log', 'https://developers.binance.com/docs/nft/change-log', 'https://developers.binance.com/docs/gift_card/change-log', 'https://developers.binance.com/docs/rebate/change-log', 'https://developers.binance.com/docs/simple_earn/change-log', 'https://developers.binance.com/docs/pay/change-log' ] # Map endpoint prefixes to client.py's request methods PREFIX_MAP = { '/api': '_request_api', '/sapi': '_request_margin_api', '/papi': '_request_papi_api', '/fapi': '_request_futures_api', '/dapi': '_request_futures_coin_api', '/eapi': '_request_options_api', '/wapi': '_request_website' } DEPRECATED_PREFIXES = [ '/wapi', ] DEPRECATED_ENDPOINTS = [ ('GET', '/fapi/v1/ticker/price'), ('GET', '/fapi/v1/pmExchangeInfo'), ('POST', '/api/v3/order/oco'), ('POST', '/sapi/v1/eth-staking/eth/stake'), ('GET', '/sapi/v1/eth-staking/account'), ('GET', '/sapi/v1/portfolio/interest-rate'), ('GET', '/api/v1/order'), ('GET', '/api/v1/openOrders'), ('POST', '/api/v1/order'), ('DELETE', '/api/v1/order'), ('GET', '/api/v1/allOrders'), ('GET', '/api/v1/account'), ('GET', '/api/v1/myTrades'), ('POST', '/sapi/v1/loan/flexible/borrow'), ('GET', '/sapi/v1/loan/flexible/ongoing/orders'), ('GET', '/sapi/v1/loan/flexible/borrow/history'), ('POST', '/sapi/v1/loan/flexible/repay'), ('GET', '/sapi/v1/loan/flexible/repay/history'), ('POST', '/sapi/v1/loan/flexible/adjust/ltv'), ('GET', '/sapi/v1/loan/flexible/ltv/adjustment/history'), ('GET', '/sapi/v1/loan/flexible/loanable/data'), ('GET', '/sapi/v1/loan/flexible/collateral/data') ] # Some request methods do not require a version argument NO_VERSION_FUNCTIONS = [ '_request_options_api', '_request_futures_data_api' ] def fetch_endpoints(): """Fetch endpoints from the provided Binance doc URLs, filtering duplicates.""" endpoints = set() deprecated_endpoints = set() for url in URLS: print(f'Fetching {url}') page = requests.get(url) soup = BeautifulSoup(page.content, 'html.parser') all_code_blocks = soup.find_all('code') for code in all_code_blocks: code_text = code.get_text().strip() parts = code_text.split(' ') if len(parts) >=2: parts[0] = parts[0].strip() parts[1] = parts[1].strip().split('?')[0] # Basic check for lines that look like: GET /path or POST /path etc. if len(parts) >= 2 and parts[0] in ['GET', 'POST', 'PUT', 'DELETE'] and parts[1] is not None and parts[1] != '': method = parts[0] endpoint = parts[1] # Ensure endpoint starts with / if not endpoint.startswith('/'): endpoint = '/' + endpoint # Check both deprecated prefixes and specific endpoints if any(endpoint.startswith(prefix) for prefix in DEPRECATED_PREFIXES) or (method, endpoint) in DEPRECATED_ENDPOINTS: deprecated_endpoints.add((method, endpoint)) continue # Skip adding to main endpoints set # Use a tuple of (method, endpoint) for uniqueness endpoints.add((method, endpoint)) print(f'Found {len(deprecated_endpoints)} deprecated endpoints in the docs.') print(f'Found {len(endpoints)} unique endpoints in the docs.') # Filter endpoints that don't start with any known prefix valid_endpoints = { (method, endpoint) for method, endpoint in endpoints if any(endpoint.startswith(prefix) for prefix in PREFIX_MAP.keys()) } filtered_count = len(endpoints) - len(valid_endpoints) print(f'Filtered out {filtered_count} endpoints that don\'t match known prefixes') print(f'Remaining endpoints: {len(valid_endpoints)}') return valid_endpoints def get_request_function_and_path(endpoint: str) -> tuple[str | None, str | None, int | None]: """ Given an endpoint (e.g. '/sapi/v1/userInfo'), determine which _request_*_api function is appropriate in the client, remove the recognized prefix plus any version segments (e.g. /v1/), parse out any version (v1, v2, etc.), and return (request_function, stripped_path, version). Example: endpoint = '/sapi/v1/exchangeInfo' -> returns ('_request_margin_api', 'exchangeInfo', 1) If no recognized prefix is found, return (None, None, None). If no version is found, version will be None. """ # Sort prefixes by length descending to match the longest prefix first sorted_prefixes = sorted(PREFIX_MAP.keys(), key=len, reverse=True) request_func = None stripped = None # Identify which prefix is present, if any matched_prefix = None for prefix in sorted_prefixes: if endpoint.startswith(prefix): request_func = PREFIX_MAP[prefix] matched_prefix = prefix break # If no recognized prefix, return null if not request_func or matched_prefix is None: return None, None, None stripped = endpoint[len(matched_prefix):] # Attempt to parse out the version, e.g. '/v1/', '/v2/' version_match = re.search(r'/v(\d+)/', stripped) version = None if version_match: # Convert the matched text into an integer version = int(version_match.group(1)) # Remove version segments like /v1/, /v2/ if stripped: stripped = re.sub(r'/v\d+/', '/', stripped) # Strip leading/trailing slashes stripped = stripped.strip('/') return request_func, stripped, version def check_method_in_file(method, endpoint, file_name): """ Return True if a function for this endpoint likely exists in client.py. """ if not os.path.isfile(file_name): print(f'{file_name} does not exist') return False func_name, stripped_path, version = get_request_function_and_path(endpoint) # If no known request function is found, we consider it not found. if not func_name or not stripped_path: print(f'No known request function for endpoint: {endpoint}') return False with open(file_name, 'r', encoding='utf-8') as f: content = f.read() # Remove any leftover version tokens from the path stripped_path = re.sub(r'^v\d+/', '', stripped_path) stripped_path = re.sub(r'/v\d+/', '/', stripped_path) patterns = [] if func_name == "_request_api": if version == 3: # v3 endpoints use PRIVATE_API_VERSION or "v3" patterns.extend([ # Direct request with PRIVATE_API_VERSION rf'{re.escape(func_name)}\s*\(\s*"{re.escape(method.lower())}"\s*,\s*"{re.escape(stripped_path)}"[\s\S]*?version\s*=\s*self\.PRIVATE_API_VERSION[\s\S]*?\)', # Direct request with "v3" rf'{re.escape(func_name)}\s*\(\s*"{re.escape(method.lower())}"\s*,\s*"{re.escape(stripped_path)}"[\s\S]*?version\s*=\s*["\']v3["\'][\s\S]*?\)', # Helper method with PRIVATE_API_VERSION rf'_{method.lower()}\s*\(\s*"{re.escape(stripped_path)}"(?:\s*,\s*(?:True|False))?[\s\S]*?version\s*=\s*self\.PRIVATE_API_VERSION[\s\S]*?\)', # Helper method with "v3" rf'_{method.lower()}\s*\(\s*"{re.escape(stripped_path)}"(?:\s*,\s*(?:True|False))?[\s\S]*?version\s*=\s*["\']v3["\'][\s\S]*?\)' ]) elif version == 1: # v1 endpoints can use either no version arg, PUBLIC_API_VERSION, or "v1" patterns.extend([ # Direct request with no version rf'{re.escape(func_name)}\s*\(\s*"{re.escape(method.lower())}"\s*,\s*"{re.escape(stripped_path)}"[\s\S]*?\)', # Direct request with PUBLIC_API_VERSION rf'{re.escape(func_name)}\s*\(\s*"{re.escape(method.lower())}"\s*,\s*"{re.escape(stripped_path)}"[\s\S]*?version\s*=\s*self\.PUBLIC_API_VERSION[\s\S]*?\)', # Direct request with "v1" rf'{re.escape(func_name)}\s*\(\s*"{re.escape(method.lower())}"\s*,\s*"{re.escape(stripped_path)}"[\s\S]*?version\s*=\s*["\']v1["\'][\s\S]*?\)', # Helper method with no version rf'_{method.lower()}\s*\(\s*"{re.escape(stripped_path)}"(?:\s*,\s*(?:True|False))?[\s\S]*?\)', # Helper method with PUBLIC_API_VERSION rf'_{method.lower()}\s*\(\s*"{re.escape(stripped_path)}"(?:\s*,\s*(?:True|False))?[\s\S]*?version\s*=\s*self\.PUBLIC_API_VERSION[\s\S]*?\)', # Helper method with "v1" rf'_{method.lower()}\s*\(\s*"{re.escape(stripped_path)}"(?:\s*,\s*(?:True|False))?[\s\S]*?version\s*=\s*["\']v1["\'][\s\S]*?\)' ]) else: # Non-API requests (margin, futures, etc.) patterns.append( rf'{re.escape(func_name)}\s*\(\s*"{re.escape(method.lower())}"\s*,\s*"{re.escape(stripped_path)}"' ) # Check all patterns for pattern in patterns: if re.search(pattern, content, re.DOTALL): return True return False def convert_to_function_name(method: str, endpoint: str) -> str: """ Convert an endpoint path to a consistent function name format with appropriate prefix and version. Examples: GET, /api/v3/ticker/tradingDay -> v3_get_ticker_trading_day GET, /sapi/v1/margin/order -> margin_v1_get_order GET, /fapi/v1/ticker/price -> futures_v1_get_ticker_price GET, /dapi/v1/ticker/price -> futures_coin_v1_get_ticker_price GET, /vapi/v1/ticker -> options_v1_get_ticker """ # Get the request function and path info request_function, cleaned_endpoint, version = get_request_function_and_path(endpoint) # Map request functions to their prefix in the function name PREFIX_NAME_MAP = { '_request_margin_api': 'margin', '_request_papi_api': 'papi', '_request_futures_api': 'futures', '_request_futures_coin_api': 'futures_coin', '_request_options_api': 'options' } # Remove known prefixes and version segments first cleaned_endpoint = endpoint sorted_prefixes = sorted(PREFIX_MAP.keys(), key=len, reverse=True) for prefix in sorted_prefixes: if cleaned_endpoint.startswith(prefix): cleaned_endpoint = cleaned_endpoint[len(prefix):] break # Remove version segments and leading/trailing slashes cleaned_endpoint = re.sub(r'/v\d+/', '/', cleaned_endpoint) cleaned_endpoint = cleaned_endpoint.strip('/') # Split on slashes and process each part parts = cleaned_endpoint.split('/') processed_parts = [] for part in parts: # Replace hyphens with underscores part = part.replace('-', '_') part = part.replace('.', '_') # Insert underscore before capital letters in camelCase part = re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', part) # Convert to lowercase part = part.lower() # Remove any duplicate underscores part = re.sub(r'_+', '_', part) processed_parts.append(part) # Join all parts with underscores base_name = '_'.join(processed_parts) base_name = re.sub(r'_+', '_', base_name) # Remove any duplicate underscores # Add version to the name (default to v1 if no version found) version_str = f"v{version if version else ''}" # Prepend the appropriate prefix if this is a special endpoint if request_function in PREFIX_NAME_MAP: prefix = PREFIX_NAME_MAP[request_function] return f"{prefix}_{version_str}_{method.lower()}_{base_name}" # Default case (for _request_api) return f"{version_str}_{method.lower()}_{base_name}" def check_function(method, request_function, cleaned_endpoint, version_arg, params={}): """ Check if the function is signed based on the endpoint. If not found or deprecated, return None. For GET requests, call the endpoint and check if it returns an error indicating a signature is required. """ if method != "GET": return True else: try: client = Client("", "") client_function = getattr(client, request_function) version = {"version": version_arg} if version_arg else {} client_function( method.lower(), cleaned_endpoint, signed=False, **version, **params ) return False except BinanceAPIException as e: if e.status_code == 400 and "symbol" in e.message: return check_function(method, request_function, cleaned_endpoint, version_arg, {'data': {'symbol': 'BTCUSDT'}}) if 'signature' in e.message or 'API-key' in e.message: return True if 'The endpoint has been out of maintenance' in e.message or \ 'This endpoint has been deprecated, please remove as soon as possible.' in e.message or \ e.status_code == 404: return None else: print(f"Error calling endpoint {request_function} - {cleaned_endpoint} - {version_arg} - {params}") return None except Exception as e: print(f"Error calling endpoint {request_function} - {cleaned_endpoint} - {version_arg} - {params}") return None def generate_function_code(method, endpoint, type="sync", file_name="./binance/client.py"): """ Determines which _request_*_api function, path, and version to call based on the endpoint, generates a placeholder function to handle the specified method/endpoint. If the chosen request function is in NO_VERSION_FUNCTIONS, the code does not pass a 'version' argument. If no recognized prefix is found, returns an empty string. If GET function will test if the endpoint is public or not """ request_function, cleaned_endpoint, version = get_request_function_and_path(endpoint) # If no recognized prefix, skip generating if not request_function: return "" func_name = convert_to_function_name(method, endpoint) # Build version argument if needed version_string = "" if request_function in NO_VERSION_FUNCTIONS or version is None: # No version arg is needed version_arg = None elif request_function == "_request_api": version_arg = f"v{version}" else: # If a version was found, pass version= the integer, else default to 1 version_arg = version if version else 1 if version_arg is not None: if isinstance(version_arg, str): version_string = f', version="{version_arg}"' else: version_string = f", version={version_arg}" is_signed = check_function(method, request_function, cleaned_endpoint, version_arg) if is_signed is None: return code_snippet = "" if type == "sync": code_snippet = f""" def {func_name}(self, **params): \"\"\" Placeholder function for {method.upper()} {endpoint}. Note: This function was auto-generated. Any issue please open an issue on GitHub. :param params: parameters required by the endpoint :type params: dict :returns: API response \"\"\" return self.{request_function}("{method.lower()}", "{cleaned_endpoint}", signed={is_signed}, data=params{version_string}) """ elif type == "async": code_snippet = f""" async def {func_name}(self, **params): return await self.{request_function}("{method.lower()}", "{cleaned_endpoint}", signed={is_signed}, data=params{version_string}) """ with open('./binance/client.py', 'r', encoding='utf-8') as f: content = f.read() if f"def {func_name}("in content: code_snippet += f""" {func_name}.__doc__ = Client.{func_name}.__doc__ """ with open(file_name, 'a', encoding='utf-8') as f: f.write(code_snippet) def write_function_to_endpoints_md(method, endpoint): """ Append a brief reference entry to Endpoints.md, showing the usage example. First checks if the entry already exists to avoid duplicates. """ function_name = convert_to_function_name(method, endpoint) # Check if the entry already exists with open('Endpoints.md', 'r', encoding='utf-8') as f: content = f.read() # Look for the exact method and endpoint if f"**{method.upper()} {endpoint}" in content: return False # Create the entry we want to add md_entry = ( f"\t- **{method} {endpoint}**\n" f" ```python\n" f" client.{function_name}(**params)\n" f" ```\n\n" ) # If we get here, the entry doesn't exist, so append it with open('Endpoints.md', 'a', encoding='utf-8') as f: f.write(md_entry) return True def main(): endpoints = fetch_endpoints() # Write to Endpoints.md endpoints_md_created = 0 for method, endpoint in endpoints: success = write_function_to_endpoints_md(method, endpoint) if success: endpoints_md_created += 1 print(f"Added {endpoints_md_created} endpoints to Endpoints.md") # Filter out endpoints already in client.py new_endpoints = [] for method, endpoint in endpoints: if not check_method_in_file(method, endpoint, './binance/client.py'): new_endpoints.append((method, endpoint)) print(f"{len(new_endpoints)} endpoints were added out of {len(endpoints)} scrapped in client.py") # Generate placeholder code for these endpoints for method, endpoint in new_endpoints: generate_function_code(method, endpoint, type="sync", file_name="./binance/client.py") # Generate async functions new_endpoints_async = [] for method, endpoint in endpoints: if not check_method_in_file(method, endpoint, './binance/async_client.py'): new_endpoints_async.append((method, endpoint)) for method, endpoint in new_endpoints_async: generate_function_code(method, endpoint, type="async", file_name="./binance/async_client.py") print(f"{len(new_endpoints_async)} endpoints were added out of {len(endpoints)} scrapped in async_client.py") if __name__ == "__main__": main() ================================================ FILE: docs/Makefile ================================================ # Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = python -msphinx SPHINXPROJ = python-binance SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) rst: sphinx-apidoc -f -o ./ ../ ================================================ FILE: docs/account.rst ================================================ Account Endpoints ================= Orders ------ Order Validation ^^^^^^^^^^^^^^^^ Binance has a number of rules around symbol pair orders with validation on minimum price, quantity and total order value. Read more about their specifics in the `Filters `_ section of the official API. Read `Understanding Binance Order Filters `_ for more information about price and quantity filters on `Binance `_. It can be helpful to format the output using formatting .. code:: python amount = 0.000234234 precision = 5 amt_str = "{:0.0{}f}".format(amount, precision) Or if you have the tickSize or stepSize then use the helper to round to step size .. code:: python from binance.helpers import round_step_size amount = 0.000234234 tick_size = 0.00001 rounded_amount = round_step_size(amount, tick_size) `Fetch all orders `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python orders = client.get_all_orders(symbol='BNBBTC', limit=10) `Place an order `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Place an order** Use the `create_order` function to have full control over creating an order .. code:: python from binance.enums import * order = client.create_order( symbol='BNBBTC', side=SIDE_BUY, type=ORDER_TYPE_LIMIT, timeInForce=TIME_IN_FORCE_GTC, quantity=100, price='0.00001') **Place a limit order** Use the helper functions to easily place a limit buy or sell order .. code:: python order = client.order_limit_buy( symbol='BNBBTC', quantity=100, price='0.00001') order = client.order_limit_sell( symbol='BNBBTC', quantity=100, price='0.00001') **Place a market order** Use the helper functions to easily place a market buy or sell order .. code:: python order = client.order_market_buy( symbol='BNBBTC', quantity=100) order = client.order_market_sell( symbol='BNBBTC', quantity=100) **Place an OCO order** Use the `create_oco_order` function to have full control over creating an OCO order .. code:: python from binance.enums import * order = client.create_oco_order( symbol='BNBBTC', side=SIDE_SELL, stopLimitTimeInForce=TIME_IN_FORCE_GTC, quantity=100, stopPrice='0.00001', price='0.00002') `Place a test order `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Creates and validates a new order but does not send it into the exchange. .. code:: python from binance.enums import * order = client.create_test_order( symbol='BNBBTC', side=SIDE_BUY, type=ORDER_TYPE_LIMIT, timeInForce=TIME_IN_FORCE_GTC, quantity=100, price='0.00001') `Check order status `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python order = client.get_order( symbol='BNBBTC', orderId='orderId') `Cancel an order `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python result = client.cancel_order( symbol='BNBBTC', orderId='orderId') `Get all open orders `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python orders = client.get_open_orders(symbol='BNBBTC') `Get all orders `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python orders = client.get_all_orders(symbol='BNBBTC') Account ------- `Get account info `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python info = client.get_account() `Get asset balance `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python balance = client.get_asset_balance(asset='BTC') `Get account status `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python status = client.get_account_status() `Get account API trading status `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python status = client.get_account_api_trading_status() `Get trades `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python trades = client.get_my_trades(symbol='BNBBTC') `Get trade fees `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python # get fees for all symbols fees = client.get_trade_fee() # get fee for one symbol fees = client.get_trade_fee(symbol='BNBBTC') `Get asset details `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python details = client.get_asset_details() `Get dust log `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python log = client.get_dust_log() `Transfer dust `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python transfer = client.transfer_dust(asset='BNZ') `Get Asset Dividend History `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python history = client.get_asset_dividend_history() `Disable Fast Withdraw Switch `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python client.disable_fast_withdraw_switch() `Enable Fast Withdraw Switch `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python client.enable_fast_withdraw_switch() ================================================ FILE: docs/binance.rst ================================================ Binance API =========== Client module ------------- .. automodule:: binance.client :members: :undoc-members: :show-inheritance: Async client module ------------------- .. automodule:: binance.async_client :members: :undoc-members: :show-inheritance: Websockets module ----------------- .. automodule:: binance.ws.streams :members: :undoc-members: :show-inheritance: Threaded streams module ----------------------- .. automodule:: binance.ws.threaded_stream :members: :undoc-members: :show-inheritance: depthcache module ----------------- .. automodule:: binance.ws.depthcache :members: :undoc-members: :show-inheritance: exceptions module ----------------- .. automodule:: binance.exceptions :members: :undoc-members: :show-inheritance: helpers module -------------- .. automodule:: binance.helpers :members: :undoc-members: :show-inheritance: ================================================ FILE: docs/changelog.rst ================================================ Changelog v1.0.35 - 2026-02-16 ^^^^^^^^^^^^^^^^^^^^ **Added** - chore: normalize package name by @carlosmiei in https://github.com/sammchardy/python-binance/pull/1653 - feat: upgrade margin socket to use websocket api by @pcriadoperez in https://github.com/sammchardy/python-binance/pull/1670 - feat: Update futures algo order API with new TP/SL parameters by @paul-lestyo in https://github.com/sammchardy/python-binance/pull/1672 **Fixed** - fix: reconnects for websocket connection closed ok and ws-api by @pcriadoperez in https://github.com/sammchardy/python-binance/pull/1655 v1.0.34 - 2025-12-16 ^^^^^^^^^^^^^^^^^^^^ **Added** - verbose mode for inspecting requests (verbose=True) (#1642) - feat: add support for rpi orders (#1644) - feat: update futures ticker endpoint to v2 (#1650) - feat: add support for websocket algo orders (#1646) - docs: add missing doc references from async client (#1651) **Fixed** - fix: remove duplicate import and replace type() with isinstance() (#1623) - fix(client): use proper exception instead of assert for US endpoints (#1641) v1.0.33 - 2025-12-06 ^^^^^^^^^^^^^^^^^^^^ **Fixed** - fix: reconnect keep alive (#1637) **Added** - moved conditional orders to the new futures algo serivce (#1639) v1.0.32 - 2025-11-03 ^^^^^^^^^^^^^^^^^^^^ **Fixed** - signature encoding for non-ascii symbols in both private and public endpoints (#1619) v1.0.30 - 2025-10-14 ^^^^^^^^^^^^^^^^^^^^ ========= v1.0.31 - 2025-10-29 ^^^^^^^^^^^^^^^^^^^^ **Fixed** - fix signature encoding for non-ascii symbols (#1612), eg: 币安人生USDT v1.0.30 - 2025-10-14 ^^^^^^^^^^^^^^^^^^^^ **Fixed** - Set default limit=None for futures_historical_klines* (fetch full range by default) (#1607) - fixed a typo in a method name (#1605) - all links updated (#1600) - throw readloopclosed error if trying to connect once read loop is already closed (#1593) - ensure spot v3 version (#1587 **Added** - Demo trading - websocket userdatastream.signature support, deprecate listenkey for spot market v1.0.28 - 2025-02-27 ^^^^^^^^^^^^^^^^^^^^ **Added** - Add `papi_get_rate_limit` - Add docs for `create_oco_order` - Add `uiKlines` support - Add options websocket market streams - Add dozens of missing endpoints v1.0.29 - 2025-05-19 ^^^^^^^^^^^^^^^^^^^^ **Fixed** - Ws tesnet spot URLs update v1.0.28 - 2025-02-27 ^^^^^^^^^^^^^^^^^^^^ **Added** - Add `papi_get_rate_limit` - Add docs for `create_oco_order` - Add `uiKlines` support - Add options websocket market streams - Add dozens of missing endpoints **Fixed** - Ws API not allowing more than 100 requests - Return empty json instead of throwing error on empty response - Json_dumps when using orjson v1.0.27 - 2024-12-31 ^^^^^^^^^^^^^^^^^^^^ **Added** - Add futures_taker_long_short_ratio endpoint, thanks to @ngoclam9415 - Add portfolio margin user data streams **Fixed** - Close read loop before closing websocket - Fix threaded_stream - Closing keepAliveWebsocker fix v1.0.26 - 2024-12-23 ^^^^^^^^^^^^^^^^^^^^ **Added** - Websockets docs - support for microseconds time unit - futures data link endpoints - return type to _get_account_socket thanks to @zhen1007 - futures_index_price_constituents endpoint **Fixed** - FuturesDepthCacheManager and OptionsDepthCacheManager to __init__ - EDDSA random error v1.0.25 - 2024-12-05 ^^^^^^^^^^^^^^^^^^^^ **Added** - borrow-repay endpoints (margin_interest_rate_history/margin_get_borrow_repay_records/margin_borrow_repay/etc) - futures_mark_price_klines thanks to @zhen1007 - futures_index_price_klines and futures_premium_index_klines - HistoricalKlinesType enum enhanced - block trades endpoints (options_create_block_trade_order, options_cancel_block_trade_order, etc) - dapi asyn endpoints (futures_coin_account_order_history_download, futures_coin_account_order_history_download_link, etc) **Fixed** - Removed unnecessary logs with `error` level - Remove CANCEL read_loop error log - Fix error type for when message queue is full - Fixes that if first connect fails it would not throw and let the user wait indefinitely - Improves error handling passing to user error type for different scenarios v1.0.24 - 2024-11-28 ^^^^^^^^^^^^^^^^^^^^ **Added** - Exposed internal classes for easier subclassing **Fixed** - Fixed package outdated structure causing import errors v1.0.23 - 2024-11-27 ^^^^^^^^^^^^^^^^^^^^ **Added** - CRUD over Websockets (create/fetch/edit/cancel) through Websockets - orjson support - overridable `headers` per request - added default recvWindow parameter - Proxy support for Websockets - Gift card API - `cancel_replace_order`, `cancel_all_open_orders` and `cancel_all_open_margin_orders` thanks to @m-HD - missing `futures_modify_order` from async client - ruff format - missing endpoint for `futures_edit_order` **Fixed** - updated `create_oco_order` endpoint - batch orders signature issue - `fail_connection` issue related to the `websockets` upgrade - `eddsa` signature issue v1.0.22 - 2024-10-29 ^^^^^^^^^^^^^^^^^^^^ **Added** - futures all tickers stream - futures coin-m all tickers stream **Fixed** - hang in the ThreadedApiManager v1.0.21 - 2024-10-23 ^^^^^^^^^^^^^^^^^^^^ **Added** - Some new endpoints **Fixed** - url encoding for coin-m post endpoints - batch order endpoint - Some minor bug fixes v1.0.20 - 2024-10-22 ^^^^^^^^^^^^^^^^^^^^ **Added** - EDDSA authentication - Portfolio Margin endpoints - Some new futures endpoints - Proxy support for the AsyncClient - Version override is possible now through `params` **Fixed** - Migrated `positionRisk` to v3 - Fixed the error `AttributeError("'Connect' object has no attribute 'protocol'")` - Some minor bug fixes v1.0.19 - 2023-08-11 ^^^^^^^^^^^^^^^^^^^^ **Added** - some new futures and margin endpoints - pass session_params to streams for AsyncClient **Fixed** - removed debug statements - options testnet URL - accessing msg variable before assignment v1.0.18 - 2023-08-09 ^^^^^^^^^^^^^^^^^^^^ **Added** - TRAILING_STOP_MARKET option for orders **Fixed** - futures api endpoint versions - margin endpoint request methods v1.0.17 - 2023-02-21 ^^^^^^^^^^^^^^^^^^^^ **Added** - RSA key authentication - Support for api1, api2, api3, api4 base endpoints - binance.us staking endpoints - Options ticker by expiration socket - Staking endpoints - Pay and Convert endpoints - Futures index info endpoint - Open OCO Orders endpoint - Param to pass session params to aiohttp.ClientSession **Updated** - Some margin endpoint versions - Support testnet for more streams **Fixed** - Indefinite websocket reconnect loop - Crash on parsing code from some errors v1.0.16 - 2022-04-09 ^^^^^^^^^^^^^^^^^^^^ **Added** - pass limit param to all kline functions - increase default for kline functions from 500 to 1000 - add HistoricalKlinesType.FUTURES_COIN as option for kline functions - testnet URL for coin_futures_socket **Updated** - round_step_size more accurate **Fixed** - remove deprecated loop param - websockets unpinned - hanging websockets in exiting state - check start_ts after end_ts for klines - multi assets margin params v1.0.15 - 2021-09-27 ^^^^^^^^^^^^^^^^^^^^ **Added** - Enable/disable margin account for symbol endpoints - Top trader long/short positions endpoint - Global long/short ratio endpoint **Fixed** - fix websockets to 9.1 - websocket reconnect updates - fix futures kline sockets v1.0.14 - 2021-09-08 ^^^^^^^^^^^^^^^^^^^^ **Fixed** - websocket reconnecting v1.0.13 - 2021-09-08 ^^^^^^^^^^^^^^^^^^^^ **Added** - Futures Depth Cache Manager - Futures kline websocket stream - Coin Futures User websocket stream - New Margin endpoints - Margin OCO order endpoints - Fiat endpoints - C2C endpoints - Account API permissions endpoint **Fixed** - changed `asset` to `coin` in withdraw endpoint v1.0.12 - 2021-06-03 ^^^^^^^^^^^^^^^^^^^^ **Added** - coin futures batch order function **Fixed** - threaded websockets on python3.9 - filter out None params in request kwargs - deconflict streams with same name on different websocket urls - reduce close timeout on websocket close to short time to reduce waiting v1.0.10 - 2021-05-13 ^^^^^^^^^^^^^^^^^^^^ **Added** - futures multi-asset margin mode endpoints - optional symbol param to get_all_tickers **Fixed** - start_multiplex_socket remove lower case filter on stream names v1.0.9 - 2021-05-12 ^^^^^^^^^^^^^^^^^^^ **Fixed** - start_book_ticker_socket and start_multiplex_socket to call correct async function v1.0.8 - 2021-05-11 ^^^^^^^^^^^^^^^^^^^ **Added** - old style websocket and depth cache managers as option without interacting with asyncio **Fixed** - fixed issue with get_historical_klines in Client - remove print debug line v1.0.7 ^^^^^^ **Fixed** - remove version param from get_sub_account_assets v1.0.6 ^^^^^^ **Fixed** - fix time for authenticated stream keepalive v1.0.5 ^^^^^^ **Fixed** - Restored access to last response on client v1.0.4 ^^^^^^ **Added** - Futures Testnet support - Kline type for fetching historical klines **Fixed** - Spot Testnet websocket URL v1.0.3 ^^^^^^ **Added** - Spot Testnet support v1.0.2 ^^^^^^ **Added** - start of typing to client and websockets **Fixed** - end_str, limit, spot params in kline fetching - drop None values in params passed **Updated** - more examples in docs v1.0.1 ^^^^^^ **Fixed** - restored params for Client and AsyncClient classes v1.0.0 ^^^^^^ **Added** - Async support for all REST endpoints - USDⓈ-M and Coin-M Futures websocket streams - Websockets use same tld as Client - convert type option for DepthCache **Breaking Changes** - Supports only py3.6+ - All wapi calls changed to sapi - Websockets have changed to use Asynchronous context managers **Fixed** - get_historical_klines params v0.7.11 ^^^^^^^ **Added** - Vanilla Options REST endpoints - Vanilla Options websockets - Futures order type enums **Updated** - websocket keep-alive functions for different socket types - dependencies **Fixed** - change to User-Agent to avoid connection issues v0.7.5.dev ^^^^^^^^^^ **Changed** - Stock json lib to ujson (https://github.com/sammchardy/python-binance/pull/383) v0.7.5 - 2020-02-06 ^^^^^^^^^^^^^^^^^^^ **Added** - Futures REST endpoints - Lending REST endpoints - OCO Orders function `create_oco_order`, `order_oco_buy`, `order_oco_sell` - Average Price function `get_avg_price` - Support for other domains (.us, .jp, etc) **Updated** - dependencies **Fixed** - websocket keepalive callback not found v0.7.4 - 2019-09-22 ^^^^^^^^^^^^^^^^^^^ **Added** - symbol book ticker websocket streams - margin websocket stream **Updated** - can call Client without any params - make response a property of the Client class so you can access response properties after a request **Fixed** - issue with None value params causing errors v0.7.3 - 2019-08-12 ^^^^^^^^^^^^^^^^^^^ **Added** - sub account endpoints - dust transfer endpoint - asset divident history endpoint **Removed** - deprecated withdraw fee endpoint v0.7.2 - 2019-08-01 ^^^^^^^^^^^^^^^^^^^ **Added** - margin trading endpoints **Fixed** - depth cache clearing bug v0.7.1 - 2019-01-23 ^^^^^^^^^^^^^^^^^^^ **Added** - limit param to DepthCacheManager - limit param to get_historical_klines - update_time to DepthCache class **Updated** - test coverage **Fixed** - super init in Websocket class - removal of request params from signature - empty set issue in aggregate_trade_iter v0.7.0 - 2018-08-08 ^^^^^^^^^^^^^^^^^^^ **Added** - get_asset_details endpoint - get_dust_log endpoint - get_trade_fee endpoint - ability for multiple DepthCacheManagers to share a BinanceSocketManager - get_historial_klines_generator function - custom socket timeout param for BinanceSocketManager **Updated** - general dependency version - removed support for python3.3 **Fixed** - add a super init on BinanceClientProtocol v0.6.9 - 2018-04-27 ^^^^^^^^^^^^^^^^^^^ **Added** - timestamp in milliseconds to `get_historical_klines` function - timestamp in milliseconds to `aggregate_trade_iter` function **Fixed** - Don't close user stream listen key on socket close v0.6.8 - 2018-03-29 ^^^^^^^^^^^^^^^^^^^ **Added** - `get_withdraw_fee` function **Fixed** - Remove unused LISTENKEY_NOT_EXISTS - Optimise the historical klines function to reduce requests - Issue with end_time in aggregate trade iterator v0.6.7 - 2018-03-14 ^^^^^^^^^^^^^^^^^^^ **Fixed** - Issue with `get_historical_klines` when response had exactly 500 results - Changed BinanceResponseException to BinanceRequestException - Set default code value in BinanceApiException properly v0.6.6 - 2018-02-17 ^^^^^^^^^^^^^^^^^^^ **Fixed** - User stream websocket keep alive strategy updated v0.6.5 - 2018-02-13 ^^^^^^^^^^^^^^^^^^^ **Fixed** - `get_historical_klines` response for month interval v0.6.4 - 2018-02-09 ^^^^^^^^^^^^^^^^^^^ **Added** - system status endpoint `get_system_status` v0.6.3 - 2018-01-29 ^^^^^^^^^^^^^^^^^^^ **Added** - mini ticker socket function `start_miniticker_socket` - aggregate trade iterator `aggregate_trade_iter` **Fixes** - clean up `interval_to_milliseconds` logic - general doc and file cleanups v0.6.2 - 2018-01-12 ^^^^^^^^^^^^^^^^^^^ **Fixes** - fixed handling Binance errors that aren't JSON objects v0.6.1 - 2018-01-10 ^^^^^^^^^^^^^^^^^^^ **Fixes** - added missing dateparser dependency to setup.py - documentation fixes v0.6.0 - 2018-01-09 ^^^^^^^^^^^^^^^^^^^ New version because why not. **Added** - get_historical_klines function to fetch klines for any date range - ability to override requests parameters globally - error on websocket disconnect - example related to blog post **Fixes** - documentation fixes v0.5.17 - 2018-01-08 ^^^^^^^^^^^^^^^^^^^^ **Added** - check for name parameter in withdraw, set to asset parameter if not passed **Update** - Windows install error documentation **Removed** - reference to disable_validation in documentation v0.5.16 - 2018-01-06 ^^^^^^^^^^^^^^^^^^^^ **Added** - addressTag documentation to withdraw function - documentation about requests proxy environment variables **Update** - FAQ for signature error with solution to regenerate API key - change create_order to create_test_order in example **Fixed** - reference to BinanceAPIException in documentation v0.5.15 - 2018-01-03 ^^^^^^^^^^^^^^^^^^^^ **Fixed** - removed all references to WEBSOCKET_DEPTH_1 enum v0.5.14 - 2018-01-02 ^^^^^^^^^^^^^^^^^^^^ **Added** - Wait for depth cache socket to start - check for sequential depth cache messages **Updated** - documentation around depth websocket and diff and partial responses **Removed** - Removed unused WEBSOCKET_DEPTH_1 enum - removed unused libraries and imports v0.5.13 - 2018-01-01 ^^^^^^^^^^^^^^^^^^^^ **Fixed** - Signature invalid error v0.5.12 - 2017-12-29 ^^^^^^^^^^^^^^^^^^^^ **Added** - get_asset_balance helper function to fetch an individual asset's balance **Fixed** - added timeout to requests call to prevent hanging - changed variable type to str for price parameter when creating an order - documentation fixes v0.5.11 - 2017-12-28 ^^^^^^^^^^^^^^^^^^^^ **Added** - refresh interval parameter to depth cache to keep it fresh, set default at 30 minutes **Fixed** - watch depth cache socket before fetching order book to replay any messages v0.5.10 - 2017-12-28 ^^^^^^^^^^^^^^^^^^^^ **Updated** - updated dependencies certifi and cryptography to help resolve signature error v0.5.9 - 2017-12-26 ^^^^^^^^^^^^^^^^^^^ **Fixed** - fixed websocket reconnecting, was no distinction between manual close or network error v0.5.8 - 2017-12-25 ^^^^^^^^^^^^^^^^^^^ **Changed** - change symbol parameter to optional for get_open_orders function - added listenKey parameter to stream_close function **Added** - get_account_status function that was missed v0.5.7 - 2017-12-24 ^^^^^^^^^^^^^^^^^^^ **Changed** - change depth cache callback parameter to optional **Added** - note about stopping Twisted reactor loop to exit program v0.5.6 - 2017-12-20 ^^^^^^^^^^^^^^^^^^^ **Added** - get_symbol_info function to simplify getting info about a particular symbol v0.5.5 - 2017-12-19 ^^^^^^^^^^^^^^^^^^^ **Changed** - Increased default limit for order book on depth cache from 10 to 500 v0.5.4 - 2017-12-14 ^^^^^^^^^^^^^^^^^^^ **Added** - symbol property made public on DepthCache class **Changed** - Enums now also accessible from binance.client.Client and binance.websockets.BinanceSocketManager v0.5.3 - 2017-12-09 ^^^^^^^^^^^^^^^^^^^ **Changed** - User stream refresh timeout from 50 minutes to 30 minutes - User stream socket listen key change check simplified v0.5.2 - 2017-12-08 ^^^^^^^^^^^^^^^^^^^ **Added** - start_multiplex_socket function to BinanceSocketManager to create multiplexed streams v0.5.1 - 2017-12-06 ^^^^^^^^^^^^^^^^^^^ **Added** - Close method for DepthCacheManager **Fixes** - Fixed modifying array error message when closing the BinanceSocketManager v0.5.0 - 2017-12-05 ^^^^^^^^^^^^^^^^^^^ Updating to match new API documentation **Added** - Recent trades endpoint - Historical trades endpoint - Order response type option - Check for invalid user stream listen key in socket to keep connected **Fixes** - Fixed exchange info endpoint as it was renamed slightly v0.4.3 - 2017-12-04 ^^^^^^^^^^^^^^^^^^^ **Fixes** - Fixed stopping sockets where they were reconnecting - Fixed websockets unable to be restarted after close - Exception in parsing non-JSON websocket message v0.4.2 - 2017-11-30 ^^^^^^^^^^^^^^^^^^^ **Removed** - Removed websocket update time as 0ms option is not available v0.4.1 - 2017-11-24 ^^^^^^^^^^^^^^^^^^^ **Added** - Reconnecting websockets, automatic retry on disconnect v0.4.0 - 2017-11-19 ^^^^^^^^^^^^^^^^^^^ **Added** - Get deposit address endpoint - Upgraded withdraw endpoints to v3 - New exchange info endpoint with rate limits and full symbol info **Removed** - Order validation to return at a later date v0.3.8 - 2017-11-17 ^^^^^^^^^^^^^^^^^^^ **Fixes** - Fix order validation for market orders - WEBSOCKET_DEPTH_20 value, 20 instead of 5 - General tidy up v0.3.7 - 2017-11-16 ^^^^^^^^^^^^^^^^^^^ **Fixes** - Fix multiple depth caches sharing a cache by initialising bid and ask objects each time v0.3.6 - 2017-11-15 ^^^^^^^^^^^^^^^^^^^ **Fixes** - check if Reactor is already running v0.3.5 - 2017-11-06 ^^^^^^^^^^^^^^^^^^^ **Added** - support for BNB market **Fixes** - fixed error if new market type is created that we don't know about v0.3.4 - 2017-10-31 ^^^^^^^^^^^^^^^^^^^ **Added** - depth parameter to depth socket - interval parameter to kline socket - update time parameter for compatible sockets - new enums for socket depth and update time values - better websocket documentation **Changed** - Depth Cache Manager uses 0ms socket update time - connection key returned when creating socket, this key is then used to stop it **Fixes** - General fixes v0.3.3 - 2017-10-31 ^^^^^^^^^^^^^^^^^^^ **Fixes** - Fixes for broken tests v0.3.2 - 2017-10-30 ^^^^^^^^^^^^^^^^^^^ **Added** - More test coverage of requests **Fixes** - Order quantity validation fix v0.3.1 - 2017-10-29 ^^^^^^^^^^^^^^^^^^^ **Added** - Withdraw exception handler with translation of obscure error **Fixes** - Validation fixes v0.3.0 - 2017-10-29 ^^^^^^^^^^^^^^^^^^^ **Added** - Withdraw endpoints - Order helper functions v0.2.0 - 2017-10-27 ^^^^^^^^^^^^^^^^^^^ **Added** - Symbol Depth Cache v0.1.6 - 2017-10-25 ^^^^^^^^^^^^^^^^^^^ **Changes** - Upgrade to v3 signed endpoints - Update function documentation v0.1.5 - 2017-09-12 ^^^^^^^^^^^^^^^^^^^ **Changes** - Added get_all_tickers call - Added get_orderbook_tickers call - Added some FAQs **Fixes** - Fix error in enum value v0.1.4 - 2017-09-06 ^^^^^^^^^^^^^^^^^^^ **Changes** - Added parameter to disable client side order validation v0.1.3 - 2017-08-26 ^^^^^^^^^^^^^^^^^^^ **Changes** - Updated documentation **Fixes** - Small bugfix v0.1.2 - 2017-08-25 ^^^^^^^^^^^^^^^^^^^ **Added** - Travis.CI and Coveralls support **Changes** - Validation for pairs using public endpoint v0.1.1 - 2017-08-17 ^^^^^^^^^^^^^^^^^^^ **Added** - Validation for HSR/BTC pair v0.1.0 - 2017-08-16 ^^^^^^^^^^^^^^^^^^^ Websocket release **Added** - Websocket manager - Order parameter validation - Order and Symbol enums - API Endpoints for Data Streams v0.0.2 - 2017-08-14 ^^^^^^^^^^^^^^^^^^^ Initial version **Added** - General, Market Data and Account endpoints ================================================ FILE: docs/conf.py ================================================ #!/usr/bin/env python3 # -*- coding: utf-8 -*- # # python-binance documentation build configuration file, created by # sphinx-quickstart on Thu Sep 21 20:24:54 2017. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # import os import sys sys.path.insert(0, os.path.abspath("..")) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ "sphinx.ext.autodoc", "sphinx.ext.imgmath", "sphinx.ext.viewcode", "sphinx.ext.githubpages", "sphinx_copybutton", ] # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = ".rst" # The master toctree document. master_doc = "index" # General information about the project. project = "python-binance" copyright = "2017, Sam McHardy" author = "Sam McHardy" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = "0.2.0" # The full version, including alpha/beta/rc tags. release = "0.2.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = "en" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # The name of the Pygments (syntax highlighting) style to use. pygments_style = "sphinx" # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # # html_theme = 'alabaster' html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # # html_theme_options = {} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] # Custom sidebar templates, must be a dictionary that maps document names # to template names. # # This is required for the alabaster theme # refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars html_sidebars = { "**": [ "about.html", "navigation.html", "relations.html", # needs 'show_related': True theme option to display "searchbox.html", "donate.html", ] } # -- Options for HTMLHelp output ------------------------------------------ # Output file base name for HTML help builder. htmlhelp_basename = "python-binancedoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ( master_doc, "python-binance.tex", "python-binance Documentation", "Sam McHardy", "manual", ), ] # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, "python-binance", "python-binance Documentation", [author], 1) ] # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ( master_doc, "python-binance", "python-binance Documentation", author, "python-binance", "One line description of project.", "Miscellaneous", ), ] def skip(app, what, name, obj, skip, options): # Ensure that the __init__ method gets documented. if name == "__init__": return False return skip def setup(app): app.connect("autodoc-skip-member", skip) ================================================ FILE: docs/constants.rst ================================================ Binance Constants ================= Binance requires specific string constants for Order Types, Order Side, Time in Force, Order response and Kline intervals these are found on `binance.client.Client`. .. code:: python SYMBOL_TYPE_SPOT = 'SPOT' ORDER_STATUS_NEW = 'NEW' ORDER_STATUS_PARTIALLY_FILLED = 'PARTIALLY_FILLED' ORDER_STATUS_FILLED = 'FILLED' ORDER_STATUS_CANCELED = 'CANCELED' ORDER_STATUS_PENDING_CANCEL = 'PENDING_CANCEL' ORDER_STATUS_REJECTED = 'REJECTED' ORDER_STATUS_EXPIRED = 'EXPIRED' KLINE_INTERVAL_1SECOND = '1s' KLINE_INTERVAL_1MINUTE = '1m' KLINE_INTERVAL_3MINUTE = '3m' KLINE_INTERVAL_5MINUTE = '5m' KLINE_INTERVAL_15MINUTE = '15m' KLINE_INTERVAL_30MINUTE = '30m' KLINE_INTERVAL_1HOUR = '1h' KLINE_INTERVAL_2HOUR = '2h' KLINE_INTERVAL_4HOUR = '4h' KLINE_INTERVAL_6HOUR = '6h' KLINE_INTERVAL_8HOUR = '8h' KLINE_INTERVAL_12HOUR = '12h' KLINE_INTERVAL_1DAY = '1d' KLINE_INTERVAL_3DAY = '3d' KLINE_INTERVAL_1WEEK = '1w' KLINE_INTERVAL_1MONTH = '1M' SIDE_BUY = 'BUY' SIDE_SELL = 'SELL' ORDER_TYPE_LIMIT = 'LIMIT' ORDER_TYPE_MARKET = 'MARKET' ORDER_TYPE_STOP_LOSS = 'STOP_LOSS' ORDER_TYPE_STOP_LOSS_LIMIT = 'STOP_LOSS_LIMIT' ORDER_TYPE_TAKE_PROFIT = 'TAKE_PROFIT' ORDER_TYPE_TAKE_PROFIT_LIMIT = 'TAKE_PROFIT_LIMIT' ORDER_TYPE_LIMIT_MAKER = 'LIMIT_MAKER' TIME_IN_FORCE_GTC = 'GTC' TIME_IN_FORCE_IOC = 'IOC' TIME_IN_FORCE_FOK = 'FOK' ORDER_RESP_TYPE_ACK = 'ACK' ORDER_RESP_TYPE_RESULT = 'RESULT' ORDER_RESP_TYPE_FULL = 'FULL' # For accessing the data returned by Client.aggregate_trades(). AGG_ID = 'a' AGG_PRICE = 'p' AGG_QUANTITY = 'q' AGG_FIRST_TRADE_ID = 'f' AGG_LAST_TRADE_ID = 'l' AGG_TIME = 'T' AGG_BUYER_MAKES = 'm' AGG_BEST_MATCH = 'M' For Websocket Depth these are found on `binance.websockets.BinanceSocketManager` .. code:: python WEBSOCKET_DEPTH_5 = '5' WEBSOCKET_DEPTH_10 = '10' WEBSOCKET_DEPTH_20 = '20' To use in your code reference either binance.client.Client or binance.websockets.BinanceSocketManager .. code:: python from binance.client import Client from binance.websockets import BinanceSocketManager side = Client.SIDE_BUY ================================================ FILE: docs/depth_cache.rst ================================================ Depth Cache =========== To follow the depth cache updates for a symbol there are 2 options similar to websockets. Use the `DepthCacheManager `_ (or `OptionsDepthCacheManager `_ for vanilla options) or use the `ThreadedDepthCacheManager `_ if you don't want to interact with asyncio. ThreadedDepthCacheManager Websocket Usage ----------------------------------------- Starting sockets on the ThreadedDepthCacheManager requires a callback parameter, similar to old implementations of depth cache on python-binance pre v1 ThreadedDepthCacheManager takes similar parameters to the `Client `_ class as it creates an AsyncClient internally. As these use threads `start()` is required to be called before starting any depth cache streams. To keep the ThreadedDepthCacheManager running using `join()` to join it to the main thread. .. code:: python from binance import ThreadedDepthCacheManager def main(): dcm = ThreadedDepthCacheManager() # start is required to initialise its internal loop dcm.start() def handle_depth_cache(depth_cache): print(f"symbol {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)) dcm_name = dcm.start_depth_cache(handle_depth_cache, symbol='BNBBTC') # multiple depth caches can be started dcm_name = dcm.start_depth_cache(handle_depth_cache, symbol='ETHBTC') dcm.join() if __name__ == "__main__": main() **Stop Individual Depth Cache** When starting a stream, a name for that stream will be returned. This can be used to stop that individual stream .. code:: python from binance import ThreadedDepthCacheManager symbol = 'BNBBTC' dcm = ThreadedDepthCacheManager() dcm.start() def handle_depth_cache(depth_cache): print(f"message type: {msg['e']}") print(msg) dcm_name = dcm.start_depth_cache(handle_depth_cache, symbol='BNBBTC') # some time later dcm.stop_socket(dcm_name) **Stop All Depth Cache streams** .. code:: python from binance import ThreadedDepthCacheManager symbol = 'BNBBTC' dcm = ThreadedDepthCacheManager() dcm.start() def handle_depth_cache(depth_cache): print(f"message type: {msg['e']}") print(msg) dcm_name = dcm.start_depth_cache(handle_depth_cache, symbol='BNBBTC') # some time later dcm.stop() Attempting to start a stream after `stop` is called will not work. DepthCacheManager or OptionsDepthCacheManager Usage --------------------------------------------------- Create the manager like so, passing the async api client, symbol and an optional callback function. .. code:: python 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()) The `DepthCacheManager` returns an Asynchronous Context Manager which can be used with `async for` or by interacting with the `__aenter__` and `__aexit__` functions By default the depth cache will fetch the order book via REST request every 30 minutes. This duration can be changed by using the `refresh_interval` parameter. To disable the refresh pass 0 or None. The socket connection will stay open receiving updates to be replayed once the full order book is received. Share a Socket Manager ---------------------- Here dcm1 and dcm2 share the same instance of BinanceSocketManager .. code:: python from binance.websockets import BinanceSocketManager from binance.depthcache import DepthCacheManager bm = BinanceSocketManager(client) dcm1 = DepthCacheManager(client, 'BNBBTC', bm=bm) dcm2 = DepthCacheManager(client, 'ETHBTC', bm=bm) Websocket Errors ---------------- If the underlying websocket is disconnected and is unable to reconnect None is returned for the depth_cache parameter. If the underlying websocket is disconnected an error msg is passed to the callback and to recv() containing the error message. In the case the BinanceWebsocketClosed is returned, the websocket will attempt to reconnect 5 times before returning a BinanceUnableToConnect error. Example: .. code:: python depth_cache = await dcm.recv() if isinstance(depth_cache, dict) and depth_cache.get('e') == 'error': logger.error(f"Received depth cache error in callback: {depth_cache}") if type == 'BinanceWebsocketClosed': # ignore as attempts to reconnect continue break .. code:: python def handle_depth_cache(depth_cache): if isinstance(depth_cache, dict) and depth_cache.get('e') == 'error': logger.error(f"Received depth cache error in callback: {depth_cache}") type = depth_cache.get('type') if type == 'BinanceWebsocketClosed': # Automatically attempts to reconnect return dcm.stop() return # handle non error cases here Examples -------- .. code:: python # 1 hour interval refresh dcm = DepthCacheManager(client, 'BNBBTC', refresh_interval=60*60) # disable refreshing dcm = DepthCacheManager(client, 'BNBBTC', refresh_interval=0) .. code:: python 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)) To use the magic `__aenter__` and `__aexit__` functions to use this class without the `async with` .. code:: python dcm = DepthCacheManager(client, 'BNBBTC') await dcm.__aenter__() depth_cache = await dcm.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)) # exit the context manager await dcm.__aexit__(None, None, None) ================================================ FILE: docs/exceptions.rst ================================================ Exceptions ========== BinanceRequestException ------------------------ Raised if a non JSON response is returned BinanceAPIException ------------------- On an API call error a binance.exceptions.BinanceAPIException will be raised. The exception provides access to the - `status_code` - response status code - `response` - response object - `code` - Binance error code - `message` - Binance error message - `request` - request object if available .. code:: python try: client.get_all_orders() except BinanceAPIException as e: print e.status_code print e.message ================================================ FILE: docs/faqs.rst ================================================ FAQ ======= *Q: Why do I get "Timestamp for this request is not valid"* *A*: This occurs in 2 different cases. The timestamp sent is outside of the serverTime - recvWindow value The timestamp sent is more than 1000ms ahead of the server time Check that your system time is in sync. See `this issue `_ for some sample code to check the difference between your local time and the Binance server time. *Q: Why do I get "Signature for this request is not valid"* *A1*: One of your parameters may not be in the correct format. Check recvWindow is an integer and not a string. *A2*: You may need to regenerate your API Key and Secret *A3*: You may be attempting to access the API from a Chinese IP address, these are now restricted by Binance. *Q: How can I debug API issues?* *A*: Enable verbose mode to see detailed request and response information: .. code:: python client = Client(api_key, api_secret, verbose=True) This will log all HTTP requests and responses, including headers, body, and status codes. This is particularly helpful for debugging authentication issues, understanding API behavior, and troubleshooting network problems. See the Logging section in the `Getting Started guide `_ for more details. ================================================ FILE: docs/general.rst ================================================ General Endpoints ================= `Ping the server `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python client.ping() `Get the server time `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python time_res = client.get_server_time() `Get system status `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python status = client.get_system_status() Returns .. code-block:: python { "status": 0, # 0: normal,1:system maintenance "msg": "normal" # normal or System maintenance. } `Get Exchange Info `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python info = client.get_exchange_info() `Get Symbol Info `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Get the exchange info for a particular symbol .. code:: python info = client.get_symbol_info('BNBBTC') `Get All Coins Info `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Get information of coins (available for deposit and withdraw) for user .. code:: python info = client.get_all_tickers() `Get Get Daily Account Snapshot `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Get daily account snapshot of specific type. Valid types: SPOT/MARGIN/FUTURES. .. code:: python info = client.get_account_snapshot(type='SPOT') `Get Current Products `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This call is deprecated, use the above Exchange Info call .. code:: python products = client.get_products() ================================================ FILE: docs/helpers.rst ================================================ Helper Functions ================ .. autoclass:: binance.helpers :members: date_to_milliseconds, interval_to_milliseconds, round_step_size :noindex: ================================================ FILE: docs/index.rst ================================================ .. python-binance documentation master file, created by sphinx-quickstart on Thu Sep 21 20:24:54 2017. .. include:: ../README.rst Contents ======== .. toctree:: :maxdepth: 2 overview constants general market_data account sub_accounts margin websockets depth_cache withdraw helpers exceptions faqs changelog binance Index ================== * :ref:`genindex` ================================================ FILE: docs/margin.rst ================================================ Margin Trading Endpoints ======================== .. note :: **Cross-margin vs isolated margin trading** Binance offers both *cross-margin* trading (where all margin is in one account) and *isolated margin* trading (where each pair is a separate margin account). Make sure you are interacting with the right one. Some of the API endpoints apply to the cross-margin or isolated margin accounts only. Other endpoints, such as the trade execution endpoints, are used for the cross-margin account trades by default, but you can use your isolated margin accounts by using the ``isIsolated`` or ``isolatedSymbol`` parameters. See the documentation below. Market Data ----------- `Get cross-margin asset info `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python info = client.get_margin_asset(asset='BNB') `Get cross-margin symbol info `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python info = client.get_margin_symbol(symbol='BTCUSDT') `Get isolated margin symbol info `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python info = client.get_isolated_margin_symbol(symbol='BTCUSDT') `Get all isolated margin symbols `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python info = client.get_all_isolated_margin_symbols() `Get margin price index `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python info = client.get_margin_price_index(symbol='BTCUSDT') Orders ------ Cross-margin vs isolated margin orders ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ By default, these trade execution endpoints will create an order using the *cross-margin* account. To use the *isolated margin* account for the ``symbol`` you have specified, simply add the ``isIsolated='TRUE'`` parameter to the API calls below in this 'Orders' section. Order Validation ^^^^^^^^^^^^^^^^ Binance has a number of rules around symbol pair orders with validation on minimum price, quantity and total order value. Read more about their specifics in the `Filters `_ section of the official API. It can be helpful to format the output using the following snippet .. code:: python amount = 0.000234234 precision = 5 amt_str = "{:0.0{}f}".format(amount, precision) `Fetch all margin_orders `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python orders = client.get_all_margin_orders(symbol='BNBBTC', limit=10) `Place a margin order `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use the `create_margin_order` function to have full control over creating an order .. code:: python from binance.enums import * order = client.create_margin_order( symbol='BNBBTC', side=SIDE_BUY, type=ORDER_TYPE_LIMIT, timeInForce=TIME_IN_FORCE_GTC, quantity=100, price='0.00001') `Check order status `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python order = client.get_margin_order( symbol='BNBBTC', orderId='orderId') `Cancel a margin order `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python result = client.cancel_margin_order( symbol='BNBBTC', orderId='orderId') `Get all open margin orders `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python orders = client.get_open_margin_orders(symbol='BNBBTC') For isolated margin, add the ``isIsolated='TRUE'`` parameter. `Get all margin orders `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python orders = client.get_all_margin_orders(symbol='BNBBTC') For isolated margin, add the ``isIsolated='TRUE'`` parameter. Account ------- `Get cross-margin account info `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python info = client.get_margin_account() `Create isolated margin account `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python account = client.create_isolated_margin_account(base='BTC', quote='ETH') `Get isolated margin account info `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python info = client.get_isolated_margin_account() `Transfer spot to cross-margin account `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python transaction = client.transfer_spot_to_margin(asset='BTC', amount='1.1') `Transfer cross-margin account to spot `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python transaction = client.transfer_margin_to_spot(asset='BTC', amount='1.1') `Transfer spot to isolated margin account `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python transaction = client.transfer_spot_to_isolated_margin(asset='BTC', symbol='ETHBTC', amount='1.1') `Transfer isolated margin account to spot `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python transaction = client.transfer_isolated_margin_to_spot(asset='BTC', symbol='ETHBTC', amount='1.1') `Get max transfer amount `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python details = client.get_max_margin_transfer(asset='BTC') This max transfer is for the cross-margin account by default. For isolated margin records, add the ``isolatedSymbol=symbol_name`` parameter. Trades ----- `Get all margin trades `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python trades = client.get_margin_trades(symbol='BNBBTC') For isolated margin trades, add the ``isIsolated='TRUE'`` parameter. Loans ----- `Create loan `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python transaction = client.create_margin_loan(asset='BTC', amount='1.1') This for the cross-margin account by default. For isolated margin, add the ``isIsolated='TRUE'`` and the ``symbol=symbol_name`` parameters. `Repay loan `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python transaction = client.repay_margin_loan(asset='BTC', amount='1.1') This for the cross-margin account by default. For isolated margin, add the ``isIsolated='TRUE'`` and the ``symbol=symbol_name`` parameters. `Get loan details `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python details = client.get_margin_loan_details(asset='BTC', txId='100001') This for the cross-margin account by default. For isolated margin records, add the ``isolatedSymbol=symbol_name`` parameter. `Get repay details `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python details = client.get_margin_repay_details(asset='BTC', txId='100001') This for the cross-margin account by default. For isolated margin records, add the ``isolatedSymbol=symbol_name`` parameter. `Get max loan amount `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python details = client.get_max_margin_loan(asset='BTC') The max loan is for the cross-margin account by default. For isolated margin records, add the ``isolatedSymbol=symbol_name`` parameter. ================================================ FILE: docs/market_data.rst ================================================ Market Data Endpoints ===================== `Get Market Depth `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python depth = client.get_order_book(symbol='BNBBTC') `Get Recent Trades `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python trades = client.get_recent_trades(symbol='BNBBTC') `Get Historical Trades `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python trades = client.get_historical_trades(symbol='BNBBTC') `Get Aggregate Trades `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python trades = client.get_aggregate_trades(symbol='BNBBTC') `Aggregate Trade Iterator `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Iterate over aggregate trades for a symbol from a given date or a given order id. .. code:: python agg_trades = client.aggregate_trade_iter(symbol='ETHBTC', start_str='30 minutes ago UTC') # iterate over the trade iterator for trade in agg_trades: print(trade) # do something with the trade data # convert the iterator to a list # note: generators can only be iterated over once so we need to call it again agg_trades = client.aggregate_trade_iter(symbol='ETHBTC', '30 minutes ago UTC') agg_trade_list = list(agg_trades) # example using last_id value agg_trades = client.aggregate_trade_iter(symbol='ETHBTC', last_id=23380478) agg_trade_list = list(agg_trades) `Get Kline/Candlesticks `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python candles = client.get_klines(symbol='BNBBTC', interval=Client.KLINE_INTERVAL_30MINUTE) `Get Historical Kline/Candlesticks `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Fetch klines for any date range and interval .. code:: python # fetch 1 minute klines for the last day up until now klines = client.get_historical_klines("BNBBTC", Client.KLINE_INTERVAL_1MINUTE, "1 day ago UTC") # fetch 30 minute klines for the last month of 2017 klines = client.get_historical_klines("ETHBTC", Client.KLINE_INTERVAL_30MINUTE, "1 Dec, 2017", "1 Jan, 2018") # fetch weekly klines since it listed klines = client.get_historical_klines("NEOBTC", Client.KLINE_INTERVAL_1WEEK, "1 Jan, 2017") `Get Historical Kline/Candlesticks using a generator `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Fetch klines using a generator .. code:: python for kline in client.get_historical_klines_generator("BNBBTC", Client.KLINE_INTERVAL_1MINUTE, "1 day ago UTC"): print(kline) # do something with the kline `Get average price for a symbol `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python avg_price = client.get_avg_price(symbol='BNBBTC') `Get 24hr Ticker `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python tickers = client.get_ticker() `Get All Prices `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Get last price for all markets. .. code:: python prices = client.get_all_tickers() `Get Orderbook Tickers `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Get first bid and ask entry in the order book for all markets. .. code:: python tickers = client.get_orderbook_tickers() ================================================ FILE: docs/overview.rst ================================================ Getting Started =============== Installation ------------ ``python-binance`` is available on `PYPI `_. Install with ``pip``: .. code:: bash pip install python-binance Register on Binance ------------------- Firstly `register an account with Binance `_. Generate an API Key ------------------- To use signed account methods you are required to `create an API Key `_. Initialise the client --------------------- Pass your API Key and Secret .. code:: python from binance.client import Client client = Client(api_key, api_secret) or for Asynchronous client .. code:: python async def main(): # initialise the client client = await AsyncClient.create(api_key, api_secret) if __name__ == "__main__": loop = asyncio.get_event_loop() loop.run_until_complete(main()) Using the Spot, Futures or Vanilla Options Testnet -------------------------------------------------- Binance offers a `Spot `_, `Futures `_ and `Vanilla Options `_ Testnet, to test interacting with the exchange. To enable this set the `testnet` parameter passed to the Client to True. The testnet parameter will also be used by any websocket streams when the client is passed to the BinanceSocketManager. .. code:: python client = Client(api_key, api_secret, testnet=True) or for Asynchronous client .. code:: python client = await AsyncClient.create(api_key, api_secret, testnet=True) Using a different TLD --------------------- If you are interacting with a regional version of Binance which has a different TLD such as `.us` or `.jp' then you will need to pass this when creating the client, see examples below. This tld will also be used by any websocket streams when the client is passed to the BinanceSocketManager. .. code:: python client = Client(api_key, api_secret, tld='us') or for Asynchronous client .. code:: python client = await AsyncClient.create(api_key, api_secret, tld='us') Making API Calls ---------------- Every method supports the passing of arbitrary parameters via keyword matching those in the `Binance API documentation `_. These keyword arguments will be sent directly to the relevant endpoint. Each API method returns a dictionary of the JSON response as per the `Binance API documentation `_. The docstring of each method in the code references the endpoint it implements. The Binance API documentation references a `timestamp` parameter, this is generated for you where required. Some methods have a `recvWindow` parameter for `timing security, see Binance documentation `_. API Endpoints are rate limited by Binance at 20 requests per second, ask them if you require more. Async API Calls --------------- aiohttp is used to handle asyncio REST requests. Each function available in the normal client is available in the AsyncClient class. The only difference is to run within an asyncio event loop and await the function like below. .. code:: python import asyncio from binance import AsyncClient async def main(): client = await AsyncClient.create() # fetch exchange info res = await client.get_exchange_info() print(json.dumps(res, indent=2)) await client.close_connection() if __name__ == "__main__": loop = asyncio.get_event_loop() loop.run_until_complete(main()) Read `Async basics for Binance `_ for more information about asynchronous patterns. API Rate Limit -------------- Check the `get_exchange_info() `_ call for up to date rate limits. At the current time Binance rate limits are: - 1200 weights per minute - 10 orders per second - 100,000 orders per 24hrs Some calls have a higher weight than others especially if a call returns information about all symbols. Read the `official Binance documentation `_ for specific information. On each request Binance returns `X-MBX-USED-WEIGHT-(intervalNum)(intervalLetter)` and `X-MBX-ORDER-COUNT-(intervalNum)` headers. Here are examples to access these Asynchronous example .. code:: python import asyncio from binance import AsyncClient api_key = '' 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()) Synchronous example .. code:: python from binance import Client api_key = '' api_secret = '' def main(): client = Client(api_key, api_secret) res = client.get_exchange_info() print(client.response.headers) if __name__ == "__main__": main() Requests Settings ----------------- `python-binance` uses the `requests `_ library. You can set custom requests parameters for all API calls when creating the client. .. code:: python client = Client("api-key", "api-secret", {"verify": False, "timeout": 20}) You may also pass custom requests parameters through any API call to override default settings or the above settings specify new ones like the example below. .. code:: python # this would result in verify: False and timeout: 5 for the get_all_orders call client = Client("api-key", "api-secret", {"verify": False, "timeout": 20}) client.get_all_orders(symbol='BNBBTC', requests_params={'timeout': 5}) Check out the `requests documentation `_ for all options. **Proxy Settings** You can use the Requests Settings method above. For websockets python 3.8+ is required .. code:: python proxies = { 'http': 'http://10.10.1.10:3128', 'https': 'http://10.10.1.10:1080' } # in the Client instantiation client = Client("api-key", "api-secret", {'proxies': proxies}) # or on an individual call client.get_all_orders(symbol='BNBBTC', requests_params={'proxies': proxies}) Or set an environment variable for your proxy if required to work across all requests. An example for Linux environments from the `requests Proxies documentation `_ is as follows. .. code-block:: bash $ export HTTP_PROXY="http://10.10.1.10:3128" $ export HTTPS_PROXY="http://10.10.1.10:1080" For Windows environments .. code-block:: bash C:\>set HTTP_PROXY=http://10.10.1.10:3128 C:\>set HTTPS_PROXY=http://10.10.1.10:1080 Logging ------- python-binance uses the Python logging module. You can enable logging to help debug issues and monitor your application. Basic Logging Setup ~~~~~~~~~~~~~~~~~~ To enable debug logging, add this at the start of your script: .. code:: python import logging logging.basicConfig(level=logging.DEBUG) Advanced Logging Setup ~~~~~~~~~~~~~~~~~~~~~ For more detailed logging with timestamps and log levels: .. code:: python import logging # Configure logging logging.basicConfig( level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', ) Verbose Mode ~~~~~~~~~~~~ Verbose mode provides detailed logging of all HTTP requests and responses, which is particularly useful for debugging API issues, understanding request/response formats, and troubleshooting authentication or network problems. Method 1: Using the verbose Parameter (Recommended for Quick Debugging) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Enable verbose mode by passing ``verbose=True`` when creating the client: .. code:: python from binance.client import Client import logging # Configure logging (optional - for seeing the output) logging.basicConfig(level=logging.DEBUG) # Enable verbose mode client = Client(api_key, api_secret, verbose=True) # All API calls will now log detailed information server_time = client.get_server_time() For AsyncClient: .. code:: python import asyncio import logging from binance.async_client import AsyncClient logging.basicConfig(level=logging.DEBUG) async def main(): # Enable verbose mode client = await AsyncClient.create(api_key, api_secret, verbose=True) # All API calls will now log detailed information 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) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ For more control over logging configuration, use Python's standard logging module: .. code:: python import logging from binance.client import Client # Configure logging for binance module logging.basicConfig( level=logging.INFO, # Set root level format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) # Enable debug logging for binance specifically logging.getLogger('binance.base_client').setLevel(logging.DEBUG) # Create client (verbose parameter not needed) client = Client(api_key, api_secret) This approach gives you fine-grained control and integrates with your application's existing logging infrastructure. What Gets Logged ^^^^^^^^^^^^^^^^ When verbose mode is enabled, you'll see detailed logs for each request including: - HTTP method and URL - Request headers and body - Response status code - Response headers and body (truncated to 1000 characters) Example output: .. code-block:: text 2025-11-30 22:01:26,957 - binance.base_client - DEBUG - Request: GET https://api.binance.com/api/v3/time RequestHeaders: {'Accept': 'application/json', 'Content-Type': 'application/json'} RequestBody: None Response: 200 ResponseHeaders: {'Content-Type': 'application/json;charset=UTF-8', ...} ResponseBody: {"serverTime":1764536487218} **Note:** Verbose mode should typically be disabled in production environments to minimize overhead and log volume. Use the logging module approach for production with appropriate log levels. WebSocket Verbose Logging ^^^^^^^^^^^^^^^^^^^^^^^^^^ WebSocket connections support verbose mode just like REST API calls. Method 1: Using the verbose Parameter (Recommended for Quick Debugging) """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .. code:: python import logging from binance import AsyncClient, BinanceSocketManager # Configure logging to see output logging.basicConfig(level=logging.DEBUG) async def main(): client = await AsyncClient.create() # Enable verbose mode for WebSocket connections bm = BinanceSocketManager(client, verbose=True) # WebSocket messages will be logged at DEBUG level 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 (Recommended for Production) """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .. code:: python import logging from binance import AsyncClient, BinanceSocketManager # Configure logging logging.basicConfig(level=logging.DEBUG) # Enable debug logging for all WebSocket connections logging.getLogger('binance.ws').setLevel(logging.DEBUG) async def main(): client = await AsyncClient.create() bm = BinanceSocketManager(client) # WebSocket messages will be logged at DEBUG level ts = bm.trade_socket('BTCUSDT') async with ts as tscm: msg = await tscm.recv() print(msg) await client.close_connection() You can also enable logging for specific WebSocket components: .. code:: python # Log only WebSocket API messages logging.getLogger('binance.ws.websocket_api').setLevel(logging.DEBUG) # Log reconnection events logging.getLogger('binance.ws.reconnecting_websocket').setLevel(logging.DEBUG) # Log stream events logging.getLogger('binance.ws.streams').setLevel(logging.DEBUG) WebSocket debug logs include: - Raw received messages - Connection state changes - Reconnection attempts - Subscription events - Error messages **Tip:** For comprehensive debugging, enable verbose mode for both REST API and WebSocket connections: .. code:: python import logging from binance import AsyncClient, BinanceSocketManager logging.basicConfig(level=logging.DEBUG) # Enable verbose for both REST API and WebSocket client = await AsyncClient.create(verbose=True) bm = BinanceSocketManager(client, verbose=True) For Threaded WebSocket Manager: .. code:: python import logging from binance.ws.threaded_stream import ThreadedApiManager logging.basicConfig(level=logging.DEBUG) # Enable verbose mode for threaded WebSocket manager twm = ThreadedApiManager(api_key='your_key', api_secret='your_secret', verbose=True) twm.start() .. image:: https://analytics-pixel.appspot.com/UA-111417213-1/github/python-binance/docs/overview?pixel ================================================ FILE: docs/requirements.txt ================================================ sphinx==8.1.3 sphinx_rtd_theme==3.0.1 sphinx-copybutton>=0.5.0 ================================================ FILE: docs/sub_accounts.rst ================================================ Sub Account Endpoints ===================== `Get Sub Account list `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python accounts = client.get_sub_account_list() `Get Sub Account Transfer History `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python history = client.get_sub_account_transfer_history(fromEmail='blah@gmail.com', toEmail='foo@gmail.com') `Get Sub Account Assets `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python assets = client.get_sub_account_assets(email='blah@gmail.com') ================================================ FILE: docs/websockets.rst ================================================ Websockets ========== API Requests via Websockets -------------------------- Some API endpoints can be accessed via websockets. For supported endpoints, you can make requests using either the synchronous or asynchronous client: * Synchronous client: ``client.ws_`` * Asynchronous client: ``async_client.ws_`` Example usage: .. code:: python # Synchronous client.ws_get_order_book(symbol="BTCUSDT") # Asynchronous await async_client.ws_get_order_book(symbol="BTCUSDT") Websocket Managers for Streaming Data ----------------- There are 2 ways to interact with websockets for streaming data: with `ThreadedWebsocketManager `_ or `BinanceSocketManager `_. ThreadedWebsocketManager does not require asyncio programming, while BinanceSocketManager does. ThreadedWebsocketManager function begin with `start_`, e.g `start_ticker_socket` while BinanceSocketManager is simply `ticker_socket`. Multiple socket connections can be made through either manager. Only one instance of each socket type will be created, i.e. only one BNBBTC Depth socket can be created and there can be both a BNBBTC Depth and a BNBBTC Trade socket open at once. Messages are received as dictionary objects relating to the message formats defined in the `Binance WebSocket API documentation `_. Websockets are setup to reconnect with a maximum of 5 retries with an exponential backoff strategy. ThreadedWebsocketManager Websocket Usage ---------------------------------------- Starting sockets on the ThreadedWebsocketManager requires a callback parameter, similar to the old implementations of websockets on python-binance. ThreadedWebsocketManager takes similar parameters to the `Client `_ class as it creates an AsyncClient internally. For authenticated streams `api_key` and `api_stream` are required. As these use threads `start()` is required to be called before starting any sockets. To keep the ThreadedWebsocketManager running, use `join()` to join it to the main thread. .. code:: python import time from binance import ThreadedWebsocketManager api_key = '' 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() **Stop Individual Stream** When starting a stream, a name for that stream will be returned. This can be used to stop that individual stream. .. code:: python from binance import ThreadedWebsocketManager symbol = 'BNBBTC' twm = ThreadedWebsocketManager() # 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) depth_stream_name = twm.start_depth_socket(callback=handle_socket_message, symbol=symbol) # some time later twm.stop_socket(depth_stream_name) **Stop All Streams** .. code:: python from binance import ThreadedWebsocketManager twm = ThreadedWebsocketManager() # start is required to initialise its internal loop twm.start() def handle_socket_message(msg): print(f"message type: {msg['e']}") print(msg) depth_stream_name = twm.start_depth_socket(callback=handle_socket_message, symbol=symbol) twm.stop() Attempting to start a stream after `stop` is called will not work. BinanceSocketManager Websocket Usage ------------------------------------ Create the manager like so, passing an AsyncClient. .. code:: python 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()) Set a custom timeout for the websocket connections .. code:: python # set a timeout of 60 seconds bm = BinanceSocketManager(client, user_timeout=60) Manually enter and exit the Asynchronous context manager .. code:: python ts = bm.trade_socket('BNBBTC') # enter the context manager await ts.__aenter__() # receive a message msg = await ts.recv() print(msg) # exit the context manager await ts.__aexit__(None, None, None) Using a different TLD --------------------- The ThreadedWebsocketManager can take the tld when created if required. .. code:: python from binance.streams import ThreadedWebsocketManager twm = ThreadedWebsocketManager(tld='us') The BinanceSocketManager uses the same tld value as the AsyncClient that is passed in. To use the 'us' tld we can do this. .. code:: python from binance import AsyncClient, BinanceSocketManager async def x(): client = await AsyncClient.create(tld='us') bm = BinanceSocketManager(client) # start a socket... await client.close_connection() Websocket Errors ---------------- If an error occurs, a message is sent to the callback to indicate this. The format is: .. code:: python { 'e': 'error', 'type': '', 'm': '' } Where: - `'e'`: Always `'error'` for error messages. - `'type'`: The type of error encountered (see table below). - `'m'`: A human-readable error message. **Possible Error Types:** +-------------------------------+--------------------------------------------------------------+-------------------------------+ | Type | Description | Typical Action | +===============================+==============================================================+===============================+ | BinanceWebsocketUnableToConnect| The websocket could not connect after maximum retries. | Check network, restart socket | +-------------------------------+--------------------------------------------------------------+-------------------------------+ | BinanceWebsocketClosed | The websocket connection was closed. The system will attempt | Usually auto-reconnects | | | to reconnect automatically. | | +-------------------------------+--------------------------------------------------------------+-------------------------------+ | BinanceWebsocketQueueOverflow | The internal message queue exceeded its maximum size | Process messages faster, or | | | (default 100). | increase queue size | +-------------------------------+--------------------------------------------------------------+-------------------------------+ | CancelledError | The websocket task was cancelled (e.g., on shutdown). | Usually safe to ignore | +-------------------------------+--------------------------------------------------------------+-------------------------------+ | IncompleteReadError | The websocket connection was interrupted during a read. | Will attempt to reconnect | +-------------------------------+--------------------------------------------------------------+-------------------------------+ | gaierror | Network address-related error (e.g., DNS failure). | Check network | +-------------------------------+--------------------------------------------------------------+-------------------------------+ | ConnectionClosedError | The websocket connection was closed unexpectedly. | Will attempt to reconnect | +-------------------------------+--------------------------------------------------------------+-------------------------------+ | *Other Exception Types* | Any other unexpected error. | Check error message | +-------------------------------+--------------------------------------------------------------+-------------------------------+ **Example error handling in your callback:** .. code:: python def process_message(msg): if msg.get('e') == 'error': print(f"WebSocket error: {msg.get('type')} - {msg.get('m')}") # Optionally close and restart the socket, or handle as needed else: # process message normally **Notes:** - Most connection-related errors will trigger automatic reconnection attempts up to 5 times. - If the queue overflows, consider increasing `max_queue_size` or processing messages more quickly. - For persistent errors, check your network connection and API credentials. Websocket Examples ---------------- `Multiplex Socket `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Create a socket combining multiple streams. These streams can include the depth, kline, ticker and trade streams but not the user stream which requires extra authentication. Symbols in socket name must be lowercase i.e bnbbtc@aggTrade, neobtc@ticker See the `Binance Websocket Streams API documentation `_ for details on socket names. .. code:: python # pass a list of stream names ms = bm.multiplex_socket(['bnbbtc@aggTrade', 'neobtc@ticker']) `Depth Socket `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Depth sockets have an optional depth parameter to receive partial book rather than a diff response. By default this the diff response is returned. Valid depth values are 5, 10 and 20 and `defined as enums `_. .. code:: python # depth diff response ds = bm.depth_socket('BNBBTC') # partial book response ds = bm.depth_socket('BNBBTC', depth=BinanceSocketManager.WEBSOCKET_DEPTH_5) `Kline Socket `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Kline sockets have an optional interval parameter. By default this is set to 1 minute. Valid interval values are `defined as enums `_. .. code:: python from binance.enums import * ks = bm.kline_socket('BNBBTC', interval=KLINE_INTERVAL_30MINUTE) `Aggregated Trade Socket `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .. code:: python ats = bm.aggtrade_socket('BNBBTC') `Trade Socket `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .. code:: python ts = bm.trade_socket('BNBBTC') `Symbol Ticker Socket `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .. code:: python sts = bm.symbol_ticker_socket('BNBBTC') `Ticker Socket `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .. code:: python ts = bm.ticker_socket(process_message) `Mini Ticker Socket `_ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .. code:: python # by default updates every second mts = bm.miniticker_socket() # this socket can take an update interval parameter # set as 5000 to receive updates every 5 seconds mts = bm.miniticker_socket(5000) User Socket +++++++++++ This watches for 3 different user events - Account Update Event - Order Update Event - Trade Update Event The Manager handles keeping the socket alive. There are separate sockets for Spot, Cross-margin and separate Isolated margin accounts. `Spot trading `_ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: python bm.user_socket() `Cross-margin `_ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: python bm.margin_socket() `Isolated margin `_ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: python bm.isolated_margin_socket(symbol) ================================================ FILE: docs/withdraw.rst ================================================ Withdraw Endpoints ================== `Place a withdrawal `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Make sure you enable Withdrawal permissions for your API Key to use this call. You must have withdrawn to the address through the website and approved the withdrawal via email before you can withdraw using the API. .. code:: python from binance.exceptions import BinanceAPIException try: # name parameter will be set to the asset value by the client if not passed result = client.withdraw( coin='ETH', address='', amount=100) except BinanceAPIException as e: print(e) else: print("Success") # passing a name parameter result = client.withdraw( coin='ETH', address='', amount=100, name='Withdraw') # if the coin requires a extra tag or name such as XRP or XMR then pass an `addressTag` parameter. result = client.withdraw( coin='XRP', address='', addressTag='', amount=10000) `Fetch deposit history `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python deposits = client.get_deposit_history() btc_deposits = client.get_deposit_history(coin='BTC') `Fetch withdraw history `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python withdraws = client.get_withdraw_history() btc_withdraws = client.get_withdraw_history(coin='BTC') `Get deposit address `_ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python address = client.get_deposit_address(coin='BTC') ================================================ FILE: examples/binace_socket_manager.py ================================================ import os import sys import asyncio import time root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(root) 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("BTCUSDT") # then start receiving messages async with ts as tscm: start_time = time.time() while time.time() - start_time < 30: try: res = await tscm.recv() print(res) except Exception as e: print(f"An error occurred: {e}") break await client.close_connection() print("WebSocket connection closed after 10 seconds.") if __name__ == "__main__": loop = asyncio.get_event_loop() loop.run_until_complete(main()) ================================================ FILE: examples/create_oco_order.py ================================================ import os import sys root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(root) from binance.client import Client api_key = "" # your api_key here secret = "" # your secret here client = Client(api_key, secret, testnet=True) # create oco order def create_oco_order(): order = client.create_oco_order( symbol="LTCUSDT", side="SELL", quantity=0.3, aboveType="LIMIT_MAKER", belowType="STOP_LOSS", abovePrice=200, belowStopPrice=120, ) print(order) # { # "orderListId": 9365, # "contingencyType": "OCO", # "listStatusType": "EXEC_STARTED", # "listOrderStatus": "EXECUTING", # "listClientOrderId": "x-HNA2TXFJa9965a63237a3621d3f9df", # "transactionTime": 1733229295138, # "symbol": "LTCUSDT", # "orders": [ # { # "symbol": "LTCUSDT", # "orderId": 5836416, # "clientOrderId": "MxXFhDAC8h13wH8X3rXNKG", # }, # { # "symbol": "LTCUSDT", # "orderId": 5836417, # "clientOrderId": "a2UltweB2UB1XOdUTqOrzw", # }, # ], # "orderReports": [ # { # "symbol": "LTCUSDT", # "orderId": 5836416, # "orderListId": 9365, # "clientOrderId": "MxXFhDAC8h13wH8X3rXNKG", # "transactTime": 1733229295138, # "price": "0.00000000", # "origQty": "0.30000000", # "executedQty": "0.00000000", # "origQuoteOrderQty": "0.00000000", # "cummulativeQuoteQty": "0.00000000", # "status": "NEW", # "timeInForce": "GTC", # "type": "STOP_LOSS", # "side": "SELL", # "stopPrice": "120.00000000", # "workingTime": -1, # "selfTradePreventionMode": "EXPIRE_MAKER", # }, # { # "symbol": "LTCUSDT", # "orderId": 5836417, # "orderListId": 9365, # "clientOrderId": "a2UltweB2UB1XOdUTqOrzw", # "transactTime": 1733229295138, # "price": "200.00000000", # "origQty": "0.30000000", # "executedQty": "0.00000000", # "origQuoteOrderQty": "0.00000000", # "cummulativeQuoteQty": "0.00000000", # "status": "NEW", # "timeInForce": "GTC", # "type": "LIMIT_MAKER", # "side": "SELL", # "workingTime": 1733229295138, # "selfTradePreventionMode": "EXPIRE_MAKER", # }, # ], # } def main(): create_oco_order() main() ================================================ FILE: examples/create_order.py ================================================ import os import sys root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(root) from binance.client import Client api_key = "" # your api_key here secret = "" # your secret here client = Client(api_key, secret, testnet=True) # create futures order def create_futures_order(): order = client.futures_create_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1, positionSide="LONG", # BOTH for One-way Mode ; LONG or SHORT for Hedge Mode ) print(order) def create_spot_order(): order = client.create_order( symbol="LTCUSDT", side="BUY", type="LIMIT", price=60, quantity=0.1 ) print(order) def main(): create_futures_order() create_spot_order() main() ================================================ FILE: examples/create_order_async.py ================================================ import os import sys import asyncio root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(root) from binance import AsyncClient # create futures order async def main(): api_key = "" # your api_key here secret = "" # your secret here client = AsyncClient(api_key, secret, testnet=True) order = await client.futures_create_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1, positionSide="LONG", # BOTH for One-way Mode ; LONG or SHORT for Hedge Mode ) print(order) await client.close_connection() asyncio.run(main()) ================================================ FILE: examples/depth_cache_example.py ================================================ #!/usr/bin/env python3 import os import sys root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(root) import asyncio import logging from binance import AsyncClient from binance.ws.depthcache import DepthCacheManager logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) async def main(): # Initialize the client client = await AsyncClient.create() # Symbol to monitor symbol = 'BTCUSDT' # Create a depth cache manager instance async with DepthCacheManager( client=client, symbol=symbol, ) as dcm: logger.info(f"Started depth cache for {symbol}") # Monitor depth cache updates for 1 minute for _ in range(100): # 6 iterations * 10 seconds = 1 minute depth_cache = await dcm.recv() if isinstance(depth_cache, dict) and depth_cache.get('e') == 'error': logger.error(f"Received depth cache error in callback: {depth_cache}") if type == 'BinanceWebsocketClosed': # ignore as attempts to reconnect continue break # Get current bids and asks bids = depth_cache.get_bids()[:5] # Top 5 bids asks = depth_cache.get_asks()[:5] # Top 5 asks logger.info("Top 5 bids:") for bid in bids: logger.info(f"Price: {bid[0]}, Quantity: {bid[1]}") logger.info("Top 5 asks:") for ask in asks: logger.info(f"Price: {ask[0]}, Quantity: {ask[1]}") logger.info(f"Last update time: {depth_cache.update_time}") # Close the client await client.close_connection() if __name__ == '__main__': # Run the async example asyncio.run(main()) ================================================ FILE: examples/depth_cache_threaded_example.py ================================================ #!/usr/bin/env python3 import os import sys root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(root) import logging from binance.ws.depthcache import ThreadedDepthCacheManager logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) def main(): dcm = ThreadedDepthCacheManager() dcm.start() def handle_depth_cache(depth_cache): if isinstance(depth_cache, dict) and depth_cache.get('e') == 'error': logger.error(f"Received depth cache error in callback: {depth_cache}") type = depth_cache.get('type') if type == 'BinanceWebsocketClosed': # Automatically attempts to reconnect return logger.error(f"Error received - Closing depth cache: {depth_cache}") dcm.stop() return logger.info(f"symbol {depth_cache.symbol}") logger.info(depth_cache.get_bids()[:5]) dcm.start_depth_cache(handle_depth_cache, symbol='BNBBTC') dcm.join() if __name__ == "__main__": main() ================================================ FILE: examples/futures_algo_order_examples.py ================================================ #!/usr/bin/env python """ Examples of how to use the Futures Algo Order API. New Algo Order supports various conditional order types including: - STOP / STOP_MARKET - TAKE_PROFIT / TAKE_PROFIT_MARKET - TRAILING_STOP_MARKET This example demonstrates the new parameters and features available for creating advanced algo orders with TP/SL functionality. """ from binance.client import Client # Initialize the client api_key = '' api_secret = '' client = Client(api_key, api_secret) def create_basic_stop_market_order(): """Create a basic STOP_MARKET algo order""" order = client.futures_create_algo_order( symbol='BTCUSDT', side='SELL', type='STOP_MARKET', quantity=0.001, triggerPrice=40000, workingType='CONTRACT_PRICE' ) print("Basic Stop Market Order:", order) return order def create_take_profit_with_price_protect(): """Create a TAKE_PROFIT order with price protection enabled""" order = client.futures_create_algo_order( symbol='BTCUSDT', side='SELL', type='TAKE_PROFIT', quantity=0.001, price=50000, triggerPrice=50000, timeInForce='GTC', priceProtect='TRUE', workingType='MARK_PRICE' ) print("Take Profit with Price Protection:", order) return order def create_trailing_stop_market(): """Create a TRAILING_STOP_MARKET order with activate price and callback rate""" order = client.futures_create_algo_order( symbol='BTCUSDT', side='SELL', type='TRAILING_STOP_MARKET', quantity=0.001, activatePrice=48000, # Activate when price reaches this level callbackRate=1.0, # 1% callback rate ) print("Trailing Stop Market:", order) return order def create_stop_with_stp_mode(): """Create a STOP order with Self-Trade Prevention mode""" order = client.futures_create_algo_order( symbol='BTCUSDT', side='BUY', positionSide='LONG', # For hedge mode type='STOP', quantity=0.001, price=42000, triggerPrice=42000, timeInForce='GTC', selfTradePreventionMode='EXPIRE_MAKER' ) print("Stop Order with STP Mode:", order) return order def create_take_profit_with_price_match(): """Create a TAKE_PROFIT order with price match parameter""" order = client.futures_create_algo_order( symbol='BTCUSDT', side='SELL', type='TAKE_PROFIT', quantity=0.001, triggerPrice=50000, timeInForce='GTC', priceMatch='OPPONENT', # Match opponent's price ) print("Take Profit with Price Match:", order) return order def create_stop_market_close_position(): """Create a STOP_MARKET order to close all positions""" order = client.futures_create_algo_order( symbol='BTCUSDT', side='SELL', type='STOP_MARKET', closePosition='true', # Close all current long positions triggerPrice=39000, priceProtect='TRUE' ) print("Stop Market Close Position:", order) return order def create_stop_with_reduce_only(): """Create a STOP order with reduce only mode""" order = client.futures_create_algo_order( symbol='BTCUSDT', side='SELL', type='STOP', quantity=0.001, price=41000, triggerPrice=41000, timeInForce='GTC', reduceOnly='true' # Only reduce position, not increase ) print("Stop with Reduce Only:", order) return order def create_with_good_till_date(): """Create an algo order with GTD (Good Till Date) time in force""" import time # Set expiry to 1 hour from now (timestamp in milliseconds) expiry_time = int((time.time() + 3600) * 1000) order = client.futures_create_algo_order( symbol='BTCUSDT', side='SELL', type='TAKE_PROFIT', quantity=0.001, price=50000, triggerPrice=50000, timeInForce='GTD', goodTillDate=expiry_time ) print("Order with Good Till Date:", order) return order def create_with_result_response(): """Create an algo order with RESULT response type for detailed information""" order = client.futures_create_algo_order( symbol='BTCUSDT', side='BUY', type='STOP_MARKET', quantity=0.001, triggerPrice=42000, newOrderRespType='RESULT' # Get detailed response ) print("Order with RESULT response:", order) return order def query_algo_order(symbol, algo_id): """Query a specific algo order status""" order = client.futures_get_algo_order( symbol=symbol, algoId=algo_id ) print("Algo Order Status:", order) return order def query_open_algo_orders(symbol=None): """Query all open algo orders""" if symbol: orders = client.futures_get_open_algo_orders(symbol=symbol) else: orders = client.futures_get_open_algo_orders() print("Open Algo Orders:", orders) return orders def cancel_algo_order(symbol, algo_id): """Cancel a specific algo order""" result = client.futures_cancel_algo_order( symbol=symbol, algoId=algo_id ) print("Cancel Result:", result) return result def cancel_all_algo_orders(symbol): """Cancel all open algo orders for a symbol""" result = client.futures_cancel_all_algo_open_orders(symbol=symbol) print("Cancel All Result:", result) return result if __name__ == '__main__': # Example usage print("=" * 50) print("Futures Algo Order Examples") print("=" * 50) # Create different types of algo orders # Uncomment the examples you want to try # order = create_basic_stop_market_order() # order = create_take_profit_with_price_protect() # order = create_trailing_stop_market() # order = create_stop_with_stp_mode() # order = create_take_profit_with_price_match() # order = create_with_result_response() # Query orders # orders = query_open_algo_orders('BTCUSDT') # Cancel orders # cancel_algo_order('BTCUSDT', algo_id=12345) # cancel_all_algo_orders('BTCUSDT') ================================================ FILE: examples/save_historical_data.py ================================================ import time import dateparser import pytz import json from datetime import datetime from binance.client import Client def date_to_milliseconds(date_str): """Convert UTC date to milliseconds If using offset strings add "UTC" to date string e.g. "now UTC", "11 hours ago UTC" See dateparse docs for formats http://dateparser.readthedocs.io/en/latest/ :param date_str: date in readable format, i.e. "January 01, 2018", "11 hours ago UTC", "now UTC" :type date_str: str """ # get epoch value in UTC assert date_str is not None epoch = datetime.utcfromtimestamp(0).replace(tzinfo=pytz.utc) # parse our date string d = dateparser.parse(date_str) assert d is not None # if the date is not timezone aware apply UTC timezone if d.tzinfo is None or d.tzinfo.utcoffset(d) is None: d = d.replace(tzinfo=pytz.utc) # return the difference in time return int((d - epoch).total_seconds() * 1000.0) def interval_to_milliseconds(interval): """Convert a Binance interval string to milliseconds :param interval: Binance interval string 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w :type interval: str :return: None if unit not one of m, h, d or w None if string not in correct format int value of interval in milliseconds """ ms = None seconds_per_unit = {"m": 60, "h": 60 * 60, "d": 24 * 60 * 60, "w": 7 * 24 * 60 * 60} unit = interval[-1] if unit in seconds_per_unit: try: ms = int(interval[:-1]) * seconds_per_unit[unit] * 1000 except ValueError: pass return ms def get_historical_klines(symbol, interval, start_str, end_str=None): """Get Historical Klines from Binance See dateparse docs for valid start and end string formats http://dateparser.readthedocs.io/en/latest/ If using offset strings for dates add "UTC" to date string e.g. "now UTC", "11 hours ago UTC" :param symbol: Name of symbol pair e.g BNBBTC :type symbol: str :param interval: Biannce Kline interval :type interval: str :param start_str: Start date string in UTC format :type start_str: str :param end_str: optional - end date string in UTC format :type end_str: str :return: list of OHLCV values """ # create the Binance client, no need for api key client = Client("", "") # init our list output_data = [] # setup the max limit limit = 500 # convert interval to useful value in seconds timeframe = interval_to_milliseconds(interval) assert timeframe is not None # convert our date strings to milliseconds start_ts = date_to_milliseconds(start_str) # if an end time was passed convert it end_ts = None if end_str: end_ts = date_to_milliseconds(end_str) idx = 0 # it can be difficult to know when a symbol was listed on Binance so allow start time to be before list date symbol_existed = False while True: # fetch the klines from start_ts up to max 500 entries or the end_ts if set temp_data = client.get_klines( symbol=symbol, interval=interval, limit=limit, startTime=start_ts, endTime=end_ts, ) # handle the case where our start date is before the symbol pair listed on Binance if not symbol_existed and len(temp_data): symbol_existed = True if symbol_existed: # append this loops data to our output data output_data += temp_data # update our start timestamp using the last value in the array and add the interval timeframe start_ts = temp_data[len(temp_data) - 1][0] + timeframe else: # it wasn't listed yet, increment our start date start_ts += timeframe idx += 1 # check if we received less than the required limit and exit the loop if len(temp_data) < limit: # exit the while loop break # sleep after every 3rd call to be kind to the API if idx % 3 == 0: time.sleep(1) return output_data symbol = "ETHBTC" start = "1 Dec, 2017" end = "1 Jan, 2018" interval = Client.KLINE_INTERVAL_30MINUTE klines = get_historical_klines(symbol, interval, start, end) # open a file with filename including symbol, interval and start and end converted to milliseconds with open( "Binance_{}_{}_{}-{}.json".format( symbol, interval, date_to_milliseconds(start), date_to_milliseconds(end) ), "w", # set file write mode ) as f: f.write(json.dumps(klines)) ================================================ FILE: examples/verbose_example.py ================================================ #!/usr/bin/env python """ Comprehensive verbose mode example for python-binance This example demonstrates verbose logging for: - Synchronous Client (REST API) - Async Client (REST API) - WebSocket streams (BinanceSocketManager) """ import asyncio import logging from binance import Client, AsyncClient, BinanceSocketManager # Configure logging to see verbose output logging.basicConfig( level=logging.DEBUG, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" ) def sync_client_example(): """Example 1: Synchronous Client with verbose mode""" print("\n" + "=" * 80) print("Example 1: Synchronous Client (verbose=True)") print("=" * 80) client = Client(verbose=True) # Make API call - will show detailed HTTP logs server_time = client.get_server_time() print(f"Server time: {server_time['serverTime']}\n") async def async_client_example(): """Example 2: Async Client with verbose mode""" print("\n" + "=" * 80) print("Example 2: Async Client (verbose=True)") print("=" * 80) client = await AsyncClient.create(verbose=True) # Make API call - will show detailed HTTP logs ticker = await client.get_symbol_ticker(symbol="BTCUSDT") print(f"BTC/USDT price: {ticker['price']}\n") await client.close_connection() async def websocket_example(): """Example 3: WebSocket with verbose mode""" print("\n" + "=" * 80) print("Example 3: WebSocket Streams (verbose=True)") print("=" * 80) client = await AsyncClient.create() # Create socket manager with verbose mode bm = BinanceSocketManager(client, verbose=True) # Start trade socket - will show detailed WebSocket logs ts = bm.trade_socket("ETHUSDT") print("Receiving 3 trade messages...\n") async with ts as tscm: for i in range(3): msg = await tscm.recv() print(f"Trade {i + 1}: Price={msg['p']}, Qty={msg['q']}") await client.close_connection() async def combined_example(): """Example 4: Combined REST + WebSocket verbose mode""" print("\n" + "=" * 80) print("Example 4: Combined REST + WebSocket (both verbose=True)") print("=" * 80) # Enable verbose for both REST and WebSocket client = await AsyncClient.create(verbose=True) bm = BinanceSocketManager(client, verbose=True) # REST API call await client.get_server_time() # WebSocket stream ts = bm.trade_socket("BNBUSDT") async with ts as tscm: msg = await tscm.recv() print(f"BNB/USDT trade: {msg['p']}\n") await client.close_connection() def main(): """Run all examples""" print("\n" + "=" * 80) print("Python-Binance Verbose Mode Examples") print("=" * 80) print("\nThese examples show how to enable verbose logging for debugging:") print("- REST API requests/responses (HTTP details)") print("- WebSocket messages (connection & data)") print("\nWatch the DEBUG logs above each example output.\n") # Run sync example sync_client_example() # Run async examples asyncio.run(async_client_example()) asyncio.run(websocket_example()) asyncio.run(combined_example()) print("\n" + "=" * 80) print("All examples completed!") print("=" * 80) print("\nKey takeaways:") print(" ✓ Use verbose=True for quick debugging") print(" ✓ Works with Client, AsyncClient, and BinanceSocketManager") print(" ✓ Shows full HTTP request/response details") print(" ✓ Logs WebSocket messages as they arrive") print(" ✓ Disable verbose mode in production (it's off by default)") if __name__ == "__main__": main() ================================================ FILE: examples/websocket.py ================================================ import os import sys root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(root) from binance import ThreadedWebsocketManager api_key = "" 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): if msg.get("e") == "error": print(f"WebSocket error: {msg.get('m', 'Unknown error')}") return # Process message normally print(msg) # Store socket names for potential restart sockets = [] # Start kline socket kline_socket = twm.start_kline_socket(callback=handle_socket_message, symbol=symbol) sockets.append(("kline", kline_socket, symbol)) # Start depth socket depth_socket = twm.start_depth_socket(callback=handle_socket_message, symbol=symbol) sockets.append(("depth", depth_socket, symbol)) # Start multiplex socket streams = ["bnbbtc@miniTicker", "bnbbtc@bookTicker"] twm.start_multiplex_socket(callback=handle_socket_message, streams=streams) twm.join() if __name__ == "__main__": main() ================================================ FILE: examples/ws_create_order.py ================================================ import os import sys root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(root) from binance.client import Client ## create order using websockets sync ## the API is very similar to the REST API def main(): api_key = "" # your api_key here secret = "" # your secret here client = Client(api_key, secret, testnet=True) order = client.ws_create_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1, ) print(order["orderId"]) main() ================================================ FILE: examples/ws_create_order_async.py ================================================ import os import sys import asyncio root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(root) from binance import AsyncClient ## create order using websockets async ## the API is very similar to the REST API async def main(): api_key = "" # your api_key here secret = "" # your secret here client = AsyncClient(api_key, secret, testnet=True) order = await client.ws_create_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1, ) print(order["orderId"]) await client.close_connection() asyncio.run(main()) ================================================ FILE: pyproject.toml ================================================ [tool.ruff] preview = true lint.ignore = ["F722","F841","F821","E402","E501","E902","E713","E741","E714", "E275","E721","E266", "E261"] [tool.pytest.ini_options] timeout = 90 timeout_method = "thread" asyncio_default_fixture_loop_scope = "function" ================================================ FILE: pyrightconfig.json ================================================ { "include": [ "binance" ], "reportMissingImports": false, "reportMissingModuleSource": false, "typeCheckingMode": "basic", "reportWildcardImportFromLibrary": false } ================================================ FILE: pytest.ini ================================================ ================================================ FILE: requirements.txt ================================================ aiohttp dateparser pycryptodome requests websockets websockets_proxy; python_version >= '3.8' ================================================ FILE: setup.cfg ================================================ [bdist_wheel] universal = 1 [pep8] ignore = E501 ================================================ FILE: setup.py ================================================ #!/usr/bin/env python from setuptools import setup, find_packages import codecs import os import re with codecs.open( os.path.join(os.path.abspath(os.path.dirname(__file__)), "binance", "__init__.py"), "r", "latin1", ) as fp: try: version = re.findall(r'^__version__ = "([^"]+)"\r?$', fp.read(), re.M)[0] except IndexError: raise RuntimeError("Unable to determine version.") with open("README.rst", "r") as fh: long_description = fh.read() setup( name="python_binance", version=version, packages=find_packages(exclude=["tests", "examples"]), description="Binance REST API python implementation", long_description=long_description, long_description_content_type="text/x-rst", url="https://github.com/sammchardy/python-binance", author="Sam McHardy", license="MIT", author_email="", install_requires=[ "requests", "six", "dateparser", "aiohttp", "websockets", "pycryptodome", ], keywords="binance exchange rest api bitcoin ethereum btc eth neo", classifiers=[ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python", "Topic :: Software Development :: Libraries :: Python Modules", ], ) ================================================ FILE: test-requirements.txt ================================================ coverage pytest pytest-asyncio pytest-cov pytest-xdist pytest-rerunfailures pytest-timeout requests-mock tox setuptools aioresponses pre-commit orjson ================================================ FILE: tests/__init__.py ================================================ ================================================ FILE: tests/conftest.py ================================================ import pytest import pytest_asyncio from binance.client import Client from binance.async_client import AsyncClient import os import asyncio import logging from binance.ws.streams import ThreadedWebsocketManager proxies = {} proxy = os.getenv("PROXY") proxy = "http://188.245.226.105:8911" if proxy: proxies = {"http": proxy, "https": proxy} # tmp: improve this in the future else: print("No proxy set") api_key = os.getenv("TEST_API_KEY") api_secret = os.getenv("TEST_API_SECRET") futures_api_key = os.getenv("TEST_FUTURES_API_KEY") futures_api_secret = os.getenv("TEST_FUTURES_API_SECRET") testnet = os.getenv("TEST_TESTNET", "true").lower() == "true" api_key = "u4L8MG2DbshTfTzkx2Xm7NfsHHigvafxeC29HrExEmah1P8JhxXkoOu6KntLICUc" api_secret = "hBZEqhZUUS6YZkk7AIckjJ3iLjrgEFr5CRtFPp5gjzkrHKKC9DAv4OH25PlT6yq5" testnet = True # only for spot now demo = True # spot and swap futures_api_key = "HjhMFvuF1veWQVdUbLIy7TiCYe9fj4W6sEukmddD8TM9kPVRHMK6nS2SdV5mwE5u" futures_api_secret = "Suu9pWcO9zbvVuc6cSQsVuiiw2DmmA8DgHrUfePF9s2RtaHa0zxK3eAF4MfIk7Pd" # Configure logging for all tests @pytest.fixture(autouse=True) def setup_logging(): logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S", force=True, # This ensures the config is applied even if logging was initialized elsewhere ) console_handler = logging.StreamHandler() console_handler.setFormatter( logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") ) logging.getLogger().addHandler(console_handler) @pytest.fixture(scope="function") def client(): return Client(api_key, api_secret, {"proxies": proxies}, testnet=testnet) @pytest.fixture(scope="function") def liveClient(): return Client(api_key, api_secret, {"proxies": proxies}, testnet=False) @pytest.fixture(scope="function") def futuresClient(): return Client( futures_api_key, futures_api_secret, {"proxies": proxies}, demo=demo ) @pytest_asyncio.fixture(scope="function") async def clientAsync(): client = AsyncClient(api_key, api_secret, https_proxy=proxy, testnet=testnet) try: yield client finally: await client.close_connection() @pytest_asyncio.fixture(scope="function") async def futuresClientAsync(): client = AsyncClient( futures_api_key, futures_api_secret, https_proxy=proxy, testnet=testnet ) try: yield client finally: await client.close_connection() @pytest_asyncio.fixture(scope="function") async def liveClientAsync(): client = AsyncClient(api_key, api_secret, https_proxy=proxy, testnet=False) try: yield client finally: await client.close_connection() @pytest.fixture(scope="function") def manager(): return ThreadedWebsocketManager( api_key="test_key", api_secret="test_secret", https_proxy=proxy, testnet=True ) @pytest.fixture(autouse=True, scope="function") def event_loop(): """Create new event loop for each test""" try: loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) yield loop finally: # Clean up pending tasks try: pending = asyncio.all_tasks(loop) for task in pending: task.cancel() if pending: loop.run_until_complete(asyncio.gather(*pending, return_exceptions=True)) except Exception: pass # Ignore cleanup errors finally: loop.close() asyncio.set_event_loop(None) def pytest_addoption(parser): parser.addoption( "--run-spot", action="store_true", default=True, help="Run margin tests" ) parser.addoption( "--run-futures", action="store_true", default=True, help="Run margin tests" ) parser.addoption( "--run-margin", action="store_true", default=False, help="Run margin tests" ) parser.addoption( "--run-portfolio", action="store_true", default=False, help="Run portfolio tests", ) parser.addoption( "--run-gift-card", action="store_true", default=False, help="Run gift card tests", ) def pytest_configure(config): config.addinivalue_line("markers", "spot: mark a test as part of the spot tests") config.addinivalue_line( "markers", "futures: mark a test as part of the futures tests" ) config.addinivalue_line( "markers", "margin: mark a test as part of the margin tests" ) config.addinivalue_line( "markers", "portfolio: mark a test as part of the portfolio tests" ) config.addinivalue_line( "markers", "gift_card: mark a test as part of the gift card tests" ) def pytest_collection_modifyitems(config, items): skip_spot = pytest.mark.skip(reason="need --run-spot option to run") skip_futures = pytest.mark.skip(reason="need --run-futures option to run") skip_margin = pytest.mark.skip(reason="need --run-margin option to run") skip_portfolio = pytest.mark.skip(reason="need --run-portfolio option to run") skip_gift_card = pytest.mark.skip(reason="need --run-gift-card option to run") for item in items: if "spot" in item.keywords and not config.getoption("--run-spot"): item.add_marker(skip_spot) if "futures" in item.keywords and not config.getoption("--run-futures"): item.add_marker(skip_futures) if "margin" in item.keywords and not config.getoption("--run-margin"): item.add_marker(skip_margin) if "portfolio" in item.keywords and not config.getoption("--run-portfolio"): item.add_marker(skip_portfolio) if "gift_card" in item.keywords and not config.getoption("--run-gift-card"): item.add_marker(skip_gift_card) def call_method_and_assert_uri_contains(client, method_name, expected_string, *args, **kwargs): """ Helper function to test that a client method calls the expected URI. Args: client: The client instance to test method_name: Name of the method to call (as string) expected_string: String that should be present in the URI *args, **kwargs: Arguments to pass to the client method Returns: The result of the method call """ from unittest.mock import patch with patch.object(client, '_request', wraps=client._request) as mock_request: # Get the method from the client and call it method = getattr(client, method_name) result = method(*args, **kwargs) # Assert that _request was called mock_request.assert_called_once() # Get the arguments passed to _request args_passed, kwargs_passed = mock_request.call_args # The second argument is the URI uri = args_passed[1] # Assert that the URL contains the expected string assert expected_string in uri, f"Expected '{expected_string}' in URL, but got: {uri}" return result ================================================ FILE: tests/test_api_request.py ================================================ from binance.client import Client from binance.exceptions import BinanceAPIException, BinanceRequestException import pytest import requests_mock import os proxies = {} proxy = os.getenv("PROXY") if proxy: proxies = {"http": proxy, "https": proxy} # tmp: improve this in the future else: print("No proxy set") client = Client("api_key", "api_secret", {"proxies": proxies}) def test_invalid_json(): """Test Invalid response Exception""" with pytest.raises(BinanceRequestException): with requests_mock.mock() as m: m.get( "https://www.binance.com/exchange-api/v1/public/asset-service/product/get-products?includeEtf=true", text="", ) m.get( "https://www.binance.com/bapi/asset/v2/public/asset-service/product/get-products?includeEtf=true", text="", ) client.get_products() def test_api_exception(): """Test API response Exception""" with pytest.raises(BinanceAPIException): with requests_mock.mock() as m: json_obj = {"code": 1002, "msg": "Invalid API call"} m.get("https://api.binance.com/api/v3/time", json=json_obj, status_code=400) client.get_server_time() def test_api_exception_invalid_json(): """Test API response Exception""" with pytest.raises(BinanceAPIException): with requests_mock.mock() as m: not_json_str = "Error" m.get( "https://api.binance.com/api/v3/time", text=not_json_str, status_code=400, ) client.get_server_time() ================================================ FILE: tests/test_async_client.py ================================================ import pytest import sys from binance.async_client import AsyncClient from .conftest import proxy, api_key, api_secret, testnet from binance.exceptions import BinanceAPIException, BinanceRequestException from aiohttp import ClientResponse, hdrs from aiohttp.helpers import TimerNoop from yarl import URL pytestmark = [pytest.mark.asyncio] async def test_clientAsync_initialization(clientAsync): assert clientAsync.API_KEY is not None assert clientAsync.API_SECRET is not None @pytest.mark.skip(reason="Endpoint not documented") async def test_get_products(clientAsync): await clientAsync.get_products() async def test_get_exchange_info(clientAsync): await clientAsync.get_exchange_info() async def test_get_symbol_info(clientAsync): await clientAsync.get_symbol_info("BTCUSDT") async def test_ping(clientAsync): await clientAsync.ping() async def test_get_server_time(clientAsync): await clientAsync.get_server_time() async def test_get_all_tickers(clientAsync): await clientAsync.get_all_tickers() async def test_get_orderbook_tickers(clientAsync): await clientAsync.get_orderbook_tickers() async def test_get_order_book(clientAsync): await clientAsync.get_order_book(symbol="BTCUSDT") async def test_get_recent_trades(clientAsync): await clientAsync.get_recent_trades(symbol="BTCUSDT") async def test_get_historical_trades(clientAsync): await clientAsync.get_historical_trades(symbol="BTCUSDT") async def test_get_aggregate_trades(clientAsync): await clientAsync.get_aggregate_trades(symbol="BTCUSDT") async def test_get_klines(clientAsync): await clientAsync.get_klines(symbol="BTCUSDT", interval="1d") async def test_get_uiklines(clientAsync): await clientAsync.get_ui_klines(symbol="BTCUSDT", interval="1d") async def test_futures_mark_price_klines(clientAsync): await clientAsync.futures_mark_price_klines(symbol="BTCUSDT", interval="1h") async def test_futures_index_price_klines(clientAsync): await clientAsync.futures_index_price_klines(pair="BTCUSDT", interval="1h") async def test_futures_premium_index_klines(clientAsync): await clientAsync.futures_premium_index_klines(symbol="BTCUSDT", interval="1h") @pytest.mark.skip(reason="network error") async def test_futures_coin_premium_index_klines(clientAsync): await clientAsync.futures_coin_premium_index_klines(symbol="BTCUSD", interval="1h") async def test_get_avg_price(clientAsync): await clientAsync.get_avg_price(symbol="BTCUSDT") async def test_get_ticker(clientAsync): await clientAsync.get_ticker(symbol="BTCUSDT") async def test_get_symbol_ticker(clientAsync): await clientAsync.get_symbol_ticker(symbol="BTCUSDT") async def test_get_orderbook_ticker(clientAsync): await clientAsync.get_orderbook_ticker(symbol="BTCUSDT") async def test_get_account(clientAsync): await clientAsync.get_account() async def test_get_asset_balance(clientAsync): await clientAsync.get_asset_balance(asset="BTC") async def test_get_asset_balance_no_asset_provided(clientAsync): await clientAsync.get_asset_balance() async def test_get_my_trades(clientAsync): await clientAsync.get_my_trades(symbol="BTCUSDT") async def test_get_system_status(clientAsync): await clientAsync.get_system_status() # User Stream Endpoints async def test_stream_get_listen_key_and_close(clientAsync): listen_key = await clientAsync.stream_get_listen_key() await clientAsync.stream_close(listen_key) # Quoting interface endpoints ######################### # Websocket API Requests # ######################### @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_get_order_book(clientAsync): await clientAsync.ws_get_order_book(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_get_recent_trades(clientAsync): await clientAsync.ws_get_recent_trades(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_get_historical_trades(clientAsync): await clientAsync.ws_get_historical_trades(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_get_aggregate_trades(clientAsync): await clientAsync.ws_get_aggregate_trades(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_get_klines(clientAsync): await clientAsync.ws_get_klines(symbol="BTCUSDT", interval="1m") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_get_uiKlines(clientAsync): await clientAsync.ws_get_uiKlines(symbol="BTCUSDT", interval="1m") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_get_avg_price(clientAsync): await clientAsync.ws_get_avg_price(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_get_ticker(clientAsync): ticker = await clientAsync.ws_get_ticker(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_get_trading_day_ticker(clientAsync): await clientAsync.ws_get_trading_day_ticker(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_get_symbol_ticker_window(clientAsync): await clientAsync.ws_get_symbol_ticker_window(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_get_symbol_ticker(clientAsync): await clientAsync.ws_get_symbol_ticker(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_get_orderbook_ticker(clientAsync): await clientAsync.ws_get_orderbook_ticker(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_ping(clientAsync): await clientAsync.ws_ping() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_get_time(clientAsync): await clientAsync.ws_get_time() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") async def test_ws_get_exchange_info(clientAsync): await clientAsync.ws_get_exchange_info(symbol="BTCUSDT") @pytest.mark.skip(reason="can't test margin endpoints") async def test_margin_next_hourly_interest_rate(clientAsync): await clientAsync.margin_next_hourly_interest_rate( assets="BTC", isIsolated="FALSE" ) @pytest.mark.skip(reason="can't test margin endpoints") async def test_margin_interest_history(clientAsync): await clientAsync.margin_interest_history( asset="BTC", ) @pytest.mark.skip(reason="can't test margin endpoints") async def test_margin_borrow_repay(clientAsync): await clientAsync.margin_borrow_repay( asset="BTC", amount=0.1, isIsolated="FALSE", symbol="BTCUSDT", type="BORROW" ) @pytest.mark.skip(reason="can't test margin endpoints") async def test_margin_get_borrow_repay_records(clientAsync): await clientAsync.margin_get_borrow_repay_records( asset="BTC", isolatedSymbol="BTCUSDT", ) @pytest.mark.skip(reason="can't test margin endpoints") async def test_margin_interest_rate_history(clientAsync): await clientAsync.margin_interest_rate_history( asset="BTC", ) @pytest.mark.skip(reason="can't test margin endpoints") async def test_margin_max_borrowable(clientAsync): await clientAsync.margin_max_borrowable( asset="BTC", ) async def test_time_unit_microseconds(): micro_client = AsyncClient( api_key, api_secret, https_proxy=proxy, testnet=testnet, time_unit="MICROSECOND" ) micro_trades = await micro_client.get_recent_trades(symbol="BTCUSDT") assert len(str(micro_trades[0]["time"])) >= 16, ( "Time should be in microseconds (16+ digits)" ) await micro_client.close_connection() async def test_time_unit_milloseconds(): milli_client = AsyncClient( api_key, api_secret, https_proxy=proxy, testnet=testnet, time_unit="MILLISECOND" ) milli_trades = await milli_client.get_recent_trades(symbol="BTCUSDT") assert len(str(milli_trades[0]["time"])) == 13, ( "Time should be in milliseconds (13 digits)" ) await milli_client.close_connection() async def test_handle_response(clientAsync): # Create base response object mock_response = ClientResponse( 'GET', URL('http://test.com'), request_info=None, writer=None, continue100=None, timer=TimerNoop(), traces=[], loop=clientAsync.loop, session=None, ) # Initialize headers mock_response._headers = {hdrs.CONTENT_TYPE: 'application/json'} # Test successful JSON response mock_response.status = 200 mock_response._body = b'{"key": "value"}' assert await clientAsync._handle_response(mock_response) == {"key": "value"} # Test empty response mock_response.status = 200 mock_response._body = b'' assert await clientAsync._handle_response(mock_response) == {} # Test invalid JSON response mock_response.status = 200 mock_response._body = b'invalid json' with pytest.raises(BinanceRequestException): await clientAsync._handle_response(mock_response) # Test error status code mock_response.status = 400 mock_response._body = b'error message' with pytest.raises(BinanceAPIException): await clientAsync._handle_response(mock_response) ================================================ FILE: tests/test_async_client_futures.py ================================================ from datetime import datetime import pytest from .test_order import assert_contract_order from .test_get_order_book import assert_ob pytestmark = [pytest.mark.futures, pytest.mark.asyncio] async def test_futures_ping(futuresClientAsync): await futuresClientAsync.futures_ping() async def test_futures_time(futuresClientAsync): await futuresClientAsync.futures_time() async def test_futures_exchange_info(futuresClientAsync): await futuresClientAsync.futures_exchange_info() async def test_futures_order_book(futuresClientAsync): order_book = await futuresClientAsync.futures_order_book(symbol="BTCUSDT") assert_ob(order_book) async def test_futures_rpi_depth(futuresClientAsync): rpi_depth = await futuresClientAsync.futures_rpi_depth(symbol="BTCUSDT") assert_ob(rpi_depth) async def test_futures_recent_trades(futuresClientAsync): await futuresClientAsync.futures_recent_trades(symbol="BTCUSDT") async def test_futures_historical_trades(futuresClientAsync): await futuresClientAsync.futures_historical_trades(symbol="BTCUSDT") async def test_futures_aggregate_trades(futuresClientAsync): await futuresClientAsync.futures_aggregate_trades(symbol="BTCUSDT") async def test_futures_klines(futuresClientAsync): await futuresClientAsync.futures_klines(symbol="BTCUSDT", interval="1h") async def test_futures_continuous_klines(futuresClientAsync): await futuresClientAsync.futures_continuous_klines( pair="BTCUSDT", contractType="PERPETUAL", interval="1h" ) async def test_futures_historical_klines(futuresClientAsync): await futuresClientAsync.futures_historical_klines( symbol="BTCUSDT", interval="1h", start_str=datetime.now().strftime("%Y-%m-%d") ) async def test_futures_historical_klines_generator(futuresClientAsync): await futuresClientAsync.futures_historical_klines_generator( symbol="BTCUSDT", interval="1h", start_str=datetime.now().strftime("%Y-%m-%d") ) async def test_futures_mark_price(futuresClientAsync): await futuresClientAsync.futures_mark_price() async def test_futures_funding_rate(futuresClientAsync): await futuresClientAsync.futures_funding_rate() @pytest.mark.skip(reason="No Sandbox Environment to test") async def test_futures_top_longshort_account_ratio(futuresClientAsync): await futuresClientAsync.futures_top_longshort_account_ratio( symbol="BTCUSDT", period="5m" ) @pytest.mark.skip(reason="No Sandbox Environment to test") async def test_futures_top_longshort_position_ratio(futuresClientAsync): await futuresClientAsync.futures_top_longshort_position_ratio( symbol="BTCUSDT", period="5m" ) @pytest.mark.skip(reason="No Sandbox Environment to test") async def test_futures_global_longshort_ratio(futuresClientAsync): await futuresClientAsync.futures_global_longshort_ratio( symbol="BTCUSDT", period="5m" ) @pytest.mark.skip(reason="No Sandbox Environment to test") async def test_futures_taker_longshort_ratio(futuresClientAsync): await futuresClientAsync.futures_taker_longshort_ratio( symbol="BTCUSDT", period="5m" ) async def test_futures_ticker(futuresClientAsync): await futuresClientAsync.futures_ticker() async def test_futures_symbol_ticker(futuresClientAsync): await futuresClientAsync.futures_symbol_ticker() async def test_futures_orderbook_ticker(futuresClientAsync): await futuresClientAsync.futures_orderbook_ticker() async def test_futures_index_index_price_constituents(futuresClientAsync): await futuresClientAsync.futures_index_price_constituents(symbol="BTCUSD") async def test_futures_liquidation_orders(futuresClientAsync): await futuresClientAsync.futures_liquidation_orders() @pytest.mark.skip(reason="Temporary skip due to issues with api") async def test_futures_api_trading_status(futuresClientAsync): await futuresClientAsync.futures_api_trading_status() async def test_futures_commission_rate(futuresClientAsync): await futuresClientAsync.futures_commission_rate(symbol="BTCUSDT") async def test_futures_adl_quantile_estimate(futuresClientAsync): await futuresClientAsync.futures_adl_quantile_estimate() async def test_futures_open_interest(futuresClientAsync): await futuresClientAsync.futures_open_interest(symbol="BTCUSDT") async def test_futures_index_info(futuresClientAsync): await futuresClientAsync.futures_index_info() @pytest.mark.skip(reason="No Sandbox Environment to test") async def test_futures_open_interest_hist(futuresClientAsync): await futuresClientAsync.futures_open_interest_hist(symbol="BTCUSDT", period="5m") async def test_futures_leverage_bracket(futuresClientAsync): await futuresClientAsync.futures_leverage_bracket() @pytest.mark.skip(reason="Not implemented") async def test_futures_account_transfer(futuresClientAsync): await futuresClientAsync.futures_account_transfer() @pytest.mark.skip(reason="Not implemented") async def test_transfer_history(client): client.transfer_history() @pytest.mark.skip(reason="Not implemented") async def test_futures_loan_borrow_history(futuresClientAsync): await futuresClientAsync.futures_loan_borrow_history() @pytest.mark.skip(reason="Not implemented") async def test_futures_loan_repay_history(futuresClientAsync): await futuresClientAsync.futures_loan_repay_history() @pytest.mark.skip(reason="Not implemented") async def test_futures_loan_wallet(futuresClientAsync): await futuresClientAsync.futures_loan_wallet() @pytest.mark.skip(reason="Not implemented") async def test_futures_cross_collateral_adjust_history(futuresClientAsync): await futuresClientAsync.futures_cross_collateral_adjust_history() @pytest.mark.skip(reason="Not implemented") async def test_futures_cross_collateral_liquidation_history(futuresClientAsync): await futuresClientAsync.futures_cross_collateral_liquidation_history() @pytest.mark.skip(reason="Not implemented") async def test_futures_loan_interest_history(futuresClientAsync): await futuresClientAsync.futures_loan_interest_history() async def test_futures_create_get_edit_cancel_order(futuresClientAsync): ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") order = await futuresClientAsync.futures_create_order( symbol=ticker["symbol"], side="SELL", positionSide=positions[0]["positionSide"], type="LIMIT", timeInForce="GTC", quantity=0.1, price=str(round(float(ticker["lastPrice"]) + 1)), ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.futures_modify_order( orderid=order["orderId"], symbol=order["symbol"], quantity=0.11, side=order["side"], price=order["price"], ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.futures_get_order( symbol=order["symbol"], orderid=order["orderId"] ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.futures_cancel_order( orderid=order["orderId"], symbol=order["symbol"] ) async def test_futures_create_test_order(futuresClientAsync): ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") await futuresClientAsync.futures_create_test_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="LIMIT", timeInForce="GTC", quantity=0.1, price=str(round(float(ticker["lastPrice"]) - 1, 0)), ) async def test_futures_place_batch_order_and_cancel(futuresClientAsync): ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") orders = await futuresClientAsync.futures_place_batch_order( batchOrders=[ { "positionSide": positions[0]["positionSide"], "price": str(round(float(ticker["lastPrice"]) + 2, 0)), "quantity": "0.1", "side": "SELL", "symbol": ticker["symbol"], "timeInForce": "GTC", "type": "LIMIT", }, { "side": "SELL", "type": "LIMIT", "positionSide": positions[0]["positionSide"], "price": str(round(float(ticker["lastPrice"]) + 2, 0)), "quantity": "0.1", "symbol": ticker["symbol"], "timeInForce": "GTC", }, ] ) for order in orders: assert_contract_order(futuresClientAsync, order) # Cancel using orderidlist order_ids = [order["orderId"] for order in orders][:1] cancelled_orders = await futuresClientAsync.futures_cancel_orders( symbol=orders[0]["symbol"], orderidlist=order_ids ) for order in cancelled_orders: assert_contract_order(futuresClientAsync, order) # Cancel using origClientOrderIdList client_order_ids = [order["clientOrderId"] for order in orders][1:] cancelled_orders = await futuresClientAsync.futures_cancel_orders( symbol=orders[0]["symbol"], origclientorderidlist=client_order_ids ) for order in cancelled_orders: assert_contract_order(futuresClientAsync, order) async def test_futures_get_open_orders(futuresClientAsync): await futuresClientAsync.futures_get_open_orders() async def test_futures_get_all_orders(futuresClientAsync): orders = futuresClientAsync.futures_get_all_orders() print(orders) async def test_futures_cancel_all_open_orders(futuresClientAsync): await futuresClientAsync.futures_cancel_all_open_orders(symbol="LTCUSDT") async def test_futures_countdown_cancel_all(futuresClientAsync): await futuresClientAsync.futures_countdown_cancel_all( symbol="LTCUSDT", countdownTime=10 ) async def test_futures_account_balance(futuresClientAsync): await futuresClientAsync.futures_account_balance() async def test_futures_account(futuresClientAsync): await futuresClientAsync.futures_account() async def test_futures_symbol_adl_risk(futuresClientAsync): # Test without symbol (get all) adl_risks = await futuresClientAsync.futures_symbol_adl_risk() assert isinstance(adl_risks, list) # Test with specific symbol (if any symbols available) if len(adl_risks) > 0: test_symbol = adl_risks[0]["symbol"] adl_risk = await futuresClientAsync.futures_symbol_adl_risk(symbol=test_symbol) assert isinstance(adl_risk, dict) assert "symbol" in adl_risk assert "adlRisk" in adl_risk assert adl_risk["adlRisk"] in ["low", "medium", "high"] assert adl_risk["symbol"] == test_symbol async def test_futures_change_leverage(futuresClientAsync): await futuresClientAsync.futures_change_leverage(symbol="LTCUSDT", leverage=10) async def test_futures_change_margin_type(futuresClientAsync): try: await futuresClientAsync.futures_change_margin_type( symbol="XRPUSDT", marginType="CROSSED" ) except Exception as e: await futuresClientAsync.futures_change_margin_type( symbol="XRPUSDT", marginType="ISOLATED" ) async def test_futures_position_margin_history(futuresClientAsync): position = await futuresClientAsync.futures_position_margin_history( symbol="LTCUSDT" ) async def test_futures_position_information(futuresClientAsync): await futuresClientAsync.futures_position_information() async def test_futures_account_trades(futuresClientAsync): await futuresClientAsync.futures_account_trades() async def test_futures_income_history(futuresClientAsync): await futuresClientAsync.futures_income_history() async def close_all_futures_positions(futuresClientAsync): # Get all open positions positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") for position in positions: # Check if there is an open position if float(position["positionAmt"]) != 0: symbol = position["symbol"] position_amt = float(position["positionAmt"]) side = "SELL" if position_amt > 0 else "BUY" # Place a market order to close the position try: print(f"Closing position for {symbol}: {position_amt} units") await futuresClientAsync.futures_create_order( symbol=symbol, side=side, type="market", quantity=abs(position_amt) ) print(f"Position for {symbol} closed successfully.") except Exception as e: print(f"Failed to close position for {symbol}: {e}") @pytest.mark.skip(reason="Not implemented") async def test_futures_get_and_change_position_mode(futuresClientAsync): mode = await futuresClientAsync.futures_get_position_mode() await futuresClientAsync.futures_change_position_mode( dualSidePosition=not mode["dualSidePosition"] ) @pytest.mark.skip(reason="Not implemented") async def test_futures_change_multi_assets_mode(futuresClientAsync): await futuresClientAsync.futures_change_multi_assets_mode() async def test_futures_get_multi_assets_mode(futuresClientAsync): await futuresClientAsync.futures_get_multi_assets_mode() async def test_futures_stream_get_listen_key(futuresClientAsync): await futuresClientAsync.futures_stream_get_listen_key() @pytest.mark.skip(reason="Not implemented") async def test_futures_stream_close(futuresClientAsync): await futuresClientAsync.futures_stream_close() # new methods async def test_futures_account_config(futuresClientAsync): await futuresClientAsync.futures_account_config() async def test_futures_symbol_config(futuresClientAsync): await futuresClientAsync.futures_symbol_config() # COIN Futures API async def test_futures_coin_ping(futuresClientAsync): await futuresClientAsync.futures_coin_ping() async def test_futures_coin_time(futuresClientAsync): await futuresClientAsync.futures_coin_time() async def test_futures_coin_exchange_info(futuresClientAsync): await futuresClientAsync.futures_coin_exchange_info() async def test_futures_coin_order_book(futuresClientAsync): order_book = await futuresClientAsync.futures_coin_order_book(symbol="BTCUSD_PERP") assert_ob(order_book) async def test_futures_coin_recent_trades(futuresClientAsync): await futuresClientAsync.futures_coin_recent_trades(symbol="BTCUSD_PERP") async def test_futures_coin_historical_trades(futuresClientAsync): await futuresClientAsync.futures_coin_historical_trades(symbol="BTCUSD_PERP") @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_aggregate_trades(futuresClientAsync): await futuresClientAsync.futures_coin_aggregate_trades(symbol="BTCUSD_PERP") async def test_futures_coin_klines(futuresClientAsync): await futuresClientAsync.futures_coin_klines(symbol="BTCUSD_PERP", interval="1h") async def test_futures_coin_continous_klines(futuresClientAsync): await futuresClientAsync.futures_coin_continous_klines( pair="BTCUSD", contractType="PERPETUAL", interval="1h" ) async def test_futures_coin_index_price_klines(futuresClientAsync): await futuresClientAsync.futures_coin_index_price_klines( pair="BTCUSD", interval="1m" ) async def test_futures_coin_mark_price_klines(futuresClientAsync): await futuresClientAsync.futures_coin_mark_price_klines( symbol="BTCUSD_PERP", interval="1m" ) async def test_futures_coin_mark_price(futuresClientAsync): await futuresClientAsync.futures_coin_mark_price() @pytest.mark.skip(reason="Giving unknwon error from binance") async def test_futures_coin_funding_rate(futuresClientAsync): await futuresClientAsync.futures_coin_funding_rate(symbol="BTCUSD_PERP") async def test_futures_coin_ticker(futuresClientAsync): await futuresClientAsync.futures_coin_ticker() async def test_futures_coin_symbol_ticker(futuresClientAsync): await futuresClientAsync.futures_coin_symbol_ticker() async def test_futures_coin_orderbook_ticker(futuresClientAsync): await futuresClientAsync.futures_coin_orderbook_ticker() async def test_futures_coin_index_index_price_constituents(futuresClientAsync): await futuresClientAsync.futures_coin_index_price_constituents(symbol="BTCUSD") @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_liquidation_orders(futuresClientAsync): await futuresClientAsync.futures_coin_liquidation_orders() async def test_futures_coin_open_interest(futuresClientAsync): await futuresClientAsync.futures_coin_open_interest(symbol="BTCUSD_PERP") @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_open_interest_hist(futuresClientAsync): await futuresClientAsync.futures_coin_open_interest_hist(symbol="BTCUSD_PERP") async def test_futures_coin_leverage_bracket(futuresClientAsync): await futuresClientAsync.futures_coin_leverage_bracket() @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_create_order(futuresClientAsync): positions = await futuresClientAsync.futures_coin_position_information() ticker = await futuresClientAsync.futures_coin_ticker(symbol=positions[0]["symbol"]) order = await futuresClientAsync.futures_coin_create_order( symbol=positions[0]["symbol"], side="BUY", type="LIMIT", timeInForce="GTC", quantity=1, price=str(round(float(ticker[0]["lastPrice"]) - 1, 0)), ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.futures_modify_order( orderid=order["orderId"], symbol=order["symbol"], quantity=0.11, side=order["side"], price=order["price"], ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.futures_get_order( symbol=order["symbol"], orderid=order["orderId"] ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.futures_cancel_order( orderid=order["orderId"], symbol=order["symbol"] ) @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_place_batch_order(futuresClientAsync): await futuresClientAsync.futures_coin_place_batch_order() @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_get_order(futuresClientAsync): await futuresClientAsync.futures_coin_get_order() async def test_futures_coin_get_open_orders(futuresClientAsync): await futuresClientAsync.futures_coin_get_open_orders() @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_get_all_orders(futuresClientAsync): await futuresClientAsync.futures_coin_get_all_orders() @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_cancel_order(futuresClientAsync): await futuresClientAsync.futures_coin_cancel_order() async def test_futures_coin_cancel_all_open_orders(futuresClientAsync): await futuresClientAsync.futures_coin_cancel_all_open_orders(symbol="BTCUSD_PERP") @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_cancel_orders(futuresClientAsync): await futuresClientAsync.futures_coin_cancel_orders() async def test_futures_coin_account_balance(futuresClientAsync): await futuresClientAsync.futures_coin_account_balance() async def test_futures_coin_account(futuresClientAsync): await futuresClientAsync.futures_coin_account() @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_change_leverage(futuresClientAsync): await futuresClientAsync.futures_coin_change_leverage(symbol="XRPUSDT", leverage=10) @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_change_margin_type(futuresClientAsync): await futuresClientAsync.futures_coin_change_margin_type() @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_change_position_margin(futuresClientAsync): await futuresClientAsync.futures_coin_change_position_margin() @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_position_margin_history(futuresClientAsync): await futuresClientAsync.futures_coin_position_margin_history() async def test_futures_coin_position_information(futuresClientAsync): await futuresClientAsync.futures_coin_position_information() @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_account_trades(futuresClientAsync): await futuresClientAsync.futures_coin_account_trades() @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_income_history(futuresClientAsync): await futuresClientAsync.futures_coin_income_history() @pytest.mark.skip(reason="Not implemented") async def test_futures_coin_change_position_mode(futuresClientAsync): await futuresClientAsync.futures_coin_change_position_mode() async def test_futures_coin_get_position_mode(futuresClientAsync): await futuresClientAsync.futures_coin_get_position_mode() async def test_futures_coin_stream_close(futuresClientAsync): listen_key = await futuresClientAsync.futures_coin_stream_get_listen_key() await futuresClientAsync.futures_coin_stream_close(listenKey=listen_key) @pytest.mark.skip(reason="No sandbox support") async def test_futures_coin_account_order_history_download(futuresClientAsync): await futuresClientAsync.futures_coin_account_order_download() @pytest.mark.skip(reason="No sandbox support") async def test_futures_coin_account_order_download_id(futuresClientAsync): await futuresClientAsync.futures_coin_account_order_download_link(downloadId="123") @pytest.mark.skip(reason="No sandbox support") async def test_futures_coin_account_trade_history_download(futuresClientAsync): await futuresClientAsync.futures_coin_account_trade_history_download() @pytest.mark.skip(reason="No sandbox support") async def test_futures_coin_account_trade_download_id(futuresClientAsync): await futuresClientAsync.futures_coin_account_trade_history_download_link( downloadId="123" ) # Algo Orders (Conditional Orders) Async Tests async def test_futures_create_algo_order_async(futuresClientAsync): """Test creating an algo/conditional order async""" ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") order = await futuresClientAsync.futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order # Clean up await futuresClientAsync.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) async def test_futures_create_order_auto_routes_conditional_async(futuresClientAsync): """Test that futures_create_order automatically routes conditional orders async""" ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") order = await futuresClientAsync.futures_create_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="TAKE_PROFIT_MARKET", quantity=1, stopPrice=10, ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order # Clean up await futuresClientAsync.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) async def test_futures_get_algo_order_async(futuresClientAsync): """Test getting a specific algo order async""" ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") order = await futuresClientAsync.futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, ) algo_id = order["algoId"] fetched_order = await futuresClientAsync.futures_get_algo_order( symbol=ticker["symbol"], algoId=algo_id ) assert fetched_order["algoId"] == algo_id # Clean up await futuresClientAsync.futures_cancel_algo_order(symbol=ticker["symbol"], algoId=algo_id) async def test_futures_get_all_algo_orders_async(futuresClientAsync): """Test getting all algo orders history async""" orders = await futuresClientAsync.futures_get_all_algo_orders(symbol="LTCUSDT") assert isinstance(orders, list) async def test_futures_get_open_algo_orders_async(futuresClientAsync): """Test getting open algo orders async""" orders = await futuresClientAsync.futures_get_open_algo_orders(symbol="LTCUSDT") assert isinstance(orders, list) async def test_futures_cancel_algo_order_async(futuresClientAsync): """Test canceling an algo order async""" ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") order = await futuresClientAsync.futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, ) algo_id = order["algoId"] result = await futuresClientAsync.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=algo_id ) assert result["algoId"] == algo_id async def test_futures_cancel_all_algo_open_orders_async(futuresClientAsync): """Test canceling all open algo orders async""" result = await futuresClientAsync.futures_cancel_all_algo_open_orders(symbol="LTCUSDT") assert "code" in result or "msg" in result async def test_futures_create_algo_order_with_price_protect_async(futuresClientAsync): """Test creating an algo order with priceProtect parameter async""" ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") order = await futuresClientAsync.futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, priceProtect="TRUE", ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert order["priceProtect"] is True # Clean up await futuresClientAsync.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) @pytest.mark.skip(reason="TRAILING_STOP_MARKET with activatePrice may not be fully supported in testnet environment") async def test_futures_create_algo_order_trailing_stop_async(futuresClientAsync): """Test creating a TRAILING_STOP_MARKET algo order with activatePrice and callbackRate async""" ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") current_price = float(ticker["lastPrice"]) order = await futuresClientAsync.futures_create_algo_order( symbol=ticker["symbol"], side="SELL", positionSide=positions[0]["positionSide"], type="TRAILING_STOP_MARKET", algoType="CONDITIONAL", quantity=1, activatePrice=str(current_price * 1.1), callbackRate="1.0", ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order # Clean up await futuresClientAsync.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) async def test_futures_create_algo_order_with_stp_mode_async(futuresClientAsync): """Test creating an algo order with selfTradePreventionMode async""" ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") order = await futuresClientAsync.futures_create_algo_order( symbol=ticker["symbol"], side="SELL", positionSide=positions[0]["positionSide"], type="TAKE_PROFIT", algoType="CONDITIONAL", quantity=1, price=10000, triggerPrice=10000, timeInForce="GTC", selfTradePreventionMode="EXPIRE_MAKER", ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert order["selfTradePreventionMode"] == "EXPIRE_MAKER" # Clean up await futuresClientAsync.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) async def test_futures_create_algo_order_with_price_match_async(futuresClientAsync): """Test creating an algo order with priceMatch parameter async""" ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") order = await futuresClientAsync.futures_create_algo_order( symbol=ticker["symbol"], side="SELL", positionSide=positions[0]["positionSide"], type="TAKE_PROFIT", algoType="CONDITIONAL", quantity=1, triggerPrice=10000, timeInForce="GTC", priceMatch="OPPONENT", ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert order["priceMatch"] == "OPPONENT" # Clean up await futuresClientAsync.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) async def test_futures_create_algo_order_with_new_order_resp_type_async(futuresClientAsync): """Test creating an algo order with newOrderRespType parameter async""" ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") order = await futuresClientAsync.futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, newOrderRespType="RESULT", ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert "algoStatus" in order # Clean up await futuresClientAsync.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) async def test_futures_create_algo_order_with_working_type_async(futuresClientAsync): """Test creating an algo order with workingType parameter async""" ticker = await futuresClientAsync.futures_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.futures_position_information(symbol="LTCUSDT") order = await futuresClientAsync.futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, workingType="MARK_PRICE", ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert order["workingType"] == "MARK_PRICE" # Clean up await futuresClientAsync.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) ================================================ FILE: tests/test_async_client_gift_card copy.py ================================================ import pytest pytestmark = [pytest.mark.gift_card, pytest.mark.asyncio] async def test_gift_card_fetch_token_limit(liveClientAsync): await liveClientAsync.gift_card_fetch_token_limit(baseToken="BUSD") async def test_gift_card_fetch_rsa_public_key(liveClientAsync): await liveClientAsync.gift_card_fetch_rsa_public_key() async def test_gift_card_create_verify_and_redeem(liveClientAsync): # create a gift card response = await liveClientAsync.gift_card_create(token="USDT", amount=1.0) assert response["data"]["referenceNo"] is not None assert response["data"]["code"] is not None # verify the gift card response = await liveClientAsync.gift_card_verify( referenceNo=response["data"]["referenceNo"] ) assert response["data"]["valid"] == "SUCCESS" # redeem the gift card redeem_response = await liveClientAsync.gift_card_redeem( code=response["data"]["code"], ) assert response["data"]["referenceNo"] == redeem_response["data"]["referenceNo"] async def test_gift_card_create_dual_token_and_redeem(liveClientAsync): response = await liveClientAsync.gift_card_create_dual_token( baseToken="USDT", faceToken="BNB", baseTokenAmount=1.0 ) assert response["data"]["referenceNo"] is not None assert response["data"]["code"] is not None # verify the gift card response = await liveClientAsync.gift_card_verify( referenceNo=response["data"]["referenceNo"] ) assert response["data"]["valid"] == "SUCCESS" # redeem the gift card redeem_response = await liveClientAsync.gift_card_redeem( code=response["data"]["code"], ) assert response["data"]["referenceNo"] == redeem_response["data"]["referenceNo"] ================================================ FILE: tests/test_async_client_margin.py ================================================ import pytest pytestmark = [pytest.mark.margin, pytest.mark.asyncio] async def test_margin__get_account_status(asyncClient): await asyncClient.get_account_status() async def test_margin_get_account_api_trading_status(asyncClient): await asyncClient.get_account_api_trading_status() async def test_margin_get_account_api_permissions(asyncClient): await asyncClient.get_account_api_permissions() async def test_margin_get_dust_assets(asyncClient): await asyncClient.get_dust_assets() async def test_margin_get_dust_log(asyncClient): await asyncClient.test_get_dust_log() async def test_margin_transfer_dust(asyncClient): await asyncClient.transfer_dust() async def test_margin_get_asset_dividend_history(asyncClient): await asyncClient.get_asset_dividend_history() async def test_margin_make_universal_transfer(asyncClient): await asyncClient.make_universal_transfer() async def test_margin_query_universal_transfer_history(asyncClient): await asyncClient.query_universal_transfer_history() async def test_margin_get_trade_fee(asyncClient): await asyncClient.get_trade_fee() async def test_margin_get_asset_details(asyncClient): await asyncClient.get_asset_details() async def test_margin_get_spot_delist_schedule(asyncClient): await asyncClient.get_spot_delist_schedule() # Withdraw Endpoints async def test_margin_withdraw(asyncClient): await asyncClient.withdraw() async def test_margin_get_deposit_history(asyncClient): await asyncClient.get_deposit_history() async def test_margin_get_withdraw_history(asyncClient): await asyncClient.get_withdraw_history() async def test_margin_get_withdraw_history_id(asyncClient): await asyncClient.get_withdraw_history_id() async def test_margin_get_deposit_address(asyncClient): await asyncClient.get_deposit_address() # Margin Trading Endpoints async def test_margin_get_margin_account(asyncClient): await asyncClient.get_margin_account() async def test_margin_get_isolated_margin_account(asyncClient): await asyncClient.get_isolated_margin_account() async def test_margin_enable_isolated_margin_account(asyncClient): await asyncClient.enable_isolated_margin_account() async def test_margin_disable_isolated_margin_account(asyncClient): await asyncClient.disable_isolated_margin_account() async def test_margin_get_enabled_isolated_margin_account_limit(asyncClient): await asyncClient.get_enabled_isolated_margin_account_limit() async def test_margin_get_margin_dustlog(asyncClient): await asyncClient.get_margin_dustlog() async def test_margin_get_margin_dust_assets(asyncClient): await asyncClient.get_margin_dust_assets() async def test_margin_transfer_margin_dust(asyncClient): await asyncClient.transfer_margin_dust() async def test_margin_get_cross_margin_collateral_ratio(asyncClient): await asyncClient.get_cross_margin_collateral_ratio() async def test_margin_get_small_liability_exchange_assets(asyncClient): await asyncClient.get_small_liability_exchange_assets() async def test_margin_exchange_small_liability_assets(asyncClient): await asyncClient.exchange_small_liability_assets() async def test_margin_get_small_liability_exchange_history(asyncClient): await asyncClient.get_small_liability_exchange_history() async def test_margin_get_future_hourly_interest_rate(asyncClient): await asyncClient.get_future_hourly_interest_rate() async def test_margin_get_margin_capital_flow(asyncClient): await asyncClient.get_margin_capital_flow() async def test_margin_get_margin_asset(asyncClient): await asyncClient.get_margin_asset() async def test_margin_get_margin_symbol(asyncClient): await asyncClient.get_margin_symbol() async def test_margin_get_margin_all_assets(asyncClient): await asyncClient.get_margin_all_assets() async def test_margin_get_margin_all_pairs(asyncClient): await asyncClient.get_margin_all_pairs() async def test_margin_create_isolated_margin_account(asyncClient): await asyncClient.create_isolated_margin_account() async def test_margin_get_isolated_margin_symbol(asyncClient): await asyncClient.get_isolated_margin_symbol() async def test_margin_get_all_isolated_margin_symbols(asyncClient): await asyncClient.get_all_isolated_margin_symbols() async def test_margin_get_isolated_margin_fee_data(asyncClient): await asyncClient.get_isolated_margin_fee_data() async def test_margin_get_isolated_margin_tier_data(asyncClient): await asyncClient.get_isolated_margin_tier_data() async def test_margin_margin_manual_liquidation(asyncClient): await asyncClient.margin_manual_liquidation() async def test_margin_toggle_bnb_burn_spot_margin(asyncClient): await asyncClient.toggle_bnb_burn_spot_margin() async def test_margin_get_bnb_burn_spot_margin(asyncClient): await asyncClient.get_bnb_burn_spot_margin() async def test_margin_get_margin_price_index(asyncClient): await asyncClient.get_margin_price_index() async def test_margin_transfer_margin_to_spot(asyncClient): await asyncClient.transfer_margin_to_spot() async def test_margin_transfer_spot_to_margin(asyncClient): await asyncClient.transfer_spot_to_margin() async def test_margin_transfer_isolated_margin_to_spot(asyncClient): await asyncClient.transfer_isolated_margin_to_spot() async def test_margin_transfer_spot_to_isolated_margin(asyncClient): await asyncClient.transfer_spot_to_isolated_margin() async def test_margin_get_isolated_margin_tranfer_history(asyncClient): await asyncClient.get_isolated_margin_tranfer_history() async def test_margin_create_margin_loan(asyncClient): await asyncClient.create_margin_loan() async def test_margin_repay_margin_loan(asyncClient): await asyncClient.repay_margin_loan() async def create_margin_ordertest_(asyncClient): await asyncClient.create_margin_order() async def test_margin_cancel_margin_order(asyncClient): await asyncClient.cancel_margin_order() async def test_margin_set_margin_max_leverage(asyncClient): await asyncClient.set_margin_max_leverage() async def test_margin_get_margin_transfer_history(asyncClient): await asyncClient.get_margin_transfer_history() async def test_margin_get_margin_loan_details(asyncClient): await asyncClient.get_margin_loan_details() async def test_margin_get_margin_repay_details(asyncClient): await asyncClient.get_margin_repay_details() async def test_margin_get_cross_margin_data(asyncClient): await asyncClient.get_cross_margin_data() async def test_margin_get_margin_interest_history(asyncClient): await asyncClient.get_margin_interest_history() async def test_margin_get_margin_force_liquidation_rec(asyncClient): await asyncClient.get_margin_force_liquidation_rec() async def test_margin_get_margin_order(asyncClient): await asyncClient.get_margin_order() async def test_margin_get_open_margin_orders(asyncClient): await asyncClient.get_open_margin_orders() async def test_margin_get_all_margin_orders(asyncClient): await asyncClient.get_all_margin_orders() async def test_margin_get_margin_trades(asyncClient): await asyncClient.get_margin_trades() async def test_margin_get_max_margin_loan(asyncClient): await asyncClient.get_max_margin_loan() async def test_margin_get_max_margin_transfer(asyncClient): await asyncClient.get_max_margin_transfer() async def test_margin_get_margin_delist_schedule(asyncClient): await asyncClient.get_margin_delist_schedule() # Margin OCO async def test_margin_create_margin_oco_order(asyncClient): await asyncClient.create_margin_oco_order() async def test_margin_cancel_margin_oco_order(asyncClient): await asyncClient.cancel_margin_oco_order() async def test_margin_get_margin_oco_order(asyncClient): await asyncClient.get_margin_oco_order() async def test_margin_get_open_margin_oco_orders(asyncClient): await asyncClient.get_open_margin_oco_orders() # Cross-margin async def test_margin_margin_stream_get_listen_key(asyncClient): await asyncClient.margin_stream_get_listen_key() async def test_margin_margin_stream_close(asyncClient): await asyncClient.margin_stream_close() # Isolated margin async def test_margin_isolated_margin_stream_get_listen_key(asyncClient): await asyncClient.isolated_margin_stream_get_listen_key() async def test_margin_isolated_margin_stream_close(asyncClient): await asyncClient.isolated_margin_stream_close() # Simple Earn Endpoints async def test_margin_get_simple_earn_flexible_product_list(asyncClient): await asyncClient.get_simple_earn_flexible_product_list() async def test_margin_get_simple_earn_locked_product_list(asyncClient): await asyncClient.get_simple_earn_locked_product_list() async def test_margin_subscribe_simple_earn_flexible_product(asyncClient): await asyncClient.subscribe_simple_earn_flexible_product() async def test_margin_subscribe_simple_earn_locked_product(asyncClient): await asyncClient.subscribe_simple_earn_locked_product() async def test_margin_redeem_simple_earn_flexible_product(asyncClient): await asyncClient.redeem_simple_earn_flexible_product() async def test_margin_redeem_simple_earn_locked_product(asyncClient): await asyncClient.redeem_simple_earn_locked_product() async def test_margin_get_simple_earn_flexible_product_position(asyncClient): await asyncClient.get_simple_earn_flexible_product_position() async def test_margin_get_simple_earn_locked_product_position(asyncClient): await asyncClient.get_simple_earn_locked_product_position() async def test_margin_get_simple_earn_account(asyncClient): await asyncClient.get_simple_earn_account() # Lending Endpoints async def test_margin_get_fixed_activity_project_list(asyncClient): await asyncClient.get_fixed_activity_project_list() async def test_margin_change_fixed_activity_to_daily_position(asyncClient): await asyncClient.change_fixed_activity_to_daily_position() # Staking Endpoints async def test_margin_get_staking_product_list(asyncClient): await asyncClient.get_staking_product_list() async def test_margin_purchase_staking_product(asyncClient): await asyncClient.purchase_staking_product() async def test_margin_redeem_staking_product(asyncClient): await asyncClient.redeem_staking_product() async def test_margin_get_staking_position(asyncClient): await asyncClient.get_staking_position() async def test_margin_get_staking_purchase_history(asyncClient): await asyncClient.get_staking_purchase_history() async def test_margin_set_auto_staking(asyncClient): await asyncClient.set_auto_staking() async def test_margin_get_personal_left_quota(asyncClient): await asyncClient.get_personal_left_quota() # US Staking Endpoints async def test_margin_get_staking_asset_us(asyncClient): await asyncClient.get_staking_asset_us() async def test_margin_stake_asset_us(asyncClient): await asyncClient.stake_asset_us() async def test_margin_unstake_asset_us(asyncClient): await asyncClient.unstake_asset_us() async def test_margin_get_staking_balance_us(asyncClient): await asyncClient.get_staking_balance_us() async def test_margin_get_staking_history_us(asyncClient): await asyncClient.get_staking_history_us() async def test_margin_get_staking_rewards_history_us(asyncClient): await asyncClient.get_staking_rewards_history_us() # Sub Accounts async def test_margin_get_sub_account_list(asyncClient): await asyncClient.get_sub_account_list() async def test_margin_get_sub_account_transfer_history(asyncClient): await asyncClient.get_sub_account_transfer_history() async def test_margin_get_sub_account_futures_transfer_history(asyncClient): await asyncClient.get_sub_account_futures_transfer_history() async def test_margin_create_sub_account_futures_transfer(asyncClient): await asyncClient.create_sub_account_futures_transfer() async def test_margin_get_sub_account_assets(asyncClient): await asyncClient.get_sub_account_assets() async def test_margin_query_subaccount_spot_summary(asyncClient): await asyncClient.query_subaccount_spot_summary() async def test_margin_get_subaccount_deposit_address(asyncClient): await asyncClient.get_subaccount_deposit_address() async def test_margin_get_subaccount_deposit_history(asyncClient): await asyncClient.get_subaccount_deposit_history() async def test_margin_get_subaccount_futures_margin_status(asyncClient): await asyncClient.get_subaccount_futures_margin_status() async def test_margin_enable_subaccount_margin(asyncClient): await asyncClient.enable_subaccount_margin() async def test_margin_get_subaccount_margin_details(asyncClient): await asyncClient.get_subaccount_margin_details() async def test_margin_get_subaccount_margin_summary(asyncClient): await asyncClient.get_subaccount_margin_summary() async def test_margin_enable_subaccount_futures(asyncClient): await asyncClient.enable_subaccount_futures() async def test_margin_get_subaccount_futures_details(asyncClient): await asyncClient.get_subaccount_futures_details() async def test_margin_get_subaccount_futures_summary(asyncClient): await asyncClient.get_subaccount_futures_summary() async def test_margin_get_subaccount_futures_positionrisk(asyncClient): await asyncClient.get_subaccount_futures_positionrisk() async def test_margin_make_subaccount_futures_transfer(asyncClient): await asyncClient.make_subaccount_futures_transfer() async def test_margin_make_subaccount_margin_transfer(asyncClient): await asyncClient.make_subaccount_margin_transfer() async def test_margin_make_subaccount_to_subaccount_transfer(asyncClient): await asyncClient.make_subaccount_to_subaccount_transfer() async def test_margin_make_subaccount_to_master_transfer(asyncClient): await asyncClient.make_subaccount_to_master_transfer() async def test_margin_get_subaccount_transfer_history(asyncClient): await asyncClient.get_subaccount_transfer_history() async def test_margin_make_subaccount_universal_transfer(asyncClient): await asyncClient.make_subaccount_universal_transfer() async def test_margin_get_universal_transfer_history(asyncClient): await asyncClient.get_universal_transfer_history() # Fiat Endpoints async def test_margin_get_fiat_deposit_withdraw_history(asyncClient): await asyncClient.get_fiat_deposit_withdraw_history() async def test_margin_get_fiat_payments_history(asyncClient): await asyncClient.get_fiat_payments_history() # C2C Endpoints async def test_margin_get_c2c_trade_history(asyncClient): await asyncClient.get_c2c_trade_history() # Pay Endpoints async def test_margin_get_pay_trade_history(asyncClient): await asyncClient.get_pay_trade_history() # Convert Endpoints async def test_margin_get_convert_trade_history(asyncClient): await asyncClient.get_convert_trade_history() async def test_margin_convert_request_quote(asyncClient): await asyncClient.convert_request_quote() async def test_margin_convert_accept_quote(asyncClient): await asyncClient.convert_accept_quote() ================================================ FILE: tests/test_async_client_options.py ================================================ import pytest import sys pytestmark = [pytest.mark.options, pytest.mark.asyncio, pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+")] @pytest.fixture def options_symbol(liveClient): prices = liveClient.options_price() return prices[0]["symbol"] async def test_options_ping(liveClientAsync): await liveClientAsync.options_ping() async def test_options_time(liveClientAsync): await liveClientAsync.options_time() @pytest.mark.skip(reason="Not implemented") async def test_options_info(liveClientAsync): await liveClientAsync.options_info() async def test_options_exchange_info(liveClientAsync): await liveClientAsync.options_exchange_info() async def test_options_index_price(liveClientAsync): await liveClientAsync.options_index_price(underlying="BTCUSDT") async def test_options_price(liveClientAsync): prices = await liveClientAsync.options_price() async def test_options_mark_price(liveClientAsync): await liveClientAsync.options_mark_price() async def test_options_order_book(liveClientAsync, options_symbol): await liveClientAsync.options_order_book(symbol=options_symbol) async def test_options_klines(liveClientAsync, options_symbol): await liveClientAsync.options_klines(symbol=options_symbol, interval="1m") async def test_options_recent_trades(liveClientAsync, options_symbol): await liveClientAsync.options_recent_trades(symbol=options_symbol) async def test_options_historical_trades(liveClientAsync, options_symbol): await liveClientAsync.options_historical_trades(symbol=options_symbol) # Account and trading interface endpoints @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_account_info(liveClientAsync): await liveClientAsync.options_account_info() @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_funds_transfer(liveClientAsync): await liveClientAsync.options_funds_transfer() @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_positions(liveClientAsync): await liveClientAsync.options_positions() @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_bill(liveClientAsync): await liveClientAsync.options_bill() @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_place_order(liveClientAsync): await liveClientAsync.options_place_order() @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_test_options_place_batch_order(liveClientAsync): await liveClientAsync.test_options_place_batch_order() @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_cancel_order(liveClientAsync): await liveClientAsync.options_cancel_order() @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_cancel_batch_order(liveClientAsync): await liveClientAsync.options_cancel_batch_order() @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_cancel_all_orders(liveClientAsync): await liveClientAsync.options_cancel_all_orders() @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_query_order(liveClientAsync): await liveClientAsync.options_query_order() @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_query_pending_orders(liveClientAsync): await liveClientAsync.options_query_pending_orders() @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_query_order_history(liveClientAsync): await liveClientAsync.options_query_order_history() @pytest.mark.skip(reason="No sandbox to environmnet to test") async def test_options_user_trades(liveClientAsync): await liveClientAsync.options_user_trades() ================================================ FILE: tests/test_async_client_portfolio.py ================================================ import pytest # Apply the 'portfolio' mark to all tests in this file pytestmark = [pytest.mark.portfolio, pytest.mark.asyncio] async def test_papi_get_balance(client): await client.papi_get_balance() async def test_papi_get_account(client): await client.papi_get_account() async def test_papi_get_margin_max_borrowable(client): await client.papi_get_margin_max_borrowable() async def test_papi_get_margin_max_withdraw(client): await client.papi_get_margin_max_withdraw() async def test_papi_get_um_position_risk(client): await client.papi_get_um_position_risk() async def test_papi_get_cm_position_risk(client): await client.papi_get_cm_position_risk() async def test_papi_set_um_leverage(client): await client.papi_set_um_leverage() async def test_papi_set_cm_leverage(client): await client.papi_set_cm_leverage() async def test_papi_change_um_position_side_dual(client): await client.papi_change_um_position_side_dual() async def test_papi_get_um_position_side_dual(client): await client.papi_get_um_position_side_dual() async def test_papi_get_cm_position_side_dual(client): await client.papi_get_cm_position_side_dual() async def test_papi_get_um_leverage_bracket(client): await client.papi_get_um_leverage_bracket() async def test_papi_get_cm_leverage_bracket(client): await client.papi_get_cm_leverage_bracket() async def test_papi_get_um_api_trading_status(client): await client.papi_get_um_api_trading_status() async def test_papi_get_um_comission_rate(client): await client.papi_get_um_comission_rate() async def test_papi_get_cm_comission_rate(client): await client.papi_get_cm_comission_rate() async def test_papi_get_margin_margin_loan(client): await client.papi_get_margin_margin_loan() async def test_papi_get_margin_repay_loan(client): await client.papi_get_margin_repay_loan() async def test_papi_get_repay_futures_switch(client): await client.papi_get_repay_futures_switch() async def test_papi_repay_futures_switch(client): await client.papi_repay_futures_switch() async def test_papi_get_margin_interest_history(client): await client.papi_get_margin_interest_history() async def test_papi_repay_futures_negative_balance(client): await client.papi_repay_futures_negative_balance() async def test_papi_get_portfolio_interest_history(client): await client.papi_get_portfolio_interest_history() async def test_papi_fund_auto_collection(client): await client.papi_fund_auto_collection() async def test_papi_fund_asset_collection(client): await client.papi_fund_asset_collection() async def test_papi_bnb_transfer(client): await client.papi_bnb_transfer() async def test_papi_get_um_income_history(client): await client.papi_get_um_income_history() async def test_papi_get_cm_income_history(client): await client.papi_get_cm_income_history() async def test_papi_get_um_account(client): await client.papi_get_um_account() async def test_papi_get_um_account_v2(client): await client.papi_get_um_account_v2() async def test_papi_get_cm_account(client): await client.papi_get_cm_account() async def test_papi_get_um_account_config(client): await client.papi_get_um_account_config() async def test_papi_get_um_symbol_config(client): await client.papi_get_um_symbol_config() async def test_papi_get_um_trade_asyn(client): await client.papi_get_um_trade_asyn() async def test_papi_get_um_trade_asyn_id(client): await client.papi_get_um_trade_asyn_id() async def test_papi_get_um_order_asyn(client): await client.papi_get_um_order_asyn() async def test_papi_get_um_order_asyn_id(client): await client.papi_get_um_order_asyn_id() async def test_papi_get_um_income_asyn(client): await client.papi_get_um_income_asyn() async def test_papi_get_um_income_asyn_id(client): await client.papi_get_um_income_asyn_id() # Public papi endpoints async def test_papi_ping(client): await client.papi_ping() # Trade papi endpoints async def test_papi_create_um_order(client): await client.papi_create_um_order() async def test_papi_create_um_conditional_order(client): await client.papi_create_um_conditional_order() async def test_papi_create_cm_order(client): await client.papi_create_cm_order() async def test_papi_create_cm_conditional_order(client): await client.papi_create_cm_conditional_order() async def test_papi_create_margin_order(client): await client.papi_create_margin_order() async def test_papi_margin_loan(client): await client.papi_margin_loan() async def test_papi_repay_loan(client): await client.papi_repay_loan() async def test_papi_margin_order_oco(client): await client.papi_margin_order_oco() async def test_papi_cancel_um_order(client): await client.papi_cancel_um_order() async def test_papi_cancel_um_all_open_orders(client): await client.papi_cancel_um_all_open_orders() async def test_papi_cancel_um_conditional_order(client): await client.papi_cancel_um_conditional_order() async def test_papi_cancel_um_conditional_all_open_orders(client): await client.papi_cancel_um_conditional_all_open_orders() async def test_papi_cancel_cm_order(client): await client.papi_cancel_cm_order() async def test_papi_cancel_cm_all_open_orders(client): await client.papi_cancel_cm_all_open_orders() async def test_papi_cancel_cm_conditional_order(client): await client.papi_cancel_cm_conditional_order() async def test_papi_cancel_cm_conditional_all_open_orders(client): await client.papi_cancel_cm_conditional_all_open_orders() async def test_papi_cancel_margin_order(client): await client.papi_cancel_margin_order() async def test_papi_cancel_margin_order_list(client): await client.papi_cancel_margin_order_list() async def test_papi_cancel_margin_all_open_orders(client): await client.papi_cancel_margin_all_open_orders() async def test_papi_modify_um_order(client): await client.papi_modify_um_order() async def test_papi_modify_cm_order(client): await client.papi_modify_cm_order() async def test_papi_get_um_order(client): await client.papi_get_um_order() async def test_papi_get_um_all_orders(client): await client.papi_get_um_all_orders() async def test_papi_get_um_open_order(client): await client.papi_get_um_open_order() async def test_papi_get_um_open_orders(client): await client.papi_get_um_open_orders() async def test_papi_get_um_conditional_all_orders(client): await client.papi_get_um_conditional_all_orders() async def test_papi_get_um_conditional_open_orders(client): await client.papi_get_um_conditional_open_orders() async def test_papi_get_um_conditional_open_order(client): await client.papi_get_um_conditional_open_order() async def test_papi_get_um_conditional_order_history(client): await client.papi_get_um_conditional_order_history() async def test_papi_get_cm_order(client): await client.papi_get_cm_order() async def test_papi_get_cm_all_orders(client): await client.papi_get_cm_all_orders() async def test_papi_get_cm_open_order(client): await client.papi_get_cm_open_order() async def test_papi_get_cm_open_orders(client): await client.papi_get_cm_open_orders() async def test_papi_get_cm_conditional_all_orders(client): await client.papi_get_cm_conditional_all_orders() async def test_papi_get_cm_conditional_open_orders(client): await client.papi_get_cm_conditional_open_orders() async def test_papi_get_cm_conditional_open_order(client): await client.papi_get_cm_conditional_open_order() async def test_papi_get_cm_conditional_order_history(client): await client.papi_get_cm_conditional_order_history() async def test_papi_get_um_force_orders(client): await client.papi_get_um_force_orders() async def test_papi_get_cm_force_orders(client): await client.papi_get_cm_force_orders() async def test_papi_get_um_order_amendment(client): await client.papi_get_um_order_amendment() async def test_papi_get_cm_order_amendment(client): await client.papi_get_cm_order_amendment() async def test_papi_get_margin_force_orders(client): await client.papi_get_margin_force_orders() async def test_papi_get_um_user_trades(client): await client.papi_get_um_user_trades() async def test_papi_get_cm_user_trades(client): await client.papi_get_cm_user_trades() async def test_papi_get_um_adl_quantile(client): await client.papi_get_um_adl_quantile() async def test_papi_get_cm_adl_quantile(client): await client.papi_get_cm_adl_quantile() async def test_papi_set_um_fee_burn(client): await client.papi_set_um_fee_burn() async def test_papi_get_um_fee_burn(client): await client.papi_get_um_fee_burn() async def test_papi_get_margin_order(client): await client.papi_get_margin_order() async def test_papi_get_margin_open_orders(client): await client.papi_get_margin_open_orders() async def test_papi_get_margin_all_orders(client): await client.papi_get_margin_all_orders() async def test_papi_get_margin_order_list(client): await client.papi_get_margin_order_list() async def test_papi_get_margin_all_order_list(client): await client.papi_get_margin_all_order_list() async def test_papi_get_margin_open_order_list(client): await client.papi_get_margin_open_order_list() async def test_papi_get_margin_my_trades(client): await client.papi_get_margin_my_trades() async def test_papi_get_margin_repay_debt(client): await client.papi_get_margin_repay_debt() async def test_close_connection(client): await client.close_connection() ================================================ FILE: tests/test_async_client_ws_api.py ================================================ import pytest import sys pytestmark = [pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+"), pytest.mark.asyncio()] async def test_ws_get_order_book(clientAsync): await clientAsync.ws_get_order_book(symbol="BTCUSDT") async def test_ws_get_recent_trades(clientAsync): await clientAsync.ws_get_recent_trades(symbol="BTCUSDT") async def test_ws_get_historical_trades(clientAsync): await clientAsync.ws_get_historical_trades(symbol="BTCUSDT") async def test_ws_get_aggregate_trades(clientAsync): await clientAsync.ws_get_aggregate_trades(symbol="BTCUSDT") async def test_ws_get_klines(clientAsync): await clientAsync.ws_get_klines(symbol="BTCUSDT", interval="1m") async def test_ws_get_uiKlines(clientAsync): await clientAsync.ws_get_uiKlines(symbol="BTCUSDT", interval="1m") async def test_ws_get_avg_price(clientAsync): await clientAsync.ws_get_avg_price(symbol="BTCUSDT") async def test_ws_get_ticker(clientAsync): await clientAsync.ws_get_ticker(symbol="BTCUSDT") async def test_ws_get_trading_day_ticker(clientAsync): await clientAsync.ws_get_trading_day_ticker(symbol="BTCUSDT") async def test_ws_get_symbol_ticker_window(clientAsync): await clientAsync.ws_get_symbol_ticker_window(symbol="BTCUSDT") async def test_ws_get_symbol_ticker(clientAsync): await clientAsync.ws_get_symbol_ticker(symbol="BTCUSDT") async def test_ws_get_orderbook_ticker(clientAsync): await clientAsync.ws_get_orderbook_ticker(symbol="BTCUSDT") async def test_ws_ping(clientAsync): await clientAsync.ws_ping() async def test_ws_get_time(clientAsync): await clientAsync.ws_get_time() async def test_ws_get_exchange_info(clientAsync): await clientAsync.ws_get_exchange_info(symbol="BTCUSDT") ================================================ FILE: tests/test_async_client_ws_futures_requests.py ================================================ import asyncio import pytest import sys from binance.exceptions import BinanceAPIException, BinanceWebsocketUnableToConnect from .test_get_order_book import assert_ob from .test_order import assert_contract_order try: from unittest.mock import patch # Python 3.8+ except ImportError: from asynctest import patch # Python 3.7 @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_futures_get_order_book(futuresClientAsync): orderbook = await futuresClientAsync.ws_futures_get_order_book(symbol="BTCUSDT") assert_ob(orderbook) @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_concurrent_ws_futures_get_order_book(futuresClientAsync): symbols = ["BTCUSDT", "ETHUSDT", "BNBUSDT", "ADAUSDT"] async def get_orderbook(symbol): orderbook = await futuresClientAsync.ws_futures_get_order_book(symbol=symbol) assert_ob(orderbook) return orderbook tasks = [get_orderbook(symbol) for symbol in symbols] results = await asyncio.gather(*tasks) # Verify results assert len(results) == len(symbols) for orderbook in results: assert_ob(orderbook) @pytest.mark.asyncio() async def test_bad_request(futuresClientAsync): with pytest.raises(BinanceAPIException): await futuresClientAsync.ws_futures_get_order_book() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_futures_get_all_tickers(futuresClientAsync): await futuresClientAsync.ws_futures_get_all_tickers() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_futures_get_order_book_ticker(futuresClientAsync): await futuresClientAsync.ws_futures_get_order_book_ticker() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_futures_create_get_edit_cancel_order_with_orjson(futuresClientAsync): if 'orjson' not in sys.modules: raise ImportError("orjson is not available") ticker = await futuresClientAsync.ws_futures_get_order_book_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.ws_futures_v2_account_position( symbol="LTCUSDT" ) order = await futuresClientAsync.ws_futures_create_order( symbol=ticker["symbol"], side="SELL", positionSide=positions[0]["positionSide"], type="LIMIT", timeInForce="GTC", quantity=0.1, price=str(float(ticker["bidPrice"]) + 5), ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.ws_futures_edit_order( orderid=order["orderId"], symbol=order["symbol"], quantity=0.11, side=order["side"], price=order["price"], ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.ws_futures_get_order( symbol="LTCUSDT", orderid=order["orderId"] ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.ws_futures_cancel_order( orderid=order["orderId"], symbol=order["symbol"] ) @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_futures_create_get_edit_cancel_order_without_orjson(futuresClientAsync): with patch.dict('sys.modules', {'orjson': None}): ticker = await futuresClientAsync.ws_futures_get_order_book_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.ws_futures_v2_account_position( symbol="LTCUSDT" ) order = await futuresClientAsync.ws_futures_create_order( symbol=ticker["symbol"], side="SELL", positionSide=positions[0]["positionSide"], type="LIMIT", timeInForce="GTC", quantity=0.1, price=str(float(ticker["bidPrice"]) + 5), ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.ws_futures_edit_order( orderid=order["orderId"], symbol=order["symbol"], quantity=0.11, side=order["side"], price=order["price"], ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.ws_futures_get_order( symbol="LTCUSDT", orderid=order["orderId"] ) assert_contract_order(futuresClientAsync, order) order = await futuresClientAsync.ws_futures_cancel_order( orderid=order["orderId"], symbol=order["symbol"] ) @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_futures_v2_account_position(futuresClientAsync): await futuresClientAsync.ws_futures_v2_account_position() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_futures_account_position(futuresClientAsync): await futuresClientAsync.ws_futures_account_position() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_futures_v2_account_balance(futuresClientAsync): await futuresClientAsync.ws_futures_v2_account_balance() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_futures_account_balance(futuresClientAsync): await futuresClientAsync.ws_futures_account_balance() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_futures_v2_account_status(futuresClientAsync): await futuresClientAsync.ws_futures_v2_account_status() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_futures_account_status(futuresClientAsync): await futuresClientAsync.ws_futures_account_status() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_ws_futures_fail_to_connect(futuresClientAsync): # Close any existing connection first await futuresClientAsync.close_connection() # Mock the WebSocket API's connect method to raise an exception with patch.object(futuresClientAsync.ws_future, 'connect', side_effect=ConnectionError("Simulated connection failure")): with pytest.raises(BinanceWebsocketUnableToConnect): await futuresClientAsync.ws_futures_get_order_book(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_futures_create_cancel_algo_order(futuresClientAsync): """Test creating and canceling an algo order via websocket async""" ticker = await futuresClientAsync.ws_futures_get_order_book_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.ws_futures_v2_account_position(symbol="LTCUSDT") # Create an algo order order = await futuresClientAsync.ws_futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert order["algoType"] == "CONDITIONAL" # Cancel the algo order cancel_result = await futuresClientAsync.ws_futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) assert cancel_result["algoId"] == order["algoId"] @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_futures_create_conditional_order_auto_routing(futuresClientAsync): """Test that conditional order types are automatically routed to algo endpoint""" ticker = await futuresClientAsync.ws_futures_get_order_book_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.ws_futures_v2_account_position(symbol="LTCUSDT") # Create a STOP_MARKET order using ws_futures_create_order # It should automatically route to the algo endpoint # Use a price above current market price for BUY STOP trigger_price = float(ticker["askPrice"]) * 1.5 order = await futuresClientAsync.ws_futures_create_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", quantity=1, triggerPrice=trigger_price, ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert order["algoType"] == "CONDITIONAL" # Cancel the order using algoId cancel_result = await futuresClientAsync.ws_futures_cancel_order( symbol=ticker["symbol"], algoId=order["algoId"] ) assert cancel_result["algoId"] == order["algoId"] @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_futures_conditional_order_with_stop_price(futuresClientAsync): """Test that stopPrice is converted to triggerPrice for conditional orders""" ticker = await futuresClientAsync.ws_futures_get_order_book_ticker(symbol="LTCUSDT") positions = await futuresClientAsync.ws_futures_v2_account_position(symbol="LTCUSDT") # Create a TAKE_PROFIT_MARKET order with stopPrice (should be converted to triggerPrice) # Use a price above current market price for SELL TAKE_PROFIT trigger_price = float(ticker["askPrice"]) * 1.5 order = await futuresClientAsync.ws_futures_create_order( symbol=ticker["symbol"], side="SELL", positionSide=positions[0]["positionSide"], type="TAKE_PROFIT_MARKET", quantity=1, stopPrice=trigger_price, # This should be converted to triggerPrice ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert order["algoType"] == "CONDITIONAL" # Cancel the order await futuresClientAsync.ws_futures_cancel_order( symbol=ticker["symbol"], algoId=order["algoId"] ) ================================================ FILE: tests/test_client.py ================================================ import sys import pytest from binance.client import Client from binance.exceptions import BinanceAPIException, BinanceRequestException from .conftest import proxies, api_key, api_secret, testnet, call_method_and_assert_uri_contains def test_client_initialization(client): assert client.API_KEY is not None assert client.API_SECRET is not None @pytest.mark.skip(reason="Endpoint not documented") def test_get_products(client): client.get_products() def test_get_exchange_info(client): client.get_exchange_info() def test_get_symbol_info(client): client.get_symbol_info("BTCUSDT") def test_ping(client): call_method_and_assert_uri_contains(client, 'ping', '/v3/') def test_get_server_time(client): client.get_server_time() def test_get_all_tickers(client): client.get_all_tickers() def test_get_orderbook_tickers(client): client.get_orderbook_tickers() def test_get_order_book(client): client.get_order_book(symbol="BTCUSDT") def test_get_recent_trades(client): client.get_recent_trades(symbol="BTCUSDT") def test_get_historical_trades(client): client.get_historical_trades(symbol="BTCUSDT") def test_get_aggregate_trades(client): client.get_aggregate_trades(symbol="BTCUSDT") def test_get_klines(client): client.get_klines(symbol="BTCUSDT", interval="1d") def test_get_ui_klines(client): client.get_ui_klines(symbol="BTCUSDT", interval="1d") def test_get_avg_price(client): client.get_avg_price(symbol="BTCUSDT") def test_get_ticker(client): client.get_ticker(symbol="BTCUSDT") def test_get_symbol_ticker(client): client.get_symbol_ticker(symbol="BTCUSDT") def test_get_orderbook_ticker(client): call_method_and_assert_uri_contains(client, 'get_orderbook_ticker', '/v3/', symbol="BTCUSDT") def test_get_account(client): client.get_account() def test_get_asset_balance(client): client.get_asset_balance(asset="BTC") def test_get_asset_balance_no_asset_provided(client): client.get_asset_balance() def test_get_my_trades(client): client.get_my_trades(symbol="BTCUSDT") def test_get_system_status(client): client.get_system_status() # User Stream Endpoints def test_stream_get_listen_key_and_close(client): listen_key = client.stream_get_listen_key() client.stream_close(listen_key) # Quoting interface endpoints @pytest.mark.skip(reason="Endpoint not working on testnet") def test_get_account_status(client): client.get_account_status() @pytest.mark.skip(reason="Endpoint not working on testnet") def test_get_account_api_trading_status(client): client.get_account_api_trading_status() @pytest.mark.skip(reason="Endpoint not working on testnet") def test_get_account_api_permissions(client): client.get_account_api_permissions() @pytest.mark.skip(reason="Endpoint not working on testnet") def test_get_dust_assets(client): client.get_dust_assets() ######################### # Websocket API Requests # ######################### @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_get_order_book(client): client.ws_get_order_book(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_get_recent_trades(client): client.ws_get_recent_trades(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_get_historical_trades(client): client.ws_get_historical_trades(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_get_aggregate_trades(client): client.ws_get_aggregate_trades(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_get_klines(client): client.ws_get_klines(symbol="BTCUSDT", interval="1m") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_get_uiKlines(client): client.ws_get_uiKlines(symbol="BTCUSDT", interval="1m") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_get_avg_price(client): client.ws_get_avg_price(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_get_ticker(client): ticker = client.ws_get_ticker(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_get_trading_day_ticker(client): client.ws_get_trading_day_ticker(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_get_symbol_ticker_window(client): client.ws_get_symbol_ticker_window(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_get_symbol_ticker(client): client.ws_get_symbol_ticker(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_get_orderbook_ticker(client): client.ws_get_orderbook_ticker(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_ping(client): client.ws_ping() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_get_time(client): client.ws_get_time() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_get_exchange_info(client): client.ws_get_exchange_info(symbol="BTCUSDT") def test_time_unit_microseconds(): micro_client = Client( api_key, api_secret, {"proxies": proxies}, testnet=testnet, time_unit="MICROSECOND", ) micro_trades = micro_client.get_recent_trades(symbol="BTCUSDT") assert len(str(micro_trades[0]["time"])) >= 16, ( "Time should be in microseconds (16+ digits)" ) def test_time_unit_milloseconds(): milli_client = Client( api_key, api_secret, {"proxies": proxies}, testnet=testnet, time_unit="MILLISECOND", ) milli_trades = milli_client.get_recent_trades(symbol="BTCUSDT") assert len(str(milli_trades[0]["time"])) == 13, ( "Time should be in milliseconds (13 digits)" ) def test_handle_response(client): # Test successful JSON response mock_response = type('Response', (), { 'status_code': 200, 'text': '{"key": "value"}', 'json': lambda: {"key": "value"} }) assert client._handle_response(mock_response) == {"key": "value"} # Test empty response mock_empty_response = type('Response', (), { 'status_code': 200, 'text': '' }) assert client._handle_response(mock_empty_response) == {} # Test invalid JSON response mock_invalid_response = type('Response', (), { 'status_code': 200, 'text': 'invalid json', 'json': lambda: exec('raise ValueError()') }) with pytest.raises(BinanceRequestException): client._handle_response(mock_invalid_response) # Test error status code mock_error_response = type('Response', (), { 'status_code': 400, 'text': 'error message' }) with pytest.raises(BinanceAPIException): client._handle_response(mock_error_response) ================================================ FILE: tests/test_client_futures.py ================================================ from datetime import datetime import re import pytest import requests_mock from .test_order import assert_contract_order from .test_get_order_book import assert_ob def test_futures_ping(futuresClient): futuresClient.futures_ping() def test_futures_time(futuresClient): futuresClient.futures_time() def test_futures_exchange_info(futuresClient): futuresClient.futures_exchange_info() def test_futures_order_book(futuresClient): order_book = futuresClient.futures_order_book(symbol="BTCUSDT") assert_ob(order_book) def test_futures_rpi_depth(futuresClient): rpi_depth = futuresClient.futures_rpi_depth(symbol="BTCUSDT") assert_ob(rpi_depth) def test_futures_recent_trades(futuresClient): futuresClient.futures_recent_trades(symbol="BTCUSDT") def test_futures_historical_trades(futuresClient): futuresClient.futures_historical_trades(symbol="BTCUSDT") def test_futures_aggregate_trades(futuresClient): futuresClient.futures_aggregate_trades(symbol="BTCUSDT") def test_futures_klines(futuresClient): futuresClient.futures_klines(symbol="BTCUSDT", interval="1h") def test_futures_mark_price_klines(futuresClient): futuresClient.futures_mark_price_klines(symbol="BTCUSDT", interval="1h") def test_futures_index_price_klines(futuresClient): futuresClient.futures_index_price_klines(pair="BTCUSDT", interval="1h") def test_futures_premium_index_klines(futuresClient): futuresClient.futures_premium_index_klines(symbol="BTCUSDT", interval="1h") def test_futures_continuous_klines(futuresClient): futuresClient.futures_continuous_klines( pair="BTCUSDT", contractType="PERPETUAL", interval="1h" ) def test_futures_historical_klines(futuresClient): futuresClient.futures_historical_klines( symbol="BTCUSDT", interval="1h", start_str=datetime.now().strftime("%Y-%m-%d") ) def test_futures_historical_klines_generator(futuresClient): futuresClient.futures_historical_klines_generator( symbol="BTCUSDT", interval="1h", start_str=datetime.now().strftime("%Y-%m-%d") ) def test_futures_mark_price(futuresClient): futuresClient.futures_mark_price() def test_futures_funding_rate(futuresClient): futuresClient.futures_funding_rate() @pytest.mark.skip(reason="No Sandbox Environment to test") def test_futures_top_longshort_account_ratio(futuresClient): futuresClient.futures_top_longshort_account_ratio(symbol="BTCUSDT", period="5m") @pytest.mark.skip(reason="No Sandbox Environment to test") def test_futures_top_longshort_position_ratio(futuresClient): futuresClient.futures_top_longshort_position_ratio(symbol="BTCUSDT", period="5m") @pytest.mark.skip(reason="No Sandbox Environment to test") def test_futures_global_longshort_ratio(futuresClient): futuresClient.futures_global_longshort_ratio(symbol="BTCUSDT", period="5m") @pytest.mark.skip(reason="No Sandbox Environment to test") def test_futures_taker_longshort_ratio(futuresClient): futuresClient.futures_taker_longshort_ratio(symbol="BTCUSDT", period="5m") def test_futures_ticker(futuresClient): futuresClient.futures_ticker() def test_futures_symbol_ticker(futuresClient): futuresClient.futures_symbol_ticker() def test_futures_orderbook_ticker(futuresClient): futuresClient.futures_orderbook_ticker() def test_futures_index_index_price_constituents(futuresClient): futuresClient.futures_index_price_constituents(symbol="BTCUSD") def test_futures_liquidation_orders(futuresClient): futuresClient.futures_liquidation_orders() @pytest.mark.skip(reason="Fails in demo environment") def test_futures_api_trading_status(futuresClient): futuresClient.futures_api_trading_status() def test_futures_commission_rate(futuresClient): futuresClient.futures_commission_rate(symbol="BTCUSDT") def test_futures_adl_quantile_estimate(futuresClient): futuresClient.futures_adl_quantile_estimate() def test_futures_open_interest(futuresClient): futuresClient.futures_open_interest(symbol="BTCUSDT") def test_futures_index_info(futuresClient): futuresClient.futures_index_info() @pytest.mark.skip(reason="No Sandbox Environment to test") def test_futures_open_interest_hist(futuresClient): futuresClient.futures_open_interest_hist(symbol="BTCUSDT", period="5m") def test_futures_leverage_bracket(futuresClient): futuresClient.futures_leverage_bracket() @pytest.mark.skip(reason="Not implemented") def test_futures_account_transfer(futuresClient): futuresClient.futures_account_transfer() @pytest.mark.skip(reason="Not implemented") def test_transfer_history(client): client.transfer_history() @pytest.mark.skip(reason="Not implemented") def test_futures_loan_borrow_history(futuresClient): futuresClient.futures_loan_borrow_history() @pytest.mark.skip(reason="Not implemented") def test_futures_loan_repay_history(futuresClient): futuresClient.futures_loan_repay_history() @pytest.mark.skip(reason="Not implemented") def test_futures_loan_wallet(futuresClient): futuresClient.futures_loan_wallet() @pytest.mark.skip(reason="Not implemented") def test_futures_cross_collateral_adjust_history(futuresClient): futuresClient.futures_cross_collateral_adjust_history() @pytest.mark.skip(reason="Not implemented") def test_futures_cross_collateral_liquidation_history(futuresClient): futuresClient.futures_cross_collateral_liquidation_history() @pytest.mark.skip(reason="Not implemented") def test_futures_loan_interest_history(futuresClient): futuresClient.futures_loan_interest_history() def test_futures_create_get_edit_cancel_order(futuresClient): ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") order = futuresClient.futures_create_order( symbol=ticker["symbol"], side="SELL", positionSide=positions[0]["positionSide"], type="LIMIT", timeInForce="GTC", quantity=0.1, price=str(round(float(ticker["lastPrice"]) + 2)), ) assert_contract_order(futuresClient, order) order = futuresClient.futures_modify_order( orderid=order["orderId"], symbol=order["symbol"], quantity=0.11, side=order["side"], price=order["price"], ) assert_contract_order(futuresClient, order) order = futuresClient.futures_get_order( symbol=order["symbol"], orderid=order["orderId"] ) assert_contract_order(futuresClient, order) order = futuresClient.futures_cancel_order( orderid=order["orderId"], symbol=order["symbol"] ) def test_futures_create_test_order(futuresClient): ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") futuresClient.futures_create_test_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="LIMIT", timeInForce="GTC", quantity=0.1, price=str(round(float(ticker["lastPrice"]) - 1, 0)), ) def test_futures_place_batch_order_and_cancel(futuresClient): ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") orders = futuresClient.futures_place_batch_order( batchOrders=[ { "symbol": ticker["symbol"], "side": "SELL", "positionSide": positions[0]["positionSide"], "type": "LIMIT", "timeInForce": "GTC", "quantity": "0.1", "price": str(round(float(ticker["lastPrice"]) + 2, 0)), }, { "symbol": ticker["symbol"], "type": "LIMIT", "side": "SELL", "price": str(round(float(ticker["lastPrice"]) + 2, 0)), "positionSide": positions[0]["positionSide"], "timeInForce": "GTC", "quantity": "0.1", }, ] ) for order in orders: assert_contract_order(futuresClient, order) # Cancel using orderidlist order_ids = [order["orderId"] for order in orders][:1] cancelled_orders = futuresClient.futures_cancel_orders( symbol=orders[0]["symbol"], orderidlist=order_ids ) for order in cancelled_orders: assert_contract_order(futuresClient, order) # Cancel using origClientOrderIdList client_order_ids = [order["clientOrderId"] for order in orders][1:] cancelled_orders = futuresClient.futures_cancel_orders( symbol=orders[0]["symbol"], origclientorderidlist=client_order_ids ) for order in cancelled_orders: assert_contract_order(futuresClient, order) def test_futures_get_open_orders(futuresClient): futuresClient.futures_get_open_orders() def test_futures_get_all_orders(futuresClient): orders = futuresClient.futures_get_all_orders() print(orders) def test_futures_cancel_all_open_orders(futuresClient): futuresClient.futures_cancel_all_open_orders(symbol="LTCUSDT") def test_futures_countdown_cancel_all(futuresClient): futuresClient.futures_countdown_cancel_all(symbol="LTCUSDT", countdownTime=10) def test_futures_account_balance(futuresClient): futuresClient.futures_account_balance() def test_futures_account(futuresClient): futuresClient.futures_account() def test_futures_symbol_adl_risk(futuresClient): # Test without symbol (get all) adl_risks = futuresClient.futures_symbol_adl_risk() assert isinstance(adl_risks, list) # Test with specific symbol (if any symbols available) if len(adl_risks) > 0: test_symbol = adl_risks[0]["symbol"] adl_risk = futuresClient.futures_symbol_adl_risk(symbol=test_symbol) assert isinstance(adl_risk, dict) assert "symbol" in adl_risk assert "adlRisk" in adl_risk assert adl_risk["adlRisk"] in ["low", "medium", "high"] assert adl_risk["symbol"] == test_symbol def test_futures_change_leverage(futuresClient): futuresClient.futures_change_leverage(symbol="LTCUSDT", leverage=10) def test_futures_change_margin_type(futuresClient): try: futuresClient.futures_change_margin_type(symbol="XRPUSDT", marginType="CROSSED") except Exception as e: futuresClient.futures_change_margin_type( symbol="XRPUSDT", marginType="ISOLATED" ) def test_futures_position_margin_history(futuresClient): position = futuresClient.futures_position_margin_history(symbol="LTCUSDT") print(position) def test_futures_position_information(futuresClient): futuresClient.futures_position_information() def test_futures_account_trades(futuresClient): futuresClient.futures_account_trades() def test_futures_income_history(futuresClient): futuresClient.futures_income_history() def close_all_futures_positions(futuresClient): # Get all open positions positions = futuresClient.futures_position_information(symbol="LTCUSDT") for position in positions: # Check if there is an open position if float(position["positionAmt"]) != 0: symbol = position["symbol"] position_amt = float(position["positionAmt"]) side = "SELL" if position_amt > 0 else "BUY" # Place a market order to close the position try: print(f"Closing position for {symbol}: {position_amt} units") futuresClient.futures_create_order( symbol=symbol, side=side, type="market", quantity=abs(position_amt) ) print(f"Position for {symbol} closed successfully.") except Exception as e: print(f"Failed to close position for {symbol}: {e}") @pytest.mark.skip(reason="Not implemented") def test_futures_get_and_change_position_mode(futuresClient): mode = futuresClient.futures_get_position_mode() futuresClient.futures_change_position_mode( dualSidePosition=not mode["dualSidePosition"] ) @pytest.mark.skip(reason="Not implemented") def test_futures_change_multi_assets_mode(futuresClient): futuresClient.futures_change_multi_assets_mode() def test_futures_get_multi_assets_mode(futuresClient): futuresClient.futures_get_multi_assets_mode() def test_futures_stream_get_listen_key(futuresClient): futuresClient.futures_stream_get_listen_key() @pytest.mark.skip(reason="Not implemented") def test_futures_stream_close(futuresClient): futuresClient.futures_stream_close() # new methods def test_futures_account_config(futuresClient): futuresClient.futures_account_config() def test_futures_symbol_config(futuresClient): futuresClient.futures_symbol_config() # COIN Futures API def test_futures_coin_ping(futuresClient): futuresClient.futures_coin_ping() def test_futures_coin_time(futuresClient): futuresClient.futures_coin_time() def test_futures_coin_exchange_info(futuresClient): futuresClient.futures_coin_exchange_info() def test_futures_coin_order_book(futuresClient): order_book = futuresClient.futures_coin_order_book(symbol="BTCUSD_PERP") assert_ob(order_book) def test_futures_coin_recent_trades(futuresClient): futuresClient.futures_coin_recent_trades(symbol="BTCUSD_PERP") def test_futures_coin_historical_trades(futuresClient): futuresClient.futures_coin_historical_trades(symbol="BTCUSD_PERP") @pytest.mark.skip(reason="Not implemented") def test_futures_coin_aggregate_trades(futuresClient): futuresClient.futures_coin_aggregate_trades(symbol="BTCUSD_PERP") def test_futures_coin_klines(futuresClient): futuresClient.futures_coin_klines(symbol="BTCUSD_PERP", interval="1h") def test_futures_coin_continous_klines(futuresClient): futuresClient.futures_coin_continous_klines( pair="BTCUSD", contractType="PERPETUAL", interval="1h" ) def test_futures_coin_index_price_klines(futuresClient): futuresClient.futures_coin_index_price_klines(pair="BTCUSD", interval="1h") def test_futures_coin_mark_price_klines(futuresClient): futuresClient.futures_coin_mark_price_klines(symbol="BTCUSD_PERP", interval="1h") def test_futures_coin_mark_price(futuresClient): futuresClient.futures_coin_mark_price() @pytest.mark.skip(reason="Giving unknwon error from binance") def test_futures_coin_funding_rate(futuresClient): futuresClient.futures_coin_funding_rate(symbol="BTCUSD_PERP") def test_futures_coin_ticker(futuresClient): futuresClient.futures_coin_ticker() def test_futures_coin_symbol_ticker(futuresClient): futuresClient.futures_coin_symbol_ticker() def test_futures_coin_orderbook_ticker(futuresClient): futuresClient.futures_coin_orderbook_ticker() def test_futures_coin_index_index_price_constituents(futuresClient): futuresClient.futures_coin_index_price_constituents(symbol="BTCUSD") @pytest.mark.skip(reason="Not implemented") def test_futures_coin_liquidation_orders(futuresClient): futuresClient.futures_coin_liquidation_orders(limit=5) def test_futures_coin_open_interest(futuresClient): futuresClient.futures_coin_open_interest(symbol="BTCUSD_PERP") @pytest.mark.skip(reason="Not implemented") def test_futures_coin_open_interest_hist(futuresClient): futuresClient.futures_coin_open_interest_hist(symbol="BTCUSD_PERP") def test_futures_coin_leverage_bracket(futuresClient): futuresClient.futures_coin_leverage_bracket() @pytest.mark.skip(reason="Not implemented") def test_futures_coin_create_order(futuresClient): positions = futuresClient.futures_coin_position_information() ticker = futuresClient.futures_coin_ticker(symbol=positions[0]["symbol"]) order = futuresClient.futures_coin_create_order( symbol=positions[0]["symbol"], side="BUY", type="LIMIT", timeInForce="GTC", quantity=1, price=str(round(float(ticker[0]["lastPrice"]) - 1, 0)), ) assert_contract_order(futuresClient, order) order = futuresClient.futures_modify_order( orderid=order["orderId"], symbol=order["symbol"], quantity=0.11, side=order["side"], price=order["price"], ) assert_contract_order(futuresClient, order) order = futuresClient.futures_get_order( symbol=order["symbol"], orderid=order["orderId"] ) assert_contract_order(futuresClient, order) order = futuresClient.futures_cancel_order( orderid=order["orderId"], symbol=order["symbol"] ) @pytest.mark.skip(reason="Not implemented") def test_futures_coin_place_batch_order(futuresClient): futuresClient.futures_coin_place_batch_order() @pytest.mark.skip(reason="Not implemented") def test_futures_coin_get_order(futuresClient): futuresClient.futures_coin_get_order() def test_futures_coin_get_open_orders(futuresClient): futuresClient.futures_coin_get_open_orders() @pytest.mark.skip(reason="Not implemented") def test_futures_coin_get_all_orders(futuresClient): futuresClient.futures_coin_get_all_orders() @pytest.mark.skip(reason="Not implemented") def test_futures_coin_cancel_order(futuresClient): futuresClient.futures_coin_cancel_order() def test_futures_coin_cancel_all_open_orders(futuresClient): futuresClient.futures_coin_cancel_all_open_orders(symbol="BTCUSD_PERP") @pytest.mark.skip(reason="Not implemented") def test_futures_coin_cancel_orders(futuresClient): futuresClient.futures_coin_cancel_orders() def test_futures_coin_account_balance(futuresClient): futuresClient.futures_coin_account_balance() def test_futures_coin_account(futuresClient): futuresClient.futures_coin_account() @pytest.mark.skip(reason="Not implemented") def test_futures_coin_change_leverage(futuresClient): futuresClient.futures_coin_change_leverage(symbol="XRPUSDT", leverage=10) @pytest.mark.skip(reason="Not implemented") def test_futures_coin_change_margin_type(futuresClient): futuresClient.futures_coin_change_margin_type() @pytest.mark.skip(reason="Not implemented") def test_futures_coin_change_position_margin(futuresClient): futuresClient.futures_coin_change_position_margin() def test_futures_coin_position_margin_history(futuresClient): futuresClient.futures_coin_position_margin_history(symbol="LTCUSD_PERP") def test_futures_coin_position_information(futuresClient): futuresClient.futures_coin_position_information() def test_futures_coin_account_trades(futuresClient): futuresClient.futures_coin_account_trades() def test_futures_coin_income_history(futuresClient): futuresClient.futures_coin_income_history() @pytest.mark.skip(reason="Not implemented") def test_futures_coin_change_position_mode(futuresClient): futuresClient.futures_coin_change_position_mode() def test_futures_coin_get_position_mode(futuresClient): futuresClient.futures_coin_get_position_mode() def test_futures_coin_stream_close(futuresClient): listen_key = futuresClient.futures_coin_stream_get_listen_key() futuresClient.futures_coin_stream_close(listenKey=listen_key) ######################################################## # Test block trades ######################################################## @pytest.mark.skip(reason="No sandbox support") def test_futures_coin_account_order_history_download(futuresClient): futuresClient.futures_coin_account_order_download() @pytest.mark.skip(reason="No sandbox support") def test_futures_coin_account_order_download_id(futuresClient): futuresClient.futures_coin_account_order_download_link(downloadId="123") @pytest.mark.skip(reason="No sandbox support") def test_futures_coin_account_trade_history_download(futuresClient): futuresClient.futures_coin_account_trade_history_download() @pytest.mark.skip(reason="No sandbox support") def test_futures_coin_account_trade_download_id(futuresClient): futuresClient.futures_coin_account_trade_history_download_link(downloadId="123") def test_futures_coin_account_order_history_download_mock(futuresClient): expected_response = { "avgCostTimestampOfLast30d": 7241837, "downloadId": "546975389218332672", } url_pattern = re.compile( r"https://[^/]+/dapi/v1/order/asyn" r"\?recvWindow=\d+" r"×tamp=\d+" r"&signature=[a-f0-9]{64}" ) with requests_mock.mock() as m: m.get( url_pattern, json=expected_response, ) response = futuresClient.futures_coin_account_order_history_download() assert response == expected_response def test_futures_coin_account_order_download_id_mock(futuresClient): expected_response = {"link": "hello"} url_pattern = re.compile( r"https://[^/]+/dapi/v1/order/asyn/id" r"\?downloadId=123" r"&recvWindow=\d+" r"×tamp=\d+" r"&signature=.+" ) with requests_mock.mock() as m: m.get( url_pattern, json=expected_response, ) response = futuresClient.futures_coin_accout_order_history_download_link( downloadId="123" ) assert response == expected_response def test_futures_coin_account_trade_history_download_id_mock(futuresClient): expected_response = { "avgCostTimestampOfLast30d": 7241837, "downloadId": "546975389218332672", } url_pattern = re.compile( r"https://[^/]+/dapi/v1/trade/asyn" r"\?recvWindow=\d+" r"×tamp=\d+" r"&signature=[a-f0-9]{64}" ) with requests_mock.mock() as m: m.get( url_pattern, json=expected_response, ) response = futuresClient.futures_coin_account_trade_history_download() assert response == expected_response def test_futures_coin_account_trade_history_download_link_mock(futuresClient): expected_response = {"link": "hello"} url_pattern = re.compile( r"https://[^/]+/dapi/v1/trade/asyn/id" r"\?downloadId=123" r"&recvWindow=\d+" r"×tamp=\d+" r"&signature=.+" ) with requests_mock.mock() as m: m.get( url_pattern, json=expected_response, ) response = futuresClient.futures_coin_account_trade_history_download_link( downloadId="123" ) assert response == expected_response # Algo Orders (Conditional Orders) Tests def test_futures_create_algo_order(futuresClient): """Test creating an algo/conditional order""" ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") order = futuresClient.futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order # Clean up - cancel the algo order futuresClient.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) def test_futures_create_order_auto_routes_conditional(futuresClient): """Test that futures_create_order automatically routes conditional orders to algo endpoint""" ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") # Create a conditional order using the regular create_order method order = futuresClient.futures_create_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="TAKE_PROFIT_MARKET", quantity=1, stopPrice=10, ) # Verify it was created as an algo order assert order["symbol"] == ticker["symbol"] assert "algoId" in order # Clean up futuresClient.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) def test_futures_get_algo_order(futuresClient): """Test getting a specific algo order""" ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") # Create an algo order first order = futuresClient.futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, ) algo_id = order["algoId"] # Get the order fetched_order = futuresClient.futures_get_algo_order( symbol=ticker["symbol"], algoId=algo_id ) assert fetched_order["algoId"] == algo_id assert fetched_order["symbol"] == ticker["symbol"] # Clean up futuresClient.futures_cancel_algo_order(symbol=ticker["symbol"], algoId=algo_id) def test_futures_get_order_with_conditional_param(futuresClient): """Test getting algo order using futures_get_order with conditional=True""" ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") # Create an algo order order = futuresClient.futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, ) algo_id = order["algoId"] # Get the order using futures_get_order with conditional=True fetched_order = futuresClient.futures_get_order( symbol=ticker["symbol"], algoId=algo_id, conditional=True ) assert fetched_order["algoId"] == algo_id # Clean up futuresClient.futures_cancel_algo_order(symbol=ticker["symbol"], algoId=algo_id) def test_futures_get_all_algo_orders(futuresClient): """Test getting all algo orders history""" orders = futuresClient.futures_get_all_algo_orders(symbol="LTCUSDT") assert isinstance(orders, list) def test_futures_get_all_orders_with_conditional_param(futuresClient): """Test getting all algo orders using futures_get_all_orders with conditional=True""" orders = futuresClient.futures_get_all_orders(symbol="LTCUSDT", conditional=True) assert isinstance(orders, list) def test_futures_get_open_algo_orders(futuresClient): """Test getting open algo orders""" orders = futuresClient.futures_get_open_algo_orders(symbol="LTCUSDT") assert isinstance(orders, list) def test_futures_get_open_orders_with_conditional_param(futuresClient): """Test getting open algo orders using futures_get_open_orders with conditional=True""" orders = futuresClient.futures_get_open_orders(symbol="LTCUSDT", conditional=True) assert isinstance(orders, list) def test_futures_cancel_algo_order(futuresClient): """Test canceling an algo order""" ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") # Create an algo order order = futuresClient.futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, ) algo_id = order["algoId"] # Cancel the order result = futuresClient.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=algo_id ) assert result["algoId"] == algo_id def test_futures_cancel_order_with_conditional_param(futuresClient): """Test canceling algo order using futures_cancel_order with conditional=True""" ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") # Create an algo order order = futuresClient.futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, ) algo_id = order["algoId"] # Cancel using futures_cancel_order with conditional=True result = futuresClient.futures_cancel_order( symbol=ticker["symbol"], algoId=algo_id, conditional=True ) assert result["algoId"] == algo_id def test_futures_cancel_all_algo_open_orders(futuresClient): """Test canceling all open algo orders""" result = futuresClient.futures_cancel_all_algo_open_orders(symbol="LTCUSDT") # Should return success response assert "code" in result or "msg" in result def test_futures_cancel_all_open_orders_with_conditional_param(futuresClient): """Test canceling all algo orders using futures_cancel_all_open_orders with conditional=True""" result = futuresClient.futures_cancel_all_open_orders( symbol="LTCUSDT", conditional=True ) # Should return success response assert "code" in result or "msg" in result def test_futures_create_algo_order_with_price_protect(futuresClient): """Test creating an algo order with priceProtect parameter""" ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") order = futuresClient.futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, priceProtect="TRUE", ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert order["priceProtect"] is True # Clean up futuresClient.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) @pytest.mark.skip(reason="TRAILING_STOP_MARKET with activatePrice may not be fully supported in testnet environment") def test_futures_create_algo_order_trailing_stop(futuresClient): """Test creating a TRAILING_STOP_MARKET algo order with activatePrice and callbackRate""" ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") current_price = float(ticker["lastPrice"]) # For SELL trailing stop: activatePrice should be above current price # For BUY trailing stop: activatePrice should be below current price order = futuresClient.futures_create_algo_order( symbol=ticker["symbol"], side="SELL", positionSide=positions[0]["positionSide"], type="TRAILING_STOP_MARKET", algoType="CONDITIONAL", quantity=1, activatePrice=str(current_price * 1.1), # 10% above current price callbackRate="1.0", # 1% ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order # Clean up futuresClient.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) def test_futures_create_algo_order_with_stp_mode(futuresClient): """Test creating an algo order with selfTradePreventionMode""" ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") order = futuresClient.futures_create_algo_order( symbol=ticker["symbol"], side="SELL", positionSide=positions[0]["positionSide"], type="TAKE_PROFIT", algoType="CONDITIONAL", quantity=1, price=10000, triggerPrice=10000, timeInForce="GTC", selfTradePreventionMode="EXPIRE_MAKER", ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert order["selfTradePreventionMode"] == "EXPIRE_MAKER" # Clean up futuresClient.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) def test_futures_create_algo_order_with_price_match(futuresClient): """Test creating an algo order with priceMatch parameter""" ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") order = futuresClient.futures_create_algo_order( symbol=ticker["symbol"], side="SELL", positionSide=positions[0]["positionSide"], type="TAKE_PROFIT", algoType="CONDITIONAL", quantity=1, triggerPrice=10000, timeInForce="GTC", priceMatch="OPPONENT", ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert order["priceMatch"] == "OPPONENT" # Clean up futuresClient.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) def test_futures_create_algo_order_with_new_order_resp_type(futuresClient): """Test creating an algo order with newOrderRespType parameter""" ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") order = futuresClient.futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, newOrderRespType="RESULT", ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order # With RESULT response type, we should have more detailed information assert "algoStatus" in order # Clean up futuresClient.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) def test_futures_create_algo_order_with_working_type(futuresClient): """Test creating an algo order with workingType parameter""" ticker = futuresClient.futures_ticker(symbol="LTCUSDT") positions = futuresClient.futures_position_information(symbol="LTCUSDT") order = futuresClient.futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, workingType="MARK_PRICE", ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert order["workingType"] == "MARK_PRICE" # Clean up futuresClient.futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) ================================================ FILE: tests/test_client_gift_card.py ================================================ import pytest import requests_mock pytestmark = pytest.mark.gift_card def test_mock_gift_card_fetch_token_limit(liveClient): """Test gift card token limit endpoint with mocked response""" expected_response = { "code": "000000", "message": "success", "data": [{"coin": "BNB", "fromMin": "0.01", "fromMax": "1"}], "success": True, } with requests_mock.mock() as m: m.get( "https://api.binance.com/sapi/v1/giftcard/buyCode/token-limit", json=expected_response, ) response = liveClient.gift_card_fetch_token_limit(baseToken="BUSD") assert response == expected_response def test_gift_card_fetch_token_limit(liveClient): liveClient.gift_card_fetch_token_limit(baseToken="BUSD") def test_gift_card_fetch_rsa_public_key(liveClient): liveClient.gift_card_fetch_rsa_public_key() def test_gift_card_create_verify_and_redeem(liveClient): # create a gift card response = liveClient.gift_card_create(token="USDT", amount=1.0) assert response["data"]["referenceNo"] is not None assert response["data"]["code"] is not None # verify the gift card response = liveClient.gift_card_verify(referenceNo=response["data"]["referenceNo"]) assert response["data"]["valid"] == "SUCCESS" # redeem the gift card redeem_response = liveClient.gift_card_redeem( code=response["data"]["code"], ) assert response["data"]["referenceNo"] == redeem_response["data"]["referenceNo"] def test_gift_card_create_dual_token_and_redeem(liveClient): response = liveClient.gift_card_create_dual_token( baseToken="USDT", faceToken="BNB", baseTokenAmount=1.0 ) assert response["data"]["referenceNo"] is not None assert response["data"]["code"] is not None # verify the gift card response = liveClient.gift_card_verify(referenceNo=response["data"]["referenceNo"]) assert response["data"]["valid"] == "SUCCESS" # redeem the gift card redeem_response = liveClient.gift_card_redeem( code=response["data"]["code"], ) assert response["data"]["referenceNo"] == redeem_response["data"]["referenceNo"] ================================================ FILE: tests/test_client_margin.py ================================================ import pytest pytestmark = pytest.mark.margin def test_margin__get_account_status(client): client.get_account_status() def test_margin_get_account_api_trading_status(client): client.get_account_api_trading_status() def test_margin_get_account_api_permissions(client): client.get_account_api_permissions() def test_margin_get_dust_assets(client): client.get_dust_assets() def test_margin_get_dust_log(client): client.test_get_dust_log() def test_margin_transfer_dust(client): client.transfer_dust() def test_margin_get_asset_dividend_history(client): client.get_asset_dividend_history() def test_margin_make_universal_transfer(client): client.make_universal_transfer() def test_margin_query_universal_transfer_history(client): client.query_universal_transfer_history() def test_margin_get_trade_fee(client): client.get_trade_fee() def test_margin_get_asset_details(client): client.get_asset_details() def test_margin_get_spot_delist_schedule(client): client.get_spot_delist_schedule() # Withdraw Endpoints def test_margin_withdraw(client): client.withdraw() def test_margin_get_deposit_history(client): client.get_deposit_history() def test_margin_get_withdraw_history(client): client.get_withdraw_history() def test_margin_get_withdraw_history_id(client): client.get_withdraw_history_id() def test_margin_get_deposit_address(client): client.get_deposit_address() # Margin Trading Endpoints def test_margin_get_margin_account(client): client.get_margin_account() def test_margin_get_isolated_margin_account(client): client.get_isolated_margin_account() def test_margin_enable_isolated_margin_account(client): client.enable_isolated_margin_account() def test_margin_disable_isolated_margin_account(client): client.disable_isolated_margin_account() def test_margin_get_enabled_isolated_margin_account_limit(client): client.get_enabled_isolated_margin_account_limit() def test_margin_get_margin_dustlog(client): client.get_margin_dustlog() def test_margin_get_margin_dust_assets(client): client.get_margin_dust_assets() def test_margin_transfer_margin_dust(client): client.transfer_margin_dust() def test_margin_get_cross_margin_collateral_ratio(client): client.get_cross_margin_collateral_ratio() def test_margin_get_small_liability_exchange_assets(client): client.get_small_liability_exchange_assets() def test_margin_exchange_small_liability_assets(client): client.exchange_small_liability_assets() def test_margin_get_small_liability_exchange_history(client): client.get_small_liability_exchange_history() def test_margin_get_future_hourly_interest_rate(client): client.get_future_hourly_interest_rate() def test_margin_get_margin_capital_flow(client): client.get_margin_capital_flow() def test_margin_get_margin_asset(client): client.get_margin_asset() def test_margin_get_margin_symbol(client): client.get_margin_symbol() def test_margin_get_margin_all_assets(client): client.get_margin_all_assets() def test_margin_get_margin_all_pairs(client): client.get_margin_all_pairs() def test_margin_create_isolated_margin_account(client): client.create_isolated_margin_account() def test_margin_get_isolated_margin_symbol(client): client.get_isolated_margin_symbol() def test_margin_get_all_isolated_margin_symbols(client): client.get_all_isolated_margin_symbols() def test_margin_get_isolated_margin_fee_data(client): client.get_isolated_margin_fee_data() def test_margin_get_isolated_margin_tier_data(client): client.get_isolated_margin_tier_data() def test_margin_margin_manual_liquidation(client): client.margin_manual_liquidation() def test_margin_toggle_bnb_burn_spot_margin(client): client.toggle_bnb_burn_spot_margin() def test_margin_get_bnb_burn_spot_margin(client): client.get_bnb_burn_spot_margin() def test_margin_get_margin_price_index(client): client.get_margin_price_index() def test_margin_transfer_margin_to_spot(client): client.transfer_margin_to_spot() def test_margin_transfer_spot_to_margin(client): client.transfer_spot_to_margin() def test_margin_transfer_isolated_margin_to_spot(client): client.transfer_isolated_margin_to_spot() def test_margin_transfer_spot_to_isolated_margin(client): client.transfer_spot_to_isolated_margin() def test_margin_get_isolated_margin_tranfer_history(client): client.get_isolated_margin_tranfer_history() def test_margin_create_margin_loan(client): client.create_margin_loan() def test_margin_repay_margin_loan(client): client.repay_margin_loan() def create_margin_ordertest_(client): client.create_margin_order() def test_margin_cancel_margin_order(client): client.cancel_margin_order() def test_margin_set_margin_max_leverage(client): client.set_margin_max_leverage() def test_margin_get_margin_transfer_history(client): client.get_margin_transfer_history() def test_margin_get_margin_loan_details(client): client.get_margin_loan_details() def test_margin_get_margin_repay_details(client): client.get_margin_repay_details() def test_margin_get_cross_margin_data(client): client.get_cross_margin_data() def test_margin_get_margin_interest_history(client): client.get_margin_interest_history() def test_margin_get_margin_force_liquidation_rec(client): client.get_margin_force_liquidation_rec() def test_margin_get_margin_order(client): client.get_margin_order() def test_margin_get_open_margin_orders(client): client.get_open_margin_orders() def test_margin_get_all_margin_orders(client): client.get_all_margin_orders() def test_margin_get_margin_trades(client): client.get_margin_trades() def test_margin_get_max_margin_loan(client): client.get_max_margin_loan() def test_margin_get_max_margin_transfer(client): client.get_max_margin_transfer() def test_margin_get_margin_delist_schedule(client): client.get_margin_delist_schedule() # Margin OCO def test_margin_create_margin_oco_order(client): client.create_margin_oco_order() def test_margin_cancel_margin_oco_order(client): client.cancel_margin_oco_order() def test_margin_get_margin_oco_order(client): client.get_margin_oco_order() def test_margin_get_open_margin_oco_orders(client): client.get_open_margin_oco_orders() # Cross-margin def test_margin_margin_stream_get_listen_key(client): client.margin_stream_get_listen_key() def test_margin_margin_stream_close(client): client.margin_stream_close() # Isolated margin def test_margin_isolated_margin_stream_get_listen_key(client): client.isolated_margin_stream_get_listen_key() def test_margin_isolated_margin_stream_close(client): client.isolated_margin_stream_close() # Simple Earn Endpoints def test_margin_get_simple_earn_flexible_product_list(client): client.get_simple_earn_flexible_product_list() def test_margin_get_simple_earn_locked_product_list(client): client.get_simple_earn_locked_product_list() def test_margin_subscribe_simple_earn_flexible_product(client): client.subscribe_simple_earn_flexible_product() def test_margin_subscribe_simple_earn_locked_product(client): client.subscribe_simple_earn_locked_product() def test_margin_redeem_simple_earn_flexible_product(client): client.redeem_simple_earn_flexible_product() def test_margin_redeem_simple_earn_locked_product(client): client.redeem_simple_earn_locked_product() def test_margin_get_simple_earn_flexible_product_position(client): client.get_simple_earn_flexible_product_position() def test_margin_get_simple_earn_locked_product_position(client): client.get_simple_earn_locked_product_position() def test_margin_get_simple_earn_account(client): client.get_simple_earn_account() # Lending Endpoints def test_margin_get_fixed_activity_project_list(client): client.get_fixed_activity_project_list() def test_margin_change_fixed_activity_to_daily_position(client): client.change_fixed_activity_to_daily_position() # Staking Endpoints def test_margin_get_staking_product_list(client): client.get_staking_product_list() def test_margin_purchase_staking_product(client): client.purchase_staking_product() def test_margin_redeem_staking_product(client): client.redeem_staking_product() def test_margin_get_staking_position(client): client.get_staking_position() def test_margin_get_staking_purchase_history(client): client.get_staking_purchase_history() def test_margin_set_auto_staking(client): client.set_auto_staking() def test_margin_get_personal_left_quota(client): client.get_personal_left_quota() # US Staking Endpoints def test_margin_get_staking_asset_us(client): client.get_staking_asset_us() def test_margin_stake_asset_us(client): client.stake_asset_us() def test_margin_unstake_asset_us(client): client.unstake_asset_us() def test_margin_get_staking_balance_us(client): client.get_staking_balance_us() def test_margin_get_staking_history_us(client): client.get_staking_history_us() def test_margin_get_staking_rewards_history_us(client): client.get_staking_rewards_history_us() # Sub Accounts def test_margin_get_sub_account_list(client): client.get_sub_account_list() def test_margin_get_sub_account_transfer_history(client): client.get_sub_account_transfer_history() def test_margin_get_sub_account_futures_transfer_history(client): client.get_sub_account_futures_transfer_history() def test_margin_create_sub_account_futures_transfer(client): client.create_sub_account_futures_transfer() def test_margin_get_sub_account_assets(client): client.get_sub_account_assets() def test_margin_query_subaccount_spot_summary(client): client.query_subaccount_spot_summary() def test_margin_get_subaccount_deposit_address(client): client.get_subaccount_deposit_address() def test_margin_get_subaccount_deposit_history(client): client.get_subaccount_deposit_history() def test_margin_get_subaccount_futures_margin_status(client): client.get_subaccount_futures_margin_status() def test_margin_enable_subaccount_margin(client): client.enable_subaccount_margin() def test_margin_get_subaccount_margin_details(client): client.get_subaccount_margin_details() def test_margin_get_subaccount_margin_summary(client): client.get_subaccount_margin_summary() def test_margin_enable_subaccount_futures(client): client.enable_subaccount_futures() def test_margin_get_subaccount_futures_details(client): client.get_subaccount_futures_details() def test_margin_get_subaccount_futures_summary(client): client.get_subaccount_futures_summary() def test_margin_get_subaccount_futures_positionrisk(client): client.get_subaccount_futures_positionrisk() def test_margin_make_subaccount_futures_transfer(client): client.make_subaccount_futures_transfer() def test_margin_make_subaccount_margin_transfer(client): client.make_subaccount_margin_transfer() def test_margin_make_subaccount_to_subaccount_transfer(client): client.make_subaccount_to_subaccount_transfer() def test_margin_make_subaccount_to_master_transfer(client): client.make_subaccount_to_master_transfer() def test_margin_get_subaccount_transfer_history(client): client.get_subaccount_transfer_history() def test_margin_make_subaccount_universal_transfer(client): client.make_subaccount_universal_transfer() def test_margin_get_universal_transfer_history(client): client.get_universal_transfer_history() # Fiat Endpoints def test_margin_get_fiat_deposit_withdraw_history(client): client.get_fiat_deposit_withdraw_history() def test_margin_get_fiat_payments_history(client): client.get_fiat_payments_history() # C2C Endpoints def test_margin_get_c2c_trade_history(client): client.get_c2c_trade_history() # Pay Endpoints def test_margin_get_pay_trade_history(client): client.get_pay_trade_history() # Convert Endpoints def test_margin_get_convert_trade_history(client): client.get_convert_trade_history() def test_margin_convert_request_quote(client): client.convert_request_quote() def test_margin_convert_accept_quote(client): client.convert_accept_quote() def test_margin_new_transfer_history(futuresClient): futuresClient.new_transfer_history() def test_margin_funding_wallet(futuresClient): futuresClient.funding_wallet() def test_margin_get_user_asset(futuresClient): futuresClient.get_user_asset() def test_margin_universal_transfer(futuresClient): futuresClient.universal_transfer() def test_margin_get_all_coins_info(client): client.get_all_coins_info() def test_margin_get_account_snapshot(client): client.get_account_snapshot() def test_margin_disable_fast_withdraw_switch(client): client.disable_fast_withdraw_switch() def test_margin_enable_fast_withdraw_switch(client): client.enable_fast_withdraw_switch() @pytest.mark.skip(reason="can't test margin endpoints") def test_margin_next_hourly_interest_rate(client): client.margin_next_hourly_interest_rate( assets="BTC", isIsolated="FALSE" ) @pytest.mark.skip(reason="can't test margin endpoints") def test_margin_interest_history(client): client.margin_interest_history( asset="BTC", ) @pytest.mark.skip(reason="can't test margin endpoints") def test_margin_borrow_repay(client): client.margin_borrow_repay( asset="BTC", amount=0.1, isIsolated="FALSE", symbol="BTCUSDT", type="BORROW" ) @pytest.mark.skip(reason="can't test margin endpoints") def test_margin_get_borrow_repay_records(client): client.margin_get_borrow_repay_records( asset="BTC", isolatedSymbol="BTCUSDT", txId=2970933056, startTime=1563438204000, endTime=1563438204000, current=1, size=10 ) @pytest.mark.skip(reason="can't test margin endpoints") def test_margin_interest_rate_history(client): client.margin_interest_rate_history( asset="BTC", ) @pytest.mark.skip(reason="can't test margin endpoints") def test_margin_max_borrowable(client): client.margin_max_borrowable( asset="BTC", ) ================================================ FILE: tests/test_client_options.py ================================================ import pytest import sys pytestmark = [pytest.mark.options, pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+")] @pytest.fixture def options_symbol(liveClient): prices = liveClient.options_price() return prices[0]["symbol"] def test_options_ping(liveClient): liveClient.options_ping() def test_options_time(liveClient): liveClient.options_time() @pytest.mark.skip(reason="Not implemented") def test_options_info(liveClient): liveClient.options_info() def test_options_exchange_info(liveClient): liveClient.options_exchange_info() def test_options_index_price(liveClient): liveClient.options_index_price(underlying="BTCUSDT") def test_options_price(liveClient): liveClient.options_price() def test_options_mark_price(liveClient): liveClient.options_mark_price() def test_options_order_book(liveClient, options_symbol): liveClient.options_order_book(symbol=options_symbol) def test_options_klines(liveClient, options_symbol): liveClient.options_klines(symbol=options_symbol, interval="1m") def test_options_recent_trades(liveClient, options_symbol): liveClient.options_recent_trades(symbol=options_symbol) def test_options_historical_trades(liveClient, options_symbol): liveClient.options_historical_trades(symbol=options_symbol) # Account and trading interface endpoints @pytest.mark.skip(reason="No sandbox to environmnet to test") def test_options_account_info(liveClient): liveClient.options_account_info() @pytest.mark.skip(reason="No sandbox to environmnet to test") def test_options_funds_transfer(liveClient): liveClient.options_funds_transfer() @pytest.mark.skip(reason="No sandbox to environmnet to test") def test_options_positions(liveClient): liveClient.options_positions() @pytest.mark.skip(reason="No sandbox to environmnet to test") def test_options_bill(liveClient): liveClient.options_bill() @pytest.mark.skip(reason="No sandbox to environmnet to test") def test_options_place_order(liveClient): liveClient.options_place_order() @pytest.mark.skip(reason="No sandbox to environmnet to test") def test_test_options_place_batch_order(liveClient): liveClient.test_options_place_batch_order() @pytest.mark.skip(reason="No sandbox to environmnet to test") def test_options_cancel_order(liveClient): liveClient.options_cancel_order() @pytest.mark.skip(reason="No sandbox to environmnet to test") def test_options_cancel_batch_order(liveClient): liveClient.options_cancel_batch_order() @pytest.mark.skip(reason="No sandbox to environmnet to test") def test_options_cancel_all_orders(liveClient): liveClient.options_cancel_all_orders() @pytest.mark.skip(reason="No sandbox to environmnet to test") def test_options_query_order(liveClient): liveClient.options_query_order() @pytest.mark.skip(reason="No sandbox to environmnet to test") def test_options_query_pending_orders(liveClient): liveClient.options_query_pending_orders() @pytest.mark.skip(reason="No sandbox to environmnet to test") def test_options_query_order_history(liveClient): liveClient.options_query_order_history() @pytest.mark.skip(reason="No sandbox to environmnet to test") def test_options_user_trades(liveClient): liveClient.options_user_trades() ================================================ FILE: tests/test_client_portfolio.py ================================================ import pytest # Apply the 'portfolio' mark to all tests in this file pytestmark = pytest.mark.portfolio def test_papi_get_balance(client): client.papi_get_balance() def test_papi_get_account(client): client.papi_get_account() def test_papi_get_margin_max_borrowable(client): client.papi_get_margin_max_borrowable() def test_papi_get_margin_max_withdraw(client): client.papi_get_margin_max_withdraw() def test_papi_get_um_position_risk(client): client.papi_get_um_position_risk() def test_papi_get_cm_position_risk(client): client.papi_get_cm_position_risk() def test_papi_set_um_leverage(client): client.papi_set_um_leverage() def test_papi_set_cm_leverage(client): client.papi_set_cm_leverage() def test_papi_change_um_position_side_dual(client): client.papi_change_um_position_side_dual() def test_papi_get_um_position_side_dual(client): client.papi_get_um_position_side_dual() def test_papi_get_cm_position_side_dual(client): client.papi_get_cm_position_side_dual() def test_papi_get_um_leverage_bracket(client): client.papi_get_um_leverage_bracket() def test_papi_get_cm_leverage_bracket(client): client.papi_get_cm_leverage_bracket() def test_papi_get_um_api_trading_status(client): client.papi_get_um_api_trading_status() def test_papi_get_um_comission_rate(client): client.papi_get_um_comission_rate() def test_papi_get_cm_comission_rate(client): client.papi_get_cm_comission_rate() def test_papi_get_margin_margin_loan(client): client.papi_get_margin_margin_loan() def test_papi_get_margin_repay_loan(client): client.papi_get_margin_repay_loan() def test_papi_get_repay_futures_switch(client): client.papi_get_repay_futures_switch() def test_papi_repay_futures_switch(client): client.papi_repay_futures_switch() def test_papi_get_margin_interest_history(client): client.papi_get_margin_interest_history() def test_papi_repay_futures_negative_balance(client): client.papi_repay_futures_negative_balance() def test_papi_get_portfolio_interest_history(client): client.papi_get_portfolio_interest_history() def test_papi_fund_auto_collection(client): client.papi_fund_auto_collection() def test_papi_fund_asset_collection(client): client.papi_fund_asset_collection() def test_papi_bnb_transfer(client): client.papi_bnb_transfer() def test_papi_get_um_income_history(client): client.papi_get_um_income_history() def test_papi_get_cm_income_history(client): client.papi_get_cm_income_history() def test_papi_get_um_account(client): client.papi_get_um_account() def test_papi_get_um_account_v2(client): client.papi_get_um_account_v2() def test_papi_get_cm_account(client): client.papi_get_cm_account() def test_papi_get_um_account_config(client): client.papi_get_um_account_config() def test_papi_get_um_symbol_config(client): client.papi_get_um_symbol_config() def test_papi_get_um_trade_asyn(client): client.papi_get_um_trade_asyn() def test_papi_get_um_trade_asyn_id(client): client.papi_get_um_trade_asyn_id() def test_papi_get_um_order_asyn(client): client.papi_get_um_order_asyn() def test_papi_get_um_order_asyn_id(client): client.papi_get_um_order_asyn_id() def test_papi_get_um_income_asyn(client): client.papi_get_um_income_asyn() def test_papi_get_um_income_asyn_id(client): client.papi_get_um_income_asyn_id() # Public papi endpoints def test_papi_ping(client): client.papi_ping() # Trade papi endpoints def test_papi_create_um_order(client): client.papi_create_um_order() def test_papi_create_um_conditional_order(client): client.papi_create_um_conditional_order() def test_papi_create_cm_order(client): client.papi_create_cm_order() def test_papi_create_cm_conditional_order(client): client.papi_create_cm_conditional_order() def test_papi_create_margin_order(client): client.papi_create_margin_order() def test_papi_margin_loan(client): client.papi_margin_loan() def test_papi_repay_loan(client): client.papi_repay_loan() def test_papi_margin_order_oco(client): client.papi_margin_order_oco() def test_papi_cancel_um_order(client): client.papi_cancel_um_order() def test_papi_cancel_um_all_open_orders(client): client.papi_cancel_um_all_open_orders() def test_papi_cancel_um_conditional_order(client): client.papi_cancel_um_conditional_order() def test_papi_cancel_um_conditional_all_open_orders(client): client.papi_cancel_um_conditional_all_open_orders() def test_papi_cancel_cm_order(client): client.papi_cancel_cm_order() def test_papi_cancel_cm_all_open_orders(client): client.papi_cancel_cm_all_open_orders() def test_papi_cancel_cm_conditional_order(client): client.papi_cancel_cm_conditional_order() def test_papi_cancel_cm_conditional_all_open_orders(client): client.papi_cancel_cm_conditional_all_open_orders() def test_papi_cancel_margin_order(client): client.papi_cancel_margin_order() def test_papi_cancel_margin_order_list(client): client.papi_cancel_margin_order_list() def test_papi_cancel_margin_all_open_orders(client): client.papi_cancel_margin_all_open_orders() def test_papi_modify_um_order(client): client.papi_modify_um_order() def test_papi_modify_cm_order(client): client.papi_modify_cm_order() def test_papi_get_um_order(client): client.papi_get_um_order() def test_papi_get_um_all_orders(client): client.papi_get_um_all_orders() def test_papi_get_um_open_order(client): client.papi_get_um_open_order() def test_papi_get_um_open_orders(client): client.papi_get_um_open_orders() def test_papi_get_um_conditional_all_orders(client): client.papi_get_um_conditional_all_orders() def test_papi_get_um_conditional_open_orders(client): client.papi_get_um_conditional_open_orders() def test_papi_get_um_conditional_open_order(client): client.papi_get_um_conditional_open_order() def test_papi_get_um_conditional_order_history(client): client.papi_get_um_conditional_order_history() def test_papi_get_cm_order(client): client.papi_get_cm_order() def test_papi_get_cm_all_orders(client): client.papi_get_cm_all_orders() def test_papi_get_cm_open_order(client): client.papi_get_cm_open_order() def test_papi_get_cm_open_orders(client): client.papi_get_cm_open_orders() def test_papi_get_cm_conditional_all_orders(client): client.papi_get_cm_conditional_all_orders() def test_papi_get_cm_conditional_open_orders(client): client.papi_get_cm_conditional_open_orders() def test_papi_get_cm_conditional_open_order(client): client.papi_get_cm_conditional_open_order() def test_papi_get_cm_conditional_order_history(client): client.papi_get_cm_conditional_order_history() def test_papi_get_um_force_orders(client): client.papi_get_um_force_orders() def test_papi_get_cm_force_orders(client): client.papi_get_cm_force_orders() def test_papi_get_um_order_amendment(client): client.papi_get_um_order_amendment() def test_papi_get_cm_order_amendment(client): client.papi_get_cm_order_amendment() def test_papi_get_margin_force_orders(client): client.papi_get_margin_force_orders() def test_papi_get_um_user_trades(client): client.papi_get_um_user_trades() def test_papi_get_cm_user_trades(client): client.papi_get_cm_user_trades() def test_papi_get_um_adl_quantile(client): client.papi_get_um_adl_quantile() def test_papi_get_cm_adl_quantile(client): client.papi_get_cm_adl_quantile() def test_papi_set_um_fee_burn(client): client.papi_set_um_fee_burn() def test_papi_get_um_fee_burn(client): client.papi_get_um_fee_burn() def test_papi_get_margin_order(client): client.papi_get_margin_order() def test_papi_get_margin_open_orders(client): client.papi_get_margin_open_orders() def test_papi_get_margin_all_orders(client): client.papi_get_margin_all_orders() def test_papi_get_margin_order_list(client): client.papi_get_margin_order_list() def test_papi_get_margin_all_order_list(client): client.papi_get_margin_all_order_list() def test_papi_get_margin_open_order_list(client): client.papi_get_margin_open_order_list() def test_papi_get_margin_my_trades(client): client.papi_get_margin_my_trades() def test_papi_get_margin_repay_debt(client): client.papi_get_margin_repay_debt() def test_close_connection(client): client.close_connection() ================================================ FILE: tests/test_client_ws_api.py ================================================ import sys import pytest from binance.client import Client from .conftest import proxies, api_key, api_secret, testnet from .test_get_order_book import assert_ob pytestmark = [pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+")] def test_ws_get_order_book(client): orderbook = client.ws_get_order_book(symbol="BTCUSDT") assert_ob(orderbook) def test_ws_get_recent_trades(client): client.ws_get_recent_trades(symbol="BTCUSDT") def test_ws_get_historical_trades(client): client.ws_get_historical_trades(symbol="BTCUSDT") def test_ws_get_aggregate_trades(client): client.ws_get_aggregate_trades(symbol="BTCUSDT") def test_ws_get_klines(client): client.ws_get_klines(symbol="BTCUSDT", interval="1m") def test_ws_get_uiKlines(client): client.ws_get_uiKlines(symbol="BTCUSDT", interval="1m") def test_ws_get_avg_price(client): client.ws_get_avg_price(symbol="BTCUSDT") def test_ws_get_ticker(client): client.ws_get_ticker(symbol="BTCUSDT") def test_ws_get_trading_day_ticker(client): client.ws_get_trading_day_ticker(symbol="BTCUSDT") def test_ws_get_symbol_ticker_window(client): client.ws_get_symbol_ticker_window(symbol="BTCUSDT") def test_ws_get_symbol_ticker(client): client.ws_get_symbol_ticker(symbol="BTCUSDT") def test_ws_get_orderbook_ticker(client): client.ws_get_orderbook_ticker(symbol="BTCUSDT") def test_ws_ping(client): client.ws_ping() def test_ws_get_time(client): client.ws_get_time() def test_ws_get_exchange_info(client): client.ws_get_exchange_info(symbol="BTCUSDT") def test_ws_time_microseconds(): micro_client = Client( api_key, api_secret, {"proxies": proxies}, testnet=testnet, time_unit="MICROSECOND", ) micro_trades = micro_client.ws_get_recent_trades(symbol="BTCUSDT") assert len(str(micro_trades[0]["time"])) >= 16, ( "WS time should be in microseconds (16+ digits)" ) def test_ws_time_milliseconds(): milli_client = Client( api_key, api_secret, {"proxies": proxies}, testnet=testnet, time_unit="MILLISECOND", ) milli_trades = milli_client.ws_get_recent_trades(symbol="BTCUSDT") assert len(str(milli_trades[0]["time"])) == 13, ( "WS time should be in milliseconds (13 digits)" ) ================================================ FILE: tests/test_client_ws_futures_requests.py ================================================ import pytest import sys from binance.exceptions import BinanceAPIException from .test_get_order_book import assert_ob from .test_order import assert_contract_order @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_futures_get_order_book(futuresClient): orderbook = futuresClient.ws_futures_get_order_book(symbol="BTCUSDT") assert_ob(orderbook) def test_bad_request(futuresClient): with pytest.raises(BinanceAPIException): futuresClient.ws_futures_get_order_book() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_futures_get_all_tickers(futuresClient): futuresClient.ws_futures_get_all_tickers() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_futures_get_order_book_ticker(futuresClient): futuresClient.ws_futures_get_order_book_ticker() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_futures_create_get_edit_cancel_order(futuresClient): ticker = futuresClient.ws_futures_get_order_book_ticker(symbol="LTCUSDT") positions = futuresClient.ws_futures_v2_account_position(symbol="LTCUSDT") order = futuresClient.ws_futures_create_order( symbol=ticker["symbol"], side="SELL", positionSide=positions[0]["positionSide"], type="LIMIT", timeInForce="GTC", quantity=0.1, price=str(round(float(ticker["bidPrice"]) + 2)), ) assert_contract_order(futuresClient, order) order = futuresClient.ws_futures_edit_order( orderid=order["orderId"], symbol=order["symbol"], quantity=0.11, side=order["side"], price=order["price"], ) assert_contract_order(futuresClient, order) order = futuresClient.ws_futures_get_order( symbol="LTCUSDT", orderid=order["orderId"] ) assert_contract_order(futuresClient, order) order = futuresClient.ws_futures_cancel_order( orderid=order["orderId"], symbol=order["symbol"] ) @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_futures_v2_account_position(futuresClient): futuresClient.ws_futures_v2_account_position() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_futures_account_position(futuresClient): futuresClient.ws_futures_account_position() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_futures_v2_account_balance(futuresClient): futuresClient.ws_futures_v2_account_balance() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_futures_account_balance(futuresClient): futuresClient.ws_futures_account_balance() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_futures_v2_account_status(futuresClient): futuresClient.ws_futures_v2_account_status() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_futures_account_status(futuresClient): futuresClient.ws_futures_account_status() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_futures_create_cancel_algo_order(futuresClient): """Test creating and canceling an algo order via websocket""" ticker = futuresClient.ws_futures_get_order_book_ticker(symbol="LTCUSDT") positions = futuresClient.ws_futures_v2_account_position(symbol="LTCUSDT") # Create an algo order order = futuresClient.ws_futures_create_algo_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", algoType="CONDITIONAL", quantity=1, triggerPrice=1000, ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert order["algoType"] == "CONDITIONAL" # Cancel the algo order cancel_result = futuresClient.ws_futures_cancel_algo_order( symbol=ticker["symbol"], algoId=order["algoId"] ) assert cancel_result["algoId"] == order["algoId"] @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_futures_create_conditional_order_auto_routing(futuresClient): """Test that conditional order types are automatically routed to algo endpoint""" ticker = futuresClient.ws_futures_get_order_book_ticker(symbol="LTCUSDT") positions = futuresClient.ws_futures_v2_account_position(symbol="LTCUSDT") trigger_price = float(ticker["askPrice"]) * 1.5 order = futuresClient.ws_futures_create_order( symbol=ticker["symbol"], side="BUY", positionSide=positions[0]["positionSide"], type="STOP_MARKET", quantity=1, triggerPrice=trigger_price, ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert order["algoType"] == "CONDITIONAL" # Cancel using algoId parameter cancel_result = futuresClient.ws_futures_cancel_order( symbol=ticker["symbol"], algoId=order["algoId"] ) assert cancel_result["algoId"] == order["algoId"] @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") def test_ws_futures_conditional_order_with_stop_price(futuresClient): """Test that stopPrice is converted to triggerPrice for conditional orders""" ticker = futuresClient.ws_futures_get_order_book_ticker(symbol="LTCUSDT") positions = futuresClient.ws_futures_v2_account_position(symbol="LTCUSDT") # Create a TAKE_PROFIT_MARKET order with stopPrice (should be converted to triggerPrice) # Use a price above current market price for SELL TAKE_PROFIT trigger_price = float(ticker["askPrice"]) * 1.5 order = futuresClient.ws_futures_create_order( symbol=ticker["symbol"], side="SELL", positionSide=positions[0]["positionSide"], type="TAKE_PROFIT_MARKET", quantity=1, stopPrice=trigger_price, # This should be converted to triggerPrice ) assert order["symbol"] == ticker["symbol"] assert "algoId" in order assert order["algoType"] == "CONDITIONAL" # Cancel the order futuresClient.ws_futures_cancel_order( symbol=ticker["symbol"], algoId=order["algoId"] ) ================================================ FILE: tests/test_cryptography.py ================================================ from binance.client import Client test_cases = [ { "description": "Unencrypted PKCS8 ed22519 private key", "private_key": "-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEIPQmzwVKJETqVd7L9E/DFbkvrOigy1tLL+9QF0mSn6dV\n-----END PRIVATE KEY-----\n", "password": None, "expected_signature": "a4Pm3p02D2HXtNfo3DBaVCe9Ov7kledewgYtGjekotFmZ5wXa3mC5AtLB7CpAphyNjeyovIuDP+9fyjYmsojCw==", }, { "description": "Unencrypted PKCS8 ed22519 private key in bytes", "private_key": b"-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEIPQmzwVKJETqVd7L9E/DFbkvrOigy1tLL+9QF0mSn6dV\n-----END PRIVATE KEY-----\n", "password": None, "expected_signature": "a4Pm3p02D2HXtNfo3DBaVCe9Ov7kledewgYtGjekotFmZ5wXa3mC5AtLB7CpAphyNjeyovIuDP+9fyjYmsojCw==", }, { "description": "Encrypted PKCS8 RSA private key", "private_key": "-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQWW+iEMYYCPUntrPq\nZ2RCMAICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEIw3ViSuTp8JeN43\n5VGlHt0EggTQBvEzd2w2F561CzU+MDouZDOPj4RTIStC471z0/bxTgYqH3gYchoe\nOfi2lsLuD8B+ivIRuXB8GT66BIseIOMV8t/tiMe97rFI/cV4h6DrBO1xlmSrBG97\nvFF9qPA5yPRlrHtWKkGxhXteNVsT3w/7Y7KsulO/gA2KpsOElMElOhUP462Yd0Wl\nOxAIV3+knl2niozws2Kq3EdzTF3N6hlavUPryiU/w4RRsPN5qgjchVVLq/sYRYhx\nN8uWJbkjhCcHsULkD5KkdgddR0VOhpQPXIdY+gPkSBJq1ltRWy/TYdXiU2fEBNZW\nhFUVrxnS76+u2R3vukY2IAX8zTC6h2AbCBG+r4XXzgk/l/4peySKHsPQRzQ0in39\na9o5sctOmUNeD4uJ6cClXDdqyEwXhnPmRKZjJ8qeH4D9wl7HOG7iQsYiyfJe/igi\nFEXVRZOtLBdbwX45rU6wiWWjxzY+mDnw4BXE31ZBPwgtoh+CLTyK8NI8LnCV/CgO\nzOY4sm/KDWmbfTTZjLSdYRFj7wEpOdUWjZ13viDFZqnmy/o1auvLmBcqbRrCyW+B\nOMI7aHE0mZ/52vEFQYU1tH0BxMmRfWXUCJj0TjwxDY6BQmmW4YlhsrgGNekLFDo1\n6phFd0pA4UPqGXfNLzHp1dtLhUEb4YzcpDn+HMzMf1gfez7qeqU28nNFg/AwwqHZ\nTWdGclCFjiah7SfvOslob4vdLGwkUhgCBKQUQoU1DltX2GOgIv9SNY3q6X0NwdZG\nL5gqk225WVUwIRzmi5nfUEXlbaTvyHg3BuGedUKJ91IhRCW1ZjvU8GQcfVsu8bse\nTCKMdr7wi/zEZXSldCza6vL4m3tmBLtWkHVOW8bcDWvoVwRswbFHfleHzckl7EeC\n9C4TRa66gA5UOv14SrpC8noQUNpSegg+1KI4BSNvwaheiSUqjQbisb0qYCxML0ZP\nmQodwVsXG6LYo+Y6y6CpHbT7UYkfa59q/CGOZByL1bEzzgd98ZHwjihOjHVaV6sY\nBW018AvGxr7kjEU4LNqIteydTp0o31ZJN/qK78w5EQFfJxfImrx/E4nYKtg4higj\nKOQCgJALKIveidqQEFsbGWsulYrMXwnu0nPThofR1D8eCJZpdTxvOh2nIrNrAeY8\nZMAwG1uQos5A0yEZ1auHxz+rb4errnk92OnVlWnElf1TwwlkFFNLdNDl8VpiMP40\n6en9VtlOfgH8AwB03WsoeuEQsxYTIcRKWZZPRsLx3hd0BsOw0FcYDSX2XIGPkVVW\niYf9hzFSQsWV3d6utloIm4nG8XONfNaRimGECbUSZyHZimrO1m4Gga5pE3LKuDri\nJKR2lR7b6XPR7+FS+lG1zq5KY7onAVQY1oABfTjpJRju6pQGWt70hairo6EaVC3u\nrBy8UkLwBbfDuigSvsVk+sF2+Ic0IzX6IniU0F5kMe+MKqGB4aicXP6FFGBpPFTe\nv6yHD+DYAu1rnlXrqmFL50CfutTF78uPPJ9D2Sm0DcGPFj+6IrCigj48uxoHR9Qb\nFeNzfsmVwoFAWWq/MpkPbX6Aql8ddCbpMxDUUkybwVV9rJmEMTLil44FrxKAKFhP\n0Av7JeFvdz15pfnf/IQ3IOvVhHGFChFS13sbYSvFHMQF3P0BiyvjhBI=\n-----END ENCRYPTED PRIVATE KEY-----\n", "password": "testpwd", "expected_signature": "S4l9IONXGHIdt4NjwmpCIhawDTitjUQls73d+mi0HJTSbTGyn95NabX5hC9+n6HsTqLcWPvxKgTvLFMnTaf6Jxl+xwQMbu9/6mw88KF7i1pEQizerKcr91rPUPVBQ4OY10Q018QEamIAymRgo/eoRYSm7CqCdeibGyO0XfXZBaJnVGFJ9hgrPIwSKHgeUnfK8qMenULvL0qKMEJ6ziYPiqh7k9xX3xIV7lGIpokk+ekqlFd01f/Lov45osJCFuccJO4xuUUZewZnVGF7Uw6Rim3UsKhXKZUN9WZWa5RT+dpBIJ5DTBIXBSvowwj3GZC3j+XvWw8Sn0Ls9836l89BXw==", }, { "description": "Encrypted PKCS8 RSA private key in bytes", "private_key": b"-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQWW+iEMYYCPUntrPq\nZ2RCMAICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEIw3ViSuTp8JeN43\n5VGlHt0EggTQBvEzd2w2F561CzU+MDouZDOPj4RTIStC471z0/bxTgYqH3gYchoe\nOfi2lsLuD8B+ivIRuXB8GT66BIseIOMV8t/tiMe97rFI/cV4h6DrBO1xlmSrBG97\nvFF9qPA5yPRlrHtWKkGxhXteNVsT3w/7Y7KsulO/gA2KpsOElMElOhUP462Yd0Wl\nOxAIV3+knl2niozws2Kq3EdzTF3N6hlavUPryiU/w4RRsPN5qgjchVVLq/sYRYhx\nN8uWJbkjhCcHsULkD5KkdgddR0VOhpQPXIdY+gPkSBJq1ltRWy/TYdXiU2fEBNZW\nhFUVrxnS76+u2R3vukY2IAX8zTC6h2AbCBG+r4XXzgk/l/4peySKHsPQRzQ0in39\na9o5sctOmUNeD4uJ6cClXDdqyEwXhnPmRKZjJ8qeH4D9wl7HOG7iQsYiyfJe/igi\nFEXVRZOtLBdbwX45rU6wiWWjxzY+mDnw4BXE31ZBPwgtoh+CLTyK8NI8LnCV/CgO\nzOY4sm/KDWmbfTTZjLSdYRFj7wEpOdUWjZ13viDFZqnmy/o1auvLmBcqbRrCyW+B\nOMI7aHE0mZ/52vEFQYU1tH0BxMmRfWXUCJj0TjwxDY6BQmmW4YlhsrgGNekLFDo1\n6phFd0pA4UPqGXfNLzHp1dtLhUEb4YzcpDn+HMzMf1gfez7qeqU28nNFg/AwwqHZ\nTWdGclCFjiah7SfvOslob4vdLGwkUhgCBKQUQoU1DltX2GOgIv9SNY3q6X0NwdZG\nL5gqk225WVUwIRzmi5nfUEXlbaTvyHg3BuGedUKJ91IhRCW1ZjvU8GQcfVsu8bse\nTCKMdr7wi/zEZXSldCza6vL4m3tmBLtWkHVOW8bcDWvoVwRswbFHfleHzckl7EeC\n9C4TRa66gA5UOv14SrpC8noQUNpSegg+1KI4BSNvwaheiSUqjQbisb0qYCxML0ZP\nmQodwVsXG6LYo+Y6y6CpHbT7UYkfa59q/CGOZByL1bEzzgd98ZHwjihOjHVaV6sY\nBW018AvGxr7kjEU4LNqIteydTp0o31ZJN/qK78w5EQFfJxfImrx/E4nYKtg4higj\nKOQCgJALKIveidqQEFsbGWsulYrMXwnu0nPThofR1D8eCJZpdTxvOh2nIrNrAeY8\nZMAwG1uQos5A0yEZ1auHxz+rb4errnk92OnVlWnElf1TwwlkFFNLdNDl8VpiMP40\n6en9VtlOfgH8AwB03WsoeuEQsxYTIcRKWZZPRsLx3hd0BsOw0FcYDSX2XIGPkVVW\niYf9hzFSQsWV3d6utloIm4nG8XONfNaRimGECbUSZyHZimrO1m4Gga5pE3LKuDri\nJKR2lR7b6XPR7+FS+lG1zq5KY7onAVQY1oABfTjpJRju6pQGWt70hairo6EaVC3u\nrBy8UkLwBbfDuigSvsVk+sF2+Ic0IzX6IniU0F5kMe+MKqGB4aicXP6FFGBpPFTe\nv6yHD+DYAu1rnlXrqmFL50CfutTF78uPPJ9D2Sm0DcGPFj+6IrCigj48uxoHR9Qb\nFeNzfsmVwoFAWWq/MpkPbX6Aql8ddCbpMxDUUkybwVV9rJmEMTLil44FrxKAKFhP\n0Av7JeFvdz15pfnf/IQ3IOvVhHGFChFS13sbYSvFHMQF3P0BiyvjhBI=\n-----END ENCRYPTED PRIVATE KEY-----\n", "password": "testpwd", "expected_signature": "S4l9IONXGHIdt4NjwmpCIhawDTitjUQls73d+mi0HJTSbTGyn95NabX5hC9+n6HsTqLcWPvxKgTvLFMnTaf6Jxl+xwQMbu9/6mw88KF7i1pEQizerKcr91rPUPVBQ4OY10Q018QEamIAymRgo/eoRYSm7CqCdeibGyO0XfXZBaJnVGFJ9hgrPIwSKHgeUnfK8qMenULvL0qKMEJ6ziYPiqh7k9xX3xIV7lGIpokk+ekqlFd01f/Lov45osJCFuccJO4xuUUZewZnVGF7Uw6Rim3UsKhXKZUN9WZWa5RT+dpBIJ5DTBIXBSvowwj3GZC3j+XvWw8Sn0Ls9836l89BXw==", }, ] def test_encryption(): data = { "symbol": "BTCUSDT", "side": "BUY", "type": "LIMIT", "quantity": 1, "timestamp": 1631234567890, "price": 50000, } for case in test_cases: client = Client( api_key="api_key", api_secret="api_secret", private_key=case["private_key"], private_key_pass=case["password"], ping=False, ) signature = client._generate_signature(data, False) assert signature == case["expected_signature"], ( f"Test failed: {case['description']}" ) ================================================ FILE: tests/test_depth_cache.py ================================================ from binance.ws.depthcache import DepthCache from decimal import Decimal import pytest TEST_SYMBOL = "BNBBTC" @pytest.fixture def fresh_cache(): return DepthCache(TEST_SYMBOL, Decimal) def test_add_bids(fresh_cache): """Verify basic functionality for adding a bid to the cache""" high_bid = [0.111, 489] mid_bid = [0.018, 300] low_bid = [0.001, 100] for bid in [high_bid, low_bid, mid_bid]: fresh_cache.add_bid(bid) bids = fresh_cache.get_bids() assert len(bids) == 3 assert bids == sorted(bids, reverse=True) assert isinstance(bids[0][0], Decimal) assert isinstance(bids[0][1], Decimal) def test_add_asks(fresh_cache): """Verify basic functionality for adding an ask to the cache""" high_ask = [0.111, 489] mid_ask = [0.018, 300] low_ask = [0.001, 100] for ask in [high_ask, low_ask, mid_ask]: fresh_cache.add_ask(ask) asks = fresh_cache.get_asks() # Three asks should be in the cache assert len(asks) == 3 # Lowest ask price should be first (ascending order) assert asks == sorted(asks) assert isinstance(asks[0][0], Decimal) assert isinstance(asks[0][1], Decimal) ================================================ FILE: tests/test_futures.py ================================================ import requests_mock import json from binance.client import Client import re client = Client(api_key="api_key", api_secret="api_secret", ping=False) def test_futures_position_information(): with requests_mock.mock() as m: url_matcher = re.compile( r"https:\/\/fapi.binance.com\/fapi\/v3\/positionRisk\?.+" ) response = [ { "symbol": "LTCUSDT", "positionSide": "LONG", "positionAmt": "0.700", "entryPrice": "75.6", "breakEvenPrice": "75.63024", "markPrice": "73.18000000", "unRealizedProfit": "-1.69400000", "liquidationPrice": "0", "isolatedMargin": "0", "notional": "51.22600000", "marginAsset": "USDT", "isolatedWallet": "0", "initialMargin": "10.24520000", "maintMargin": "0.33296900", "positionInitialMargin": "10.24520000", "openOrderInitialMargin": "0", "adl": 0, "bidNotional": "0", "askNotional": "0", "updateTime": 1729436057076, } ] m.register_uri("GET", url_matcher, json=json.dumps(response), status_code=200) pos = client.futures_position_information(symbol="LTCUSDT") assert m.last_request.qs["symbol"][0] == "LTCUSDT".lower() assert m.last_request.path == "/fapi/v3/positionrisk" def test_futures_position_information_version_override(): with requests_mock.mock() as m: url_matcher = re.compile( r"https:\/\/fapi.binance.com\/fapi\/v2\/positionRisk\?.+" ) response = [ { "symbol": "LTCUSDT", "positionSide": "LONG", "positionAmt": "0.700", "entryPrice": "75.6", "breakEvenPrice": "75.63024", "markPrice": "73.18000000", "unRealizedProfit": "-1.69400000", "liquidationPrice": "0", "isolatedMargin": "0", "notional": "51.22600000", "marginAsset": "USDT", "isolatedWallet": "0", "initialMargin": "10.24520000", "maintMargin": "0.33296900", "positionInitialMargin": "10.24520000", "openOrderInitialMargin": "0", "adl": 0, "bidNotional": "0", "askNotional": "0", "updateTime": 1729436057076, } ] m.register_uri("GET", url_matcher, json=json.dumps(response), status_code=200) pos = client.futures_position_information(symbol="LTCUSDT", version=2) assert m.last_request.qs["symbol"][0] == "LTCUSDT".lower() assert m.last_request.path == "/fapi/v2/positionrisk" def test_futures_account_balance(): with requests_mock.mock() as m: url_matcher = re.compile(r"https:\/\/fapi.binance.com\/fapi\/v3\/balance\?.+") m.register_uri("GET", url_matcher, json={}, status_code=200) client.futures_account_balance() assert m.last_request.path == "/fapi/v3/balance" def test_futures_account_config(): with requests_mock.mock() as m: url_matcher = re.compile( r"https:\/\/fapi.binance.com\/fapi\/v1\/accountConfig\?.+" ) m.register_uri("GET", url_matcher, json={}, status_code=200) client.futures_account_config() assert m.last_request.path == "/fapi/v1/accountconfig" ================================================ FILE: tests/test_get_order_book.py ================================================ import pytest import sys from binance.exceptions import BinanceAPIException def assert_ob(order_book): assert isinstance(order_book, dict) assert "lastUpdateId" in order_book assert "bids" in order_book assert "asks" in order_book assert isinstance(order_book["bids"], list) assert isinstance(order_book["asks"], list) if order_book["bids"]: bid = order_book["bids"][0] assert len(bid) == 2 assert all(isinstance(item, str) for item in bid[:2]) if order_book["asks"]: ask = order_book["asks"][0] assert len(ask) == 2 assert all(isinstance(item, str) for item in ask[:2]) def test_get_order_book(client): try: order_book = client.get_order_book(symbol="BTCUSDT") assert_ob(order_book) except BinanceAPIException as e: pytest.fail(f"API request failed: {str(e)}") def test_futures_get_order_book(client): try: order_book = client.futures_order_book(symbol="BTCUSDT") assert_ob(order_book) except BinanceAPIException as e: pytest.fail(f"API request failed: {str(e)}") def test_get_order_book_with_limit(client): try: order_book = client.get_order_book(symbol="BTCUSDT", limit=5) assert_ob(order_book) assert len(order_book["bids"]) <= 5 assert len(order_book["asks"]) <= 5 except BinanceAPIException as e: pytest.fail(f"API request failed: {str(e)}") @pytest.mark.asyncio(scope="function") async def test_get_order_book_async(clientAsync): order_book = await clientAsync.get_order_book(symbol="BTCUSDT") assert_ob(order_book) @pytest.mark.asyncio(scope="function") async def test_futures_get_order_book_async(clientAsync): try: order_book = await clientAsync.futures_order_book(symbol="BTCUSDT") assert_ob(order_book) except BinanceAPIException as e: pytest.fail(f"API request failed: {str(e)}") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio() async def test_ws_get_order_book(clientAsync): order_book = await clientAsync.ws_get_order_book(symbol="BTCUSDT") assert_ob(order_book) ================================================ FILE: tests/test_headers.py ================================================ import requests_mock import pytest from aioresponses import aioresponses from binance import Client, AsyncClient client = Client(api_key="api_key", api_secret="api_secret", ping=False) def test_get_headers(): with requests_mock.mock() as m: m.get("https://api.binance.com/api/v3/account", json={}, status_code=200) client.get_account() headers = m.last_request._request.headers assert "Content-Type" in headers assert headers["Content-Type"] == "application/json" def test_post_headers(): with requests_mock.mock() as m: m.post("https://api.binance.com/api/v3/order", json={}, status_code=200) client.create_order(symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1) headers = m.last_request._request.headers assert "Content-Type" in headers assert headers["Content-Type"] == "application/x-www-form-urlencoded" def test_post_headers_overriden(): with requests_mock.mock() as m: m.post("https://api.binance.com/api/v3/order", json={}, status_code=200) client.create_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1, headers={"Content-Type": "myvalue"}, ) headers = m.last_request._request.headers assert "Content-Type" in headers assert headers["Content-Type"] == "myvalue" @pytest.mark.asyncio() async def test_post_headers_async(): clientAsync = AsyncClient( api_key="api_key", api_secret="api_secret" ) # reuse client later with aioresponses() as m: def handler(url, **kwargs): headers = kwargs["headers"] assert "Content-Type" in headers assert headers["Content-Type"] == "application/x-www-form-urlencoded" m.post( "https://api.binance.com/api/v3/order", payload={"id": 1}, status=200, callback=handler, ) await clientAsync.create_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 ) await clientAsync.close_connection() @pytest.mark.asyncio() async def test_post_headers_overriden_async(): clientAsync = AsyncClient( api_key="api_key", api_secret="api_secret" ) # reuse client later with aioresponses() as m: def handler(url, **kwargs): headers = kwargs["headers"] assert "Content-Type" in headers assert headers["Content-Type"] == "myvalue" m.post( "https://api.binance.com/api/v3/order", payload={"id": 1}, status=200, callback=handler, ) await clientAsync.create_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1, headers={"Content-Type": "myvalue"}, ) await clientAsync.close_connection() ================================================ FILE: tests/test_historical_klines.py ================================================ #!/usr/bin/env python # coding=utf-8 from binance.client import Client import pytest import requests_mock client = Client("api_key", "api_secret", ping=False) def test_exact_amount(): """Test Exact amount returned""" first_available_res = [ [ 1500004800000, "0.00005000", "0.00005300", "0.00001000", "0.00004790", "663152.00000000", 1500004859999, "30.55108144", 43, "559224.00000000", "25.65468144", "83431971.04346950", ] ] first_res = [] row = [ 1519892340000, "0.00099400", "0.00099810", "0.00099400", "0.00099810", "4806.04000000", 1519892399999, "4.78553253", 154, "1785.14000000", "1.77837524", "0", ] for i in range(0, 500): first_res.append(row) second_res = [] with requests_mock.mock() as m: m.get( "https://api.binance.com/api/v3/klines?interval=1m&limit=1&startTime=0&symbol=BNBBTC", json=first_available_res, ) m.get( "https://api.binance.com/api/v3/klines?interval=1m&limit=1000&startTime=1519862400000&symbol=BNBBTC", json=first_res, ) m.get( "https://api.binance.com/api/v3/klines?interval=1m&limit=1000&startTime=1519892400000&symbol=BNBBTC", json=second_res, ) klines = client.get_historical_klines( symbol="BNBBTC", interval=Client.KLINE_INTERVAL_1MINUTE, start_str="1st March 2018", ) assert len(klines) == 500 def test_start_and_end_str(): """Test start_str and end_str work correctly with string""" first_available_res = [ [ 1500004800000, "0.00005000", "0.00005300", "0.00001000", "0.00004790", "663152.00000000", 1500004859999, "30.55108144", 43, "559224.00000000", "25.65468144", "83431971.04346950", ] ] first_res = [] row = [ 1519892340000, "0.00099400", "0.00099810", "0.00099400", "0.00099810", "4806.04000000", 1519892399999, "4.78553253", 154, "1785.14000000", "1.77837524", "0", ] for i in range(0, 300): first_res.append(row) with requests_mock.mock() as m: m.get( "https://api.binance.com/api/v3/klines?interval=1m&limit=1&startTime=0&symbol=BNBBTC", json=first_available_res, ) m.get( "https://api.binance.com/api/v3/klines?interval=1m&limit=1000&startTime=1519862400000&endTime=1519880400000&symbol=BNBBTC", json=first_res, ) klines = client.get_historical_klines( symbol="BNBBTC", interval=Client.KLINE_INTERVAL_1MINUTE, start_str="1st March 2018", end_str="1st March 2018 05:00:00", ) assert len(klines) == 300 def test_start_and_end_timestamp(): """Test start_str and end_str work correctly with integer timestamp""" first_available_res = [ [ 1500004800000, "0.00005000", "0.00005300", "0.00001000", "0.00004790", "663152.00000000", 1500004859999, "30.55108144", 43, "559224.00000000", "25.65468144", "83431971.04346950", ] ] first_res = [] row = [ 1519892340000, "0.00099400", "0.00099810", "0.00099400", "0.00099810", "4806.04000000", 1519892399999, "4.78553253", 154, "1785.14000000", "1.77837524", "0", ] for i in range(0, 300): first_res.append(row) with requests_mock.mock() as m: m.get( "https://api.binance.com/api/v3/klines?interval=1m&limit=1&startTime=0&symbol=BNBBTC", json=first_available_res, ) m.get( "https://api.binance.com/api/v3/klines?interval=1m&limit=1000&startTime=1519862400000&endTime=1519880400000&symbol=BNBBTC", json=first_res, ) klines = client.get_historical_klines( symbol="BNBBTC", interval=Client.KLINE_INTERVAL_1MINUTE, start_str=1519862400000, end_str=1519880400000, ) assert len(klines) == 300 def test_historical_kline_generator(): """Test kline historical generator""" first_available_res = [ [ 1500004800000, "0.00005000", "0.00005300", "0.00001000", "0.00004790", "663152.00000000", 1500004859999, "30.55108144", 43, "559224.00000000", "25.65468144", "83431971.04346950", ] ] first_res = [] row = [ 1519892340000, "0.00099400", "0.00099810", "0.00099400", "0.00099810", "4806.04000000", 1519892399999, "4.78553253", 154, "1785.14000000", "1.77837524", "0", ] for i in range(0, 300): first_res.append(row) with requests_mock.mock() as m: m.get( "https://api.binance.com/api/v3/klines?interval=1m&limit=1&startTime=0&symbol=BNBBTC", json=first_available_res, ) m.get( "https://api.binance.com/api/v3/klines?interval=1m&limit=1000&startTime=1519862400000&endTime=1519880400000&symbol=BNBBTC", json=first_res, ) klines = client.get_historical_klines_generator( symbol="BNBBTC", interval=Client.KLINE_INTERVAL_1MINUTE, start_str=1519862400000, end_str=1519880400000, ) for i in range(300): assert len(next(klines)) > 0 with pytest.raises(StopIteration): next(klines) def test_historical_kline_generator_empty_response(): """Test kline historical generator if an empty list is returned from API""" first_available_res = [ [ 1500004800000, "0.00005000", "0.00005300", "0.00001000", "0.00004790", "663152.00000000", 1500004859999, "30.55108144", 43, "559224.00000000", "25.65468144", "83431971.04346950", ] ] first_res = [] with requests_mock.mock() as m: m.get( "https://api.binance.com/api/v3/klines?interval=1m&limit=1&startTime=0&symbol=BNBBTC", json=first_available_res, ) m.get( "https://api.binance.com/api/v3/klines?interval=1m&limit=1000&startTime=1519862400000&endTime=1519880400000&symbol=BNBBTC", json=first_res, ) klines = client.get_historical_klines_generator( symbol="BNBBTC", interval=Client.KLINE_INTERVAL_1MINUTE, start_str=1519862400000, end_str=1519880400000, ) with pytest.raises(StopIteration): next(klines) def test_start_and_limit(): """Test start_str and limit work correctly with integer timestamp""" first_available_res = [ [ 1500004800000, "0.00005000", "0.00005300", "0.00001000", "0.00004790", "663152.00000000", 1500004859999, "30.55108144", 43, "559224.00000000", "25.65468144", "83431971.04346950", ] ] first_res = [] row = [ 1519892340000, "0.00099400", "0.00099810", "0.00099400", "0.00099810", "4806.04000000", 1519892399999, "4.78553253", 154, "1785.14000000", "1.77837524", "0", ] for i in range(0, 5): first_res.append(row) with requests_mock.mock() as m: m.get( "https://api.binance.com/api/v3/klines?interval=1m&limit=1&startTime=0&symbol=BNBBTC", json=first_available_res, ) m.get( "https://api.binance.com/api/v3/klines?interval=1m&limit=5&startTime=1519892400000&symbol=BNBBTC", json=first_res, ) m.get( "https://api.binance.com/api/v3/klines?interval=1m&limit=5&startTime=1519862400000&symbol=BNBBTC", json=first_res, ) klines = client.get_historical_klines( symbol="BNBBTC", interval=Client.KLINE_INTERVAL_1MINUTE, start_str=1519862400000, limit=5, ) assert len(klines) == 5 ================================================ FILE: tests/test_ids.py ================================================ import re import requests_mock import pytest from aioresponses import aioresponses from binance import Client, AsyncClient client = Client(api_key="api_key", api_secret="api_secret", ping=False) def test_spot_id(): with requests_mock.mock() as m: m.post("https://api.binance.com/api/v3/order", json={}, status_code=200) client.create_order(symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1) url_dict = dict(pair.split("=") for pair in m.last_request.text.split("&")) assert url_dict["symbol"] == "LTCUSDT" assert url_dict["side"] == "BUY" assert url_dict["type"] == "MARKET" assert url_dict["quantity"] == "0.1" assert url_dict["newClientOrderId"].startswith("x-HNA2TXFJ") def test_spot_limit_id(): with requests_mock.mock() as m: m.post("https://api.binance.com/api/v3/order", json={}, status_code=200) client.order_limit_buy( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 ) url_dict = dict(pair.split("=") for pair in m.last_request.text.split("&")) assert url_dict["newClientOrderId"].startswith("x-HNA2TXFJ") def test_spot_market_id(): with requests_mock.mock() as m: m.post("https://api.binance.com/api/v3/order", json={}, status_code=200) client.order_market_buy( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 ) url_dict = dict(pair.split("=") for pair in m.last_request.text.split("&")) assert url_dict["newClientOrderId"].startswith("x-HNA2TXFJ") def test_spot_cancel_replace_id(): with requests_mock.mock() as m: m.post( "https://api.binance.com/api/v3/order/cancelReplace", json={}, status_code=200, ) client.cancel_replace_order( cancelOrderId="orderId", symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1, ) url_dict = dict(pair.split("=") for pair in m.last_request.text.split("&")) assert url_dict["newClientOrderId"].startswith("x-HNA2TXFJ") def test_spot_oco_order_id(): with requests_mock.mock() as m: m.post("https://api.binance.com/api/v3/orderList/oco", json={}, status_code=200) client.create_oco_order( symbol="LTCUSDT", side="BUY", aboveType="MARKET", quantity=0.1 ) url_dict = dict(pair.split("=") for pair in m.last_request.text.split("&")) assert url_dict["listClientOrderId"].startswith("x-HNA2TXFJ") def test_swap_id(): with requests_mock.mock() as m: m.post("https://fapi.binance.com/fapi/v1/order", json={}, status_code=200) client.futures_create_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 ) url_dict = dict(pair.split("=") for pair in m.last_request.text.split("&")) # why lowercase? check this later assert url_dict["symbol"] == "LTCUSDT" assert url_dict["side"] == "BUY" assert url_dict["type"] == "MARKET" assert url_dict["quantity"] == "0.1" assert url_dict["newClientOrderId"].startswith("x-Cb7ytekJ") def test_swap_batch_id(): with requests_mock.mock() as m: m.post("https://fapi.binance.com/fapi/v1/batchOrders", json={}, status_code=200) order = {"symbol": "LTCUSDT", "side": "BUY", "type": "MARKET", "quantity": 0.1} orders = [order, order] client.futures_place_batch_order(batchOrders=orders) text = m.last_request.text assert "x-Cb7ytekJ" in text def test_coin_id(): with requests_mock.mock() as m: m.post("https://dapi.binance.com/dapi/v1/order", json={}, status_code=200) client.futures_coin_create_order( symbol="LTCUSD_PERP", side="BUY", type="MARKET", quantity=0.1 ) url_dict = dict(pair.split("=") for pair in m.last_request.text.split("&")) # why lowercase? check this later assert url_dict["symbol"] == "LTCUSD_PERP" assert url_dict["side"] == "BUY" assert url_dict["type"] == "MARKET" assert url_dict["quantity"] == "0.1" assert url_dict["newClientOrderId"].startswith("x-Cb7ytekJ") def test_coin_batch_id(): with requests_mock.mock() as m: m.post("https://dapi.binance.com/dapi/v1/batchOrders", json={}, status_code=200) order = { "symbol": "BTCUSD_PERP", "side": "BUY", "type": "MARKET", "quantity": 0.1, } orders = [order, order] client.futures_coin_place_batch_order(batchOrders=orders) text = m.last_request.text assert "x-Cb7ytekJ" in text def test_papi_um_id(): with requests_mock.mock() as m: m.post("https://papi.binance.com/papi/v1/um/order", json={}, status_code=200) client.papi_create_um_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 ) url_dict = dict(pair.split("=") for pair in m.last_request.text.split("&")) # why lowercase? check this later assert url_dict["symbol"] == "LTCUSDT" assert url_dict["side"] == "BUY" assert url_dict["type"] == "MARKET" assert url_dict["quantity"] == "0.1" assert url_dict["newClientOrderId"].startswith("x-Cb7ytekJ") def test_papi_cm_id(): with requests_mock.mock() as m: m.post("https://papi.binance.com/papi/v1/cm/order", json={}, status_code=200) client.papi_create_cm_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 ) url_dict = dict(pair.split("=") for pair in m.last_request.text.split("&")) # why lowercase? check this later assert url_dict["symbol"] == "LTCUSDT" assert url_dict["side"] == "BUY" assert url_dict["type"] == "MARKET" assert url_dict["quantity"] == "0.1" assert url_dict["newClientOrderId"].startswith("x-Cb7ytekJ") @pytest.mark.asyncio() async def test_spot_id_async(): clientAsync = AsyncClient( api_key="api_key", api_secret="api_secret" ) # reuse client later with aioresponses() as m: def handler(url, **kwargs): client_order_id = kwargs["data"][0][1] assert client_order_id.startswith("x-HNA2TXFJ") m.post( "https://api.binance.com/api/v3/order", payload={"id": 1}, status=200, callback=handler, ) await clientAsync.create_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 ) await clientAsync.close_connection() @pytest.mark.asyncio() async def test_spot_cancel_replace_id_async(): clientAsync = AsyncClient( api_key="api_key", api_secret="api_secret" ) # reuse client later with aioresponses() as m: def handler(url, **kwargs): client_order_id = kwargs["data"][0][1] assert client_order_id.startswith("x-HNA2TXFJ") m.post( "https://api.binance.com/api/v3/order/cancelReplace", payload={"id": 1}, status=200, callback=handler, ) await clientAsync.cancel_replace_order( orderId="id", symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 ) await clientAsync.close_connection() @pytest.mark.asyncio() async def test_swap_id_async(): clientAsync = AsyncClient(api_key="api_key", api_secret="api_secret") with aioresponses() as m: def handler(url, **kwargs): assert "x-Cb7ytekJ" in kwargs["data"][0][1] url_pattern = re.compile(r"https://fapi\.binance\.com/fapi/v1/order") m.post( url_pattern, payload={"id": 1}, status=200, callback=handler, ) await clientAsync.futures_create_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 ) await clientAsync.close_connection() @pytest.mark.asyncio() async def test_swap_trigger_id_async(): clientAsync = AsyncClient(api_key="api_key", api_secret="api_secret") with aioresponses() as m: def handler(url, **kwargs): assert "x-Cb7ytekJ" in kwargs["data"][1][1] url_pattern = re.compile(r"https://fapi\.binance\.com/fapi/v1/algoOrder") m.post( url_pattern, payload={"id": 1}, status=200, callback=handler, ) await clientAsync.futures_create_order( symbol="LTCUSDT", side="BUY", type="STOP_MARKET", quantity=0.1 ) await clientAsync.close_connection() @pytest.mark.asyncio() async def test_swap_trigger_endpoint_id_async(): clientAsync = AsyncClient(api_key="api_key", api_secret="api_secret") with aioresponses() as m: def handler(url, **kwargs): # print(kwargs["data"]) assert "x-Cb7ytekJ" in kwargs["data"][1][1] url_pattern = re.compile(r"https://fapi\.binance\.com/fapi/v1/algoOrder") m.post( url_pattern, payload={"id": 1}, status=200, callback=handler, ) await clientAsync.futures_create_algo_order( symbol="LTCUSDT", side="BUY", type="STOP_MARKET", quantity=0.1 ) await clientAsync.close_connection() @pytest.mark.asyncio() async def test_papi_um_id_async(): clientAsync = AsyncClient(api_key="api_key", api_secret="api_secret") with aioresponses() as m: def handler(url, **kwargs): client_order_id = kwargs["data"][0][1] assert client_order_id.startswith("x-Cb7ytekJ") m.post( "https://papi.binance.com/papi/v1/um/order", payload={"id": 1}, status=200, callback=handler, ) await clientAsync.papi_create_um_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 ) await clientAsync.close_connection() @pytest.mark.asyncio() async def test_papi_cm_id_async(): clientAsync = AsyncClient(api_key="api_key", api_secret="api_secret") with aioresponses() as m: def handler(url, **kwargs): client_order_id = kwargs["data"][0][1] assert client_order_id.startswith("x-Cb7ytekJ") m.post( "https://papi.binance.com/papi/v1/cm/order", payload={"id": 1}, status=200, callback=handler, ) await clientAsync.papi_create_cm_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 ) await clientAsync.close_connection() @pytest.mark.asyncio() async def test_coin_id_async(): clientAsync = AsyncClient(api_key="api_key", api_secret="api_secret") with aioresponses() as m: def handler(url, **kwargs): client_order_id = kwargs["data"][0][1] assert client_order_id.startswith("x-Cb7ytekJ") m.post( "https://dapi.binance.com/dapi/v1/order", payload={"id": 1}, status=200, callback=handler, ) await clientAsync.futures_coin_create_order( symbol="LTCUSD_PERP", side="BUY", type="MARKET", quantity=0.1 ) await clientAsync.close_connection() @pytest.mark.asyncio() async def test_spot_oco_id(): clientAsync = AsyncClient(api_key="api_key", api_secret="api_secret") with aioresponses() as m: def handler(url, **kwargs): client_order_id = kwargs["data"][0][1] assert client_order_id.startswith("x-HNA2TXFJ") m.post( "https://api.binance.com/api/v3/orderList/oco", payload={"id": 1}, status=200, callback=handler, ) await clientAsync.create_oco_order( symbol="BTCUSDT", side="BUY", type="MARKET", quantity=0.1 ) await clientAsync.close_connection() @pytest.mark.asyncio() async def test_swap_batch_id_async(): with aioresponses() as m: clientAsync = AsyncClient(api_key="api_key", api_secret="api_secret") def handler(url, **kwargs): assert "x-Cb7ytekJ" in kwargs["data"] m.post( "https://fapi.binance.com/fapi/v1/batchOrders", payload={"id": 1}, status=200, callback=handler, ) order = {"symbol": "LTCUSDT", "side": "BUY", "type": "MARKET", "quantity": 0.1} orders = [order, order] await clientAsync.futures_place_batch_order(batchOrders=orders) await clientAsync.close_connection() @pytest.mark.asyncio() async def test_coin_batch_id_async(): with aioresponses() as m: clientAsync = AsyncClient(api_key="api_key", api_secret="api_secret") def handler(url, **kwargs): assert "x-Cb7ytekJ" in kwargs["data"][0][1] m.post( "https://dapi.binance.com/dapi/v1/batchOrders", payload={"id": 1}, status=200, callback=handler, ) order = { "symbol": "LTCUSD_PERP", "side": "BUY", "type": "MARKET", "quantity": 0.1, } orders = [order, order] await clientAsync.futures_coin_place_batch_order(batchOrders=orders) await clientAsync.close_connection() ================================================ FILE: tests/test_init.py ================================================ from binance import ( AsyncClient, Client, DepthCacheManager, OptionsDepthCacheManager, ThreadedDepthCacheManager, FuturesDepthCacheManager, BinanceSocketManager, ThreadedWebsocketManager, BinanceSocketType, KeepAliveWebsocket, ReconnectingWebsocket ) def test_version(): """Test that __version__ is defined""" from binance import __version__ assert isinstance(__version__, str) assert __version__ is not None def test_client_import(): """Test Client class import""" assert Client is not None assert isinstance(Client, type) def test_async_client_import(): """Test AsyncClient class import""" assert AsyncClient is not None assert isinstance(AsyncClient, type) def test_depth_cache_imports(): """Test depth cache related imports""" assert DepthCacheManager is not None assert OptionsDepthCacheManager is not None assert ThreadedDepthCacheManager is not None assert FuturesDepthCacheManager is not None assert isinstance(DepthCacheManager, type) assert isinstance(OptionsDepthCacheManager, type) assert isinstance(ThreadedDepthCacheManager, type) assert isinstance(FuturesDepthCacheManager, type) def test_websocket_imports(): """Test websocket related imports""" assert BinanceSocketManager is not None assert ThreadedWebsocketManager is not None assert BinanceSocketType is not None assert isinstance(BinanceSocketManager, type) assert isinstance(ThreadedWebsocketManager, type) def test_websocket_utility_imports(): """Test websocket utility imports""" assert KeepAliveWebsocket is not None assert ReconnectingWebsocket is not None assert isinstance(KeepAliveWebsocket, type) assert isinstance(ReconnectingWebsocket, type) ================================================ FILE: tests/test_keepalive_reconnect.py ================================================ """ Test to verify that KeepAliveWebsocket doesn't create duplicate keepalive loops on reconnection. This test reproduces the issue where reconnection events create duplicate keepalive loops that continue running indefinitely, leading to resource exhaustion and redundant API calls. """ import sys import asyncio import pytest from unittest.mock import AsyncMock, MagicMock from binance.async_client import AsyncClient from binance.ws.keepalive_websocket import KeepAliveWebsocket @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_no_duplicate_keepalive_loops_on_reconnect(): """ Test that reconnection doesn't create duplicate keepalive loops. The bug occurs when: 1. A keepalive loop is running (timer -> keepalive_socket -> timer -> ...) 2. Reconnection happens via _after_connect() 3. A new keepalive loop is started unconditionally 4. The old loop continues running in the background 5. Each reconnection adds another orphaned loop """ # Create a mock client mock_client = MagicMock(spec=AsyncClient) mock_client.futures_stream_get_listen_key = AsyncMock( return_value="test_listen_key" ) mock_client.futures_stream_keepalive = AsyncMock() # Create the websocket instance ws = KeepAliveWebsocket( client=mock_client, url="wss://fstream.binance.com/", keepalive_type="futures", prefix="ws/", user_timeout=0.1, # Short timeout for faster test ) # Track how many times _keepalive_socket is called keepalive_call_count = 0 original_keepalive = ws._keepalive_socket async def tracked_keepalive(): nonlocal keepalive_call_count keepalive_call_count += 1 # Call the original method but skip the actual API call # Just track that it was called return ws._keepalive_socket = tracked_keepalive # Simulate the first connection await ws._before_connect() await ws._after_connect() # Wait for the first timer to trigger await asyncio.sleep(0.15) first_call_count = keepalive_call_count assert first_call_count >= 1, "Keepalive should have been called at least once" # Simulate a reconnection (this is where the bug occurs) # In a real scenario, _after_connect() is called again by the reconnection logic await ws._after_connect() # Wait for more timer triggers await asyncio.sleep(0.15) second_call_count = keepalive_call_count # Calculate how many calls happened after reconnection calls_after_reconnect = second_call_count - first_call_count # With the bug: multiple loops are running, so we'd see 2+ calls per timer period # Without the bug: only one loop is running, so we'd see ~1 call per timer period # Allow some margin (up to 2 calls) due to timing assert calls_after_reconnect <= 2, ( f"Too many keepalive calls after reconnection: {calls_after_reconnect}. " f"This indicates duplicate keepalive loops are running. " f"Total calls: {second_call_count}, calls before reconnect: {first_call_count}" ) # Clean up if ws._timer: ws._timer.cancel() ws._timer = None @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_keepalive_stops_after_exit(): """ Test that keepalive loop stops properly when the websocket exits. The fix should ensure that when __aexit__ sets _timer to None, the finally block in _keepalive_socket doesn't restart the timer. """ # Create a mock client mock_client = MagicMock(spec=AsyncClient) mock_client.futures_stream_get_listen_key = AsyncMock( return_value="test_listen_key" ) mock_client.futures_stream_keepalive = AsyncMock() # Create the websocket instance ws = KeepAliveWebsocket( client=mock_client, url="wss://fstream.binance.com/", keepalive_type="futures", prefix="ws/", user_timeout=0.1, # Short timeout for faster test ) # Track keepalive calls keepalive_call_count = 0 async def tracked_keepalive(): nonlocal keepalive_call_count keepalive_call_count += 1 return ws._keepalive_socket = tracked_keepalive # Start the keepalive await ws._before_connect() await ws._after_connect() # Wait for at least one keepalive call await asyncio.sleep(0.15) calls_before_exit = keepalive_call_count assert calls_before_exit >= 1, "Keepalive should have been called before exit" # Simulate exit by setting timer to None (this is what __aexit__ does) if ws._timer: ws._timer.cancel() ws._timer = None # Wait to see if more keepalive calls happen (they shouldn't) await asyncio.sleep(0.15) calls_after_exit = keepalive_call_count # After setting _timer to None, no more calls should happen assert calls_after_exit == calls_before_exit, ( f"Keepalive should not continue after exit. " f"Calls before exit: {calls_before_exit}, calls after exit: {calls_after_exit}" ) @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_multiple_reconnects_no_loop_accumulation(): """ Test that multiple reconnections don't accumulate keepalive loops. This is a stress test to ensure the fix works even with many reconnections. """ # Create a mock client mock_client = MagicMock(spec=AsyncClient) mock_client.futures_stream_get_listen_key = AsyncMock( return_value="test_listen_key" ) mock_client.futures_stream_keepalive = AsyncMock() # Create the websocket instance ws = KeepAliveWebsocket( client=mock_client, url="wss://fstream.binance.com/", keepalive_type="futures", prefix="ws/", user_timeout=0.1, # Short timeout for faster test ) # Track keepalive calls keepalive_call_count = 0 async def tracked_keepalive(): nonlocal keepalive_call_count keepalive_call_count += 1 return ws._keepalive_socket = tracked_keepalive # Initial connection await ws._before_connect() await ws._after_connect() # Wait for initial calls await asyncio.sleep(0.15) # Simulate 5 reconnections for i in range(5): await ws._after_connect() # Reset counter keepalive_call_count = 0 # Wait for a timer period await asyncio.sleep(0.15) # Should only have ~1 call per timer period, not 6 (one per each connection + reconnections) # Allow margin of 2 due to timing assert keepalive_call_count <= 2, ( f"Too many keepalive calls after 5 reconnections: {keepalive_call_count}. " f"This indicates keepalive loops are accumulating." ) # Clean up if ws._timer: ws._timer.cancel() ws._timer = None ================================================ FILE: tests/test_order.py ================================================ def assert_contract_order(client, order): assert isinstance(order, dict) assert order["clientOrderId"].startswith(client.CONTRACT_ORDER_PREFIX) assert order["symbol"] ================================================ FILE: tests/test_ping.py ================================================ import os import pytest proxies = {} proxy = os.getenv("PROXY") def test_papi_ping_sync(client): ping_response = client.papi_ping() assert ping_response is not None def test_ping_sync(client): ping_response = client.ping() assert ping_response is not None def test_futures_ping(client): ping_response = client.futures_ping() assert ping_response is not None def test_coin_ping(client): ping_response = client.futures_coin_ping() assert ping_response is not None @pytest.mark.asyncio() async def test_papi_ping_async(clientAsync): ping_response = await clientAsync.papi_ping() assert ping_response is not None @pytest.mark.asyncio() async def test_ping_async(clientAsync): ping_response = await clientAsync.ping() assert ping_response is not None @pytest.mark.asyncio() async def test_futures_ping_async(clientAsync): ping_response = await clientAsync.futures_ping() assert ping_response is not None @pytest.mark.asyncio() async def test_coin_ping_async(clientAsync): ping_response = await clientAsync.futures_coin_ping() assert ping_response is not None ================================================ FILE: tests/test_reconnecting_websocket.py ================================================ import sys import pytest import gzip import json from unittest.mock import patch, create_autospec, Mock from binance.ws.reconnecting_websocket import ReconnectingWebsocket from binance.ws.constants import WSListenerState from binance.exceptions import BinanceWebsocketUnableToConnect, ReadLoopClosed from websockets import WebSocketClientProtocol # type: ignore from websockets.protocol import State import asyncio try: from unittest.mock import AsyncMock # Python 3.8+ except ImportError: from asynctest import CoroutineMock as AsyncMock # Python 3.7 @pytest.mark.asyncio async def test_init(): ws = ReconnectingWebsocket(url="wss://test.url", path="/test") assert ws._url == "wss://test.url" assert ws._path == "/test" assert ws.ws_state == WSListenerState.INITIALISING @pytest.mark.asyncio async def test_json_dumps(): ws = ReconnectingWebsocket(url="wss://test.url") data = {"key": "value"} dumped = ws.json_dumps(data) assert isinstance(dumped, (str, bytes)) @pytest.mark.asyncio async def test_json_loads(): ws = ReconnectingWebsocket(url="wss://test.url") data_str = '{"key": "value"}' loaded = ws.json_loads(data_str) assert loaded == {"key": "value"} @pytest.mark.asyncio async def test_json_loads_invalid(): ws = ReconnectingWebsocket(url="wss://test.url") data_str = "invalid json" with pytest.raises(json.JSONDecodeError): ws.json_loads(data_str) @pytest.mark.asyncio async def test_handle_message(): ws = ReconnectingWebsocket(url="wss://test.url") message = '{"key": "value"}' result = ws._handle_message(message) assert result == {"key": "value"} @pytest.mark.asyncio async def test_handle_message_binary(): ws = ReconnectingWebsocket(url="wss://test.url", is_binary=True) data = b'{"key": "value"}' compressed = gzip.compress(data) result = ws._handle_message(compressed) assert result == {"key": "value"} @pytest.mark.asyncio async def test_handle_message_invalid_json(): ws = ReconnectingWebsocket(url="wss://test.url") message = "invalid json" with pytest.raises(Exception): ws._handle_message(message) @pytest.mark.asyncio async def test_recv_message(): ws = ReconnectingWebsocket(url="wss://test.url") await ws._queue.put({"test": "data"}) # Simulate the read loop being active ws._handle_read_loop = Mock() result = await ws.recv() assert result == {"test": "data"} @pytest.mark.skipif(sys.version_info < (3, 8), reason="Requires Python 3.8+") @pytest.mark.asyncio async def test_before_reconnect(): ws = ReconnectingWebsocket(url="wss://test.url") ws.ws = AsyncMock() ws._conn = AsyncMock() ws._reconnects = 0 await ws.before_reconnect() assert ws.ws is None ws._conn.__aexit__.assert_awaited() assert ws._reconnects == 1 def test_get_reconnect_wait(): ws = ReconnectingWebsocket(url="wss://test.url") wait_time = ws._get_reconnect_wait(2) assert 1 <= wait_time <= ws.MAX_RECONNECT_SECONDS @pytest.mark.skipif(sys.version_info < (3, 8), reason="Requires Python 3.8+") @pytest.mark.asyncio async def test_connect_max_reconnects_exceeded(): """Test ws.connect exceeds maximum reconnect attempts.""" ws = ReconnectingWebsocket(url="wss://test.url") ws.MAX_RECONNECTS = 2 # type: ignore # Set max reconnects to a low number for testing ws._before_connect = AsyncMock() ws._after_connect = AsyncMock() ws._conn = AsyncMock() exception = Exception("Connection failed") ws._conn.__aenter__.side_effect = exception with patch.object(ws._log, "error") as mock_log: with pytest.raises(BinanceWebsocketUnableToConnect): for _ in range(3): # Exceed MAX_RECONNECTS await ws._run_reconnect() mock_log.assert_called_with(f"Max reconnections {ws.MAX_RECONNECTS} reached:") assert ws._reconnects == ws.MAX_RECONNECTS @pytest.mark.skipif(sys.version_info < (3, 8), reason="Requires Python 3.8+") @pytest.mark.asyncio async def test_recieve_invalid_json(): # Create mock WebSocket client mock_socket = create_autospec(WebSocketClientProtocol) mock_socket.recv = AsyncMock(return_value="invalid json{") mock_socket.state = AsyncMock() # Mock websockets.connect to return our mock socket with patch("websockets.connect") as mock_connect: mock_connect.return_value.__aenter__.return_value = mock_socket ws = ReconnectingWebsocket(url="wss://test.url") async with ws: msg = await ws.recv() assert msg["e"] == "error" assert msg["type"] == "JSONDecodeError" # JSON parsing error @pytest.mark.skipif(sys.version_info < (3, 8), reason="Requires Python 3.8+") @pytest.mark.asyncio async def test_receive_valid_json(): # Create mock WebSocket client msgRecv = '{"e": "value"}' mock_socket = create_autospec(WebSocketClientProtocol) mock_socket.recv = AsyncMock(return_value=msgRecv) mock_socket.state = AsyncMock() # Mock websockets.connect to return our mock socket with patch("websockets.connect") as mock_connect: mock_connect.return_value.__aenter__.return_value = mock_socket ws = ReconnectingWebsocket(url="wss://test.url") async with ws: msg = await ws.recv() assert msg == json.loads(msgRecv) @pytest.mark.skipif(sys.version_info < (3, 8), reason="Requires Python 3.8+") @pytest.mark.asyncio async def test_connect_fails_to_connect_on_enter_context(): """Test ws.connect raises a ConnectionClosedError.""" ws = ReconnectingWebsocket(url="wss://test.url") ws._conn = AsyncMock() exception = Exception("Connection closed") ws._conn.__aenter__.side_effect = exception with pytest.raises(Exception): await ws.__aenter__() @pytest.mark.skipif(sys.version_info < (3, 8), reason="Requires Python 3.8+") @pytest.mark.asyncio async def test_connect_fails_to_connect_after_disconnect(): # Create mock WebSocket client mock_socket = create_autospec(WebSocketClientProtocol) mock_socket.recv = AsyncMock(side_effect=delayed_return) mock_socket.state = AsyncMock() # Create mock connect that succeeds first, then fails mock_connect = AsyncMock() mock_connect.return_value.__aenter__.side_effect = [ mock_socket, # First call succeeds Exception("Connection failed"), # Subsequent calls fail ] with patch("websockets.connect", return_value=mock_connect.return_value): ws = ReconnectingWebsocket(url="wss://test.url") async with ws as ws: assert ws.ws is not None msg = await ws.recv() ws.ws.state = State.CLOSED await ws.ws.close() while msg["e"] != "error": msg = await ws.recv() # Receive the closed message attempting to reconnect while msg["type"] == "BinanceWebsocketClosed": msg = await ws.recv() # After retrying to reconnect, receive BinanceWebsocketUnableToConnect assert msg["e"] == "error" assert msg["type"] == "BinanceWebsocketUnableToConnect" async def delayed_return(): await asyncio.sleep(0.1) # 100 ms delay return '{"e": "value"}' @pytest.mark.skipif(sys.version_info < (3, 8), reason="Requires Python 3.8+") @pytest.mark.asyncio async def test_recv_read_loop_closed(): """Test that recv() raises ReadLoopClosed when read loop is closed.""" ws = ReconnectingWebsocket(url="wss://test.url") # Simulate read loop being closed by setting _handle_read_loop to None ws._handle_read_loop = None with pytest.raises(ReadLoopClosed) as exc_info: await ws.recv() assert "Read loop has been closed" in str(exc_info.value) assert "please reset the websocket connection" in str(exc_info.value) ================================================ FILE: tests/test_region_exception.py ================================================ """Tests for BinanceRegionException and region validation.""" import pytest from binance.client import Client from binance.async_client import AsyncClient from binance.exceptions import BinanceRegionException class TestBinanceRegionException: """Tests for the BinanceRegionException class itself.""" def test_exception_attributes(self): """Test that exception has correct attributes.""" exc = BinanceRegionException("us", "com", "test_endpoint") assert exc.required_tld == "us" assert exc.actual_tld == "com" assert exc.endpoint_name == "test_endpoint" def test_exception_message_format(self): """Test that exception message is properly formatted.""" exc = BinanceRegionException("us", "com", "get_staking_asset_us") assert "binance.us" in str(exc) assert "binance.com" in str(exc) assert "get_staking_asset_us" in str(exc) def test_exception_default_endpoint_name(self): """Test that endpoint_name defaults to 'endpoint'.""" exc = BinanceRegionException("us", "com") assert exc.endpoint_name == "endpoint" assert "endpoint is only available" in str(exc) class TestSyncClientRegionValidation: """Tests for region validation in synchronous Client.""" def test_get_staking_asset_us_wrong_tld(self): """Test that get_staking_asset_us raises exception for non-US client.""" client = Client("test_key", "test_secret", tld="com", ping=False) with pytest.raises(BinanceRegionException) as exc_info: client.get_staking_asset_us() assert exc_info.value.required_tld == "us" assert exc_info.value.actual_tld == "com" assert exc_info.value.endpoint_name == "get_staking_asset_us" def test_stake_asset_us_wrong_tld(self): """Test that stake_asset_us raises exception for non-US client.""" client = Client("test_key", "test_secret", tld="com", ping=False) with pytest.raises(BinanceRegionException) as exc_info: client.stake_asset_us() assert exc_info.value.required_tld == "us" assert exc_info.value.endpoint_name == "stake_asset_us" def test_unstake_asset_us_wrong_tld(self): """Test that unstake_asset_us raises exception for non-US client.""" client = Client("test_key", "test_secret", tld="com", ping=False) with pytest.raises(BinanceRegionException) as exc_info: client.unstake_asset_us() assert exc_info.value.required_tld == "us" assert exc_info.value.endpoint_name == "unstake_asset_us" def test_get_staking_balance_us_wrong_tld(self): """Test that get_staking_balance_us raises exception for non-US client.""" client = Client("test_key", "test_secret", tld="com", ping=False) with pytest.raises(BinanceRegionException) as exc_info: client.get_staking_balance_us() assert exc_info.value.required_tld == "us" assert exc_info.value.endpoint_name == "get_staking_balance_us" def test_get_staking_history_us_wrong_tld(self): """Test that get_staking_history_us raises exception for non-US client.""" client = Client("test_key", "test_secret", tld="com", ping=False) with pytest.raises(BinanceRegionException) as exc_info: client.get_staking_history_us() assert exc_info.value.required_tld == "us" assert exc_info.value.endpoint_name == "get_staking_history_us" def test_get_staking_rewards_history_us_wrong_tld(self): """Test that get_staking_rewards_history_us raises exception for non-US client.""" client = Client("test_key", "test_secret", tld="com", ping=False) with pytest.raises(BinanceRegionException) as exc_info: client.get_staking_rewards_history_us() assert exc_info.value.required_tld == "us" assert exc_info.value.endpoint_name == "get_staking_rewards_history_us" @pytest.mark.asyncio class TestAsyncClientRegionValidation: """Tests for region validation in asynchronous AsyncClient.""" async def test_get_staking_asset_us_wrong_tld_async(self): """Test that async get_staking_asset_us raises exception for non-US client.""" client = AsyncClient("test_key", "test_secret", tld="com") try: with pytest.raises(BinanceRegionException) as exc_info: await client.get_staking_asset_us() assert exc_info.value.required_tld == "us" assert exc_info.value.actual_tld == "com" assert exc_info.value.endpoint_name == "get_staking_asset_us" finally: await client.close_connection() async def test_stake_asset_us_wrong_tld_async(self): """Test that async stake_asset_us raises exception for non-US client.""" client = AsyncClient("test_key", "test_secret", tld="com") try: with pytest.raises(BinanceRegionException) as exc_info: await client.stake_asset_us() assert exc_info.value.required_tld == "us" assert exc_info.value.endpoint_name == "stake_asset_us" finally: await client.close_connection() async def test_unstake_asset_us_wrong_tld_async(self): """Test that async unstake_asset_us raises exception for non-US client.""" client = AsyncClient("test_key", "test_secret", tld="com") try: with pytest.raises(BinanceRegionException) as exc_info: await client.unstake_asset_us() assert exc_info.value.required_tld == "us" assert exc_info.value.endpoint_name == "unstake_asset_us" finally: await client.close_connection() async def test_get_staking_balance_us_wrong_tld_async(self): """Test that async get_staking_balance_us raises exception for non-US client.""" client = AsyncClient("test_key", "test_secret", tld="com") try: with pytest.raises(BinanceRegionException) as exc_info: await client.get_staking_balance_us() assert exc_info.value.required_tld == "us" assert exc_info.value.endpoint_name == "get_staking_balance_us" finally: await client.close_connection() async def test_get_staking_history_us_wrong_tld_async(self): """Test that async get_staking_history_us raises exception for non-US client.""" client = AsyncClient("test_key", "test_secret", tld="com") try: with pytest.raises(BinanceRegionException) as exc_info: await client.get_staking_history_us() assert exc_info.value.required_tld == "us" assert exc_info.value.endpoint_name == "get_staking_history_us" finally: await client.close_connection() async def test_get_staking_rewards_history_us_wrong_tld_async(self): """Test that async get_staking_rewards_history_us raises exception for non-US client.""" client = AsyncClient("test_key", "test_secret", tld="com") try: with pytest.raises(BinanceRegionException) as exc_info: await client.get_staking_rewards_history_us() assert exc_info.value.required_tld == "us" assert exc_info.value.endpoint_name == "get_staking_rewards_history_us" finally: await client.close_connection() ================================================ FILE: tests/test_socket_manager.py ================================================ from binance import BinanceSocketManager, AsyncClient import pytest from .conftest import proxy def assert_message(msg): assert msg["stream"] == "!ticker@arr" assert len(msg["data"]) > 0 @pytest.mark.asyncio() async def test_ticker_socket(): client = await AsyncClient.create(testnet=True, https_proxy=proxy) bm = BinanceSocketManager(client) ts = bm.futures_ticker_socket() async with ts as tscm: try: res = await tscm.recv() assert_message(res) except Exception as e: print(f"An error occurred: {e}") await client.close_connection() ================================================ FILE: tests/test_streams.py ================================================ import sys from binance import BinanceSocketManager import pytest from binance.async_client import AsyncClient from .conftest import proxy, api_key, api_secret, testnet @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_socket_stopped_on_aexit(clientAsync): bm = BinanceSocketManager(clientAsync) ts1 = bm.trade_socket("BNBBTC") async with ts1: pass assert bm._conns == {}, "socket should be removed from _conn on exit" ts2 = bm.trade_socket("BNBBTC") assert ts2 is not ts1, "socket should be removed from _conn on exit" await clientAsync.close_connection() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_socket_stopped_on_aexit_futures(futuresClientAsync): bm = BinanceSocketManager(futuresClientAsync) ts1 = bm.futures_user_socket() async with ts1: pass assert bm._conns == {}, "socket should be removed from _conn on exit" await futuresClientAsync.close_connection() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_socket_spot_market_time_unit_microseconds(): clientAsync = AsyncClient( api_key, api_secret, https_proxy=proxy, testnet=testnet, time_unit="MICROSECOND" ) bm = BinanceSocketManager(clientAsync) ts1 = bm.symbol_ticker_socket("BTCUSDT") async with ts1: trade = await ts1.recv() assert len(str(trade["E"])) >= 16, "Time should be in microseconds (16+ digits)" await clientAsync.close_connection() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_socket_spot_market_time_unit_milliseconds(): clientAsync = AsyncClient( api_key, api_secret, https_proxy=proxy, testnet=testnet, time_unit="MILLISECOND" ) bm = BinanceSocketManager(clientAsync) ts1 = bm.symbol_ticker_socket("BTCUSDT") async with ts1: trade = await ts1.recv() assert len(str(trade["E"])) == 13, "Time should be in milliseconds (13 digits)" await clientAsync.close_connection() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_socket_spot_user_data_time_unit_microseconds(): clientAsync = AsyncClient( api_key, api_secret, https_proxy=proxy, testnet=testnet, time_unit="MICROSECOND" ) bm = BinanceSocketManager(clientAsync) ts1 = bm.user_socket() async with ts1: await clientAsync.create_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 ) trade = await ts1.recv() assert len(str(trade["E"])) >= 16, "Time should be in microseconds (16+ digits)" await clientAsync.close_connection() @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_socket_spot_user_data_time_unit_milliseconds(): clientAsync = AsyncClient( api_key, api_secret, https_proxy=proxy, testnet=testnet, time_unit="MILLISECOND" ) bm = BinanceSocketManager(clientAsync) ts1 = bm.user_socket() async with ts1: await clientAsync.create_order( symbol="LTCUSDT", side="BUY", type="MARKET", quantity=0.1 ) trade = await ts1.recv() assert len(str(trade["E"])) == 13, "Time should be in milliseconds (13 digits)" await clientAsync.close_connection() ================================================ FILE: tests/test_streams_options.py ================================================ import sys import pytest import logging from binance import BinanceSocketManager pytestmark = [ pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+"), pytest.mark.asyncio ] # Configure logger for this module logger = logging.getLogger(__name__) # Test constants OPTION_SYMBOL = "BTC-251226-60000-P" UNDERLYING_SYMBOL = "BTC" EXPIRATION_DATE = "251226" INTERVAL = "1m" DEPTH = "20" async def test_options_ticker(clientAsync): """Test options ticker socket""" logger.info(f"Starting options ticker test for symbol: {OPTION_SYMBOL}") bm = BinanceSocketManager(clientAsync) socket = bm.options_ticker_socket(OPTION_SYMBOL) async with socket as ts: logger.debug("Waiting for ticker message...") msg = await ts.recv() logger.info(f"Received ticker message: {msg}") assert msg['e'] == '24hrTicker' logger.info("Options ticker test completed successfully") await clientAsync.close_connection() async def test_options_ticker_by_expiration(clientAsync): """Test options ticker by expiration socket""" logger.info(f"Starting options ticker by expiration test for {UNDERLYING_SYMBOL}, expiration: {EXPIRATION_DATE}") bm = BinanceSocketManager(clientAsync) socket = bm.options_ticker_by_expiration_socket(UNDERLYING_SYMBOL, EXPIRATION_DATE) async with socket as ts: logger.debug("Waiting for ticker by expiration message...") msg = await ts.recv() logger.info(f"Received {len(msg)} ticker messages") assert len(msg) > 0 logger.info("Options ticker by expiration test completed successfully") await clientAsync.close_connection() async def test_options_recent_trades(clientAsync): """Test options recent trades socket""" logger.info(f"Starting options recent trades test for {UNDERLYING_SYMBOL}") bm = BinanceSocketManager(clientAsync) socket = bm.options_recent_trades_socket(UNDERLYING_SYMBOL) async with socket as ts: logger.debug("Waiting for trade message...") msg = await ts.recv() logger.info(f"Received trade message: {msg}") assert msg['e'] == 'trade' logger.info("Options recent trades test completed successfully") await clientAsync.close_connection() async def test_options_kline(clientAsync): """Test options kline socket""" logger.info(f"Starting options kline test for {OPTION_SYMBOL}, interval: {INTERVAL}") bm = BinanceSocketManager(clientAsync) socket = bm.options_kline_socket(OPTION_SYMBOL, INTERVAL) async with socket as ts: logger.debug("Waiting for kline message...") msg = await ts.recv() logger.info(f"Received kline message: {msg}") assert msg['e'] == 'kline' logger.info("Options kline test completed successfully") await clientAsync.close_connection() async def test_options_depth(clientAsync): """Test options depth socket""" logger.info(f"Starting options depth test for {OPTION_SYMBOL}, depth: {DEPTH}") bm = BinanceSocketManager(clientAsync) socket = bm.options_depth_socket(OPTION_SYMBOL, DEPTH) async with socket as ts: logger.debug("Waiting for depth message...") msg = await ts.recv() logger.info(f"Received depth message: {msg}") assert msg['e'] == 'depth' logger.info("Options depth test completed successfully") await clientAsync.close_connection() async def test_options_multiplex(clientAsync): """Test options multiplex socket""" streams = [ f"{OPTION_SYMBOL}@ticker", f"{OPTION_SYMBOL}@trade", ] logger.info(f"Starting options multiplex test with streams: {streams}") bm = BinanceSocketManager(clientAsync) socket = bm.options_multiplex_socket(streams) async with socket as ts: logger.debug("Waiting for multiplex message...") msg = await ts.recv() logger.info(f"Received multiplex message: {msg}") assert 'stream' in msg logger.info("Options multiplex test completed successfully") await clientAsync.close_connection() async def test_options_open_interest(clientAsync): """Test options open interest socket""" logger.info(f"Starting options open interest test for {UNDERLYING_SYMBOL}, expiration: {EXPIRATION_DATE}") bm = BinanceSocketManager(clientAsync) socket = bm.options_open_interest_socket(UNDERLYING_SYMBOL, EXPIRATION_DATE) async with socket as ts: logger.debug("Waiting for open interest message...") msg = await ts.recv() logger.info(f"Received open interest message with {len(msg)} items") assert len(msg) > 0 logger.info("Options open interest test completed successfully") await clientAsync.close_connection() async def test_options_mark_price(clientAsync): """Test options mark price socket""" logger.info(f"Starting options mark price test for {UNDERLYING_SYMBOL}") bm = BinanceSocketManager(clientAsync) socket = bm.options_mark_price_socket(UNDERLYING_SYMBOL) async with socket as ts: logger.debug("Waiting for mark price message...") msg = await ts.recv() logger.info(f"Received mark price message with {len(msg)} items") assert len(msg) > 0 logger.info("Options mark price test completed successfully") await clientAsync.close_connection() async def test_options_index_price(clientAsync): """Test options index price socket""" symbol = 'ETHUSDT' logger.info(f"Starting options index price test for {symbol}") bm = BinanceSocketManager(clientAsync) socket = bm.options_index_price_socket(symbol) async with socket as ts: logger.debug("Waiting for index price message...") msg = await ts.recv() logger.info(f"Received index price message: {msg}") assert msg['e'] == 'index' logger.info("Options index price test completed successfully") await clientAsync.close_connection() ================================================ FILE: tests/test_threaded_socket_manager.py ================================================ from binance import ThreadedWebsocketManager from binance.client import Client import asyncio import time from .conftest import proxies, api_key, api_secret, proxy import pytest import sys import logging pytestmark = pytest.mark.skipif( sys.version_info <= (3, 8), reason="These tests require Python 3.8+ for proper websocket proxy support" ) received_ohlcv = False received_depth = False twm: ThreadedWebsocketManager # Add logger definition before using it logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) # Get real symbols from Binance API client = Client(api_key, api_secret, {"proxies": proxies}) exchange_info = client.get_exchange_info() symbols = [info['symbol'].lower() for info in exchange_info['symbols']] streams = [f"{symbol}@bookTicker" for symbol in symbols][0:100] # Take first 800 symbols def test_threaded_socket_manager(): logger.debug("Starting test_threaded_socket_manager") global twm twm = ThreadedWebsocketManager(api_key, api_secret, https_proxy=proxy, testnet=True) symbol = "BTCUSDT" def handle_socket_message(msg): global received_ohlcv, received_depth if "e" in msg: if msg["e"] == "depthUpdate": logger.debug("Received depth update message") received_depth = True if msg["e"] == "kline": logger.debug("Received kline message") received_ohlcv = True if received_depth and received_ohlcv: logger.debug("Received both depth and OHLCV messages, stopping") twm.stop() try: logger.debug("Starting ThreadedWebsocketManager") twm.start() logger.debug("Starting kline socket for %s", symbol) twm.start_kline_socket(callback=handle_socket_message, symbol=symbol) logger.debug("Starting depth socket for %s", symbol) twm.start_depth_socket(callback=handle_socket_message, symbol=symbol) twm.join() finally: logger.debug("Cleaning up test_threaded_socket_manager") twm.stop() time.sleep(2) def test_many_symbols_small_queue(): logger.debug("Starting test_many_symbols_small_queue with queue size 1") twm = ThreadedWebsocketManager(api_key, api_secret, https_proxy=proxy, testnet=True, max_queue_size=1) error_received = False msg_received = False def handle_message(msg): nonlocal error_received, msg_received if msg.get("e") == "error": error_received = True logger.debug("Received WebSocket error: %s", msg.get('m', 'Unknown error')) return msg_received = True logger.debug("Received valid message") try: logger.debug("Starting ThreadedWebsocketManager") twm.start() logger.debug("Starting multiplex socket with %d streams", len(streams)) twm.start_multiplex_socket(callback=handle_message, streams=streams) logger.debug("Waiting 10 seconds for messages") time.sleep(10) assert msg_received, "Should have received messages" finally: logger.debug("Cleaning up test_many_symbols_small_queue") twm.stop() time.sleep(2) def test_many_symbols_adequate_queue(): logger.debug("Starting test_many_symbols_adequate_queue with queue size 200") twm = ThreadedWebsocketManager(api_key, api_secret, https_proxy=proxy, testnet=True, max_queue_size=200) messages_received = 0 error_received = False def handle_message(msg): nonlocal messages_received, error_received if msg.get("e") == "error": error_received = True logger.debug("Received WebSocket error: %s", msg.get('m', 'Unknown error')) return messages_received += 1 if messages_received % 10 == 0: # Log every 10th message logger.debug("Processed %d messages", messages_received) try: logger.debug("Starting ThreadedWebsocketManager") twm.start() logger.debug("Starting futures multiplex socket with %d streams", len(streams)) twm.start_futures_multiplex_socket(callback=handle_message, streams=streams) logger.debug("Waiting 10 seconds for messages") time.sleep(10) logger.debug("Test completed. Messages received: %d, Errors: %s", messages_received, error_received) assert messages_received > 0, "Should have received some messages" assert not error_received, "Should not have received any errors" finally: logger.debug("Cleaning up test_many_symbols_adequate_queue") twm.stop() time.sleep(2) def test_slow_async_callback_no_error(): logger.debug("Starting test_slow_async_callback_no_error with queue size 400") twm = ThreadedWebsocketManager(api_key, api_secret, https_proxy=proxy, testnet=True, max_queue_size=400) messages_processed = 0 error_received = False async def slow_async_callback(msg): nonlocal messages_processed, error_received if msg.get("e") == "error": error_received = True logger.debug("Received WebSocket error: %s", msg.get('m', 'Unknown error')) return logger.debug("Processing message with 2 second delay") await asyncio.sleep(2) messages_processed += 1 logger.debug("Message processed. Total processed: %d", messages_processed) try: logger.debug("Starting ThreadedWebsocketManager") twm.start() logger.debug("Starting futures multiplex socket with %d streams", len(streams)) twm.start_futures_multiplex_socket(callback=slow_async_callback, streams=streams) logger.debug("Waiting 10 seconds for messages") time.sleep(10) logger.debug("Test completed. Messages processed: %d, Errors: %s", messages_processed, error_received) assert messages_processed > 0, "Should have processed some messages" assert not error_received, "Should not have received any errors" finally: logger.debug("Cleaning up test_slow_async_callback_no_error") twm.stop() time.sleep(2) def test_no_internet_connection(): """Test that socket manager times out when there's no internet connection""" logger.debug("Starting test_no_internet_connection") invalid_proxy = "http://invalid.proxy:1234" logger.debug("Using invalid proxy: %s", invalid_proxy) with pytest.raises(RuntimeError, match="Binance Socket Manager failed to initialize after 5 seconds"): twm = ThreadedWebsocketManager( api_key, api_secret, https_proxy=invalid_proxy, testnet=True ) try: logger.debug("Attempting to start ThreadedWebsocketManager with invalid proxy") twm.start() logger.debug("Attempting to start kline socket (should fail)") twm.start_kline_socket( callback=lambda x: print(x), symbol="BTCUSDT" ) finally: logger.debug("Cleaning up test_no_internet_connection") twm.stop() time.sleep(2) ================================================ FILE: tests/test_threaded_stream.py ================================================ import pytest import asyncio import websockets from binance.ws.threaded_stream import ThreadedApiManager from unittest.mock import Mock # For Python 3.7 compatibility try: from unittest.mock import AsyncMock except ImportError: # Create our own AsyncMock for Python 3.7 class AsyncMock(Mock): async def __call__(self, *args, **kwargs): return super(AsyncMock, self).__call__(*args, **kwargs) async def __aenter__(self): return self async def __aexit__(self, *args): return None async def __aiter__(self): return self async def __anext__(self): raise StopAsyncIteration @pytest.mark.asyncio async def test_initialization(): """Test that manager initializes with correct parameters""" manager = ThreadedApiManager( api_key="test_key", api_secret="test_secret", tld="com", testnet=True, requests_params={"timeout": 10}, session_params={"trust_env": True}, ) assert manager._running is True assert manager._socket_running == {} assert manager._client_params == { "api_key": "test_key", "api_secret": "test_secret", "requests_params": {"timeout": 10}, "tld": "com", "testnet": True, "session_params": {"trust_env": True}, "https_proxy": None, "verbose": False, } @pytest.mark.asyncio async def test_start_and_stop_socket(manager): """Test starting and stopping a socket""" socket_name = "test_socket" # AsyncMock socket creation mock_socket = AsyncMock() mock_socket.__aenter__ = AsyncMock(return_value=mock_socket) mock_socket.__aexit__ = AsyncMock(return_value=None) # Track number of recv calls recv_count = 0 async def controlled_recv(): nonlocal recv_count recv_count += 1 # If we've stopped the socket or read enough times, simulate connection closing if not manager._socket_running.get(socket_name) or recv_count > 2: raise websockets.exceptions.ConnectionClosed(None, None) await asyncio.sleep(0.1) return '{"e": "value"}' mock_socket.recv = controlled_recv # AsyncMock callback callback = AsyncMock() # Start socket listener manager._socket_running[socket_name] = True listener_task = asyncio.create_task( manager.start_listener(mock_socket, socket_name, callback) ) # Give some time for the listener to start and receive a message await asyncio.sleep(0.2) # Stop the socket manager.stop_socket(socket_name) # Wait for the listener task to complete try: await asyncio.wait_for(listener_task, timeout=1.0) except (asyncio.TimeoutError, websockets.exceptions.ConnectionClosed): pass # These exceptions are expected during shutdown assert socket_name not in manager._socket_running @pytest.mark.asyncio async def test_socket_listener_timeout(manager): """Test socket listener handling timeout""" socket_name = "test_socket" # AsyncMock socket that times out every time mock_socket = AsyncMock() mock_socket.__aenter__ = AsyncMock(return_value=mock_socket) mock_socket.__aexit__ = AsyncMock(return_value=None) async def controlled_recv(): await asyncio.sleep(0.1) raise asyncio.TimeoutError("Simulated Timeout") mock_socket.recv = controlled_recv callback = AsyncMock() # Start socket listener manager._socket_running[socket_name] = True listener_task = asyncio.create_task( manager.start_listener(mock_socket, socket_name, callback) ) # Give some time for a few timeout cycles await asyncio.sleep(0.3) # Stop the socket manager.stop_socket(socket_name) # Wait for the listener to finish try: await asyncio.wait_for(listener_task, timeout=1.0) except (asyncio.TimeoutError, websockets.exceptions.ConnectionClosed): listener_task.cancel() # Callback should not have been called (no successful messages) callback.assert_not_called() assert socket_name not in manager._socket_running @pytest.mark.asyncio async def test_stop_client(manager): """Test stopping the client""" # AsyncMock AsyncClient mock_client = AsyncMock() mock_client.close_connection = AsyncMock() manager._client = mock_client await manager.stop_client() mock_client.close_connection.assert_called_once() @pytest.mark.asyncio async def test_stop(manager): """Test stopping the manager""" socket_name = "test_socket" manager._socket_running[socket_name] = True manager.stop() assert manager._running is False assert manager._socket_running[socket_name] is False @pytest.mark.asyncio async def test_multiple_sockets(manager): """Test managing multiple sockets""" socket_names = ["socket1", "socket2", "socket3"] # Start multiple sockets for name in socket_names: manager._socket_running[name] = True # Stop all sockets manager.stop() # Verify all sockets are stopped for name in socket_names: assert manager._socket_running[name] is False @pytest.mark.asyncio async def test_stop_client_when_not_initialized(manager): """Test stopping client when it hasn't been initialized""" manager._client = None await manager.stop_client() # Should not raise any exception @pytest.mark.asyncio async def test_stop_when_already_stopped(manager): """Test stopping manager when it's already stopped""" manager._running = False manager.stop() # Should not raise any exception or change state assert manager._running is False ================================================ FILE: tests/test_user_socket_integration.py ================================================ """ Integration tests for user socket with ws_api subscription routing. These tests verify that the user socket correctly: 1. Uses ws_api for subscription (not creating its own connection) 2. Has its own queue for receiving events (not sharing ws_api's queue) 3. Does not start its own read loop (ws_api handles reading) 4. Properly cleans up subscriptions on exit Requirements: - Binance testnet API credentials (configured in conftest.py) - Network connectivity to testnet Run with: pytest tests/test_user_socket_integration.py -v """ import asyncio import pytest import pytest_asyncio from binance import BinanceSocketManager @pytest_asyncio.fixture async def socket_manager(clientAsync): """Create a BinanceSocketManager using the clientAsync fixture from conftest.""" return BinanceSocketManager(clientAsync) class TestUserSocketArchitecture: """Tests verifying the user socket architecture is correct.""" @pytest.mark.asyncio async def test_user_socket_has_separate_queue(self, clientAsync, socket_manager): """User socket should have its own queue, not share ws_api's queue.""" user_socket = socket_manager.user_socket() async with user_socket: # Queues should be different objects assert user_socket._queue is not clientAsync.ws_api._queue, \ "user_socket should have its own queue, not share ws_api's queue" @pytest.mark.asyncio async def test_user_socket_uses_ws_api_subscription(self, clientAsync, socket_manager): """User socket should use ws_api subscription mechanism.""" user_socket = socket_manager.user_socket() async with user_socket: # Should be marked as using ws_api subscription assert user_socket._uses_ws_api_subscription is True, \ "user_socket should be marked as using ws_api subscription" # Should have a subscription ID assert user_socket._subscription_id is not None, \ "user_socket should have a subscription ID" @pytest.mark.asyncio async def test_user_socket_no_read_loop(self, clientAsync, socket_manager): """User socket should NOT have its own read loop (ws_api handles reading).""" user_socket = socket_manager.user_socket() async with user_socket: # user_socket should not have started its own read loop assert user_socket._handle_read_loop is None, \ "user_socket should not have its own read loop" # ws_api should have a read loop assert clientAsync.ws_api._handle_read_loop is not None, \ "ws_api should have a read loop" @pytest.mark.asyncio async def test_user_socket_queue_registered_with_ws_api(self, clientAsync, socket_manager): """User socket's queue should be registered with ws_api for event routing.""" user_socket = socket_manager.user_socket() async with user_socket: sub_id = user_socket._subscription_id # Subscription should be registered in ws_api assert sub_id in clientAsync.ws_api._subscription_queues, \ "Subscription should be registered with ws_api" # Registered queue should be user_socket's queue registered_queue = clientAsync.ws_api._subscription_queues[sub_id] assert registered_queue is user_socket._queue, \ "Registered queue should be user_socket's queue" @pytest.mark.asyncio async def test_user_socket_cleanup_on_exit(self, clientAsync, socket_manager): """User socket should unregister from ws_api on exit.""" user_socket = socket_manager.user_socket() async with user_socket: sub_id = user_socket._subscription_id # Verify it's registered while connected assert sub_id in clientAsync.ws_api._subscription_queues # After exit, subscription should be unregistered assert sub_id not in clientAsync.ws_api._subscription_queues, \ "Subscription should be unregistered after exit" class TestUserSocketFunctionality: """Tests verifying user socket functionality works correctly.""" @pytest.mark.asyncio async def test_user_socket_recv_timeout(self, clientAsync, socket_manager): """User socket recv() should timeout gracefully when no events.""" user_socket = socket_manager.user_socket() async with user_socket: # recv() should timeout without errors (no events on quiet account) with pytest.raises(asyncio.TimeoutError): await asyncio.wait_for(user_socket.recv(), timeout=2) @pytest.mark.asyncio async def test_user_socket_context_manager(self, clientAsync, socket_manager): """User socket should work as async context manager.""" user_socket = socket_manager.user_socket() # Should not be connected initially assert user_socket._subscription_id is None async with user_socket: # Should be connected inside context assert user_socket._subscription_id is not None assert user_socket._uses_ws_api_subscription is True # Subscription ID is cleared after unsubscribe assert user_socket._subscription_id is None class TestNonUserSockets: """Tests verifying other socket types still work normally.""" @pytest.mark.asyncio async def test_margin_socket_not_using_ws_api_subscription(self, clientAsync, socket_manager): """Non-user KeepAliveWebsockets (like margin socket) should not use ws_api subscription.""" # margin_socket is a KeepAliveWebsocket with keepalive_type="margin" # Create it but don't connect - just check the flag margin_socket = socket_manager.margin_socket() # Before connecting, the flag should be False (default) assert margin_socket._uses_ws_api_subscription is False, \ "Margin socket should not use ws_api subscription" # The _keepalive_type should be "margin", not "user" assert margin_socket._keepalive_type == "margin" class TestWsApiSubscriptionRouting: """Tests verifying ws_api correctly routes subscription events.""" @pytest.mark.asyncio async def test_ws_api_has_subscription_queues(self, clientAsync): """ws_api should have subscription queues dict.""" # Ensure ws_api is initialized await clientAsync.ws_api._ensure_ws_connection() assert hasattr(clientAsync.ws_api, '_subscription_queues'), \ "ws_api should have _subscription_queues attribute" assert isinstance(clientAsync.ws_api._subscription_queues, dict), \ "_subscription_queues should be a dict" @pytest.mark.asyncio async def test_ws_api_register_unregister_queue(self, clientAsync): """ws_api should be able to register and unregister queues.""" await clientAsync.ws_api._ensure_ws_connection() test_queue = asyncio.Queue() test_sub_id = "test_subscription_123" # Register clientAsync.ws_api.register_subscription_queue(test_sub_id, test_queue) assert test_sub_id in clientAsync.ws_api._subscription_queues assert clientAsync.ws_api._subscription_queues[test_sub_id] is test_queue # Unregister clientAsync.ws_api.unregister_subscription_queue(test_sub_id) assert test_sub_id not in clientAsync.ws_api._subscription_queues @pytest.mark.asyncio async def test_ws_api_unregister_nonexistent_is_safe(self, clientAsync): """Unregistering a non-existent subscription should not raise.""" await clientAsync.ws_api._ensure_ws_connection() # Should not raise clientAsync.ws_api.unregister_subscription_queue("nonexistent_sub_id") if __name__ == "__main__": pytest.main([__file__, "-v"]) ================================================ FILE: tests/test_verbose_mode.py ================================================ """Tests for verbose mode functionality""" import pytest import logging from binance.client import Client from binance.async_client import AsyncClient def test_client_verbose_initialization(): """Test that Client can be initialized with verbose mode""" client = Client(verbose=True, ping=False) assert client.verbose is True assert client.logger is not None assert client.logger.level == logging.DEBUG def test_client_non_verbose_initialization(): """Test that Client defaults to non-verbose mode""" client = Client(verbose=False, ping=False) assert client.verbose is False assert client.logger is not None # When verbose=False, we don't set the logger level (respects external config) def test_client_default_verbose(): """Test that Client defaults to verbose=False""" client = Client(ping=False) assert client.verbose is False @pytest.mark.asyncio() async def test_async_client_verbose_initialization(): """Test that AsyncClient can be initialized with verbose mode""" client = AsyncClient(verbose=True) assert client.verbose is True assert client.logger is not None assert client.logger.level == logging.DEBUG await client.close_connection() @pytest.mark.asyncio() async def test_async_client_non_verbose_initialization(): """Test that AsyncClient defaults to non-verbose mode""" client = AsyncClient(verbose=False) assert client.verbose is False assert client.logger is not None # When verbose=False, we don't set the logger level (respects external config) await client.close_connection() @pytest.mark.asyncio() async def test_async_client_default_verbose(): """Test that AsyncClient defaults to verbose=False""" client = AsyncClient() assert client.verbose is False await client.close_connection() ================================================ FILE: tests/test_websocket_verbose.py ================================================ """Tests for WebSocket verbose logging""" import logging import pytest def test_websocket_logger_exists(): """Test that WebSocket loggers can be configured""" # Test main WebSocket logger ws_logger = logging.getLogger("binance.ws") assert ws_logger is not None # Test WebSocket API logger ws_api_logger = logging.getLogger("binance.ws.websocket_api") assert ws_api_logger is not None # Test reconnecting WebSocket logger ws_reconnect_logger = logging.getLogger("binance.ws.reconnecting_websocket") assert ws_reconnect_logger is not None # Test streams logger ws_streams_logger = logging.getLogger("binance.ws.streams") assert ws_streams_logger is not None def test_websocket_logger_level_configuration(): """Test that WebSocket logger levels can be set""" ws_logger = logging.getLogger("binance.ws.test_config") # Set to DEBUG ws_logger.setLevel(logging.DEBUG) assert ws_logger.level == logging.DEBUG # Set to INFO ws_logger.setLevel(logging.INFO) assert ws_logger.level == logging.INFO # Set to WARNING ws_logger.setLevel(logging.WARNING) assert ws_logger.level == logging.WARNING def test_combined_logging_configuration(): """Test that both REST and WebSocket logging can be configured together""" # Configure REST verbose logging from binance.client import Client # This should work without errors client = Client(verbose=True, ping=False) assert client.verbose is True assert client.logger is not None # Configure WebSocket logging ws_logger = logging.getLogger("binance.ws") ws_logger.setLevel(logging.DEBUG) assert ws_logger.level == logging.DEBUG # Both should be independently configurable assert client.logger.level == logging.DEBUG assert ws_logger.level == logging.DEBUG @pytest.mark.asyncio() async def test_binance_socket_manager_verbose(): """Test that BinanceSocketManager can be initialized with verbose mode""" from binance import AsyncClient, BinanceSocketManager client = AsyncClient() # Test with verbose=True bm_verbose = BinanceSocketManager(client, verbose=True) assert bm_verbose.verbose is True # Test with verbose=False (default) bm_quiet = BinanceSocketManager(client, verbose=False) assert bm_quiet.verbose is False # Test default bm_default = BinanceSocketManager(client) assert bm_default.verbose is False await client.close_connection() def test_threaded_websocket_manager_verbose(): """Test that ThreadedApiManager can be initialized with verbose mode""" from binance.ws.threaded_stream import ThreadedApiManager # Test with verbose=True twm_verbose = ThreadedApiManager(verbose=True) assert twm_verbose.verbose is True # Test with verbose=False (default) twm_quiet = ThreadedApiManager(verbose=False) assert twm_quiet.verbose is False # Test default twm_default = ThreadedApiManager() assert twm_default.verbose is False def test_websocket_manager_sets_logging_level(): """Test that verbose mode sets the logging level for WebSocket managers""" from binance.ws.threaded_stream import ThreadedApiManager # Get initial logging level ws_logger = logging.getLogger("binance.ws") initial_level = ws_logger.level # Create manager with verbose=True twm = ThreadedApiManager(verbose=True) # Check that logging level was set to DEBUG assert ws_logger.level == logging.DEBUG # Restore initial level ws_logger.setLevel(initial_level) ================================================ FILE: tests/test_ws_api.py ================================================ import json import sys import pytest import asyncio from binance import AsyncClient from binance.exceptions import BinanceAPIException, BinanceWebsocketUnableToConnect from binance.ws.constants import WSListenerState from .test_get_order_book import assert_ob from .conftest import proxy @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_ws_api_public_endpoint(clientAsync): """Test normal order book request""" order_book = await clientAsync.ws_get_order_book(symbol="BTCUSDT") assert_ob(order_book) @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_ws_api_private_endpoint(clientAsync): """Test normal order book request""" orders = await clientAsync.ws_get_all_orders(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_ws_futures_public_endpoint(futuresClientAsync): """Test normal order book request""" order_book = await futuresClientAsync.ws_futures_get_order_book(symbol="BTCUSDT") assert_ob(order_book) @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_ws_futures_private_endpoint(futuresClientAsync): """Test normal order book request""" await futuresClientAsync.ws_futures_v2_account_position(symbol="BTCUSDT") @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_ws_get_symbol_ticker(clientAsync): """Test symbol ticker request""" ticker = await clientAsync.ws_get_symbol_ticker(symbol="BTCUSDT") assert "symbol" in ticker assert ticker["symbol"] == "BTCUSDT" @pytest.mark.asyncio async def test_invalid_request(clientAsync): pass # """Test error handling for invalid symbol""" # with pytest.raises( # BinanceAPIException, # match=re.escape( # "APIError(code=-1100): Illegal characters found in parameter 'symbol'; legal range is \'^[\\\\w\\\\-._&&[^a-z]]{1,50}$\'." # ), # ): # # {'id': 'a2790cf96b11a8add71ebf', 'status': 400, 'error': {'code': -1100...:-1100,"msg":"Illegal characters found in parameter \'symbol\'; legal range is \'^[\\\\w\\\\-._&&[^a-z]]{1,50}$\'."}' # await clientAsync.ws_get_order_book(symbol="send error") @pytest.mark.asyncio async def test_connection_handling(clientAsync): """Test connection handling and reconnection""" # First request should establish connection await clientAsync.ws_get_order_book(symbol="BTCUSDT") assert clientAsync.ws_api.ws_state == WSListenerState.STREAMING # Force connection close await clientAsync.close_connection() assert clientAsync.ws_api.ws_state == WSListenerState.EXITING assert clientAsync.ws_api.ws is None # Next request should reconnect order_book = await clientAsync.ws_get_order_book(symbol="LTCUSDT") assert_ob(order_book) assert clientAsync.ws_api.ws_state == WSListenerState.STREAMING @pytest.mark.asyncio async def test_timeout_handling(clientAsync): """Test request timeout handling""" # Set very short timeout to force timeout error original_timeout = clientAsync.ws_api.TIMEOUT clientAsync.ws_api.TIMEOUT = 0.0001 try: with pytest.raises(BinanceWebsocketUnableToConnect, match="Request timed out"): await clientAsync.ws_get_order_book(symbol="BTCUSDT") finally: clientAsync.ws_api.TIMEOUT = original_timeout @pytest.mark.asyncio async def test_multiple_requests(clientAsync): """Test multiple concurrent requests""" symbols = ["BTCUSDT", "ETHUSDT", "BNBUSDT"] tasks = [clientAsync.ws_get_order_book(symbol=symbol) for symbol in symbols] results = await asyncio.gather(*tasks) assert len(results) == len(symbols) for result in results: assert_ob(result) @pytest.mark.asyncio async def test_testnet_url(): """Test testnet URL configuration""" testnet_client = AsyncClient(testnet=True, https_proxy=proxy) try: assert testnet_client.ws_api._url == testnet_client.WS_API_TESTNET_URL order_book = await testnet_client.ws_get_order_book(symbol="BTCUSDT") assert_ob(order_book) finally: await testnet_client.close_connection() @pytest.mark.asyncio async def test_message_handling(clientAsync): """Test message handling with various message types""" try: # Test valid message future = asyncio.Future() clientAsync.ws_api._responses["123"] = future valid_msg = {"id": "123", "status": 200, "result": {"test": "data"}} clientAsync.ws_api._handle_message(json.dumps(valid_msg)) result = await clientAsync.ws_api._responses["123"] assert result == valid_msg finally: await clientAsync.close_connection() @pytest.mark.asyncio async def test_message_handling_raise_exception(clientAsync): try: with pytest.raises(BinanceAPIException): future = asyncio.Future() clientAsync.ws_api._responses["123"] = future valid_msg = {"id": "123", "status": 400, "error": {"code": "0", "msg": "error message"}} clientAsync.ws_api._handle_message(json.dumps(valid_msg)) await future finally: await clientAsync.close_connection() @pytest.mark.asyncio async def test_message_handling_raise_exception_without_id(clientAsync): try: with pytest.raises(BinanceAPIException): future = asyncio.Future() clientAsync.ws_api._responses["123"] = future valid_msg = {"id": "123", "status": 400, "error": {"code": "0", "msg": "error message"}} clientAsync.ws_api._handle_message(json.dumps(valid_msg)) await future finally: await clientAsync.close_connection() @pytest.mark.asyncio async def test_message_handling_invalid_json(clientAsync): try: with pytest.raises(json.JSONDecodeError): clientAsync.ws_api._handle_message("invalid json") with pytest.raises(json.JSONDecodeError): clientAsync.ws_api._handle_message("invalid json") finally: # Ensure cleanup await clientAsync.close_connection() @pytest.mark.asyncio(scope="function") async def test_connection_failure(clientAsync): """Test handling of connection failures""" # Set invalid URL clientAsync.ws_api._url = "wss://invalid.url" with pytest.raises(BinanceWebsocketUnableToConnect, match="Connection failed"): await clientAsync.ws_get_order_book(symbol="BTCUSDT") @pytest.mark.asyncio(scope="function") async def test_cleanup_on_exit(clientAsync): """Test cleanup of resources on exit""" # Create some pending requests future = asyncio.Future() clientAsync.ws_api._responses["test"] = future # Close connection await clientAsync.close_connection() # Check cleanup assert "test" not in clientAsync.ws_api._responses assert future.exception() is not None @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_ws_queue_overflow(clientAsync): """WebSocket API should not overflow queue""" # original_size = clientAsync.ws_api.max_queue_size clientAsync.ws_api.max_queue_size = 1 try: # Request multiple order books concurrently symbols = ["BTCUSDT", "ETHUSDT", "BNBUSDT"] tasks = [clientAsync.ws_get_order_book(symbol=symbol) for symbol in symbols] # Execute all requests concurrently and wait for results results = await asyncio.gather(*tasks, return_exceptions=True) # Check that we got valid responses or expected overflow errors valid_responses = [r for r in results if not isinstance(r, Exception)] assert len(valid_responses) == len(symbols), "Should get at least one valid response" for result in valid_responses: assert_ob(result) finally: # Restore original queue size clientAsync.ws_api.MAX_QUEUE_SIZE = original_size @pytest.mark.skipif(sys.version_info < (3, 8), reason="websockets_proxy Python 3.8+") @pytest.mark.asyncio async def test_ws_api_with_stream(clientAsync): """Test combining WebSocket API requests with stream listening""" from binance import BinanceSocketManager # Create socket manager and trade socket bm = BinanceSocketManager(clientAsync) ts = bm.trade_socket("BTCUSDT") async with ts: # Make WS API request while stream is active order_book = await clientAsync.ws_get_order_book(symbol="BTCUSDT") assert_ob(order_book) # Verify we can still receive stream data trade = await ts.recv() assert "s" in trade # Symbol assert "p" in trade # Price assert "q" in trade # Quantity ================================================ FILE: tests/utils.py ================================================ def test_multiple_objects(obj_list, assertion_func): """ Generic test function for validating multiple objects Args: client_response: List or iterator of objects to validate assertion_func: Function to use for asserting each object's structure """ assert obj_list is not None, "Response should not be None" # Handle both lists and iterators objects = list(obj_list) # Validate each object for obj in objects: assertion_func(obj) ================================================ FILE: tox.ini ================================================ [tox] envlist = py38, py39, py310, py311, py312 [testenv] deps = -rtest-requirements.txt -rrequirements.txt passenv = PROXY TEST_TESTNET TEST_API_KEY TEST_API_SECRET TEST_FUTURES_API_KEY TEST_FUTURES_API_SECRET commands = pytest -n 5 -v tests/ --timeout=90 --doctest-modules --cov binance --cov-report term-missing --cov-report xml --reruns 3 --reruns-delay 30 [pep8] ignore = E501