diff --git a/CHANGELOG.md b/CHANGELOG.md index a9eb6640..c6fcbbc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,61 @@ # Changelog +## 3.10.0 - 2024-11-29 +### Added +- Margin + - `POST /sapi/v1/margin/order/oto` + - `POST /sapi/v1/margin/order/otoco` + +- Portfolio + - `GET /sapi/v2/portfolio/account` + - `GET /sapi/v1/portfolio/balance` + - `GET /sapi/v2/portfolio/collateralRate` + +- Simple Earn + - `POST /sapi/v1/simple-earn/locked/setRedeemOption` + +- Staking + - `GET /sapi/v2/eth-staking/account` + - `GET /sapi/v1/eth-staking/eth/quota` + - `POST /sapi/v2/eth-staking/eth/stake` + - `POST /sapi/v1/eth-staking/eth/redeem` + - `POST /sapi/v1/eth-staking/wbeth/wrap` + - `GET /sapi/v1/eth-staking/eth/history/stakingHistory` + - `GET /sapi/v1/eth-staking/eth/history/redemptionHistory` + - `GET /sapi/v1/eth-staking/eth/history/rewardsHistory` + - `GET /sapi/v1/eth-staking/eth/history/wbethRewardsHistory` + - `GET /sapi/v1/eth-staking/eth/history/rateHistory` + - `GET /sapi/v1/eth-staking/wbeth/history/wrapHistory` + - `GET /sapi/v1/eth-staking/wbeth/history/unwrapHistory` + +- Wallet + - `POST /sapi/v1/localentity/withdraw/apply` + - `GET /sapi/v1/localentity/withdraw/history` + - `PUT /sapi/v1/localentity/deposit/provide-info` + - `GET /sapi/v1/localentity/deposit/history` + +- Websocket Stream + - `kline_+08:00` + +### Updated +- Add parameters showPermissionSets and symbolStatus to `GET /api/v3/exchangeInfo` +- Add parameter timeZone to `GET /api/v3/klines`, `GET /api/v3/uiKlines`, `klines` and `uiKlines` +- Add parameter redeemTo to `POST /sapi/v1/simple-earn/locked/subscribe` +- Add parameters `txId` and `includeSource` to `GET /sapi/v1/capital/deposit/hisrec` +- Add parameter `idList` to `GET /sapi/v1/capital/withdraw/history` and `GET /sapi/v1/capital/deposit/subHisrec` +- Update Documentation +- Update `JSONDecodeError` error response + +### Removed +- Crypto-loans + - `GET /sapi/v1/loan/collateral/data` + - `POST /sapi/v1/loan/borrow` + - `POST /sapi/v1/loan/repay` + - `POST /sapi/v1/loan/adjust/ltv` + - `POST /sapi/v1/loan/customize/margin_call` + - `GET /sapi/v1/loan/ongoing/orders` + + ## 3.9.0 - 2024-10-02 ### Removed diff --git a/binance/__version__.py b/binance/__version__.py index fcd7ddb9..9ce9954c 100644 --- a/binance/__version__.py +++ b/binance/__version__.py @@ -1 +1 @@ -__version__ = "3.9.0" +__version__ = "3.10.0" diff --git a/binance/api.py b/binance/api.py index 90595fe4..09cf491c 100644 --- a/binance/api.py +++ b/binance/api.py @@ -176,7 +176,7 @@ def _handle_exception(self, response): err = json.loads(response.text) except JSONDecodeError: raise ClientError( - status_code, None, response.text, None, response.headers + status_code, None, response.text, response.headers, None ) error_data = None if "data" in err: diff --git a/binance/spot/__init__.py b/binance/spot/__init__.py index d0c7a20a..ce0b709b 100644 --- a/binance/spot/__init__.py +++ b/binance/spot/__init__.py @@ -102,6 +102,8 @@ def __init__(self, api_key=None, api_secret=None, **kwargs): from binance.spot._margin import adjust_cross_margin_max_leverage from binance.spot._margin import margin_available_inventory from binance.spot._margin import margin_manual_liquidation + from binance.spot._margin import margin_new_oto_order + from binance.spot._margin import margin_new_otoco_order from binance.spot._margin import liability_coin_leverage_bracket # WALLET @@ -126,6 +128,10 @@ def __init__(self, api_key=None, api_secret=None, **kwargs): from binance.spot._wallet import funding_wallet from binance.spot._wallet import user_asset from binance.spot._wallet import api_key_permissions + from binance.spot._wallet import local_entity_withdraw + from binance.spot._wallet import local_entity_withdraw_history + from binance.spot._wallet import local_entity_submit_deposit_questionnaire + from binance.spot._wallet import local_entity_deposit_history from binance.spot._wallet import bnb_convertible_assets from binance.spot._wallet import list_deposit_address from binance.spot._wallet import cloud_mining_trans_history @@ -206,21 +212,15 @@ def __init__(self, api_key=None, api_secret=None, **kwargs): # Crypto LOANS from binance.spot._crypto_loan import loan_history - from binance.spot._crypto_loan import loan_borrow from binance.spot._crypto_loan import loan_borrow_history - from binance.spot._crypto_loan import loan_ongoing_orders - from binance.spot._crypto_loan import loan_repay from binance.spot._crypto_loan import loan_repay_history - from binance.spot._crypto_loan import loan_adjust_ltv from binance.spot._crypto_loan import loan_adjust_ltv_history from binance.spot._crypto_loan import loan_vip_ongoing_orders from binance.spot._crypto_loan import loan_vip_repay from binance.spot._crypto_loan import loan_vip_repay_history from binance.spot._crypto_loan import loan_vip_collateral_account from binance.spot._crypto_loan import loan_loanable_data - from binance.spot._crypto_loan import loan_collateral_data from binance.spot._crypto_loan import loan_collateral_rate - from binance.spot._crypto_loan import loan_customize_margin_call # PAY from binance.spot._pay import pay_history @@ -256,11 +256,14 @@ def __init__(self, api_key=None, api_secret=None, **kwargs): # Portfolio Margin from binance.spot._portfolio_margin import portfolio_margin_account from binance.spot._portfolio_margin import portfolio_margin_collateral_rate + from binance.spot._portfolio_margin import portfolio_margin_tiered_collateral_rate from binance.spot._portfolio_margin import portfolio_margin_bankruptcy_loan_amount from binance.spot._portfolio_margin import portfolio_margin_bankruptcy_loan_repay from binance.spot._portfolio_margin import ( query_classic_portfolio_margin_negative_balance_interest_history, ) + from binance.spot._portfolio_margin import get_portfolio_margin_span_account_info + from binance.spot._portfolio_margin import get_portfolio_margin_account_balance from binance.spot._portfolio_margin import query_portfolio_margin_asset_index_price from binance.spot._portfolio_margin import fund_auto_collection from binance.spot._portfolio_margin import bnb_transfer @@ -291,6 +294,7 @@ def __init__(self, api_key=None, api_secret=None, **kwargs): from binance.spot._simple_earn import get_locked_personal_left_quota from binance.spot._simple_earn import get_flexible_subscription_preview from binance.spot._simple_earn import get_locked_subscription_preview + from binance.spot._simple_earn import set_locked_product_redeem_option from binance.spot._simple_earn import get_rate_history from binance.spot._simple_earn import get_collateral_record @@ -310,3 +314,17 @@ def __init__(self, api_key=None, api_secret=None, **kwargs): from binance.spot._auto_invest import index_linked_plan_redemption from binance.spot._auto_invest import get_index_linked_plan_redemption_history from binance.spot._auto_invest import index_linked_plan_rebalance_details + + # Staking + from binance.spot._staking import eth_staking_account + from binance.spot._staking import get_eth_staking_quota + from binance.spot._staking import subscribe_eth_staking + from binance.spot._staking import redeem_eth + from binance.spot._staking import wrap_beth + from binance.spot._staking import get_eth_staking_history + from binance.spot._staking import get_eth_redemption_history + from binance.spot._staking import get_beth_rewards_distribution_history + from binance.spot._staking import get_wbeth_rewards_history + from binance.spot._staking import get_wbeth_rate_history + from binance.spot._staking import get_wbeth_wrap_history + from binance.spot._staking import get_wbeth_unwrap_history diff --git a/binance/spot/_crypto_loan.py b/binance/spot/_crypto_loan.py index af4abe11..8c4273ff 100644 --- a/binance/spot/_crypto_loan.py +++ b/binance/spot/_crypto_loan.py @@ -26,40 +26,6 @@ def loan_history(self, asset: str, **kwargs): return self.sign_request("GET", "/sapi/v1/loan/income", payload) -def loan_borrow(self, loanCoin: str, collateralCoin: str, loanTerm: int, **kwargs): - """Crypto Loan Borrow (TRADE) - - POST /sapi/v1/loan/borrow - - https://developers.binance.com/docs/crypto_loan/stable-rate/trade/Crypto-Loan-Borrow - - Args: - loanCoin (str) - collateralCoin (str) - loanTerm (int): 7/14/30/90/180 days - Keyword Args: - loanAmount (float, optional): Mandatory when collateralAmount is empty - collateralAmount (float, optional): Mandatory when loanAmount is empty - recvWindow (int, optional): The value cannot be greater than 60000 - """ - - check_required_parameters( - [ - [loanCoin, "loanCoin"], - [collateralCoin, "collateralCoin"], - [loanTerm, "loanTerm"], - ] - ) - - payload = { - "loanCoin": loanCoin, - "collateralCoin": collateralCoin, - "loanTerm": loanTerm, - **kwargs, - } - return self.sign_request("POST", "/sapi/v1/loan/borrow", payload) - - def loan_borrow_history(self, **kwargs): """Get Loan Borrow History (USER_DATA) @@ -81,47 +47,6 @@ def loan_borrow_history(self, **kwargs): return self.sign_request("GET", "/sapi/v1/loan/borrow/history", kwargs) -def loan_ongoing_orders(self, **kwargs): - """Get Loan Ongoing Orders (USER_DATA) - - GET /sapi/v1/loan/ongoing/orders - - https://developers.binance.com/docs/crypto_loan/stable-rate/user-information/Get-Loan-Ongoing-Orders - - Keyword Args: - orderId (int, optional): orderId in POST /sapi/v1/loan/borrow - loanCoin (str, optional) - collateralCoin (str, optional) - current (int, optional): Current querying page. Start from 1; default: 1; max: 1000 - limit (int, optional): Default: 10; max: 100 - recvWindow (int, optional): The value cannot be greater than 60000 - """ - - return self.sign_request("GET", "/sapi/v1/loan/ongoing/orders", kwargs) - - -def loan_repay(self, orderId: int, amount: float, **kwargs): - """Crypto Loan Repay (TRADE) - - POST /sapi/v1/loan/repay - - https://developers.binance.com/docs/crypto_loan/stable-rate/trade/Crypto-Loan-Repay - - Args: - orderId (int) - amount (float) - Keyword Args: - type (int, optional): Default: 1. 1 for "repay with borrowed coin"; 2 for "repay with collateral" - collateralReturn (boolean, optional): Default: TRUE. TRUE: Return extra collateral to spot account; FALSE: Keep extra collateral in the order. - recvWindow (int, optional): The value cannot be greater than 60000 - """ - - check_required_parameters([[orderId, "orderId"], [amount, "amount"]]) - - payload = {"orderId": orderId, "amount": amount, **kwargs} - return self.sign_request("POST", "/sapi/v1/loan/repay", payload) - - def loan_repay_history(self, **kwargs): """Get Loan Repayment History (USER_DATA) @@ -143,29 +68,6 @@ def loan_repay_history(self, **kwargs): return self.sign_request("GET", "/sapi/v1/loan/repay/history", kwargs) -def loan_adjust_ltv(self, orderId: int, amount: float, direction: str, **kwargs): - """Crypto Loan Adjust LTV (TRADE) - - POST /sapi/v1/loan/adjust/ltv - - https://developers.binance.com/docs/crypto_loan/stable-rate/trade/Crypto-Loan-Adjust-LTV - - Args: - orderId (int) - amount (float) - direction (str): "ADDITIONAL", "REDUCED" - Keyword Args: - recvWindow (int, optional): The value cannot be greater than 60000 - """ - - check_required_parameters( - [[orderId, "orderId"], [amount, "amount"], [direction, "direction"]] - ) - - payload = {"orderId": orderId, "amount": amount, "direction": direction, **kwargs} - return self.sign_request("POST", "/sapi/v1/loan/adjust/ltv", payload) - - def loan_adjust_ltv_history(self, **kwargs): """Get Loan LTV Adjustment History (USER_DATA) @@ -279,22 +181,6 @@ def loan_loanable_data(self, **kwargs): return self.sign_request("GET", "/sapi/v1/loan/loanable/data", kwargs) -def loan_collateral_data(self, **kwargs): - """Get Collateral Assets Data (USER_DATA) - - GET /sapi/v1/loan/collateral/data - - https://developers.binance.com/docs/crypto_loan/stable-rate/market-data/Get-Collateral-Assets-Data - - Keyword Args: - collateralCoin (str, optional) - vipLevel (int, optional) - recvWindow (int, optional): The value cannot be greater than 60000 - """ - - return self.sign_request("GET", "/sapi/v1/loan/collateral/data", kwargs) - - def loan_collateral_rate( self, loanCoin: str, collateralCoin: str, repayAmount: float, **kwargs ): @@ -327,24 +213,3 @@ def loan_collateral_rate( **kwargs, } return self.sign_request("GET", "/sapi/v1/loan/repay/collateral/rate", payload) - - -def loan_customize_margin_call(self, marginCall: float, **kwargs): - """Customize Margin Call (USER_DATA) - - POST /sapi/v1/loan/customize/margin_call - - https://developers.binance.com/docs/crypto_loan/stable-rate/trade/Crypto-Loan-Customize-Margin-Call - - Args: - marginCall (float) - Keyword Args: - orderId (int, optional) - collateralCoin (str, optional) - recvWindow (int, optional): The value cannot be greater than 60000 - """ - - check_required_parameter(marginCall, "marginCall") - - payload = {"marginCall": marginCall, **kwargs} - return self.sign_request("POST", "/sapi/v1/loan/customize/margin_call", payload) diff --git a/binance/spot/_margin.py b/binance/spot/_margin.py index 628187ca..bd0ae1cf 100644 --- a/binance/spot/_margin.py +++ b/binance/spot/_margin.py @@ -901,7 +901,7 @@ def margin_available_inventory(self, type: str, **kwargs): def margin_manual_liquidation(self, type: str, **kwargs): - """Margin manual liquidation(MARGIN) + """Margin manual liquidation (MARGIN) POST /sapi/v1/margin/manual-liquidation @@ -918,6 +918,161 @@ def margin_manual_liquidation(self, type: str, **kwargs): return self.sign_request("POST", "/sapi/v1/margin/manual-liquidation", payload) +def margin_new_oto_order( + self, + symbol: str, + workingType: str, + workingSide: str, + workingPrice: float, + workingQuantity: float, + pendingType: str, + pendingSide: str, + pendingQuantity: float, + **kwargs +): + """Margin Account New OTO (TRADE) + + Post a new OTOCO order for margin account + + Weight(UID): 6 + + POST /sapi/v1/margin/order/oto + + https://developers.binance.com/docs/margin_trading/trade/Margin-Account-New-OTO + + Args: + symbol (str) + workingType (str) + workingSide (str) + workingPrice (float) + workingQuantity (float) + pendingType (str) + pendingSide (str) + pendingQuantity (float) + Keyword Args: + isIsolated (str, optional): for isolated margin or not: "TRUE", "FALSE". Default: "FALSE" + listClientOrderId (str, optional): Arbitrary unique ID among open order lists. Automatically generated if not sent. A new order list with the same listClientOrderId is accepted only when the previous one is filled or completely expired. `listClientOrderId` is distinct from the `workingClientOrderId` and the `pendingClientOrderId`. + newOrderRespType (str, optional): Set the response JSON. `ACK`, `RESULT`, or `FULL`; `MARKET` and `LIMIT` order types default to `FULL`, all other orders default to `ACK`. + sideEffectType (str, optional): `NO_SIDE_EFFECT`, `MARGIN_BUY`, `AUTO_REPAY` or `AUTO_BORROW_REPAY` + selfTradePreventionMode (str, optional): The allowed enums is dependent on what is configured on the symbol. The possible supported values are `EXPIRE_TAKER`, `EXPIRE_MAKER`, `EXPIRE_BOTH`, `NONE` + autoRepayAtCancel (bool, optional): Only when MARGIN_BUY order takes effect, true means that the debt generated by the order needs to be repay after the order is cancelled. The default is true + workingClientOrderId (str, optional): Arbitrary unique ID among open orders for the working order. Automatically generated if not sent. + workingIcebergQty (float, optional): This can only be used if `workingTimeInForce` is `GTC`. + workingTimeInForce (str, optional): `GTC`, `IOC` or `FOK` + pendingClientOrderId (str, optional): Arbitrary unique ID among open orders for the pending order. Automatically generated if not sent. + pendingPrice (float, optional) + pendingStopPrice (float, optional) + pendingTrailingDelta (float, optional) + pendingIcebergQty (float, optional): This can only be used if `pendingTimeInForce` is `GTC`. + pendingTimeInForce (str, optional): `GTC`, `IOC` or `FOK` + """ + check_required_parameters( + [ + [symbol, "symbol"], + [workingType, "workingType"], + [workingSide, "workingSide"], + [workingPrice, "workingPrice"], + [workingQuantity, "workingQuantity"], + [pendingType, "pendingType"], + [pendingSide, "pendingSide"], + [pendingQuantity, "pendingQuantity"], + ] + ) + payload = { + "symbol": symbol, + "workingType": workingType, + "workingSide": workingSide, + "workingPrice": workingPrice, + "workingQuantity": workingQuantity, + "pendingType": pendingType, + "pendingSide": pendingSide, + "pendingQuantity": pendingQuantity, + **kwargs, + } + return self.sign_request("POST", "/sapi/v1/margin/order/oto", payload) + + +def margin_new_otoco_order( + self, + symbol: str, + workingType: str, + workingSide: str, + workingPrice: float, + workingQuantity: float, + pendingSide: str, + pendingQuantity: float, + pendingAboveType: str, + **kwargs +): + """Margin Account New OTOCO (TRADE) + + Post a new OTOCO order for margin account + + Weight(UID): 6 + + POST /sapi/v1/margin/order/otoco + + https://developers.binance.com/docs/margin_trading/trade/Margin-Account-New-OTOCO + + Args: + symbol (str) + workingType (str) + workingSide (str) + workingPrice (float) + workingQuantity (float) + pendingSide (str) + pendingQuantity (float) + pendingAboveType (str) + Keyword Args: + isIsolated (str, optional): for isolated margin or not: "TRUE", "FALSE". Default: "FALSE" + sideEffectType (str, optional): `NO_SIDE_EFFECT`, `MARGIN_BUY`, `AUTO_REPAY` or `AUTO_BORROW_REPAY` + autoRepayAtCancel (bool, optional): Only when `MARGIN_BUY` order takes effect, true means that the debt generated by the order needs to be repay after the order is cancelled. The default is true + listClientOrderId (str, optional): Arbitrary unique ID among open order lists. Automatically generated if not sent. A new order list with the same listClientOrderId is accepted only when the previous one is filled or completely expired. `listClientOrderId` is distinct from the `workingClientOrderId`, `pendingAboveClientOrderId`, and the `pendingBelowClientOrderId`. + newOrderRespType (str, optional): Format of the JSON response. + selfTradePreventionMode (str, optional): The allowed enums is dependent on what is configured on the symbol. The possible supported values are `EXPIRE_TAKER`, `EXPIRE_MAKER`, `EXPIRE_BOTH`, `NONE` + workingClientOrderId (str, optional): Arbitrary unique ID among open orders for the working order. Automatically generated if not sent. + workingIcebergQty (float, optional): This can only be used if `workingTimeInForce` is `GTC`. + workingTimeInForce (str, optional): `GTC`, `IOC` or `FOK` + pendingAboveClientOrderId (str, optional): Arbitrary unique ID among open orders for the pending above order. Automatically generated if not sent. + pendingAbovePrice (float, optional) + pendingAboveStopPrice (float, optional) + pendingAboveTrailingDelta (float, optional) + pendingAboveIcebergQty (float, optional): This can only be used if `pendingAboveTimeInForce` is `GTC`. + pendingAboveTimeInForce (str, optional) + pendingBelowType (str, optional): Supported values: `LIMIT_MAKER`, `STOP_LOSS`, and `STOP_LOSS_LIMIT` + pendingBelowClientOrderId (str, optional): Arbitrary unique ID among open orders for the pending below order. Automatically generated if not sent. + pendingBelowPrice (float, optional) + pendingBelowStopPrice (float, optional) + pendingBelowTrailingDelta (float, optional) + pendingBelowIcebergQty (float, optional): This can only be used if `pendingBelowTimeInForce` is `GTC`. + pendingBelowTimeInForce (str, optional) + """ + check_required_parameters( + [ + [symbol, "symbol"], + [workingType, "workingType"], + [workingSide, "workingSide"], + [workingPrice, "workingPrice"], + [workingQuantity, "workingQuantity"], + [pendingSide, "pendingSide"], + [pendingQuantity, "pendingQuantity"], + [pendingAboveType, "pendingAboveType"], + ] + ) + payload = { + "symbol": symbol, + "workingType": workingType, + "workingSide": workingSide, + "workingPrice": workingPrice, + "workingQuantity": workingQuantity, + "pendingSide": pendingSide, + "pendingQuantity": pendingQuantity, + "pendingAboveType": pendingAboveType, + **kwargs, + } + return self.sign_request("POST", "/sapi/v1/margin/order/otoco", payload) + + def liability_coin_leverage_bracket(self, **kwargs): """Query Liability Coin Leverage Bracket in Cross Margin Pro Mode(MARKET_DATA) diff --git a/binance/spot/_market.py b/binance/spot/_market.py index 5387848e..d1f3d011 100644 --- a/binance/spot/_market.py +++ b/binance/spot/_market.py @@ -13,7 +13,7 @@ def ping(self): GET /api/v3/ping - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#test-connectivity + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#test-connectivity """ @@ -27,7 +27,7 @@ def time(self): GET /api/v3/time - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#check-server-time + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#check-server-time """ @@ -43,12 +43,14 @@ def exchange_info( GET /api/v3/exchangeinfo - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#exchange-information + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#exchange-information Args: symbol (str, optional): the trading pair symbols (list, optional): list of trading pairs permissions (list, optional): display all symbols with the permissions matching the parameter provided (eg.SPOT, MARGIN, LEVERAGED) + showPermissionSets (bool, optional): Controls whether the content of the `permissionSets` field is populated or not. Defaults to true + symbolStatus (str, optional): Filters symbols that have this `tradingStatus`. Valid values: `TRADING`, `HALT`, `BREAK`. Cannot be used in combination with `symbols` or `symbol`. """ url_path = "/api/v3/exchangeInfo" @@ -74,7 +76,7 @@ def depth(self, symbol: str, **kwargs): GET /api/v3/depth - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#order-book + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#order-book Args: symbol (str): the trading pair @@ -93,7 +95,7 @@ def trades(self, symbol: str, **kwargs): GET /api/v3/trades - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#recent-trades-list + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#recent-trades-list Args: symbol (str): the trading pair @@ -111,7 +113,7 @@ def historical_trades(self, symbol: str, **kwargs): GET /api/v3/historicalTrades - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#old-trade-lookup + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#old-trade-lookup Args: symbol (str): the trading pair @@ -129,7 +131,7 @@ def agg_trades(self, symbol: str, **kwargs): GET /api/v3/aggTrades - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#compressedaggregate-trades-list + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#compressedaggregate-trades-list Args: symbol (str): the trading pair @@ -150,7 +152,7 @@ def klines(self, symbol: str, interval: str, **kwargs): GET /api/v3/klines - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#klinecandlestick-data + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#klinecandlestick-data Args: symbol (str): the trading pair @@ -159,6 +161,7 @@ def klines(self, symbol: str, interval: str, **kwargs): limit (int, optional): limit the results. Default 500; max 1000. startTime (int, optional): Timestamp in ms to get aggregate trades from INCLUSIVE. endTime (int, optional): Timestamp in ms to get aggregate trades until INCLUSIVE. + timeZone (str, optional): Default: 0 (UTC) """ check_required_parameters([[symbol, "symbol"], [interval, "interval"]]) @@ -171,7 +174,7 @@ def ui_klines(self, symbol: str, interval: str, **kwargs): GET /api/v3/uiKlines - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#uiklines + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#uiklines Args: symbol (str): the trading pair @@ -180,6 +183,7 @@ def ui_klines(self, symbol: str, interval: str, **kwargs): limit (int, optional): limit the results. Default 500; max 1000. startTime (int, optional): Timestamp in ms to get aggregate trades from INCLUSIVE. endTime (int, optional): Timestamp in ms to get aggregate trades until INCLUSIVE. + timeZone (str, optional): Default: 0 (UTC) """ check_required_parameters([[symbol, "symbol"], [interval, "interval"]]) @@ -192,7 +196,7 @@ def avg_price(self, symbol: str): GET /api/v3/avgPrice - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#current-average-price + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#current-average-price Args: symbol (str): the trading pair @@ -210,7 +214,7 @@ def ticker_24hr(self, symbol: str = None, symbols: list = None, **kwargs): GET /api/v3/ticker/24hr - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#24hr-ticker-price-change-statistics + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#24hr-ticker-price-change-statistics Args: symbol (str, optional): the trading pair @@ -233,7 +237,7 @@ def trading_day_ticker(self, symbol: str = None, symbols: list = None): GET /api/v3/ticker/tradingDay - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#trading-day-ticker + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#trading-day-ticker Args: symbol (str, optional): Either symbol or symbols must be provided @@ -255,7 +259,7 @@ def ticker_price(self, symbol: str = None, symbols: list = None): GET /api/v3/ticker/price - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#symbol-price-ticker + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#symbol-price-ticker Args: symbol (str, optional): the trading pair @@ -274,7 +278,7 @@ def book_ticker(self, symbol: str = None, symbols: list = None): GET /api/v3/ticker/bookTicker - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#symbol-order-book-ticker + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#symbol-order-book-ticker Args: symbol (str, optional): the trading pair @@ -303,7 +307,7 @@ def rolling_window_ticker(self, symbol: str = None, symbols: list = None, **kwar GET /api/v3/ticker - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#rolling-window-price-change-statistics + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#rolling-window-price-change-statistics Args: symbol (str, optional): the trading pair diff --git a/binance/spot/_portfolio_margin.py b/binance/spot/_portfolio_margin.py index ce6ba317..b8f1ec9d 100644 --- a/binance/spot/_portfolio_margin.py +++ b/binance/spot/_portfolio_margin.py @@ -40,6 +40,24 @@ def portfolio_margin_collateral_rate(self): return self.sign_request("GET", url_path) +def portfolio_margin_tiered_collateral_rate(self, **kwargs): + """Portfolio Margin Pro Tiered Collateral Rate (USER_DATA) + + Portfolio Margin PRO Tiered Collateral Rate + + Weight(IP): 50 + + GET /sapi/v2/portfolio/collateralRate + + https://developers.binance.com/docs/derivatives/portfolio-margin-pro/market-data/Portfolio-Margin-Pro-Tiered-Collateral-Rate + + Keyword Args: + recvWindow (int, optional): The value cannot be greater than 60000 + """ + url_path = "/sapi/v2/portfolio/collateralRate" + return self.sign_request("GET", url_path, {**kwargs}) + + def portfolio_margin_bankruptcy_loan_amount(self, **kwargs): """Query Classic Portfolio Margin Bankruptcy Loan Amount (USER_DATA) @@ -106,6 +124,43 @@ def query_classic_portfolio_margin_negative_balance_interest_history( return self.sign_request("GET", url_path, params) +def get_portfolio_margin_span_account_info(self, **kwargs): + """Get Portfolio Margin Pro SPAN Account Info (USER_DATA) + + Get Portfolio Margin Pro SPAN Account Info (For Portfolio Margin Pro SPAN users only) + + Weight(IP): 5 + + GET /sapi/v2/portfolio/account + + https://developers.binance.com/docs/derivatives/portfolio-margin-pro/account/Get-Classic-Portfolio-Margin-Account-Info-V2 + + Keyword Args: + recvWindow (int, optional): The value cannot be greater than 60000 + """ + url_path = "/sapi/v2/portfolio/account" + return self.sign_request("GET", url_path, {**kwargs}) + + +def get_portfolio_margin_account_balance(self, **kwargs): + """Get Portfolio Margin Pro Account Balance (USER_DATA) + + Query Portfolio Margin Pro account balance + + Weight(IP): 20 + + GET /sapi/v1/portfolio/balance + + https://developers.binance.com/docs/derivatives/portfolio-margin-pro/account/Get-Classic-Portfolio-Margin-Balance-Info + + Keyword Args: + asset (str, optional) + recvWindow (int, optional): The value cannot be greater than 60000 + """ + url_path = "/sapi/v1/portfolio/balance" + return self.sign_request("GET", url_path, {**kwargs}) + + def query_portfolio_margin_asset_index_price(self, **kwargs): """Query Portfolio Margin Asset Index Price (MARKET_DATA) diff --git a/binance/spot/_simple_earn.py b/binance/spot/_simple_earn.py index 8cd25fae..2f3e84a0 100644 --- a/binance/spot/_simple_earn.py +++ b/binance/spot/_simple_earn.py @@ -88,7 +88,8 @@ def subscribe_locked_product(self, projectId: str, amount: float, **kwargs): amount (float) Keyword Args: autoSubscribe (boolean, optional): true or false, default true. - sourceAccount (str, optional): SPOT,FUND,ALL, default SPOT + sourceAccount (str, optional): SPOT, FUND, ALL, default SPOT + redeemTo (str, optional): SPOT, FLEXIBLE, default FLEXIBLE recvWindow (int, optional): The value cannot be greater than 60000 """ check_required_parameters([[projectId, "projectId"], [amount, "amount"]]) @@ -483,6 +484,30 @@ def get_locked_subscription_preview(self, projectId: str, amount: float, **kwarg return self.sign_request("GET", url_path, params) +def set_locked_product_redeem_option(self, positionId: str, redeemTo: str, **kwargs): + """Set Locked Product Redeem Option (USER_DATA) + + Set redeem option for Locked product + + Weight(IP): 50 + + POST /sapi/v1/simple-earn/locked/setRedeemOption + + https://developers.binance.com/docs/simple_earn/earn/Set-Locked-Redeem-Option + + Args: + positionId (str) + redeemTo (str): SPOT,FUND,ALL + Keyword Args: + recvWindow (int, optional): The value cannot be greater than 60000 + """ + check_required_parameters([[positionId, "positionId"], [redeemTo, "redeemTo"]]) + + params = {"positionId": positionId, "redeemTo": redeemTo, **kwargs} + url_path = "/sapi/v1/simple-earn/locked/setRedeemOption" + return self.sign_request("POST", url_path, params) + + def get_rate_history(self, productId: str, **kwargs): """Get Rate History (USER_DATA) diff --git a/binance/spot/_staking.py b/binance/spot/_staking.py new file mode 100644 index 00000000..ec25b22a --- /dev/null +++ b/binance/spot/_staking.py @@ -0,0 +1,263 @@ +from binance.lib.utils import check_required_parameter + + +def eth_staking_account(self, **kwargs): + """ETH Staking account (USER_DATA) + + ETH Staking account + + Weight(IP): 150 + + GET /sapi/v2/eth-staking/account + + https://developers.binance.com/docs/staking/eth-staking/account + + Keyword Args: + recvWindow (int, optional): The value cannot be greater than 60000 + """ + url_path = "/sapi/v2/eth-staking/account" + return self.sign_request("GET", url_path, {**kwargs}) + + +def get_eth_staking_quota(self, **kwargs): + """Get current ETH staking quota (USER_DATA) + + Get current ETH staking quota + + Weight(IP): 150 + + GET /sapi/v1/eth-staking/eth/quota + + https://developers.binance.com/docs/staking/eth-staking/account/Get-current-ETH-staking-quota + + Keyword Args: + recvWindow (int, optional): The value cannot be greater than 60000 + """ + url_path = "/sapi/v1/eth-staking/eth/quota" + return self.sign_request("GET", url_path, {**kwargs}) + + +def subscribe_eth_staking(self, amount: float, **kwargs): + """Subscribe ETH Staking (TRADE) + + Subscribe ETH Staking + + Weight(IP): 150 + + POST /sapi/v2/eth-staking/eth/stake + + https://developers.binance.com/docs/staking/eth-staking/staking + + Args: + amount (float): Amount in ETH, limit 4 decimals + + Keyword Args: + recvWindow (int, optional): The value cannot be greater than 60000 + """ + check_required_parameter(amount, "amount") + + params = {"amount": amount, **kwargs} + url_path = "/sapi/v2/eth-staking/eth/stake" + return self.sign_request("POST", url_path, params) + + +def redeem_eth(self, amount: float, **kwargs): + """Redeem ETH (TRADE) + + Redeem WBETH or BETH and get ETH + + Weight(IP): 150 + + POST /sapi/v1/eth-staking/eth/redeem + + https://developers.binance.com/docs/staking/eth-staking/staking/Redeem-ETH + + Args: + amount (float): Amount in BETH, limit 8 decimals + + Keyword Args: + asset (str, optional): WBETH or BETH, default to BETH + recvWindow (int, optional): The value cannot be greater than 60000 + """ + check_required_parameter(amount, "amount") + + params = {"amount": amount, **kwargs} + url_path = "/sapi/v1/eth-staking/eth/redeem" + return self.sign_request("POST", url_path, params) + + +def wrap_beth(self, amount: float, **kwargs): + """Wrap BETH (TRADE) + + Wrap BETH + + Weight(IP): 150 + + POST /sapi/v1/eth-staking/wbeth/wrap + + https://developers.binance.com/docs/staking/eth-staking/staking/Wrap-BETH + + Args: + amount (float): Amount in BETH, limit 4 decimals + Keyword Args: + recvWindow (int, optional): The value cannot be greater than 60000 + """ + check_required_parameter(amount, "amount") + + params = {"amount": amount, **kwargs} + url_path = "/sapi/v1/eth-staking/wbeth/wrap" + return self.sign_request("POST", url_path, params) + + +def get_eth_staking_history(self, **kwargs): + """Get ETH staking history (USER_DATA) + + Get ETH staking history + + Weight(IP): 150 + + GET /sapi/v1/eth-staking/eth/history/stakingHistory + + https://developers.binance.com/docs/staking/eth-staking/history + + Keyword Args: + startTime (int, optional) + endTime (int, optional) + current (int, optional): Currently querying page. Start from 1. Default: 1 + size (int, optional): Default: 10, Max: 100 + recvWindow (int, optional): The value cannot be greater than 60000 + """ + url_path = "/sapi/v1/eth-staking/eth/history/stakingHistory" + return self.sign_request("GET", url_path, {**kwargs}) + + +def get_eth_redemption_history(self, **kwargs): + """Get ETH redemption history (USER_DATA) + + Get ETH redemption history + + Weight(IP): 150 + + GET /sapi/v1/eth-staking/eth/history/redemptionHistory + + https://developers.binance.com/docs/staking/eth-staking/history/Get-ETH-redemption-history + + Keyword Args: + startTime (int, optional) + endTime (int, optional) + current (int, optional): Currently querying page. Start from 1. Default: 1 + size (int, optional): Default: 10, Max: 100 + recvWindow (int, optional): The value cannot be greater than 60000 + """ + url_path = "/sapi/v1/eth-staking/eth/history/redemptionHistory" + return self.sign_request("GET", url_path, {**kwargs}) + + +def get_beth_rewards_distribution_history(self, **kwargs): + """Get BETH rewards distribution history (USER_DATA) + + Get BETH rewards distribution history + + Weight(IP): 150 + + GET /sapi/v1/eth-staking/eth/history/rewardsHistory + + https://developers.binance.com/docs/staking/eth-staking/history/Get-ETH-rewards-distribution-history + + Keyword Args: + startTime (int, optional) + endTime (int, optional) + current (int, optional): Currently querying page. Start from 1. Default: 1 + size (int, optional): Default: 10, Max: 100 + recvWindow (int, optional): The value cannot be greater than 60000 + """ + url_path = "/sapi/v1/eth-staking/eth/history/rewardsHistory" + return self.sign_request("GET", url_path, {**kwargs}) + + +def get_wbeth_rewards_history(self, **kwargs): + """Get WBETH rewards history (USER_DATA) + + Get WBETH rewards history + + Weight(IP): 150 + + GET /sapi/v1/eth-staking/eth/history/wbethRewardsHistory + + https://developers.binance.com/docs/staking/eth-staking/history/Get-WBETH-rewards-history + + Keyword Args: + startTime (int, optional) + endTime (int, optional) + current (int, optional): Currently querying page. Start from 1. Default: 1 + size (int, optional): Default: 10, Max: 100 + recvWindow (int, optional): The value cannot be greater than 60000 + """ + url_path = "/sapi/v1/eth-staking/eth/history/wbethRewardsHistory" + return self.sign_request("GET", url_path, {**kwargs}) + + +def get_wbeth_rate_history(self, **kwargs): + """Get WBETH Rate History (USER_DATA) + + Get WBETH Rate History + + Weight(IP): 150 + + GET /sapi/v1/eth-staking/eth/history/rateHistory + + https://developers.binance.com/docs/staking/eth-staking/history/Get-BETH-Rate-History + + Keyword Args: + startTime (int, optional) + endTime (int, optional) + current (int, optional): Currently querying page. Start from 1. Default: 1 + size (int, optional): Default: 10, Max: 100 + recvWindow (int, optional): The value cannot be greater than 60000 + """ + url_path = "/sapi/v1/eth-staking/eth/history/rateHistory" + return self.sign_request("GET", url_path, {**kwargs}) + + +def get_wbeth_wrap_history(self, **kwargs): + """Get WBETH wrap history (USER_DATA) + + Get WBETH wrap history + + Weight(IP): 150 + + GET /sapi/v1/eth-staking/wbeth/history/wrapHistory + + https://developers.binance.com/docs/staking/eth-staking/history/Get-WBETH-wrap-history + + Keyword Args: + startTime (int, optional) + endTime (int, optional) + current (int, optional): Currently querying page. Start from 1. Default: 1 + size (int, optional): Default: 10, Max: 100 + recvWindow (int, optional): The value cannot be greater than 60000 + """ + url_path = "/sapi/v1/eth-staking/wbeth/history/wrapHistory" + return self.sign_request("GET", url_path, {**kwargs}) + + +def get_wbeth_unwrap_history(self, **kwargs): + """Get WBETH unwrap history (USER_DATA) + + Get WBETH unwrap history + + Weight(IP): 150 + + GET /sapi/v1/eth-staking/wbeth/history/unwrapHistory + + https://developers.binance.com/docs/staking/eth-staking/history/Get-WBETH-unwrap-history + + Keyword Args: + startTime (int, optional) + endTime (int, optional) + current (int, optional): Currently querying page. Start from 1. Default: 1 + size (int, optional): Default: 10, Max: 100 + recvWindow (int, optional): The value cannot be greater than 60000 + """ + url_path = "/sapi/v1/eth-staking/wbeth/history/unwrapHistory" + return self.sign_request("GET", url_path, {**kwargs}) diff --git a/binance/spot/_sub_account.py b/binance/spot/_sub_account.py index 2628fe2d..041345b0 100644 --- a/binance/spot/_sub_account.py +++ b/binance/spot/_sub_account.py @@ -104,6 +104,7 @@ def sub_account_deposit_history(self, email: str, **kwargs): endTime (int, optional) limit (int, optional) offset (int, optional): Default:0 + txId (str, optional) recvWindow (int, optional): The value cannot be greater than 60000 """ diff --git a/binance/spot/_trade.py b/binance/spot/_trade.py index f0c0cf21..7ffaf6b1 100644 --- a/binance/spot/_trade.py +++ b/binance/spot/_trade.py @@ -10,7 +10,7 @@ def new_order_test(self, symbol: str, side: str, type: str, **kwargs): POST /api/v3/order/test - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#test-new-order-trade + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#test-new-order-trade Args: symbol (str) @@ -41,7 +41,7 @@ def new_order(self, symbol: str, side: str, type: str, **kwargs): POST /api/v3/order - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#new-order-trade + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#new-order-trade Args: symbol (str) @@ -75,7 +75,7 @@ def cancel_order(self, symbol: str, **kwargs): DELETE /api/v3/order - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#cancel-order-trade + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#cancel-order-trade Args: symbol (str) @@ -100,7 +100,7 @@ def cancel_open_orders(self, symbol: str, **kwargs): DELETE api/v3/openOrders - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#cancel-all-open-orders-on-a-symbol-trade + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#cancel-all-open-orders-on-a-symbol-trade Args: symbol (str) @@ -121,7 +121,7 @@ def get_order(self, symbol, **kwargs): GET /api/v3/order - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#query-order-user_data + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#query-order-user_data Args: symbol (str) @@ -152,7 +152,7 @@ def cancel_and_replace( POST /api/v3/order/cancelReplace - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#cancel-an-existing-order-and-send-a-new-order-trade + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#cancel-an-existing-order-and-send-a-new-order-trade Args: symbol (str) @@ -206,7 +206,7 @@ def get_open_orders(self, symbol=None, **kwargs): GET /api/v3/openOrders - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#current-open-orders-user_data + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#current-open-orders-user_data Args: symbol (str, optional) @@ -226,7 +226,7 @@ def get_orders(self, symbol: str, **kwargs): GET /api/v3/allOrders - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#all-orders-user_data + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#all-orders-user_data Args: symbol (str) @@ -268,7 +268,7 @@ def new_oco_order( POST /api/v3/orderList/oco - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#new-order-list---oco-trade + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#new-order-list---oco-trade Args: symbol (str) @@ -345,7 +345,7 @@ def new_oto_order( POST /api/v3/orderList/oto - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#new-order-list---oto-trade + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#new-order-list---oto-trade Args: symbol (str) @@ -428,7 +428,7 @@ def new_otoco_order( POST /api/v3/orderList/otoco - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#new-order-list---otoco-trade + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#new-order-list---otoco-trade Args: symbol (str) @@ -502,7 +502,7 @@ def cancel_oco_order(self, symbol, **kwargs): DELETE /api/v3/orderList - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#cancel-order-list-trade + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#cancel-order-list-trade Args: symbol (str) @@ -526,7 +526,7 @@ def get_oco_order(self, **kwargs): GET /api/v3/orderList - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#query-order-lists-user_data + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#query-order-list-user_data Keyword Args: orderListId (int, optional): Either orderListId or listClientOrderId must be provided @@ -544,7 +544,7 @@ def get_oco_orders(self, **kwargs): GET /api/v3/allOrderList - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#query-all-order-lists-user_data + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#query-all-order-lists-user_data Keyword Args: fromId (int, optional): If supplied, neither startTime or endTime can be provided @@ -563,7 +563,7 @@ def get_oco_open_orders(self, **kwargs): GET /api/v3/openOrderList - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#query-open-order-lists-user_data + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#query-open-order-lists-user_data Keyword Args: recvWindow (int, optional): The value cannot be greater than 60000 @@ -580,7 +580,7 @@ def account(self, **kwargs): GET /api/v3/account - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#account-information-user_data + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#account-information-user_data Keyword Args: omitZeroBalances (bool, optional): When set to true, emits only the non-zero balances of an account. Default value: false @@ -598,7 +598,7 @@ def my_trades(self, symbol: str, **kwargs): GET /api/v3/myTrades - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#account-trade-list-user_data + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#account-trade-list-user_data Args: symbol (str) @@ -625,7 +625,7 @@ def get_order_rate_limit(self, **kwargs): GET /api/v3/rateLimit/order - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#query-current-order-count-usage-trade + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#query-unfilled-order-count-user_data Keyword Args: recvWindow (int, optional): The value cannot be greater than 60000 @@ -658,7 +658,7 @@ def query_prevented_matches(self, symbol: str, **kwargs): GET /api/v3/myPreventedMatches - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#query-prevented-matches-user_data + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#query-prevented-matches-user_data Args: symbol (str) @@ -681,7 +681,7 @@ def query_allocations(self, symbol: str, **kwargs): GET /api/v3/myAllocations - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#query-allocations-user_data + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#query-allocations-user_data Args: symbol (str) @@ -705,7 +705,7 @@ def query_commission_rates(self, symbol: str, **kwargs): GET /api/v3/account/commission - https://developers.binance.com/docs/binance-spot-api-docs/rest-api#query-commission-rates-user_data + https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#query-commission-rates-user_data Args: symbol (str) diff --git a/binance/spot/_wallet.py b/binance/spot/_wallet.py index 098274ff..da2521fc 100644 --- a/binance/spot/_wallet.py +++ b/binance/spot/_wallet.py @@ -125,13 +125,14 @@ def deposit_history(self, **kwargs): https://developers.binance.com/docs/wallet/capital/deposite-history Keyword Args: + includeSource (bool, optional): Default: false, return sourceAddressfield when set to true coin (str, optional) status (int, optional): Default 0 (0:pending, 6: credited but cannot withdraw, 1:success) startTime (int, optional): Default: 90 days from current timestamp endTime (int, optional): Default: present timestamp offset (int, optional): Default value: 0 limit (int, optional): Default:1000, Max:1000 - recvWindow (int, optional): The value cannot be greater than 60000 + txId (str, optional) """ return self.sign_request("GET", "/sapi/v1/capital/deposit/hisrec", kwargs) @@ -152,6 +153,7 @@ def withdraw_history(self, **kwargs): 3:Rejected, 4:Processing, 5:Failure, 6:Completed) offset (int, optional) limit (int, optional): Default: 1000, Max: 1000 + idList (str, optional): id list returned in the response of POST /sapi/v1/capital/withdraw/apply, separated by commas startTime (int, optional): Default: 90 days from current timestamp endTime (int, optional): Default: present timestamp recvWindow (int, optional): The value cannot be greater than 60000 @@ -396,6 +398,134 @@ def api_key_permissions(self, **kwargs): return self.sign_request("GET", "/sapi/v1/account/apiRestrictions", kwargs) +def local_entity_withdraw( + self, coin: str, address: str, amount: float, questionnaire: str, **kwargs +): + """Withdraw (for local entities that require travel rule) (USER_DATA) + + Submit a withdrawal request for local entities that required travel rule. + + Weight(UID): 600 + + POST /sapi/v1/localentity/withdraw/apply + + https://developers.binance.com/docs/wallet/travel-rule/withdraw + + Args: + coin (str) + address (str) + amount (float) + questionnaire (str): Questionnaire ID + Keyword Args: + withdrawOrderId (str, optional): withdrawID defined by the client (i.e. client's internal withdrawID) + network (str, optional) + addressTag (str, optional): Secondary address identifier for coins like XRP,XMR etc. + transactionFeeFlag (bool, optional): 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. + name (str, optional): Description of the address. Address book cap is 200, space in name should be encoded into %20 + walletType (int, optional): The wallet type for withdraw, 0-spot wallet, 1-funding wallet. Default walletType is the current "selected wallet" under wallet->Fiat and Spot/Funding->Deposit + recvWindow (int, optional): The value cannot be greater than 60000 + """ + check_required_parameters( + [ + [coin, "coin"], + [address, "address"], + [amount, "amount"], + [questionnaire, "questionnaire"], + ] + ) + + payload = { + "coin": coin, + "address": address, + "amount": amount, + "questionnaire": questionnaire, + **kwargs, + } + return self.sign_request("POST", "/sapi/v1/localentity/withdraw/apply", payload) + + +def local_entity_withdraw_history(self, **kwargs): + """Withdraw History (for local entities that require travel rule) (supporting network) (USER_DATA) + + Fetch withdraw history for local entities that required travel rule. + + Weight(IP): 18000 Request limit: 10 requests per second + + GET /sapi/v1/localentity/withdraw/history + + https://developers.binance.com/docs/wallet/travel-rule/withdraw-history + + Keyword Args: + trId (str, optional): Separated list of travel rule record Ids + txId (str, optional): Separated list of transaction Ids + withdrawOrderId (str, optional): Separated list of withdrawID defined by the client (i.e. client's internal withdrawID). + network (str, optional) + coin (str, optional) + travelRuleStatus (int, optional): 0: Completed, 1: Pending, 2: Failed + offset (int, optional): Default: 0 + limit (int, optional): Default: 1000, Max: 1000 + startTime (int, optional): Default: 90 days from current timestamp + endTime (int, optional): Default: present timestamp + recvWindow (int, optional): The value cannot be greater than 60000 + """ + url_path = "/sapi/v1/localentity/withdraw/history" + return self.sign_request("GET", url_path, {**kwargs}) + + +def local_entity_submit_deposit_questionnaire( + self, tranId: int, questionnaire: str, **kwargs +): + """Submit Deposit Questionnaire (For local entities that require travel rule) (supporting network) (USER_DATA) + + Submit questionnaire for local entities that require travel rule. + The questionnaire is only applies to transactions from unhosted wallets or VASPs that are not yet onboarded with GTR. + + Weight(UID): 600 + + PUT /sapi/v1/localentity/deposit/provide-info + + https://developers.binance.com/docs/wallet/travel-rule/deposit-provide-info + + Args: + tranId (int): Wallet tran Id + questionnaire (str): JSON format questionnaire answers. + """ + check_required_parameters([[tranId, "tranId"], [questionnaire, "questionnaire"]]) + + payload = {"tranId": tranId, "questionnaire": questionnaire, **kwargs} + return self.sign_request( + "PUT", "/sapi/v1/localentity/deposit/provide-info", payload + ) + + +def local_entity_deposit_history(self, **kwargs): + """Deposit History (for local entities that required travel rule) (supporting network) (USER_DATA) + + Fetch deposit history for local entities that required travel rule. + + Weight(IP): 1 + + GET /sapi/v1/localentity/deposit/history + + https://developers.binance.com/docs/wallet/travel-rule/deposit-history + + Keyword Args: + trId (str, optional): Separated list of travel rule record Ids + txId (str, optional): Separated list of transaction Ids + tranId (str, optional): Separated list of wallet tran Ids + network (str, optional) + coin (str, optional) + travelRuleStatus (int, optional): 0: Completed, 1: Pending, 2: Failed + pendingQuestionnaire (bool, optional): true: Only return records that pending deposit questionnaire. false/not provided: return all records. + startTime (int, optional): Default: 90 days from current timestamp + endTime (int, optional): Default: present timestamp + offset (int, optional): Default: 0 + limit (int, optional): Default: 1000, Max: 1000 + """ + url_path = "/sapi/v1/localentity/deposit/history" + return self.sign_request("GET", url_path, {**kwargs}) + + def bnb_convertible_assets(self, **kwargs): """Get Assets That Can Be Converted Into BNB (USER_DATA) diff --git a/binance/websocket/spot/websocket_api/_market.py b/binance/websocket/spot/websocket_api/_market.py index c810579a..25dc99ca 100644 --- a/binance/websocket/spot/websocket_api/_market.py +++ b/binance/websocket/spot/websocket_api/_market.py @@ -550,6 +550,7 @@ def klines(self, symbol: str, interval: str, **kwargs): Keyword Args: startTime (int): start time to fetch from endTime (int): end time to fetch from + timeZone (str, optional): Default: 0 (UTC) limit (int): limit of klines Message sent: @@ -626,6 +627,7 @@ def ui_klines(self, symbol: str, interval: str, **kwargs): Keyword Args: startTime (int): start time to fetch from endTime (int): end time to fetch from + timeZone (str, optional): Default: 0 (UTC) limit (int): limit of klines Message sent: diff --git a/binance/websocket/spot/websocket_stream.py b/binance/websocket/spot/websocket_stream.py index ede1f4ad..6b7bf7e2 100644 --- a/binance/websocket/spot/websocket_stream.py +++ b/binance/websocket/spot/websocket_stream.py @@ -88,12 +88,44 @@ def kline(self, symbol: str, interval: str, id=None, action=None): - 1w - 1M - Update Speed: 2000ms + Update Speed: 1000ms for 1s, 2000ms for the other intervals """ stream_name = "{}@kline_{}".format(symbol.lower(), interval) self.send_message_to_server(stream_name, action=action, id=id) + def kline_timezone_offset(self, symbol: str, interval: str, id=None, action=None): + """Kline/Candlestick Streams with timezone offset + + The Kline/Candlestick Stream push updates to the current klines/candlestick every second in UTC+8 timezone + + @kline_@+08:00 + + interval: + m -> minutes; h -> hours; d -> days; w -> weeks; M -> months + + - 1m + - 3m + - 5m + - 15m + - 30m + - 1h + - 2h + - 4h + - 6h + - 8h + - 12h + - 1d + - 3d + - 1w + - 1M + + Update Speed: 1000ms for 1s, 2000ms for the other intervals + """ + stream_name = "{}@kline_{}@+08:00".format(symbol.lower(), interval) + + self.send_message_to_server(stream_name, action=action, id=id) + def mini_ticker(self, symbol=None, id=None, action=None, **kwargs): """Individual symbol or all symbols mini ticker diff --git a/docs/source/CHANGELOG.rst b/docs/source/CHANGELOG.rst index a04284ea..6ca5ed9f 100644 --- a/docs/source/CHANGELOG.rst +++ b/docs/source/CHANGELOG.rst @@ -2,6 +2,142 @@ Changelog ========= +3.10.0 - 2024-11-29 +------------------- + +Added +^^^^^ + +* Margin + + * ``POST /sapi/v1/margin/order/oto`` + * ``POST /sapi/v1/margin/order/otoco`` + +* Portfolio + + * ``GET /sapi/v2/portfolio/account`` + * ``GET /sapi/v1/portfolio/balance`` + * ``GET /sapi/v2/portfolio/collateralRate`` + +* Simple Earn + + * ``POST /sapi/v1/simple-earn/locked/setRedeemOption`` + +* Staking + + * ``GET /sapi/v2/eth-staking/account`` + * ``GET /sapi/v1/eth-staking/eth/quota`` + * ``POST /sapi/v2/eth-staking/eth/stake`` + * ``POST /sapi/v1/eth-staking/eth/redeem`` + * ``POST /sapi/v1/eth-staking/wbeth/wrap`` + * ``GET /sapi/v1/eth-staking/eth/history/stakingHistory`` + * ``GET /sapi/v1/eth-staking/eth/history/redemptionHistory`` + * ``GET /sapi/v1/eth-staking/eth/history/rewardsHistory`` + * ``GET /sapi/v1/eth-staking/eth/history/wbethRewardsHistory`` + * ``GET /sapi/v1/eth-staking/eth/history/rateHistory`` + * ``GET /sapi/v1/eth-staking/wbeth/history/wrapHistory`` + * ``GET /sapi/v1/eth-staking/wbeth/history/unwrapHistory`` + +* Wallet + + * ``POST /sapi/v1/localentity/withdraw/apply`` + * ``GET /sapi/v1/localentity/withdraw/history`` + * ``PUT /sapi/v1/localentity/deposit/provide-info`` + * ``GET /sapi/v1/localentity/deposit/history`` + +* Websocket Stream + + * ``kline_+08:00`` + +Updated +^^^^^^^ + +* Add parameters showPermissionSets and symbolStatus to `GET /api/v3/exchangeInfo` +* Add parameter timeZone to `GET /api/v3/klines`, `GET /api/v3/uiKlines`, `klines` and `uiKlines` +* Add parameter redeemTo to `POST /sapi/v1/simple-earn/locked/subscribe` +* Add parameters `txId` and `includeSource` to `GET /sapi/v1/capital/deposit/hisrec` +* Add parameter `idList` to `GET /sapi/v1/capital/withdraw/history` and `GET /sapi/v1/capital/deposit/subHisrec` +* Update Documentation +* Update `JSONDecodeError` error response + +Removed +^^^^^^^ + +* Crypto-loans + + * ``GET /sapi/v1/loan/collateral/data`` + * ``POST /sapi/v1/loan/borrow`` + * ``POST /sapi/v1/loan/repay`` + * ``POST /sapi/v1/loan/adjust/ltv`` + * ``POST /sapi/v1/loan/customize/margin_call`` + * ``GET /sapi/v1/loan/ongoing/orders`` + +3.9.0 - 2024-10-02 +------------------ + +Removed +^^^^^^^ + +* Futures + + * ``POST /sapi/v1/futures/transfer`` + * ``GET /sapi/v1/futures/transfer`` + +* BLVT + + * ``GET /sapi/v1/blvt/tokenInfo`` + * ``POST /sapi/v1/blvt/subscribe`` + * ``GET /sapi/v1/blvt/subscribe/record`` + * ``POST /sapi/v1/blvt/redeem`` + * ``GET /sapi/v1/blvt/redeem/record`` + * ``GET /sapi/v1/blvt/userLimit`` + +* Wallet + + * ``POST /sapi/v1/asset/convert-transfer`` + * ``GET /sapi/v1/asset/convert-transfer/queryByPage`` + * ``GET /sapi/v1/capital/contract/convertible-coins`` + * ``POST /sapi/v1/capital/contract/convertible-coins`` + +3.8.1 - 2024-07-25 +------------------ + +Added +^^^^^ + +* ``.readthedocs.yml`` to resolve documentation issue + +Changed +^^^^^^^ + +* ``GET /api/v3/account`` has a new optional parameter ``omitZeroBalances``, which if enabled hides all zero balances. +* ``POST /api/v3/order/cancelReplace`` has a new optional parameter ``orderRateLimitExceededMode``. + +3.8.0 - 2024-07-04 +------------------ + +Added +^^^^^ + +* Trade + + * Spot + + * ``POST /api/v3/orderList/oto`` + * ``POST /api/v3/orderList/otoco`` + + * Websocket API + + * ``orderList.place.oto`` + * ``orderList.place.otoco`` + +Updated +^^^^^^^ + +* Updated and Resolved documentation issue +* Updated `Restful` OCO trade deprecated endpoint `POST /api/v3/order/oco` to `POST /api/v3/orderList/oco` +* Updated `Websocket API` OCO trade deprecated endpoint `orderList.place` to `orderList.place.oco` + 3.7.0 - 2024-05-03 ------------------ diff --git a/docs/source/binance.spot.crypto_loan.rst b/docs/source/binance.spot.crypto_loan.rst index c7f57594..65fb9d8c 100644 --- a/docs/source/binance.spot.crypto_loan.rst +++ b/docs/source/binance.spot.crypto_loan.rst @@ -5,30 +5,14 @@ Get Crypto Loans Income History (USER_DATA) ------------------------------------------- .. autofunction:: binance.spot.Spot.loan_history -Crypto Loan Borrow (TRADE) --------------------------- -.. autofunction:: binance.spot.Spot.loan_borrow - Get Loan Borrow History (USER_DATA) ----------------------------------- .. autofunction:: binance.spot.Spot.loan_borrow_history -Get Loan Ongoing Orders (USER_DATA) ------------------------------------ -.. autofunction:: binance.spot.Spot.loan_ongoing_orders - -Crypto Loan Repay (TRADE) -------------------------- -.. autofunction:: binance.spot.Spot.loan_repay - Get Loan Repayment History (USER_DATA) -------------------------------------- .. autofunction:: binance.spot.Spot.loan_repay_history -Crypto Loan Adjust LTV (TRADE) ------------------------------- -.. autofunction:: binance.spot.Spot.loan_adjust_ltv - Get Loan LTV Adjustment History (USER_DATA) ------------------------------------------- .. autofunction:: binance.spot.Spot.loan_adjust_ltv_history @@ -53,14 +37,6 @@ Get Loanable Assets Data (USER_DATA) ------------------------------------ .. autofunction:: binance.spot.Spot.loan_loanable_data -Get Collateral Assets Data (USER_DATA) --------------------------------------- -.. autofunction:: binance.spot.Spot.loan_collateral_data - Check Collateral Repay Rate (USER_DATA) --------------------------------------- .. autofunction:: binance.spot.Spot.loan_collateral_rate - -Customize margin call for ongoing orders only. (USER_DATA) ----------------------------------------------------------- -.. autofunction:: binance.spot.Spot.loan_customize_margin_call diff --git a/docs/source/binance.spot.margin.rst b/docs/source/binance.spot.margin.rst index 9f9f9326..0796a70f 100644 --- a/docs/source/binance.spot.margin.rst +++ b/docs/source/binance.spot.margin.rst @@ -173,6 +173,14 @@ Margin manual liquidation (MARGIN) ---------------------------------- .. autofunction:: binance.spot.Spot.margin_manual_liquidation +Margin Account New OTO (TRADE) +------------------------------ +.. autofunction:: binance.spot.Spot.margin_new_oto_order + +Margin Account New OTOCO (TRADE) +-------------------------------- +.. autofunction:: binance.spot.Spot.margin_new_otoco_order + Query Liability Coin Leverage Bracket in Cross Margin Pro Mode(MARKET_DATA) --------------------------------------------------------------------------- .. autofunction:: binance.spot.Spot.liability_coin_leverage_bracket diff --git a/docs/source/binance.spot.portfolio_margin.rst b/docs/source/binance.spot.portfolio_margin.rst index 9fb0aa7d..bacde26f 100644 --- a/docs/source/binance.spot.portfolio_margin.rst +++ b/docs/source/binance.spot.portfolio_margin.rst @@ -9,6 +9,10 @@ Portfolio Margin Collateral Rate (MARKET_DATA) ---------------------------------------------- .. autofunction:: binance.spot.Spot.portfolio_margin_collateral_rate +Portfolio Margin Pro Tiered Collateral Rate (USER_DATA) +------------------------------------------------------- +.. autofunction:: binance.spot.Spot.portfolio_margin_tiered_collateral_rate + Portfolio Margin Bankruptcy Loan Amount (USER_DATA) --------------------------------------------------- .. autofunction:: binance.spot.Spot.portfolio_margin_bankruptcy_loan_amount @@ -21,6 +25,14 @@ Query Classic Portfolio Margin Negative Balance Interest History (USER_DATA) ---------------------------------------------------------------------------- .. autofunction:: binance.spot.Spot.query_classic_portfolio_margin_negative_balance_interest_history +Get Portfolio Margin Pro SPAN Account Info (USER_DATA) +------------------------------------------------------ +.. autofunction:: binance.spot.Spot.get_portfolio_margin_span_account_info + +Get Portfolio Margin Pro Account Balance (USER_DATA) +---------------------------------------------------- +.. autofunction:: binance.spot.Spot.get_portfolio_margin_account_balance + Query Portfolio Margin Asset Index Price (MARKET_DATA) ------------------------------------------------------ .. autofunction:: binance.spot.Spot.query_portfolio_margin_asset_index_price diff --git a/docs/source/binance.spot.rst b/docs/source/binance.spot.rst index 746ab69a..b463fea7 100644 --- a/docs/source/binance.spot.rst +++ b/docs/source/binance.spot.rst @@ -18,6 +18,7 @@ Spot APIs binance.spot.pay binance.spot.portfolio_margin binance.spot.rebate + binance.spot.staking binance.spot.sub_account binance.spot.trade binance.spot.wallet diff --git a/docs/source/binance.spot.simple_earn.rst b/docs/source/binance.spot.simple_earn.rst index 3b0d52f5..9c687320 100644 --- a/docs/source/binance.spot.simple_earn.rst +++ b/docs/source/binance.spot.simple_earn.rst @@ -85,6 +85,10 @@ Get Locked Subscription Preview (USER_DATA) ------------------------------------------- .. autofunction:: binance.spot.Spot.get_locked_subscription_preview +Set Locked Product Redeem Option (USER_DATA) +-------------------------------------------- +.. autofunction:: binance.spot.Spot.set_locked_product_redeem_option + Get Rate History (USER_DATA) ---------------------------- .. autofunction:: binance.spot.Spot.get_rate_history diff --git a/docs/source/binance.spot.staking.rst b/docs/source/binance.spot.staking.rst new file mode 100644 index 00000000..42a7ac7f --- /dev/null +++ b/docs/source/binance.spot.staking.rst @@ -0,0 +1,50 @@ +Staking Endpoints +===================== + +ETH Staking account (USER_DATA) +------------------------------- +.. autofunction:: binance.spot.Spot.eth_staking_account + +Get current ETH staking quota (USER_DATA) +----------------------------------------- +.. autofunction:: binance.spot.Spot.get_eth_staking_quota + +Subscribe ETH Staking (TRADE) +----------------------------- +.. autofunction:: binance.spot.Spot.subscribe_eth_staking + +Redeem ETH (TRADE) +------------------ +.. autofunction:: binance.spot.Spot.redeem_eth + +Wrap BETH (TRADE) +----------------- +.. autofunction:: binance.spot.Spot.wrap_beth + +Get ETH staking history (USER_DATA) +----------------------------------- +.. autofunction:: binance.spot.Spot.get_eth_staking_history + +Get ETH redemption history (USER_DATA) +-------------------------------------- +.. autofunction:: binance.spot.Spot.get_eth_redemption_history + +Get BETH rewards distribution history (USER_DATA) (USER_DATA) +------------------------------------------------------------- +.. autofunction:: binance.spot.Spot.get_beth_rewards_distribution_history + +Get WBETH rewards history (USER_DATA) +------------------------------------- +.. autofunction:: binance.spot.Spot.get_wbeth_rewards_history + +Get WBETH Rate History (USER_DATA) +---------------------------------- +.. autofunction:: binance.spot.Spot.get_wbeth_rate_history + +Get WBETH wrap history (USER_DATA) +---------------------------------- +.. autofunction:: binance.spot.Spot.get_wbeth_wrap_history + +Get WBETH unwrap history (USER_DATA) +------------------------------------ +.. autofunction:: binance.spot.Spot.get_wbeth_unwrap_history diff --git a/docs/source/binance.spot.wallet.rst b/docs/source/binance.spot.wallet.rst index 0acdaa73..228541f8 100644 --- a/docs/source/binance.spot.wallet.rst +++ b/docs/source/binance.spot.wallet.rst @@ -85,6 +85,22 @@ API Key Permission (USER_DATA) ------------------------------ .. autofunction:: binance.spot.Spot.api_key_permissions +Withdraw (for local entities that require travel rule) (USER_DATA) +------------------------------------------------------------------ +.. autofunction:: binance.spot.Spot.local_entity_withdraw + +Withdraw History (for local entities that require travel rule) (supporting network) (USER_DATA) +----------------------------------------------------------------------------------------------- +.. autofunction:: binance.spot.Spot.local_entity_withdraw_history + +Submit Deposit Questionnaire (For local entities that require travel rule) (supporting network) (USER_DATA) +----------------------------------------------------------------------------------------------------------- +.. autofunction:: binance.spot.Spot.local_entity_submit_deposit_questionnaire + +Deposit History (for local entities that required travel rule) (supporting network) (USER_DATA) +----------------------------------------------------------------------------------------------- +.. autofunction:: binance.spot.Spot.local_entity_deposit_history + Get Assets That Can Be Converted Into BNB (USER_DATA) ----------------------------------------------------- .. autofunction:: binance.spot.Spot.bnb_convertible_assets diff --git a/docs/source/binance.websocket_stream.spot.rst b/docs/source/binance.websocket_stream.spot.rst index 71bec4b8..92c6b3f5 100644 --- a/docs/source/binance.websocket_stream.spot.rst +++ b/docs/source/binance.websocket_stream.spot.rst @@ -14,6 +14,10 @@ Kline/Candlestick Streams ------------------------- .. autofunction:: binance.websocket.spot.websocket_stream.SpotWebsocketStreamClient.kline +Kline/Candlestick Streams with timezone offset +---------------------------------------------- +.. autofunction:: binance.websocket.spot.websocket_stream.SpotWebsocketStreamClient.kline_timezone_offset + Individual symbol or all symbols mini ticker -------------------------------------------- .. autofunction:: binance.websocket.spot.websocket_stream.SpotWebsocketStreamClient.mini_ticker diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index 5a4e1fe9..9d66f0b1 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -58,7 +58,7 @@ Usage example: response = client.new_order(**params) print(response) -Please find `examples `_ folder to check for more endpoints. +Please find `examples `_ folder to check for more endpoints. Base URL """""""" @@ -111,6 +111,15 @@ Anything beyond the limit will result in an error response from Binance server. Websocket ^^^^^^^^^ +Websocket can be established through either of the following types of connections: + +* Websocket API (``https://github.com/binance/binance-spot-api-docs/blob/master/web-socket-api.md``) +* Websocket Stream (``https://github.com/binance/binance-spot-api-docs/blob/master/web-socket-streams.md``) + + +Websocket API +""""""""""""" + Usage example: .. code-block:: python @@ -118,8 +127,11 @@ Usage example: import logging from binance.websocket.spot.websocket_api import SpotWebsocketAPIClient + def on_close(_): + logging.info("Do custom stuff when connection is closed") + def message_handler(message): - print(message) + logging.info(message) ws_client = SpotWebsocketAPIClient(on_message=message_handler, on_close=on_close) @@ -137,8 +149,33 @@ Usage example: ws_client.stop() +The ``stream_url`` defaults to ``wss://ws-api.binance.com/ws-api/v3``. +More websocket API examples are available in the `examples websocket api `_ folder. + + +Websocket Stream +"""""""""""""""" + +Usage example: + +.. code-block:: python + + import logging + from binance.websocket.spot.websocket_stream import SpotWebsocketStreamClient as Client + + def message_handler(message): + logging.info(message) + + ws_client = Client(on_message=message_handler) + + ws_client.ticker(symbol="bnbusdt") + + logging.debug("closing ws connection") + ws_client.stop() + The ``stream_url`` defaults to ``wss://stream.binance.com:9443``. -More websocket examples are available in the `examples `_ folder. +More websocket Stream examples are available in the `websocket stream examples `_ folder. + Heartbeat """"""""" diff --git a/examples/spot/loan/loan_adjust_ltv.py b/examples/spot/loan/loan_adjust_ltv.py deleted file mode 100644 index dc37e422..00000000 --- a/examples/spot/loan/loan_adjust_ltv.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python - -import logging -from binance.spot import Spot as Client -from binance.lib.utils import config_logging -from examples.utils.prepare_env import get_api_key - -config_logging(logging, logging.DEBUG) - -api_key, api_secret = get_api_key() - - -client = Client(api_key, api_secret) -logging.info( - client.loan_adjust_ltv( - orderId=756783308056935434, amount=5.235, direction="ADDITIONAL" - ) -) diff --git a/examples/spot/loan/loan_borrow.py b/examples/spot/loan/loan_borrow.py deleted file mode 100644 index 8f03d7a0..00000000 --- a/examples/spot/loan/loan_borrow.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python - -import logging -from binance.spot import Spot as Client -from binance.lib.utils import config_logging -from examples.utils.prepare_env import get_api_key - -config_logging(logging, logging.DEBUG) - -api_key, api_secret = get_api_key() - - -client = Client(api_key, api_secret) -logging.info( - client.loan_borrow( - loanCoin="USDT", collateralCoin="BUSD", loanTerm=7, loanAmount=1.1 - ) -) diff --git a/examples/spot/loan/loan_collateral_data.py b/examples/spot/loan/loan_collateral_data.py deleted file mode 100644 index aec43d46..00000000 --- a/examples/spot/loan/loan_collateral_data.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python - -import logging -from binance.spot import Spot as Client -from binance.lib.utils import config_logging -from examples.utils.prepare_env import get_api_key - -config_logging(logging, logging.DEBUG) - -api_key, api_secret = get_api_key() - - -client = Client(api_key, api_secret) -logging.info(client.loan_collateral_data(collateralCoin="BUSD")) diff --git a/examples/spot/loan/loan_customize_margin_call.py b/examples/spot/loan/loan_customize_margin_call.py deleted file mode 100644 index 484f831f..00000000 --- a/examples/spot/loan/loan_customize_margin_call.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python - -import logging -from binance.spot import Spot as Client -from binance.lib.utils import config_logging -from examples.utils.prepare_env import get_api_key - -config_logging(logging, logging.DEBUG) - -api_key, api_secret = get_api_key() - - -client = Client(api_key, api_secret) -logging.info(client.loan_customize_margin_call(marginCall=0.1, collateralCoin="USDT")) diff --git a/examples/spot/loan/loan_ongoing_orders.py b/examples/spot/loan/loan_ongoing_orders.py deleted file mode 100644 index 2bba2309..00000000 --- a/examples/spot/loan/loan_ongoing_orders.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python - -import logging -from binance.spot import Spot as Client -from binance.lib.utils import config_logging -from examples.utils.prepare_env import get_api_key - -config_logging(logging, logging.DEBUG) - -api_key, api_secret = get_api_key() - - -client = Client(api_key, api_secret) -logging.info(client.loan_ongoing_orders(loanCoin="USDT")) diff --git a/examples/spot/loan/loan_repay.py b/examples/spot/loan/loan_repay.py deleted file mode 100644 index 31310c32..00000000 --- a/examples/spot/loan/loan_repay.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python - -import logging -from binance.spot import Spot as Client -from binance.lib.utils import config_logging -from examples.utils.prepare_env import get_api_key - -config_logging(logging, logging.DEBUG) - -api_key, api_secret = get_api_key() - - -client = Client(api_key, api_secret) -logging.info(client.loan_repay(orderId=100000001, amount=100.5)) diff --git a/examples/spot/margin/margin_new_oto_order.py b/examples/spot/margin/margin_new_oto_order.py new file mode 100644 index 00000000..6fb2329c --- /dev/null +++ b/examples/spot/margin/margin_new_oto_order.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) +logging.info( + client.margin_new_oto_order( + symbol="BNBUSDT", + workingType="LIMIT", + workingSide="SELL", + workingPrice=600.0, + workingQuantity=1.0, + pendingType="LIMIT", + pendingSide="BUY", + pendingQuantity=1.0, + workingTimeInForce="GTC", + pendingPrice=595.0, + pendingTimeInForce="GTC", + workingIcebergQty=0.1, + ) +) diff --git a/examples/spot/margin/margin_new_otoco_order.py b/examples/spot/margin/margin_new_otoco_order.py new file mode 100644 index 00000000..356ecc8a --- /dev/null +++ b/examples/spot/margin/margin_new_otoco_order.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) +logging.info( + client.margin_new_otoco_order( + symbol="BNBUSDT", + workingType="LIMIT", + workingSide="BUY", + workingPrice=600.0, + workingQuantity=1.0, + pendingSide="SELL", + pendingQuantity=1.0, + pendingAboveType="LIMIT_MAKER", + workingTimeInForce="GTC", + pendingAbovePrice=605.0, + pendingBelowType="LIMIT_MAKER", + pendingBelowPrice=595.0, + workingIcebergQty=0.1, + ) +) diff --git a/examples/spot/portfolio_margin/get_portfolio_margin_account_balance.py b/examples/spot/portfolio_margin/get_portfolio_margin_account_balance.py new file mode 100644 index 00000000..5ef0b5f1 --- /dev/null +++ b/examples/spot/portfolio_margin/get_portfolio_margin_account_balance.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.get_portfolio_margin_account_balance(recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/portfolio_margin/get_portfolio_margin_span_account_info.py b/examples/spot/portfolio_margin/get_portfolio_margin_span_account_info.py new file mode 100644 index 00000000..c8ba27b7 --- /dev/null +++ b/examples/spot/portfolio_margin/get_portfolio_margin_span_account_info.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.get_portfolio_margin_span_account_info(recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/portfolio_margin/portfolio_margin_tiered_collateral_rate.py b/examples/spot/portfolio_margin/portfolio_margin_tiered_collateral_rate.py new file mode 100644 index 00000000..621bfebc --- /dev/null +++ b/examples/spot/portfolio_margin/portfolio_margin_tiered_collateral_rate.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.portfolio_margin_tiered_collateral_rate(recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/simple_earn/set_locked_product_redeem_option.py b/examples/spot/simple_earn/set_locked_product_redeem_option.py new file mode 100644 index 00000000..e2cae9b3 --- /dev/null +++ b/examples/spot/simple_earn/set_locked_product_redeem_option.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.set_locked_product_redeem_option( + "product_001", "SPOT", recvWindow=5000 + ) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/staking/eth_staking_account.py b/examples/spot/staking/eth_staking_account.py new file mode 100644 index 00000000..b8ffea4e --- /dev/null +++ b/examples/spot/staking/eth_staking_account.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.eth_staking_account(recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/staking/get_beth_rewards_distribution_history.py b/examples/spot/staking/get_beth_rewards_distribution_history.py new file mode 100644 index 00000000..c0492f1d --- /dev/null +++ b/examples/spot/staking/get_beth_rewards_distribution_history.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.get_beth_rewards_distribution_history(recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/staking/get_eth_redemption_history.py b/examples/spot/staking/get_eth_redemption_history.py new file mode 100644 index 00000000..6a047a7a --- /dev/null +++ b/examples/spot/staking/get_eth_redemption_history.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.get_eth_redemption_history(recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/staking/get_eth_staking_history.py b/examples/spot/staking/get_eth_staking_history.py new file mode 100644 index 00000000..0bee79ba --- /dev/null +++ b/examples/spot/staking/get_eth_staking_history.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.get_eth_staking_history(recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/staking/get_eth_staking_quota.py b/examples/spot/staking/get_eth_staking_quota.py new file mode 100644 index 00000000..a2626fc6 --- /dev/null +++ b/examples/spot/staking/get_eth_staking_quota.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.get_eth_staking_quota(recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/staking/get_wbeth_rate_history.py b/examples/spot/staking/get_wbeth_rate_history.py new file mode 100644 index 00000000..f773e9af --- /dev/null +++ b/examples/spot/staking/get_wbeth_rate_history.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.get_wbeth_rate_history(recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/staking/get_wbeth_rewards_history.py b/examples/spot/staking/get_wbeth_rewards_history.py new file mode 100644 index 00000000..26d80313 --- /dev/null +++ b/examples/spot/staking/get_wbeth_rewards_history.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.get_wbeth_rewards_history(recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/staking/get_wbeth_unwrap_history.py b/examples/spot/staking/get_wbeth_unwrap_history.py new file mode 100644 index 00000000..be1d05b4 --- /dev/null +++ b/examples/spot/staking/get_wbeth_unwrap_history.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.get_wbeth_unwrap_history(recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/staking/get_wbeth_wrap_history.py b/examples/spot/staking/get_wbeth_wrap_history.py new file mode 100644 index 00000000..7d4489cf --- /dev/null +++ b/examples/spot/staking/get_wbeth_wrap_history.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.get_wbeth_wrap_history(recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/staking/redeem_eth.py b/examples/spot/staking/redeem_eth.py new file mode 100644 index 00000000..b4e75858 --- /dev/null +++ b/examples/spot/staking/redeem_eth.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.redeem_eth(amount=1.0, recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/staking/subscribe_eth_staking.py b/examples/spot/staking/subscribe_eth_staking.py new file mode 100644 index 00000000..623213e5 --- /dev/null +++ b/examples/spot/staking/subscribe_eth_staking.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.subscribe_eth_staking(amount=1.0, recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/staking/wrap_beth.py b/examples/spot/staking/wrap_beth.py new file mode 100644 index 00000000..699ce360 --- /dev/null +++ b/examples/spot/staking/wrap_beth.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.wrap_beth(amount=1.0, recvWindow=5000) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/wallet/local_entity_deposit_history.py b/examples/spot/wallet/local_entity_deposit_history.py new file mode 100644 index 00000000..d7a46a91 --- /dev/null +++ b/examples/spot/wallet/local_entity_deposit_history.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.local_entity_deposit_history(trId="1234", coin="BNB") + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/wallet/local_entity_submit_deposit_questionnaire.py b/examples/spot/wallet/local_entity_submit_deposit_questionnaire.py new file mode 100644 index 00000000..33fa9953 --- /dev/null +++ b/examples/spot/wallet/local_entity_submit_deposit_questionnaire.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.local_entity_submit_deposit_questionnaire( + tranId="1234", questionnaire='{"depositOriginator": 1}' + ) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/wallet/local_entity_withdraw.py b/examples/spot/wallet/local_entity_withdraw.py new file mode 100644 index 00000000..995c926c --- /dev/null +++ b/examples/spot/wallet/local_entity_withdraw.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.local_entity_withdraw( + coin="BNB", + address="address", + amount=0.1, + questionnaire='{"isAddressOwner": true}', + ) + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/spot/wallet/local_entity_withdraw_history.py b/examples/spot/wallet/local_entity_withdraw_history.py new file mode 100644 index 00000000..1f1a9e8d --- /dev/null +++ b/examples/spot/wallet/local_entity_withdraw_history.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +import logging +from binance.spot import Spot as Client +from binance.lib.utils import config_logging +from binance.error import ClientError + +from examples.utils.prepare_env import get_api_key + +config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +api_key, api_secret = get_api_key() + +client = Client(api_key, api_secret) + +try: + response = client.local_entity_withdraw_history(trId="1234", coin="USDT") + logger.info(response) +except ClientError as error: + logger.error( + "Found error. status: {}, error code: {}, error message: {}".format( + error.status_code, error.error_code, error.error_message + ) + ) diff --git a/examples/utils/__init__.py b/examples/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/examples/websocket/spot/websocket_stream/symbol_kline_timezone_offset.py b/examples/websocket/spot/websocket_stream/symbol_kline_timezone_offset.py new file mode 100644 index 00000000..b5340cb8 --- /dev/null +++ b/examples/websocket/spot/websocket_stream/symbol_kline_timezone_offset.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python + +import time +import logging +from binance.lib.utils import config_logging +from binance.websocket.spot.websocket_stream import SpotWebsocketStreamClient + +config_logging(logging, logging.DEBUG) + + +def message_handler(_, message): + logging.info(message) + + +my_client = SpotWebsocketStreamClient( + on_message=message_handler, + is_combined=True, + timeout=2, + proxies={"https": "http://1.2.3.4:8080"}, +) + + +# subscribe btcusdt 1m kline +my_client.kline_timezone_offset(symbol="btcusdt", interval="1m") + +time.sleep(5) + +# subscribe ethusdt 3m kline +my_client.kline_timezone_offset(symbol="ethusdt", interval="3m") + +time.sleep(10) + +# unsubscribe btcusdt 1m kline +my_client.kline_timezone_offset( + symbol="btcusdt", interval="1m", action=SpotWebsocketStreamClient.ACTION_UNSUBSCRIBE +) + +time.sleep(5) + +logging.debug("closing ws connection") +my_client.stop() diff --git a/tests/spot/loan/test_loan_adjust_ltv.py b/tests/spot/loan/test_loan_adjust_ltv.py deleted file mode 100644 index 5a98cecf..00000000 --- a/tests/spot/loan/test_loan_adjust_ltv.py +++ /dev/null @@ -1,58 +0,0 @@ -import responses - -from urllib.parse import urlencode -from tests.util import random_str -from tests.util import mock_http_response -from binance.spot import Spot as Client -from binance.error import ParameterRequiredError - -mock_item = {"key_1": "value_1", "key_2": "value_2"} - -key = random_str() -secret = random_str() -client = Client(key, secret) - -params = {"orderId": 756783308056935434, "amount": 100.1, "direction": "ADDITIONAL"} - - -def test_loan_adjust_ltv_without_orderId(): - """Tests the API endpoint to adjust LTV without orderId""" - - params = {"orderId": "", "amount": 100.1, "direction": "ADDITIONAL"} - - client.loan_adjust_ltv.when.called_with(**params).should.throw( - ParameterRequiredError - ) - - -def test_loan_adjust_ltv_without_amount(): - """Tests the API endpoint to adjust LTV without amount""" - - params = {"orderId": 756783308056935434, "amount": "", "direction": "ADDITIONAL"} - - client.loan_adjust_ltv.when.called_with(**params).should.throw( - ParameterRequiredError - ) - - -def test_loan_adjust_ltv_without_direction(): - """Tests the API endpoint to adjust LTV without direction""" - - params = {"orderId": 756783308056935434, "amount": 100.1, "direction": ""} - - client.loan_adjust_ltv.when.called_with(**params).should.throw( - ParameterRequiredError - ) - - -@mock_http_response( - responses.POST, - "/sapi/v1/loan/adjust/ltv\\?" + urlencode(params), - mock_item, - 200, -) -def test_loan_adjust_ltv(): - """Tests the API endpoint to adjust LTV""" - - response = client.loan_adjust_ltv(**params) - response.should.equal(mock_item) diff --git a/tests/spot/loan/test_loan_borrow.py b/tests/spot/loan/test_loan_borrow.py deleted file mode 100644 index 9f2c264f..00000000 --- a/tests/spot/loan/test_loan_borrow.py +++ /dev/null @@ -1,62 +0,0 @@ -import responses - -from urllib.parse import urlencode -from tests.util import random_str -from tests.util import mock_http_response -from binance.spot import Spot as Client -from binance.error import ParameterRequiredError - -mock_item = {"key_1": "value_1", "key_2": "value_2"} -mock_exception = {"code": -1105, "msg": "error message."} - -key = random_str() -secret = random_str() -client = Client(key, secret) - -params = {"loanCoin": "BUSD", "collateralCoin": "BNB", "loanTerm": 7} - - -def test_loan_borrow_without_loanCoin(): - """Tests the API endpoint to borrow loan without loanCoin""" - - params = {"loanCoin": "", "collateralCoin": "BNB", "loanTerm": 7} - - client.loan_borrow.when.called_with(**params).should.throw(ParameterRequiredError) - - -def test_loan_borrow_without_collateralCoin(): - """Tests the API endpoint to borrow loan without collateralCoin""" - - params = { - "loanCoin": "USDT", - "collateralCoin": "", - "loanTerm": 7, - } - - client.loan_borrow.when.called_with(**params).should.throw(ParameterRequiredError) - - -def test_loan_borrow_without_loanTerm(): - """Tests the API endpoint to borrow loan without loanTerm""" - - params = { - "loanCoin": "USDT", - "collateralCoin": "BNB", - "loanTerm": "", - "loanAmount": 1.1, - } - - client.loan_borrow.when.called_with(**params).should.throw(ParameterRequiredError) - - -@mock_http_response( - responses.POST, - "/sapi/v1/loan/borrow\\?" + urlencode(params), - mock_item, - 200, -) -def test_loan_borrow(): - """Tests the API endpoint to loan""" - - response = client.loan_borrow(**params) - response.should.equal(mock_item) diff --git a/tests/spot/loan/test_loan_collateral_data.py b/tests/spot/loan/test_loan_collateral_data.py deleted file mode 100644 index 62749a4a..00000000 --- a/tests/spot/loan/test_loan_collateral_data.py +++ /dev/null @@ -1,27 +0,0 @@ -import responses - -from urllib.parse import urlencode -from tests.util import random_str -from tests.util import mock_http_response -from binance.spot import Spot as Client - -mock_item = {"key_1": "value_1", "key_2": "value_2"} - -key = random_str() -secret = random_str() -client = Client(key, secret) - -params = {"collateralCoin": "BUSD", "vipLevel": 1} - - -@mock_http_response( - responses.GET, - "/sapi/v1/loan/collateral/data\\?" + urlencode(params), - mock_item, - 200, -) -def test_loan_collateral_data(): - """Tests the API endpoint to get collateral asset data""" - - response = client.loan_collateral_data(**params) - response.should.equal(mock_item) diff --git a/tests/spot/loan/test_loan_customize_margin_call.py b/tests/spot/loan/test_loan_customize_margin_call.py deleted file mode 100644 index 958266b1..00000000 --- a/tests/spot/loan/test_loan_customize_margin_call.py +++ /dev/null @@ -1,38 +0,0 @@ -import responses - -from urllib.parse import urlencode -from tests.util import random_str -from tests.util import mock_http_response -from binance.spot import Spot as Client -from binance.error import ParameterRequiredError - -mock_item = {"key_1": "value_1", "key_2": "value_2"} - -key = random_str() -secret = random_str() -client = Client(key, secret) - -params = {"marginCall": 0.1, "collateralCoin": "BUSD"} - - -def test_loan_customize_margin_call_without_margin_call(): - """Tests the API endpoint to customize margin call with missing parameter""" - - params = {"marginCall": ""} - - client.loan_customize_margin_call.when.called_with(**params).should.throw( - ParameterRequiredError - ) - - -@mock_http_response( - responses.POST, - "/sapi/v1/loan/customize/margin_call\\?" + urlencode(params), - mock_item, - 200, -) -def test_loan_customize_margin_call(): - """Tests the API endpoint to customize margin call for ongoing orders only""" - - response = client.loan_customize_margin_call(**params) - response.should.equal(mock_item) diff --git a/tests/spot/loan/test_loan_ongoing_orders.py b/tests/spot/loan/test_loan_ongoing_orders.py deleted file mode 100644 index 28d94de1..00000000 --- a/tests/spot/loan/test_loan_ongoing_orders.py +++ /dev/null @@ -1,24 +0,0 @@ -import responses - -from tests.util import random_str -from tests.util import mock_http_response -from binance.spot import Spot as Client - -mock_item = {"key_1": "value_1", "key_2": "value_2"} - -key = random_str() -secret = random_str() -client = Client(key, secret) - - -@mock_http_response( - responses.GET, - "/sapi/v1/loan/ongoing/orders\\?loanCoin=BUSD", - mock_item, - 200, -) -def test_loan_ongoing_orders(): - """Tests the API endpoint to get loan borrow ongoing orders""" - - response = client.loan_ongoing_orders(loanCoin="BUSD") - response.should.equal(mock_item) diff --git a/tests/spot/loan/test_loan_repay.py b/tests/spot/loan/test_loan_repay.py deleted file mode 100644 index 1a6421f3..00000000 --- a/tests/spot/loan/test_loan_repay.py +++ /dev/null @@ -1,47 +0,0 @@ -import responses - -from urllib.parse import urlencode -from tests.util import random_str -from tests.util import mock_http_response -from binance.spot import Spot as Client -from binance.error import ParameterRequiredError - -mock_item = {"key_1": "value_1", "key_2": "value_2"} - -key = random_str() -secret = random_str() -client = Client(key, secret) - -params = {"orderId": 100000001, "amount": 100.5} - - -def test_loan_repay_without_orderId(): - """Tests the API endpoint to repay loan without orderId""" - - params = {"orderId": "", "amount": 100.5} - - client.loan_repay.when.called_with(**params).should.throw(ParameterRequiredError) - - -def test_loan_repay_without_amount(): - """Tests the API endpoint to repay loan without amount""" - - params = { - "orderId": "USDT", - "amount": "", - } - - client.loan_repay.when.called_with(**params).should.throw(ParameterRequiredError) - - -@mock_http_response( - responses.POST, - "/sapi/v1/loan/repay\\?" + urlencode(params), - mock_item, - 200, -) -def test_loan_repay(): - """Tests the API endpoint to repay loan""" - - response = client.loan_repay(**params) - response.should.equal(mock_item) diff --git a/tests/spot/margin/test_margin_new_oto_order.py b/tests/spot/margin/test_margin_new_oto_order.py new file mode 100644 index 00000000..34f2d568 --- /dev/null +++ b/tests/spot/margin/test_margin_new_oto_order.py @@ -0,0 +1,55 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = { + "symbol": "BNBUSDT", + "workingType": "LIMIT", + "workingSide": "SELL", + "workingPrice": 600.0, + "workingQuantity": 1.0, + "pendingType": "LIMIT", + "pendingSide": "BUY", + "pendingQuantity": 1.0, + "workingTimeInForce": "GTC", + "pendingPrice": 595.0, + "pendingTimeInForce": "GTC", + "workingIcebergQty": 0.1, +} +expected_params = { + "symbol": "BNBUSDT", + "workingType": "LIMIT", + "workingSide": "SELL", + "workingPrice": 600.0, + "workingQuantity": 1.0, + "pendingType": "LIMIT", + "pendingSide": "BUY", + "pendingQuantity": 1.0, + "workingTimeInForce": "GTC", + "pendingPrice": 595.0, + "pendingTimeInForce": "GTC", + "workingIcebergQty": 0.1, +} + + +@mock_http_response( + responses.POST, + "/sapi/v1/margin/order/oto\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_margin_new_oto_order(): + """Tests the API endpoint to post a new margin oto order""" + + client = Client(key, secret) + response = client.margin_new_oto_order(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/margin/test_margin_new_otoco_order.py b/tests/spot/margin/test_margin_new_otoco_order.py new file mode 100644 index 00000000..b3d33372 --- /dev/null +++ b/tests/spot/margin/test_margin_new_otoco_order.py @@ -0,0 +1,57 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = { + "symbol": "BNBUSDT", + "workingType": "LIMIT", + "workingSide": "BUY", + "workingPrice": 600.0, + "workingQuantity": 1.0, + "pendingSide": "SELL", + "pendingQuantity": 1.0, + "pendingAboveType": "LIMIT_MAKER", + "workingTimeInForce": "GTC", + "pendingAbovePrice": 605.0, + "pendingBelowType": "LIMIT_MAKER", + "pendingBelowPrice": 595.0, + "workingIcebergQty": 0.1, +} +expected_params = { + "symbol": "BNBUSDT", + "workingType": "LIMIT", + "workingSide": "BUY", + "workingPrice": 600.0, + "workingQuantity": 1.0, + "pendingSide": "SELL", + "pendingQuantity": 1.0, + "pendingAboveType": "LIMIT_MAKER", + "workingTimeInForce": "GTC", + "pendingAbovePrice": 605.0, + "pendingBelowType": "LIMIT_MAKER", + "pendingBelowPrice": 595.0, + "workingIcebergQty": 0.1, +} + + +@mock_http_response( + responses.POST, + "/sapi/v1/margin/order/otoco\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_margin_new_otoco_order(): + """Tests the API endpoint to post a new margin otoco order""" + + client = Client(key, secret) + response = client.margin_new_otoco_order(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/portfolio_margin/test_get_portfolio_margin_account_balance.py b/tests/spot/portfolio_margin/test_get_portfolio_margin_account_balance.py new file mode 100644 index 00000000..fa1aeb58 --- /dev/null +++ b/tests/spot/portfolio_margin/test_get_portfolio_margin_account_balance.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"recvWindow": 5000} +expected_params = {"recvWindow": 5000} + + +@mock_http_response( + responses.GET, + "/sapi/v1/portfolio/balance\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_get_portfolio_margin_account_balance(): + """Tests the API endpoint to query Portfolio Margin Pro account balance""" + + client = Client(key, secret) + response = client.get_portfolio_margin_account_balance(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/portfolio_margin/test_get_portfolio_margin_span_account_info.py b/tests/spot/portfolio_margin/test_get_portfolio_margin_span_account_info.py new file mode 100644 index 00000000..7ab63480 --- /dev/null +++ b/tests/spot/portfolio_margin/test_get_portfolio_margin_span_account_info.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"recvWindow": 5000} +expected_params = {"recvWindow": 5000} + + +@mock_http_response( + responses.GET, + "/sapi/v2/portfolio/account\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_get_portfolio_margin_span_account_info(): + """Tests the API endpoint to get Portfolio Margin Pro SPAN Account Info""" + + client = Client(key, secret) + response = client.get_portfolio_margin_span_account_info(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/portfolio_margin/test_portfolio_margin_tiered_collateral_rate.py b/tests/spot/portfolio_margin/test_portfolio_margin_tiered_collateral_rate.py new file mode 100644 index 00000000..1f6bfdce --- /dev/null +++ b/tests/spot/portfolio_margin/test_portfolio_margin_tiered_collateral_rate.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"recvWindow": 5000} +expected_params = {"recvWindow": 5000} + + +@mock_http_response( + responses.GET, + "/sapi/v2/portfolio/collateralRate\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_portfolio_margin_tiered_collateral_rate(): + """Tests the API endpoint to get portfolio margin PRO tiered collateral rate""" + + client = Client(key, secret) + response = client.portfolio_margin_tiered_collateral_rate(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/simple_earn/test_set_locked_product_redeem_option.py b/tests/spot/simple_earn/test_set_locked_product_redeem_option.py new file mode 100644 index 00000000..3042847f --- /dev/null +++ b/tests/spot/simple_earn/test_set_locked_product_redeem_option.py @@ -0,0 +1,34 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"positionId": "position_001", "redeemTo": "SPOT", "recvWindow": 5000} +expected_params = { + "positionId": "position_001", + "redeemTo": "SPOT", + "recvWindow": 5000, +} + + +@mock_http_response( + responses.POST, + "/sapi/v1/simple-earn/locked/setRedeemOption\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_set_locked_product_redeem_option(): + """Tests the API endpoint to set redeem option for Locked product""" + + client = Client(key, secret) + response = client.set_locked_product_redeem_option(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/staking/test_eth_staking_account.py b/tests/spot/staking/test_eth_staking_account.py new file mode 100644 index 00000000..7c8966b3 --- /dev/null +++ b/tests/spot/staking/test_eth_staking_account.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"recvWindow": 5000} +expected_params = {"recvWindow": 5000} + + +@mock_http_response( + responses.GET, + "/sapi/v2/eth-staking/account\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_eth_staking_account(): + """Tests the API endpoint to get account ETH staking""" + + client = Client(key, secret) + response = client.eth_staking_account(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/staking/test_get_beth_rewards_distribution_history.py b/tests/spot/staking/test_get_beth_rewards_distribution_history.py new file mode 100644 index 00000000..f56f0182 --- /dev/null +++ b/tests/spot/staking/test_get_beth_rewards_distribution_history.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"recvWindow": 5000} +expected_params = {"recvWindow": 5000} + + +@mock_http_response( + responses.GET, + "/sapi/v1/eth-staking/eth/history/rewardsHistory\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_get_beth_rewards_distribution_history(): + """Tests the API endpoint to get BETH rewards distribution history""" + + client = Client(key, secret) + response = client.get_beth_rewards_distribution_history(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/staking/test_get_eth_redemption_history.py b/tests/spot/staking/test_get_eth_redemption_history.py new file mode 100644 index 00000000..81816e1b --- /dev/null +++ b/tests/spot/staking/test_get_eth_redemption_history.py @@ -0,0 +1,31 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"recvWindow": 5000} +expected_params = {"recvWindow": 5000} + + +@mock_http_response( + responses.GET, + "/sapi/v1/eth-staking/eth/history/redemptionHistory\\?" + + urlencode(expected_params), + mock_item, + 200, +) +def test_get_eth_redemption_history(): + """Tests the API endpoint to get ETH redemption history""" + + client = Client(key, secret) + response = client.get_eth_redemption_history(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/staking/test_get_eth_staking_history.py b/tests/spot/staking/test_get_eth_staking_history.py new file mode 100644 index 00000000..b977ae7a --- /dev/null +++ b/tests/spot/staking/test_get_eth_staking_history.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"recvWindow": 5000} +expected_params = {"recvWindow": 5000} + + +@mock_http_response( + responses.GET, + "/sapi/v1/eth-staking/eth/history/stakingHistory\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_get_eth_staking_history(): + """Tests the API endpoint to get ETH staking history""" + + client = Client(key, secret) + response = client.get_eth_staking_history(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/staking/test_get_eth_staking_quota.py b/tests/spot/staking/test_get_eth_staking_quota.py new file mode 100644 index 00000000..a3c9b5a2 --- /dev/null +++ b/tests/spot/staking/test_get_eth_staking_quota.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"recvWindow": 5000} +expected_params = {"recvWindow": 5000} + + +@mock_http_response( + responses.GET, + "/sapi/v1/eth-staking/eth/quota\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_get_eth_staking_quota(): + """Tests the API endpoint to get current ETH staking quota""" + + client = Client(key, secret) + response = client.get_eth_staking_quota(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/staking/test_get_wbeth_rate_history.py b/tests/spot/staking/test_get_wbeth_rate_history.py new file mode 100644 index 00000000..249a1ec6 --- /dev/null +++ b/tests/spot/staking/test_get_wbeth_rate_history.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"recvWindow": 5000} +expected_params = {"recvWindow": 5000} + + +@mock_http_response( + responses.GET, + "/sapi/v1/eth-staking/eth/history/rateHistory\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_get_wbeth_rate_history(): + """Tests the API endpoint to get WBETH Rate History""" + + client = Client(key, secret) + response = client.get_wbeth_rate_history(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/staking/test_get_wbeth_rewards_history.py b/tests/spot/staking/test_get_wbeth_rewards_history.py new file mode 100644 index 00000000..7f784b0c --- /dev/null +++ b/tests/spot/staking/test_get_wbeth_rewards_history.py @@ -0,0 +1,31 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"recvWindow": 5000} +expected_params = {"recvWindow": 5000} + + +@mock_http_response( + responses.GET, + "/sapi/v1/eth-staking/eth/history/wbethRewardsHistory\\?" + + urlencode(expected_params), + mock_item, + 200, +) +def test_get_wbeth_rewards_history(): + """Tests the API endpoint to get WBETH rewards history""" + + client = Client(key, secret) + response = client.get_wbeth_rewards_history(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/staking/test_get_wbeth_unwrap_history.py b/tests/spot/staking/test_get_wbeth_unwrap_history.py new file mode 100644 index 00000000..02225584 --- /dev/null +++ b/tests/spot/staking/test_get_wbeth_unwrap_history.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"recvWindow": 5000} +expected_params = {"recvWindow": 5000} + + +@mock_http_response( + responses.GET, + "/sapi/v1/eth-staking/wbeth/history/unwrapHistory\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_get_wbeth_unwrap_history(): + """Tests the API endpoint to get WBETH unwrap history""" + + client = Client(key, secret) + response = client.get_wbeth_unwrap_history(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/staking/test_get_wbeth_wrap_history.py b/tests/spot/staking/test_get_wbeth_wrap_history.py new file mode 100644 index 00000000..ad338234 --- /dev/null +++ b/tests/spot/staking/test_get_wbeth_wrap_history.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"recvWindow": 5000} +expected_params = {"recvWindow": 5000} + + +@mock_http_response( + responses.GET, + "/sapi/v1/eth-staking/wbeth/history/wrapHistory\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_get_wbeth_wrap_history(): + """Tests the API endpoint to get WBETH wrap history""" + + client = Client(key, secret) + response = client.get_wbeth_wrap_history(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/staking/test_redeem_eth.py b/tests/spot/staking/test_redeem_eth.py new file mode 100644 index 00000000..5357dbc8 --- /dev/null +++ b/tests/spot/staking/test_redeem_eth.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"amount": 1.0, "recvWindow": 5000} +expected_params = {"amount": 1.0, "recvWindow": 5000} + + +@mock_http_response( + responses.POST, + "/sapi/v1/eth-staking/eth/redeem\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_redeem_eth(): + """Tests the API endpoint to redeem WBETH or BETH and get ETH""" + + client = Client(key, secret) + response = client.redeem_eth(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/staking/test_subscribe_eth_staking.py b/tests/spot/staking/test_subscribe_eth_staking.py new file mode 100644 index 00000000..ce6aa9e5 --- /dev/null +++ b/tests/spot/staking/test_subscribe_eth_staking.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"amount": 1.0, "recvWindow": 5000} +expected_params = {"amount": 1.0, "recvWindow": 5000} + + +@mock_http_response( + responses.POST, + "/sapi/v2/eth-staking/eth/stake\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_subscribe_eth_staking(): + """Tests the API endpoint to subscribe to ETH Staking""" + + client = Client(key, secret) + response = client.subscribe_eth_staking(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/staking/test_wrap_beth.py b/tests/spot/staking/test_wrap_beth.py new file mode 100644 index 00000000..ee77b3aa --- /dev/null +++ b/tests/spot/staking/test_wrap_beth.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"amount": 1.0, "recvWindow": 5000} +expected_params = {"amount": 1.0, "recvWindow": 5000} + + +@mock_http_response( + responses.POST, + "/sapi/v1/eth-staking/wbeth/wrap\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_wrap_beth(): + """Tests the API endpoint to wrap BETH""" + + client = Client(key, secret) + response = client.wrap_beth(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/wallet/test_local_entity_deposit_history.py b/tests/spot/wallet/test_local_entity_deposit_history.py new file mode 100644 index 00000000..8f7d55cd --- /dev/null +++ b/tests/spot/wallet/test_local_entity_deposit_history.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"trId": "1234", "coin": "BNB"} +expected_params = {"trId": "1234", "coin": "BNB"} + + +@mock_http_response( + responses.GET, + "/sapi/v1/localentity/deposit/history\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_local_entity_deposit_history(): + """Tests the API endpoint to fetch deposit history for local entities that required travel rule""" + + client = Client(key, secret) + response = client.local_entity_deposit_history(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/wallet/test_local_entity_submit_deposit_questionnaire.py b/tests/spot/wallet/test_local_entity_submit_deposit_questionnaire.py new file mode 100644 index 00000000..c38e73bc --- /dev/null +++ b/tests/spot/wallet/test_local_entity_submit_deposit_questionnaire.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"tranId": "1234", "questionnaire": '{"questionnaire"}'} +expected_params = {"tranId": "1234", "questionnaire": '{"questionnaire"}'} + + +@mock_http_response( + responses.PUT, + "/sapi/v1/localentity/deposit/provide-info\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_local_entity_submit_deposit_questionnaire(): + """Tests the API endpoint to submit questionnaire for local entities that require travel rule.""" + + client = Client(key, secret) + response = client.local_entity_submit_deposit_questionnaire(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/wallet/test_local_entity_withdraw.py b/tests/spot/wallet/test_local_entity_withdraw.py new file mode 100644 index 00000000..89de7242 --- /dev/null +++ b/tests/spot/wallet/test_local_entity_withdraw.py @@ -0,0 +1,40 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = { + "coin": "BNB", + "address": "address", + "amount": 0.1, + "questionnaire": '{"questionnaire"}', +} +expected_params = { + "coin": "BNB", + "address": "address", + "amount": 0.1, + "questionnaire": '{"questionnaire"}', +} + + +@mock_http_response( + responses.POST, + "/sapi/v1/localentity/withdraw/apply\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_local_entity_withdraw(): + """Tests the API endpoint to submit a withdrawal request for local entities""" + + client = Client(key, secret) + response = client.local_entity_withdraw(**send_params) + response.should.equal(mock_item) diff --git a/tests/spot/wallet/test_local_entity_withdraw_history.py b/tests/spot/wallet/test_local_entity_withdraw_history.py new file mode 100644 index 00000000..bf752e48 --- /dev/null +++ b/tests/spot/wallet/test_local_entity_withdraw_history.py @@ -0,0 +1,30 @@ +import responses + +from binance.spot import Spot as Client +from tests.util import random_str +from urllib.parse import urlencode +from tests.util import mock_http_response + + +mock_item = {"key_1": "value_1", "key_2": "value_2"} +mock_exception = {"code": -1, "msg": "error message"} + +key = random_str() +secret = random_str() + +send_params = {"trId": "1234", "coin": "USDT"} +expected_params = {"trId": "1234", "coin": "USDT"} + + +@mock_http_response( + responses.GET, + "/sapi/v1/localentity/withdraw/history\\?" + urlencode(expected_params), + mock_item, + 200, +) +def test_local_entity_withdraw_history(): + """Tests the API endpoint to fetch withdraw history for local entities that required travel rule""" + + client = Client(key, secret) + response = client.local_entity_withdraw_history(**send_params) + response.should.equal(mock_item)