diff --git a/binance/async_client.py b/binance/async_client.py index 178fb1a9d..b8cf3b3b4 100644 --- a/binance/async_client.py +++ b/binance/async_client.py @@ -2458,6 +2458,28 @@ async def convert_accept_quote(self, **params): ==================================================================================================================== """ + async def papi_stream_get_listen_key(self): + res = await self._request_papi_api("post", "listenKey", signed=False, data={}) + return res["listenKey"] + + papi_stream_get_listen_key.__doc__ = Client.papi_stream_get_listen_key.__doc__ + + async def papi_stream_keepalive(self, listenKey): + params = {"listenKey": listenKey} + return await self._request_papi_api( + "put", "listenKey", signed=False, data=params + ) + + papi_stream_keepalive.__doc__ = Client.papi_stream_keepalive.__doc__ + + async def papi_stream_close(self, listenKey): + params = {"listenKey": listenKey} + return await self._request_papi_api( + "delete", "listenKey", signed=False, data=params + ) + + papi_stream_close.__doc__ = Client.papi_stream_close.__doc__ + async def papi_get_balance(self, **params): return await self._request_papi_api("get", "balance", signed=True, data=params) @@ -3986,9 +4008,9 @@ async def margin_max_borrowable(self, **params): margin_max_borrowable.__doc__ = Client.margin_max_borrowable.__doc__ -#################################################### -# Futures Data -#################################################### + #################################################### + # Futures Data + #################################################### async def futures_historical_data_link(self, **params): return await self._request_margin_api("get", "futures/data/histDataLink", signed=True, data=params) diff --git a/binance/client.py b/binance/client.py index b3a084d33..88e4f5c15 100755 --- a/binance/client.py +++ b/binance/client.py @@ -9424,6 +9424,58 @@ def papi_get_balance(self, **params): """ return self._request_papi_api("get", "balance", signed=True, data=params) + def papi_stream_get_listen_key(self): + """Start a new user data stream for Portfolio Margin account. + + https://developers.binance.com/docs/derivatives/portfolio-margin/user-data-streams/Start-User-Data-Stream + + :returns: API response + + { + "listenKey": "pM_XXXXXXX" + } + + The stream will close after 60 minutes unless a keepalive is sent. + If the account has an active listenKey, that listenKey will be returned and its validity will be extended for 60 minutes. + + Weight: 1 + + """ + res = self._request_papi_api("post", "listenKey", signed=False, data={}) + return res["listenKey"] + + def papi_stream_keepalive(self, listenKey): + """Keepalive a user data stream to prevent a time out. + + https://developers.binance.com/docs/derivatives/portfolio-margin/user-data-streams/Keepalive-User-Data-Stream + + :returns: API response + + {} + + User data streams will close after 60 minutes. It's recommended to send a ping about every 60 minutes. + + Weight: 1 + + """ + params = {"listenKey": listenKey} + return self._request_papi_api("put", "listenKey", signed=False, data=params) + + def papi_stream_close(self, listenKey): + """Close out a user data stream. + + https://developers.binance.com/docs/derivatives/portfolio-margin/user-data-streams/Close-User-Data-Stream + + :returns: API response + + {} + + Weight: 1 + + """ + params = {"listenKey": listenKey} + return self._request_papi_api("delete", "listenKey", signed=False, data=params) + def papi_get_account(self, **params): """Query account information. @@ -13469,9 +13521,9 @@ def margin_max_borrowable(self, **params): "get", "margin/maxBorrowable", signed=True, data=params ) -#################################################### -# Futures Data -#################################################### + #################################################### + # Futures Data + #################################################### def futures_historical_data_link(self, **params): """Get Future TickLevel Orderbook Historical Data Download Link. diff --git a/binance/ws/keepalive_websocket.py b/binance/ws/keepalive_websocket.py index 19346873d..b6e6a5c93 100644 --- a/binance/ws/keepalive_websocket.py +++ b/binance/ws/keepalive_websocket.py @@ -66,6 +66,8 @@ async def _get_listen_key(self): listen_key = await self._client.futures_stream_get_listen_key() elif self._keepalive_type == "coin_futures": listen_key = await self._client.futures_coin_stream_get_listen_key() + elif self._keepalive_type == "portfolio_margin": + listen_key = await self._client.papi_stream_get_listen_key() else: # isolated margin # Passing symbol for isolated margin listen_key = await self._client.isolated_margin_stream_get_listen_key( @@ -90,6 +92,8 @@ async def _keepalive_socket(self): await self._client.futures_stream_keepalive(self._listen_key) elif self._keepalive_type == "coin_futures": await self._client.futures_coin_stream_keepalive(self._listen_key) + elif self._keepalive_type == "portfolio_margin": + await self._client.papi_stream_keepalive(self._listen_key) else: # isolated margin # Passing symbol for isolated margin await self._client.isolated_margin_stream_keepalive( diff --git a/binance/ws/streams.py b/binance/ws/streams.py index b5fb46e3e..293fa768f 100755 --- a/binance/ws/streams.py +++ b/binance/ws/streams.py @@ -1003,6 +1003,21 @@ def coin_futures_socket(self): stream_url = self.DSTREAM_TESTNET_URL return self._get_account_socket("coin_futures", stream_url=stream_url) + def portfolio_margin_socket(self): + """Start a websocket for portfolio margin user data + + https://developers.binance.com/docs/derivatives/portfolio-margin/user-data-streams + + :returns: connection key string if successful, False otherwise + + Message Format - see Binance API docs for all types + """ + stream_url = self.FSTREAM_URL + if self.testnet: + stream_url = self.FSTREAM_TESTNET_URL + stream_url += "pm/" + return self._get_account_socket("portfolio_margin", stream_url=stream_url) + def isolated_margin_socket(self, symbol: str): """Start a websocket for isolated margin data