trio-binance 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
trio_binance/client.py ADDED
@@ -0,0 +1,1671 @@
1
+ from typing import Dict, Optional, List, Tuple, Union
2
+
3
+ import httpx
4
+ import h2
5
+ import trio
6
+ import hashlib
7
+ import hmac
8
+ import time
9
+ from operator import itemgetter
10
+ from urllib.parse import urlencode
11
+
12
+ from .helpers import convert_ts_str
13
+ from .exceptions import (
14
+ BinanceAPIException,
15
+ BinanceRequestException,
16
+ NotImplementedException,
17
+ )
18
+
19
+
20
+ class BaseClient:
21
+ API_URL = "https://api{}.binance.{}/api"
22
+ API_TESTNET_URL = "https://testnet.binance.vision/api"
23
+ MARGIN_API_URL = "https://api.binance.{}/sapi"
24
+ WEBSITE_URL = "https://www.binance.{}"
25
+ FUTURES_URL = "https://fapi.binance.{}/fapi"
26
+ FUTURES_TESTNET_URL = "https://testnet.binancefuture.com/fapi"
27
+ FUTURES_DATA_URL = "https://fapi.binance.{}/futures/data"
28
+ FUTURES_DATA_TESTNET_URL = "https://testnet.binancefuture.com/futures/data"
29
+ FUTURES_COIN_URL = "https://dapi.binance.{}/dapi"
30
+ FUTURES_COIN_TESTNET_URL = "https://testnet.binancefuture.com/dapi"
31
+ FUTURES_COIN_DATA_URL = "https://dapi.binance.{}/futures/data"
32
+ FUTURES_COIN_DATA_TESTNET_URL = "https://testnet.binancefuture.com/futures/data"
33
+ OPTIONS_URL = "https://vapi.binance.{}/vapi"
34
+ OPTIONS_TESTNET_URL = "https://testnet.binanceops.{}/vapi"
35
+ PORTFOLIO_MARGIN_URL = "https://papi.binance.com/papi"
36
+ PUBLIC_API_VERSION = "v1"
37
+ PRIVATE_API_VERSION = "v3"
38
+ MARGIN_API_VERSION = "v1"
39
+ FUTURES_API_VERSION = "v1"
40
+ FUTURES_API_VERSION2 = "v2"
41
+ OPTIONS_API_VERSION = "v1"
42
+ PORTFOLIO_MARGIN_VERSION = "v1"
43
+
44
+ REQUEST_TIMEOUT: float = 10
45
+
46
+ SYMBOL_TYPE_SPOT = "SPOT"
47
+
48
+ ORDER_STATUS_NEW = "NEW"
49
+ ORDER_STATUS_PARTIALLY_FILLED = "PARTIALLY_FILLED"
50
+ ORDER_STATUS_FILLED = "FILLED"
51
+ ORDER_STATUS_CANCELED = "CANCELED"
52
+ ORDER_STATUS_PENDING_CANCEL = "PENDING_CANCEL"
53
+ ORDER_STATUS_REJECTED = "REJECTED"
54
+ ORDER_STATUS_EXPIRED = "EXPIRED"
55
+
56
+ KLINE_INTERVAL_1MINUTE = "1m"
57
+ KLINE_INTERVAL_3MINUTE = "3m"
58
+ KLINE_INTERVAL_5MINUTE = "5m"
59
+ KLINE_INTERVAL_15MINUTE = "15m"
60
+ KLINE_INTERVAL_30MINUTE = "30m"
61
+ KLINE_INTERVAL_1HOUR = "1h"
62
+ KLINE_INTERVAL_2HOUR = "2h"
63
+ KLINE_INTERVAL_4HOUR = "4h"
64
+ KLINE_INTERVAL_6HOUR = "6h"
65
+ KLINE_INTERVAL_8HOUR = "8h"
66
+ KLINE_INTERVAL_12HOUR = "12h"
67
+ KLINE_INTERVAL_1DAY = "1d"
68
+ KLINE_INTERVAL_3DAY = "3d"
69
+ KLINE_INTERVAL_1WEEK = "1w"
70
+ KLINE_INTERVAL_1MONTH = "1M"
71
+
72
+ SIDE_BUY = "BUY"
73
+ SIDE_SELL = "SELL"
74
+
75
+ ORDER_TYPE_LIMIT = "LIMIT"
76
+ ORDER_TYPE_MARKET = "MARKET"
77
+ ORDER_TYPE_STOP_LOSS = "STOP_LOSS"
78
+ ORDER_TYPE_STOP_LOSS_LIMIT = "STOP_LOSS_LIMIT"
79
+ ORDER_TYPE_TAKE_PROFIT = "TAKE_PROFIT"
80
+ ORDER_TYPE_TAKE_PROFIT_LIMIT = "TAKE_PROFIT_LIMIT"
81
+ ORDER_TYPE_LIMIT_MAKER = "LIMIT_MAKER"
82
+
83
+ FUTURE_ORDER_TYPE_LIMIT = "LIMIT"
84
+ FUTURE_ORDER_TYPE_MARKET = "MARKET"
85
+ FUTURE_ORDER_TYPE_STOP = "STOP"
86
+ FUTURE_ORDER_TYPE_STOP_MARKET = "STOP_MARKET"
87
+ FUTURE_ORDER_TYPE_TAKE_PROFIT = "TAKE_PROFIT"
88
+ FUTURE_ORDER_TYPE_TAKE_PROFIT_MARKET = "TAKE_PROFIT_MARKET"
89
+ FUTURE_ORDER_TYPE_LIMIT_MAKER = "LIMIT_MAKER"
90
+
91
+ TIME_IN_FORCE_GTC = "GTC" # Good till cancelled
92
+ TIME_IN_FORCE_IOC = "IOC" # Immediate or cancel
93
+ TIME_IN_FORCE_FOK = "FOK" # Fill or kill
94
+
95
+ ORDER_RESP_TYPE_ACK = "ACK"
96
+ ORDER_RESP_TYPE_RESULT = "RESULT"
97
+ ORDER_RESP_TYPE_FULL = "FULL"
98
+
99
+ # For accessing the data returned by Client.aggregate_trades().
100
+ AGG_ID = "a"
101
+ AGG_PRICE = "p"
102
+ AGG_QUANTITY = "q"
103
+ AGG_FIRST_TRADE_ID = "f"
104
+ AGG_LAST_TRADE_ID = "l"
105
+ AGG_TIME = "T"
106
+ AGG_BUYER_MAKES = "m"
107
+ AGG_BEST_MATCH = "M"
108
+
109
+ # new asset transfer api enum
110
+ SPOT_TO_FIAT = "MAIN_C2C"
111
+ SPOT_TO_USDT_FUTURE = "MAIN_UMFUTURE"
112
+ SPOT_TO_COIN_FUTURE = "MAIN_CMFUTURE"
113
+ SPOT_TO_MARGIN_CROSS = "MAIN_MARGIN"
114
+ SPOT_TO_MINING = "MAIN_MINING"
115
+ FIAT_TO_SPOT = "C2C_MAIN"
116
+ FIAT_TO_USDT_FUTURE = "C2C_UMFUTURE"
117
+ FIAT_TO_MINING = "C2C_MINING"
118
+ USDT_FUTURE_TO_SPOT = "UMFUTURE_MAIN"
119
+ USDT_FUTURE_TO_FIAT = "UMFUTURE_C2C"
120
+ USDT_FUTURE_TO_MARGIN_CROSS = "UMFUTURE_MARGIN"
121
+ COIN_FUTURE_TO_SPOT = "CMFUTURE_MAIN"
122
+ MARGIN_CROSS_TO_SPOT = "MARGIN_MAIN"
123
+ MARGIN_CROSS_TO_USDT_FUTURE = "MARGIN_UMFUTURE"
124
+ MINING_TO_SPOT = "MINING_MAIN"
125
+ MINING_TO_USDT_FUTURE = "MINING_UMFUTURE"
126
+ MINING_TO_FIAT = "MINING_C2C"
127
+
128
+ def __init__(
129
+ self,
130
+ api_key: Optional[str] = None,
131
+ api_secret: Optional[str] = None,
132
+ requests_params: Dict[str, str] = None,
133
+ api_cluster_id: Union[int, str] = "",
134
+ tld: str = "com",
135
+ testnet: bool = False,
136
+ ):
137
+ """Binance API Client constructor
138
+
139
+ :param api_key: Api Key
140
+ :type api_key: str.
141
+ :param api_secret: Api Secret
142
+ :type api_secret: str.
143
+ :param requests_params: optional - Dictionary of requests params to use for all calls
144
+ :type requests_params: dict.
145
+ :param api_cluster_id: optional - Cluster ID for API
146
+ :type api_cluster_id: str or int
147
+ :param testnet: Use testnet environment - only available for vanilla options at the moment
148
+ :type testnet: bool
149
+
150
+ """
151
+
152
+ self.tld = tld
153
+ self.API_URL = self.API_URL.format(api_cluster_id, tld)
154
+ self.MARGIN_API_URL = self.MARGIN_API_URL.format(tld)
155
+ self.WEBSITE_URL = self.WEBSITE_URL.format(tld)
156
+ self.FUTURES_URL = self.FUTURES_URL.format(tld)
157
+ self.FUTURES_DATA_URL = self.FUTURES_DATA_URL.format(tld)
158
+ self.FUTURES_COIN_URL = self.FUTURES_COIN_URL.format(tld)
159
+ self.FUTURES_COIN_DATA_URL = self.FUTURES_COIN_DATA_URL.format(tld)
160
+ self.OPTIONS_URL = self.OPTIONS_URL.format(tld)
161
+ self.OPTIONS_TESTNET_URL = self.OPTIONS_TESTNET_URL.format(tld)
162
+
163
+ self.API_KEY = api_key
164
+ self.API_SECRET = api_secret
165
+ self._requests_params = requests_params
166
+ self.response = None
167
+ self.testnet = testnet
168
+ self.timestamp_offset = 0
169
+
170
+ def _get_headers(self) -> Dict:
171
+ headers = {
172
+ "Accept": "application/json",
173
+ "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
174
+ # noqa
175
+ }
176
+ if self.API_KEY:
177
+ assert self.API_KEY
178
+ headers["X-MBX-APIKEY"] = self.API_KEY
179
+ return headers
180
+
181
+ def _create_api_uri(self, path: str, signed: bool = True, version: str = PUBLIC_API_VERSION) -> str:
182
+ url = self.API_URL
183
+ if self.testnet:
184
+ url = self.API_TESTNET_URL
185
+ v = self.PRIVATE_API_VERSION if signed else version
186
+ return url + "/" + v + "/" + path
187
+
188
+ def _create_margin_api_uri(self, path: str, version: str = MARGIN_API_VERSION) -> str:
189
+ return self.MARGIN_API_URL + "/" + version + "/" + path
190
+
191
+ def _create_website_uri(self, path: str) -> str:
192
+ return self.WEBSITE_URL + "/" + path
193
+
194
+ def _create_futures_api_uri(self, path: str, version=1) -> str:
195
+ url = self.FUTURES_URL
196
+ if self.testnet:
197
+ url = self.FUTURES_TESTNET_URL
198
+ options = {1: self.FUTURES_API_VERSION, 2: self.FUTURES_API_VERSION2}
199
+ return url + "/" + options[version] + "/" + path
200
+
201
+ def _create_futures_data_api_uri(self, path: str) -> str:
202
+ url = self.FUTURES_DATA_URL
203
+ if self.testnet:
204
+ url = self.FUTURES_DATA_TESTNET_URL
205
+ return url + "/" + path
206
+
207
+ def _create_futures_coin_api_url(self, path: str, version=1) -> str:
208
+ url = self.FUTURES_COIN_URL
209
+ if self.testnet:
210
+ url = self.FUTURES_COIN_TESTNET_URL
211
+ options = {1: self.FUTURES_API_VERSION, 2: self.FUTURES_API_VERSION2}
212
+ return url + "/" + options[version] + "/" + path
213
+
214
+ def _create_futures_coin_data_api_url(self, path: str, version=1) -> str:
215
+ url = self.FUTURES_COIN_DATA_URL
216
+ if self.testnet:
217
+ url = self.FUTURES_COIN_DATA_TESTNET_URL
218
+ return url + "/" + path
219
+
220
+ def _create_options_api_uri(self, path: str) -> str:
221
+ url = self.OPTIONS_URL
222
+ if self.testnet:
223
+ url = self.OPTIONS_TESTNET_URL
224
+ return url + "/" + self.OPTIONS_API_VERSION + "/" + path
225
+
226
+ def _create_portfolio_margin_api_uri(self, path: str, version: int = 1) -> str:
227
+ url = self.PORTFOLIO_MARGIN_URL
228
+ options = {1: self.PORTFOLIO_MARGIN_VERSION}
229
+ return url + "/" + options[version] + "/" + path
230
+
231
+ def _generate_signature(self, data: Dict) -> str:
232
+ ordered_data = self._order_params(data)
233
+ query_string = "&".join([f"{d[0]}={d[1]}" for d in ordered_data])
234
+ m = hmac.new(
235
+ self.API_SECRET.encode("utf-8"),
236
+ query_string.encode("utf-8"),
237
+ hashlib.sha256,
238
+ )
239
+ return m.hexdigest()
240
+
241
+ @staticmethod
242
+ def _order_params(data: Dict) -> List[Tuple[str, str]]:
243
+ """Convert params to list with signature as last element
244
+
245
+ :param data:
246
+ :return:
247
+
248
+ """
249
+ data = dict(filter(lambda el: el[1] is not None, data.items()))
250
+ has_signature = False
251
+ params = []
252
+ for key, value in data.items():
253
+ if key == "signature":
254
+ has_signature = True
255
+ else:
256
+ params.append((key, str(value)))
257
+ # sort parameters by key
258
+ params.sort(key=itemgetter(0))
259
+ if has_signature:
260
+ params.append(("signature", data["signature"]))
261
+ return params
262
+
263
+ def _get_request_kwargs(self, method, signed: bool, force_params: bool = False, **kwargs) -> Dict:
264
+ # set default requests timeout
265
+ kwargs["timeout"] = self.REQUEST_TIMEOUT
266
+
267
+ # add our global requests params
268
+ if self._requests_params:
269
+ kwargs.update(self._requests_params)
270
+
271
+ data = kwargs.get("data", None)
272
+ if data and isinstance(data, dict):
273
+ kwargs["data"] = data
274
+
275
+ # find any requests params passed and apply them
276
+ if "requests_params" in kwargs["data"]:
277
+ # merge requests params into kwargs
278
+ kwargs.update(kwargs["data"]["requests_params"])
279
+ del kwargs["data"]["requests_params"]
280
+
281
+ if signed:
282
+ # generate signature
283
+ kwargs["data"]["timestamp"] = int(time.time() * 1000 + self.timestamp_offset)
284
+ kwargs["data"]["signature"] = self._generate_signature(kwargs["data"])
285
+
286
+ # sort get and post params to match signature order
287
+ if data:
288
+ # sort post params and remove any arguments with values of None
289
+ kwargs["data"] = self._order_params(kwargs["data"])
290
+ # Remove any arguments with values of None.
291
+ null_args = [i for i, (key, value) in enumerate(kwargs["data"]) if value is None]
292
+ for i in reversed(null_args):
293
+ del kwargs["data"][i]
294
+
295
+ # if get request assign data array to params value for requests lib
296
+ if data and (method == "get" or force_params):
297
+ kwargs["params"] = "&".join("%s=%s" % (data[0], data[1]) for data in kwargs["data"])
298
+ del kwargs["data"]
299
+
300
+ return kwargs
301
+
302
+
303
+ class AsyncClient(BaseClient):
304
+ def __init__(
305
+ self,
306
+ api_key: Optional[str] = None,
307
+ api_secret: Optional[str] = None,
308
+ requests_params: Dict[str, str] = None,
309
+ api_cluster_id: Union[str, int] = "",
310
+ tld: str = "com",
311
+ testnet: bool = False,
312
+ ):
313
+ super().__init__(api_key, api_secret, requests_params, api_cluster_id, tld, testnet)
314
+ self.session: httpx.AsyncClient = httpx.AsyncClient(http2=True, headers=self._get_headers())
315
+
316
+ @classmethod
317
+ async def create(
318
+ cls,
319
+ api_key: Optional[str] = None,
320
+ api_secret: Optional[str] = None,
321
+ requests_params: Dict[str, str] = None,
322
+ api_cluster_id: Union[str, int] = "",
323
+ tld: str = "com",
324
+ testnet: bool = False,
325
+ ):
326
+ self = cls(api_key, api_secret, requests_params, api_cluster_id, tld, testnet)
327
+
328
+ try:
329
+ await self.ping()
330
+
331
+ # calculate timestamp offset between local and trio_binance server
332
+ res = await self.get_server_time()
333
+ self.timestamp_offset = res["serverTime"] - int(time.time() * 1000)
334
+
335
+ return self
336
+ except Exception:
337
+ # If ping throw an exception, the current self must be cleaned
338
+ # else, we can receive a "asyncio:Unclosed client session"
339
+ await self.close_connection()
340
+ raise
341
+
342
+ async def __aenter__(self):
343
+ return self
344
+
345
+ async def __aexit__(self, *excinfo):
346
+ await self.session.aclose()
347
+
348
+ async def close_connection(self):
349
+ if self.session:
350
+ assert self.session
351
+ await self.session.aclose()
352
+
353
+ async def _request(self, method, uri: str, signed: bool, force_params: bool = False, **kwargs):
354
+ kwargs = self._get_request_kwargs(method, signed, force_params, **kwargs)
355
+ self.response = await getattr(self.session, method)(uri, **kwargs)
356
+ return await self._handle_response(self.response)
357
+
358
+ @staticmethod
359
+ async def _handle_response(response: httpx.Response):
360
+ """Internal helper for handling API responses from the Binance server.
361
+ Raises the appropriate exceptions when necessary; otherwise, returns the
362
+ response.
363
+ """
364
+ if response.is_error:
365
+ raise BinanceAPIException(response, response.status_code, response.text)
366
+ try:
367
+ return response.json()
368
+ except ValueError:
369
+ raise BinanceRequestException(f"Invalid Response: {response.text}")
370
+
371
+ async def _request_api(
372
+ self,
373
+ method,
374
+ path,
375
+ signed=False,
376
+ version=BaseClient.PUBLIC_API_VERSION,
377
+ **kwargs,
378
+ ):
379
+ uri = self._create_api_uri(path, signed, version)
380
+ return await self._request(method, uri, signed, **kwargs)
381
+
382
+ async def _request_futures_api(self, method, path, signed=False, version=1, **kwargs) -> Dict:
383
+ uri = self._create_futures_api_uri(path, version=version)
384
+
385
+ return await self._request(method, uri, signed, True, **kwargs)
386
+
387
+ async def _request_futures_data_api(self, method, path, signed=False, **kwargs) -> Dict:
388
+ uri = self._create_futures_data_api_uri(path)
389
+
390
+ return await self._request(method, uri, signed, True, **kwargs)
391
+
392
+ async def _request_futures_coin_api(self, method, path, signed=False, version=1, **kwargs) -> Dict:
393
+ uri = self._create_futures_coin_api_url(path, version=version)
394
+
395
+ return await self._request(method, uri, signed, True, **kwargs)
396
+
397
+ async def _request_futures_coin_data_api(self, method, path, signed=False, version=1, **kwargs) -> Dict:
398
+ uri = self._create_futures_coin_data_api_url(path, version=version)
399
+
400
+ return await self._request(method, uri, signed, True, **kwargs)
401
+
402
+ async def _request_options_api(self, method, path, signed=False, **kwargs) -> Dict:
403
+ uri = self._create_options_api_uri(path)
404
+
405
+ return await self._request(method, uri, signed, True, **kwargs)
406
+
407
+ async def _request_margin_api(self, method, path, signed=False, **kwargs) -> Dict:
408
+ uri = self._create_margin_api_uri(path)
409
+
410
+ return await self._request(method, uri, signed, **kwargs)
411
+
412
+ async def _request_portfolio_margin_api(self, method, path, signed=False, version: int = 1, **kwargs) -> Dict:
413
+ uri = self._create_portfolio_margin_api_uri(path, version)
414
+
415
+ return await self._request(method, uri, signed, **kwargs)
416
+
417
+ async def _request_website(self, method, path, signed=False, **kwargs) -> Dict:
418
+ uri = self._create_website_uri(path)
419
+ return await self._request(method, uri, signed, **kwargs)
420
+
421
+ async def _get(self, path, signed=False, version=BaseClient.PUBLIC_API_VERSION, **kwargs):
422
+ return await self._request_api("get", path, signed, version, **kwargs)
423
+
424
+ async def _post(self, path, signed=False, version=BaseClient.PUBLIC_API_VERSION, **kwargs) -> Dict:
425
+ return await self._request_api("post", path, signed, version, **kwargs)
426
+
427
+ async def _put(self, path, signed=False, version=BaseClient.PUBLIC_API_VERSION, **kwargs) -> Dict:
428
+ return await self._request_api("put", path, signed, version, **kwargs)
429
+
430
+ async def _delete(self, path, signed=False, version=BaseClient.PUBLIC_API_VERSION, **kwargs) -> Dict:
431
+ return await self._request_api("delete", path, signed, version, **kwargs)
432
+
433
+ # Exchange Endpoints
434
+
435
+ async def get_products(self) -> Dict:
436
+ products = await self._request_website("get", "exchange-api/v1/public/asset-service/product/get-products")
437
+ return products
438
+
439
+ async def get_exchange_info(self) -> Dict:
440
+ return await self._get("exchangeInfo", version=self.PRIVATE_API_VERSION)
441
+
442
+ async def get_symbol_info(self, symbol) -> Optional[Dict]:
443
+ res = await self.get_exchange_info()
444
+
445
+ for item in res["symbols"]:
446
+ if item["symbol"] == symbol.upper():
447
+ return item
448
+
449
+ return None
450
+
451
+ # General Endpoints
452
+
453
+ async def ping(self) -> Dict:
454
+ return await self._get("ping", version=self.PRIVATE_API_VERSION)
455
+
456
+ async def get_server_time(self) -> Dict:
457
+ return await self._get("time", version=self.PRIVATE_API_VERSION)
458
+
459
+ # Market Data Endpoints
460
+
461
+ async def get_all_tickers(self, symbol: Optional[str] = None) -> List[Dict[str, str]]:
462
+ params = {}
463
+ if symbol:
464
+ params["symbol"] = symbol
465
+ return await self._get("ticker/price", version=self.PRIVATE_API_VERSION, data=params)
466
+
467
+ async def get_orderbook_tickers(self) -> Dict:
468
+ return await self._get("ticker/bookTicker", version=self.PRIVATE_API_VERSION)
469
+
470
+ async def get_order_book(self, **params) -> Dict:
471
+ return await self._get("depth", data=params, version=self.PRIVATE_API_VERSION)
472
+
473
+ async def get_recent_trades(self, **params) -> Dict:
474
+ return await self._get("trades", data=params)
475
+
476
+ async def get_historical_trades(self, **params) -> Dict:
477
+ return await self._get("historicalTrades", data=params, version=self.PRIVATE_API_VERSION)
478
+
479
+ async def get_aggregate_trades(self, **params) -> Dict:
480
+ return await self._get("aggTrades", data=params, version=self.PRIVATE_API_VERSION)
481
+
482
+ async def aggregate_trade_iter(self, symbol, start_str=None, last_id=None):
483
+ if start_str is not None and last_id is not None:
484
+ raise ValueError("start_time and last_id may not be simultaneously specified.")
485
+
486
+ # If there's no last_id, get one.
487
+ if last_id is None:
488
+ # Without a last_id, we actually need the first trade. Normally,
489
+ # we'd get rid of it. See the next loop.
490
+ if start_str is None:
491
+ trades = await self.get_aggregate_trades(symbol=symbol, fromId=0)
492
+ else:
493
+ # The difference between startTime and endTime should be less
494
+ # or equal than an hour and the result set should contain at
495
+ # least one trade.
496
+ start_ts = convert_ts_str(start_str)
497
+ # If the resulting set is empty (i.e. no trades in that interval)
498
+ # then we just move forward hour by hour until we find at least one
499
+ # trade or reach present moment
500
+ while True:
501
+ end_ts = start_ts + (60 * 60 * 1000)
502
+ trades = await self.get_aggregate_trades(symbol=symbol, startTime=start_ts, endTime=end_ts)
503
+ if len(trades) > 0:
504
+ break
505
+ # If we reach present moment and find no trades then there is
506
+ # nothing to iterate, so we're done
507
+ if end_ts > int(time.time() * 1000):
508
+ return
509
+ start_ts = end_ts
510
+ for t in trades:
511
+ yield t
512
+ last_id = trades[-1][self.AGG_ID]
513
+
514
+ while True:
515
+ # There is no need to wait between queries, to avoid hitting the
516
+ # rate limit. We're using blocking IO, and as long as we're the
517
+ # only thread running calls like this, Binance will automatically
518
+ # add the right delay time on their end, forcing us to wait for
519
+ # data. That really simplifies this function's job. Binance is
520
+ # fucking awesome.
521
+ trades = await self.get_aggregate_trades(symbol=symbol, fromId=last_id)
522
+ # fromId=n returns a set starting with id n, but we already have
523
+ # that one. So get rid of the first item in the result set.
524
+ trades = trades[1:]
525
+ if len(trades) == 0:
526
+ return
527
+ for t in trades:
528
+ yield t
529
+ last_id = trades[-1][self.AGG_ID]
530
+
531
+ async def get_klines(self, **params) -> Dict:
532
+ return await self._get("klines", data=params, version=self.PRIVATE_API_VERSION)
533
+
534
+ async def get_avg_price(self, **params):
535
+ return await self._get("avgPrice", data=params, version=self.PRIVATE_API_VERSION)
536
+
537
+ async def get_ticker(self, **params):
538
+ return await self._get("ticker/24hr", data=params, version=self.PRIVATE_API_VERSION)
539
+
540
+ async def get_symbol_ticker(self, **params):
541
+ return await self._get("ticker/price", data=params, version=self.PRIVATE_API_VERSION)
542
+
543
+ async def get_orderbook_ticker(self, **params):
544
+ return await self._get("ticker/bookTicker", data=params, version=self.PRIVATE_API_VERSION)
545
+
546
+ # Account Endpoints
547
+
548
+ async def create_order(self, **params):
549
+ return await self._post("order", True, data=params)
550
+
551
+ async def order_limit(self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params):
552
+ params.update({"type": self.ORDER_TYPE_LIMIT, "timeInForce": timeInForce})
553
+ return await self.create_order(**params)
554
+
555
+ async def order_limit_buy(self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params):
556
+ params.update(
557
+ {
558
+ "side": self.SIDE_BUY,
559
+ }
560
+ )
561
+ return await self.order_limit(timeInForce=timeInForce, **params)
562
+
563
+ async def order_limit_sell(self, timeInForce=BaseClient.TIME_IN_FORCE_GTC, **params):
564
+ params.update({"side": self.SIDE_SELL})
565
+ return await self.order_limit(timeInForce=timeInForce, **params)
566
+
567
+ async def order_market(self, **params):
568
+ params.update({"type": self.ORDER_TYPE_MARKET})
569
+ return await self.create_order(**params)
570
+
571
+ async def order_market_buy(self, **params):
572
+ params.update({"side": self.SIDE_BUY})
573
+ return await self.order_market(**params)
574
+
575
+ async def order_market_sell(self, **params):
576
+ params.update({"side": self.SIDE_SELL})
577
+ return await self.order_market(**params)
578
+
579
+ async def create_oco_order(self, **params):
580
+ return await self._post("order/oco", True, data=params)
581
+
582
+ async def order_oco_buy(self, **params):
583
+ params.update({"side": self.SIDE_BUY})
584
+ return await self.create_oco_order(**params)
585
+
586
+ async def order_oco_sell(self, **params):
587
+ params.update({"side": self.SIDE_SELL})
588
+ return await self.create_oco_order(**params)
589
+
590
+ async def create_test_order(self, **params):
591
+ return await self._post("order/test", True, data=params)
592
+
593
+ async def get_order(self, **params):
594
+ return await self._get("order", True, data=params)
595
+
596
+ async def get_all_orders(self, **params):
597
+ return await self._get("allOrders", True, data=params)
598
+
599
+ async def cancel_order(self, **params):
600
+ return await self._delete("order", True, data=params)
601
+
602
+ async def get_open_orders(self, **params):
603
+ return await self._get("openOrders", True, data=params)
604
+
605
+ # User Stream Endpoints
606
+ async def get_account(self, **params):
607
+ return await self._get("account", True, data=params)
608
+
609
+ async def get_asset_balance(self, asset, **params):
610
+ res = await self.get_account(**params)
611
+ # find asset balance in list of balances
612
+ if "balances" in res:
613
+ for bal in res["balances"]:
614
+ if bal["asset"].lower() == asset.lower():
615
+ return bal
616
+ return None
617
+
618
+ async def get_my_trades(self, **params):
619
+ return await self._get("myTrades", True, data=params)
620
+
621
+ async def get_system_status(self):
622
+ return await self._request_margin_api("get", "system/status")
623
+
624
+ async def get_account_status(self, **params):
625
+ return await self._request_margin_api("get", "account/status", True, data=params)
626
+
627
+ async def get_account_api_trading_status(self, **params):
628
+ return await self._request_margin_api("get", "account/apiTradingStatus", True, data=params)
629
+
630
+ async def get_account_api_permissions(self, **params):
631
+ return await self._request_margin_api("get", "account/apiRestrictions", True, data=params)
632
+
633
+ async def get_dust_log(self, **params):
634
+ return await self._request_margin_api("get", "asset/dribblet", True, data=params)
635
+
636
+ async def transfer_dust(self, **params):
637
+ return await self._request_margin_api("post", "asset/dust", True, data=params)
638
+
639
+ async def get_asset_dividend_history(self, **params):
640
+ return await self._request_margin_api("get", "asset/assetDividend", True, data=params)
641
+
642
+ async def make_universal_transfer(self, **params):
643
+ return await self._request_margin_api("post", "asset/transfer", signed=True, data=params)
644
+
645
+ async def query_universal_transfer_history(self, **params):
646
+ return await self._request_margin_api("get", "asset/transfer", signed=True, data=params)
647
+
648
+ async def get_trade_fee(self, **params):
649
+ return await self._request_margin_api("get", "asset/tradeFee", True, data=params)
650
+
651
+ async def get_asset_details(self, **params):
652
+ return await self._request_margin_api("get", "asset/assetDetail", True, data=params)
653
+
654
+ # Withdraw Endpoints
655
+
656
+ async def withdraw(self, **params):
657
+ # force a name for the withdrawal if one not set
658
+ if "coin" in params and "name" not in params:
659
+ params["name"] = params["coin"]
660
+ return await self._request_margin_api("post", "capital/withdraw/apply", True, data=params)
661
+
662
+ async def get_deposit_history(self, **params):
663
+ return await self._request_margin_api("get", "capital/deposit/hisrec", True, data=params)
664
+
665
+ async def get_withdraw_history(self, **params):
666
+ return await self._request_margin_api("get", "capital/withdraw/history", True, data=params)
667
+
668
+ async def get_withdraw_history_id(self, withdraw_id, **params):
669
+ result = await self.get_withdraw_history(**params)
670
+
671
+ for entry in result:
672
+ if "id" in entry and entry["id"] == withdraw_id:
673
+ return entry
674
+
675
+ raise Exception("There is no entry with withdraw id", result)
676
+
677
+ async def get_deposit_address(self, coin: str, network: Optional[str] = None, **params):
678
+ params["coin"] = coin
679
+ if network:
680
+ params["network"] = network
681
+ return await self._request_margin_api("get", "capital/deposit/address", True, data=params)
682
+
683
+ # User Stream Endpoints
684
+
685
+ async def stream_get_listen_key(self):
686
+ res = await self._post("userDataStream", False, data={})
687
+ return res["listenKey"]
688
+
689
+ async def stream_keepalive(self):
690
+ return await self._put("userDataStream", False, data={})
691
+
692
+ async def stream_close(self):
693
+ return await self._delete("userDataStream", False, data={})
694
+
695
+ # Margin Trading Endpoints
696
+ async def get_margin_account(self, **params):
697
+ return await self._request_margin_api("get", "margin/account", True, data=params)
698
+
699
+ async def get_isolated_margin_account(self, **params):
700
+ return await self._request_margin_api("get", "margin/isolated/account", True, data=params)
701
+
702
+ async def get_margin_asset(self, **params):
703
+ return await self._request_margin_api("get", "margin/asset", data=params)
704
+
705
+ async def get_margin_symbol(self, **params):
706
+ return await self._request_margin_api("get", "margin/pair", data=params)
707
+
708
+ async def get_margin_all_assets(self, **params):
709
+ return await self._request_margin_api("get", "margin/allAssets", data=params)
710
+
711
+ async def get_margin_all_pairs(self, **params):
712
+ return await self._request_margin_api("get", "margin/allPairs", data=params)
713
+
714
+ async def create_isolated_margin_account(self, **params):
715
+ return await self._request_margin_api("post", "margin/isolated/create", signed=True, data=params)
716
+
717
+ async def get_isolated_margin_symbol(self, **params):
718
+ return await self._request_margin_api("get", "margin/isolated/pair", signed=True, data=params)
719
+
720
+ async def get_all_isolated_margin_symbols(self, **params):
721
+ return await self._request_margin_api("get", "margin/isolated/allPairs", signed=True, data=params)
722
+
723
+ async def toggle_bnb_burn_spot_margin(self, **params):
724
+ return await self._request_margin_api("post", "bnbBurn", signed=True, data=params)
725
+
726
+ async def get_bnb_burn_spot_margin(self, **params):
727
+ return await self._request_margin_api("get", "bnbBurn", signed=True, data=params)
728
+
729
+ async def get_margin_price_index(self, **params):
730
+ return await self._request_margin_api("get", "margin/priceIndex", data=params)
731
+
732
+ async def transfer_margin_to_spot(self, **params):
733
+ params["type"] = 2
734
+ return await self._request_margin_api("post", "margin/transfer", signed=True, data=params)
735
+
736
+ async def transfer_spot_to_margin(self, **params):
737
+ params["type"] = 1
738
+ return await self._request_margin_api("post", "margin/transfer", signed=True, data=params)
739
+
740
+ async def transfer_isolated_margin_to_spot(self, **params):
741
+ params["transFrom"] = "ISOLATED_MARGIN"
742
+ params["transTo"] = "SPOT"
743
+ return await self._request_margin_api("post", "margin/isolated/transfer", signed=True, data=params)
744
+
745
+ async def transfer_spot_to_isolated_margin(self, **params):
746
+ params["transFrom"] = "SPOT"
747
+ params["transTo"] = "ISOLATED_MARGIN"
748
+ return await self._request_margin_api("post", "margin/isolated/transfer", signed=True, data=params)
749
+
750
+ async def create_margin_loan(self, **params):
751
+ return await self._request_margin_api("post", "margin/loan", signed=True, data=params)
752
+
753
+ async def repay_margin_loan(self, **params):
754
+ return await self._request_margin_api("post", "margin/repay", signed=True, data=params)
755
+
756
+ async def create_margin_order(self, **params):
757
+ return await self._request_margin_api("post", "margin/order", signed=True, data=params)
758
+
759
+ async def cancel_margin_order(self, **params):
760
+ return await self._request_margin_api("delete", "margin/order", signed=True, data=params)
761
+
762
+ async def get_margin_loan_details(self, **params):
763
+ return await self._request_margin_api("get", "margin/loan", signed=True, data=params)
764
+
765
+ async def get_margin_repay_details(self, **params):
766
+ return await self._request_margin_api("get", "margin/repay", signed=True, data=params)
767
+
768
+ async def get_margin_interest_history(self, **params):
769
+ return await self._request_margin_api("get", "margin/interestHistory", signed=True, data=params)
770
+
771
+ async def get_margin_force_liquidation_rec(self, **params):
772
+ return await self._request_margin_api("get", "margin/forceLiquidationRec", signed=True, data=params)
773
+
774
+ async def get_margin_order(self, **params):
775
+ return await self._request_margin_api("get", "margin/order", signed=True, data=params)
776
+
777
+ async def get_open_margin_orders(self, **params):
778
+ return await self._request_margin_api("get", "margin/openOrders", signed=True, data=params)
779
+
780
+ async def get_all_margin_orders(self, **params):
781
+ return await self._request_margin_api("get", "margin/allOrders", signed=True, data=params)
782
+
783
+ async def get_margin_trades(self, **params):
784
+ return await self._request_margin_api("get", "margin/myTrades", signed=True, data=params)
785
+
786
+ async def get_max_margin_loan(self, **params):
787
+ return await self._request_margin_api("get", "margin/maxBorrowable", signed=True, data=params)
788
+
789
+ async def get_max_margin_transfer(self, **params):
790
+ return await self._request_margin_api("get", "margin/maxTransferable", signed=True, data=params)
791
+
792
+ # Margin OCO
793
+
794
+ async def create_margin_oco_order(self, **params):
795
+ return await self._request_margin_api("post", "margin/order/oco", signed=True, data=params)
796
+
797
+ async def cancel_margin_oco_order(self, **params):
798
+ return await self._request_margin_api("delete", "margin/orderList", signed=True, data=params)
799
+
800
+ async def get_margin_oco_order(self, **params):
801
+ return await self._request_margin_api("get", "margin/orderList", signed=True, data=params)
802
+
803
+ async def get_open_margin_oco_orders(self, **params):
804
+ return await self._request_margin_api("get", "margin/allOrderList", signed=True, data=params)
805
+
806
+ # Cross-margin
807
+
808
+ async def margin_stream_get_listen_key(self):
809
+ res = await self._request_margin_api("post", "userDataStream", signed=False, data={})
810
+ return res["listenKey"]
811
+
812
+ async def margin_stream_keepalive(self):
813
+ return await self._request_margin_api("put", "userDataStream", signed=False, data={})
814
+
815
+ async def margin_stream_close(self):
816
+ return await self._request_margin_api("delete", "userDataStream", signed=False, data={})
817
+
818
+ # Isolated margin
819
+
820
+ async def isolated_margin_stream_get_listen_key(self, symbol):
821
+ params = {"symbol": symbol}
822
+ res = await self._request_margin_api("post", "userDataStream/isolated", signed=False, data=params)
823
+ return res["listenKey"]
824
+
825
+ async def isolated_margin_stream_keepalive(self, symbol, listenKey):
826
+ params = {"symbol": symbol, "listenKey": listenKey}
827
+ return await self._request_margin_api("put", "userDataStream/isolated", signed=False, data=params)
828
+
829
+ async def isolated_margin_stream_close(self, symbol, listenKey):
830
+ params = {"symbol": symbol, "listenKey": listenKey}
831
+ return await self._request_margin_api("delete", "userDataStream/isolated", signed=False, data=params)
832
+
833
+ # Lending Endpoints
834
+
835
+ async def get_lending_product_list(self, **params):
836
+ return await self._request_margin_api("get", "lending/daily/product/list", signed=True, data=params)
837
+
838
+ async def get_lending_daily_quota_left(self, **params):
839
+ return await self._request_margin_api("get", "lending/daily/userLeftQuota", signed=True, data=params)
840
+
841
+ async def purchase_lending_product(self, **params):
842
+ return await self._request_margin_api("post", "lending/daily/purchase", signed=True, data=params)
843
+
844
+ async def get_lending_daily_redemption_quota(self, **params):
845
+ return await self._request_margin_api("get", "lending/daily/userRedemptionQuota", signed=True, data=params)
846
+
847
+ async def redeem_lending_product(self, **params):
848
+ return await self._request_margin_api("post", "lending/daily/redeem", signed=True, data=params)
849
+
850
+ async def get_lending_position(self, **params):
851
+ return await self._request_margin_api("get", "lending/daily/token/position", signed=True, data=params)
852
+
853
+ async def get_fixed_activity_project_list(self, **params):
854
+ return await self._request_margin_api("get", "lending/project/list", signed=True, data=params)
855
+
856
+ async def get_lending_account(self, **params):
857
+ return await self._request_margin_api("get", "lending/union/account", signed=True, data=params)
858
+
859
+ async def get_lending_purchase_history(self, **params):
860
+ return await self._request_margin_api("get", "lending/union/purchaseRecord", signed=True, data=params)
861
+
862
+ async def get_lending_redemption_history(self, **params):
863
+ return await self._request_margin_api("get", "lending/union/redemptionRecord", signed=True, data=params)
864
+
865
+ async def get_lending_interest_history(self, **params):
866
+ return await self._request_margin_api("get", "lending/union/interestHistory", signed=True, data=params)
867
+
868
+ async def change_fixed_activity_to_daily_position(self, **params):
869
+ return await self._request_margin_api("post", "lending/positionChanged", signed=True, data=params)
870
+
871
+ # Sub Accounts
872
+
873
+ async def get_sub_account_list(self, **params):
874
+ return await self._request_margin_api("get", "sub-account/list", True, data=params)
875
+
876
+ async def get_sub_account_transfer_history(self, **params):
877
+ return await self._request_margin_api("get", "sub-account/sub/transfer/history", True, data=params)
878
+
879
+ async def get_sub_account_futures_transfer_history(self, **params):
880
+ return await self._request_margin_api("get", "sub-account/futures/internalTransfer", True, data=params)
881
+
882
+ async def create_sub_account_futures_transfer(self, **params):
883
+ return await self._request_margin_api("post", "sub-account/futures/internalTransfer", True, data=params)
884
+
885
+ async def get_sub_account_assets(self, **params):
886
+ return await self._request_margin_api("get", "sub-account/assets", True, data=params)
887
+
888
+ async def query_subaccount_spot_summary(self, **params):
889
+ return await self._request_margin_api("get", "sub-account/spotSummary", True, data=params)
890
+
891
+ async def get_subaccount_deposit_address(self, **params):
892
+ return await self._request_margin_api("get", "capital/deposit/subAddress", True, data=params)
893
+
894
+ async def get_subaccount_deposit_history(self, **params):
895
+ return await self._request_margin_api("get", "capital/deposit/subHisrec", True, data=params)
896
+
897
+ async def get_subaccount_futures_margin_status(self, **params):
898
+ return await self._request_margin_api("get", "sub-account/status", True, data=params)
899
+
900
+ async def enable_subaccount_margin(self, **params):
901
+ return await self._request_margin_api("post", "sub-account/margin/enable", True, data=params)
902
+
903
+ async def get_subaccount_margin_details(self, **params):
904
+ return await self._request_margin_api("get", "sub-account/margin/account", True, data=params)
905
+
906
+ async def get_subaccount_margin_summary(self, **params):
907
+ return await self._request_margin_api("get", "sub-account/margin/accountSummary", True, data=params)
908
+
909
+ async def enable_subaccount_futures(self, **params):
910
+ return await self._request_margin_api("post", "sub-account/futures/enable", True, data=params)
911
+
912
+ async def get_subaccount_futures_details(self, **params):
913
+ return await self._request_margin_api("get", "sub-account/futures/account", True, data=params)
914
+
915
+ async def get_subaccount_futures_summary(self, **params):
916
+ return await self._request_margin_api("get", "sub-account/futures/accountSummary", True, data=params)
917
+
918
+ async def get_subaccount_futures_positionrisk(self, **params):
919
+ return await self._request_margin_api("get", "sub-account/futures/positionRisk", True, data=params)
920
+
921
+ async def make_subaccount_futures_transfer(self, **params):
922
+ return await self._request_margin_api("post", "sub-account/futures/transfer", True, data=params)
923
+
924
+ async def make_subaccount_margin_transfer(self, **params):
925
+ return await self._request_margin_api("post", "sub-account/margin/transfer", True, data=params)
926
+
927
+ async def make_subaccount_to_subaccount_transfer(self, **params):
928
+ return await self._request_margin_api("post", "sub-account/transfer/subToSub", True, data=params)
929
+
930
+ async def make_subaccount_to_master_transfer(self, **params):
931
+ return await self._request_margin_api("post", "sub-account/transfer/subToMaster", True, data=params)
932
+
933
+ async def get_subaccount_transfer_history(self, **params):
934
+ return await self._request_margin_api("get", "sub-account/transfer/subUserHistory", True, data=params)
935
+
936
+ async def make_subaccount_universal_transfer(self, **params):
937
+ return await self._request_margin_api("post", "sub-account/universalTransfer", True, data=params)
938
+
939
+ async def get_universal_transfer_history(self, **params):
940
+ return await self._request_margin_api("get", "sub-account/universalTransfer", True, data=params)
941
+
942
+ # Futures API
943
+
944
+ async def futures_ping(self):
945
+ return await self._request_futures_api("get", "ping")
946
+
947
+ async def futures_time(self):
948
+ return await self._request_futures_api("get", "time")
949
+
950
+ async def futures_exchange_info(self):
951
+ return await self._request_futures_api("get", "exchangeInfo")
952
+
953
+ async def futures_order_book(self, **params):
954
+ return await self._request_futures_api("get", "depth", data=params)
955
+
956
+ async def futures_recent_trades(self, **params):
957
+ return await self._request_futures_api("get", "trades", data=params)
958
+
959
+ async def futures_historical_trades(self, **params):
960
+ return await self._request_futures_api("get", "historicalTrades", data=params)
961
+
962
+ async def futures_aggregate_trades(self, **params):
963
+ return await self._request_futures_api("get", "aggTrades", data=params)
964
+
965
+ async def futures_klines(self, **params):
966
+ return await self._request_futures_api("get", "klines", data=params)
967
+
968
+ async def futures_continuous_klines(self, **params):
969
+ return await self._request_futures_api("get", "continuousKlines", data=params)
970
+
971
+ async def futures_mark_price(self, **params):
972
+ return await self._request_futures_api("get", "premiumIndex", data=params)
973
+
974
+ async def futures_funding_rate(self, **params):
975
+ return await self._request_futures_api("get", "fundingRate", data=params)
976
+
977
+ async def futures_ticker(self, **params):
978
+ return await self._request_futures_api("get", "ticker/24hr", data=params)
979
+
980
+ async def futures_symbol_ticker(self, **params):
981
+ return await self._request_futures_api("get", "ticker/price", data=params)
982
+
983
+ async def futures_orderbook_ticker(self, **params):
984
+ return await self._request_futures_api("get", "ticker/bookTicker", data=params)
985
+
986
+ async def futures_liquidation_orders(self, **params):
987
+ return await self._request_futures_api("get", "forceOrders", signed=True, data=params)
988
+
989
+ async def futures_adl_quantile_estimate(self, **params):
990
+ return await self._request_futures_api("get", "adlQuantile", signed=True, data=params)
991
+
992
+ async def futures_open_interest(self, **params):
993
+ return await self._request_futures_api("get", "openInterest", data=params)
994
+
995
+ async def futures_open_interest_hist(self, **params):
996
+ return await self._request_futures_data_api("get", "openInterestHist", data=params)
997
+
998
+ async def futures_leverage_bracket(self, **params):
999
+ return await self._request_futures_api("get", "leverageBracket", True, data=params)
1000
+
1001
+ async def futures_account_transfer(self, **params):
1002
+ return await self._request_margin_api("post", "futures/transfer", True, data=params)
1003
+
1004
+ async def transfer_history(self, **params):
1005
+ return await self._request_margin_api("get", "futures/transfer", True, data=params)
1006
+
1007
+ async def futures_create_order(self, **params):
1008
+ return await self._request_futures_api("post", "order", True, data=params)
1009
+
1010
+ async def futures_create_twap_order(self, **params):
1011
+ return await self._request_margin_api("post", "algo/futures/newOrderTwap", True, force_params=True, data=params)
1012
+
1013
+ async def futures_create_vp_order(self, **params):
1014
+ return await self._request_margin_api("post", "algo/futures/newOrderVp", True, force_params=True, data=params)
1015
+
1016
+ async def futures_cancel_algo_order(self, **params):
1017
+ return await self._request_margin_api("delete", "algo/futures/order", True, force_params=True, data=params)
1018
+
1019
+ async def futures_get_algo_open_orders(self, **params):
1020
+ return await self._request_margin_api("get", "algo/futures/openOrders", True, data=params)
1021
+
1022
+ async def futures_get_algo_historical_orders(self, **params):
1023
+ return await self._request_margin_api("get", "algo/futures/historicalOrders", True, data=params)
1024
+
1025
+ async def futures_get_algo_suborders(self, **params):
1026
+ return await self._request_margin_api("get", "algo/futures/subOrders", True, data=params)
1027
+
1028
+ async def get_staking_products(self, **params):
1029
+ return await self._request_margin_api("get", "staking/productList", True, data=params)
1030
+
1031
+ async def purchase_staking(self, **params):
1032
+ return await self._request_margin_api("post", "staking/purchase", True, data=params)
1033
+
1034
+ async def redeem_staking(self, **params):
1035
+ return await self._request_margin_api("post", "staking/redeem", True, data=params)
1036
+
1037
+ async def get_staking_position(self, **params):
1038
+ return await self._request_margin_api("get", "staking/position", True, data=params)
1039
+
1040
+ async def get_staking_purchase_history(self, **params):
1041
+ return self._request_margin_api("get", "staking/purchaseRecord", True, data=params)
1042
+
1043
+ async def set_auto_staking(self, **params):
1044
+ return await self._request_margin_api("post", "staking/setAutoStaking", True, data=params)
1045
+
1046
+ async def get_personal_left_quota(self, **params):
1047
+ return await self._request_margin_api("get", "staking/personalLeftQuota", True, data=params)
1048
+
1049
+ async def futures_place_batch_order(self, **params):
1050
+ query_string = urlencode(params)
1051
+ query_string = query_string.replace("%27", "%22")
1052
+ params["batchOrders"] = query_string[12:]
1053
+ return await self._request_futures_api("post", "batchOrders", True, data=params)
1054
+
1055
+ async def futures_get_order(self, **params):
1056
+ return await self._request_futures_api("get", "order", True, data=params)
1057
+
1058
+ async def futures_get_open_orders(self, **params):
1059
+ return await self._request_futures_api("get", "openOrders", True, data=params)
1060
+
1061
+ async def futures_get_all_orders(self, **params):
1062
+ return await self._request_futures_api("get", "allOrders", True, data=params)
1063
+
1064
+ async def futures_cancel_order(self, **params):
1065
+ return await self._request_futures_api("delete", "order", True, data=params)
1066
+
1067
+ async def futures_cancel_all_open_orders(self, **params):
1068
+ return await self._request_futures_api("delete", "allOpenOrders", True, data=params)
1069
+
1070
+ async def futures_cancel_orders(self, **params):
1071
+ return await self._request_futures_api("delete", "batchOrders", True, data=params)
1072
+
1073
+ async def futures_account_balance(self, **params):
1074
+ return await self._request_futures_api("get", "balance", True, data=params)
1075
+
1076
+ async def futures_account(self, **params):
1077
+ return await self._request_futures_api("get", "account", True, data=params, version=2)
1078
+
1079
+ async def futures_change_leverage(self, **params):
1080
+ return await self._request_futures_api("post", "leverage", True, data=params)
1081
+
1082
+ async def futures_change_margin_type(self, **params):
1083
+ return await self._request_futures_api("post", "marginType", True, data=params)
1084
+
1085
+ async def futures_change_position_margin(self, **params):
1086
+ return await self._request_futures_api("post", "positionMargin", True, data=params)
1087
+
1088
+ async def futures_position_margin_history(self, **params):
1089
+ return await self._request_futures_api("get", "positionMargin/history", True, data=params)
1090
+
1091
+ async def futures_position_information(self, **params):
1092
+ return await self._request_futures_api("get", "positionRisk", True, data=params)
1093
+
1094
+ async def futures_account_trades(self, **params):
1095
+ return await self._request_futures_api("get", "userTrades", True, data=params)
1096
+
1097
+ async def futures_income_history(self, **params):
1098
+ return await self._request_futures_api("get", "income", True, data=params)
1099
+
1100
+ async def futures_change_position_mode(self, **params):
1101
+ return await self._request_futures_api("post", "positionSide/dual", True, data=params)
1102
+
1103
+ async def futures_get_position_mode(self, **params):
1104
+ return await self._request_futures_api("get", "positionSide/dual", True, data=params)
1105
+
1106
+ async def futures_change_multi_assets_mode(self, multiAssetsMargin: bool):
1107
+ params = {"multiAssetsMargin": "true" if multiAssetsMargin else "false"}
1108
+ return await self._request_futures_api("post", "multiAssetsMargin", True, data=params)
1109
+
1110
+ async def futures_get_multi_assets_mode(self):
1111
+ return await self._request_futures_api("get", "multiAssetsMargin", True, data={})
1112
+
1113
+ async def futures_stream_get_listen_key(self):
1114
+ res = await self._request_futures_api("post", "listenKey", signed=False, data={})
1115
+ return res["listenKey"]
1116
+
1117
+ async def futures_stream_keepalive(self):
1118
+ return await self._request_futures_api("put", "listenKey", signed=False, data={})
1119
+
1120
+ async def futures_stream_close(self):
1121
+ return await self._request_futures_api("delete", "listenKey", signed=False, data={})
1122
+
1123
+ # COIN Futures API
1124
+
1125
+ async def futures_coin_ping(self):
1126
+ return await self._request_futures_coin_api("get", "ping")
1127
+
1128
+ async def futures_coin_time(self):
1129
+ return await self._request_futures_coin_api("get", "time")
1130
+
1131
+ async def futures_coin_exchange_info(self):
1132
+ return await self._request_futures_coin_api("get", "exchangeInfo")
1133
+
1134
+ async def futures_coin_order_book(self, **params):
1135
+ return await self._request_futures_coin_api("get", "depth", data=params)
1136
+
1137
+ async def futures_coin_recent_trades(self, **params):
1138
+ return await self._request_futures_coin_api("get", "trades", data=params)
1139
+
1140
+ async def futures_coin_historical_trades(self, **params):
1141
+ return await self._request_futures_coin_api("get", "historicalTrades", data=params)
1142
+
1143
+ async def futures_coin_aggregate_trades(self, **params):
1144
+ return await self._request_futures_coin_api("get", "aggTrades", data=params)
1145
+
1146
+ async def futures_coin_klines(self, **params):
1147
+ return await self._request_futures_coin_api("get", "klines", data=params)
1148
+
1149
+ async def futures_coin_continous_klines(self, **params):
1150
+ return await self._request_futures_coin_api("get", "continuousKlines", data=params)
1151
+
1152
+ async def futures_coin_index_price_klines(self, **params):
1153
+ return await self._request_futures_coin_api("get", "indexPriceKlines", data=params)
1154
+
1155
+ async def futures_coin_mark_price_klines(self, **params):
1156
+ return await self._request_futures_coin_api("get", "markPriceKlines", data=params)
1157
+
1158
+ async def futures_coin_mark_price(self, **params):
1159
+ return await self._request_futures_coin_api("get", "premiumIndex", data=params)
1160
+
1161
+ async def futures_coin_funding_rate(self, **params):
1162
+ return await self._request_futures_coin_api("get", "fundingRate", data=params)
1163
+
1164
+ async def futures_coin_ticker(self, **params):
1165
+ return await self._request_futures_coin_api("get", "ticker/24hr", data=params)
1166
+
1167
+ async def futures_coin_symbol_ticker(self, **params):
1168
+ return await self._request_futures_coin_api("get", "ticker/price", data=params)
1169
+
1170
+ async def futures_coin_orderbook_ticker(self, **params):
1171
+ return await self._request_futures_coin_api("get", "ticker/bookTicker", data=params)
1172
+
1173
+ async def futures_coin_liquidation_orders(self, **params):
1174
+ return await self._request_futures_coin_api("get", "forceOrders", signed=True, data=params)
1175
+
1176
+ async def futures_coin_open_interest(self, **params):
1177
+ return await self._request_futures_coin_api("get", "openInterest", data=params)
1178
+
1179
+ async def futures_coin_open_interest_hist(self, **params):
1180
+ return await self._request_futures_coin_data_api("get", "openInterestHist", data=params)
1181
+
1182
+ async def futures_coin_leverage_bracket(self, **params):
1183
+ return await self._request_futures_coin_api("get", "leverageBracket", version=2, signed=True, data=params)
1184
+
1185
+ async def new_transfer_history(self, **params):
1186
+ return await self._request_margin_api("get", "asset/transfer", True, data=params)
1187
+
1188
+ async def universal_transfer(self, **params):
1189
+ return await self._request_margin_api("post", "asset/transfer", signed=True, data=params)
1190
+
1191
+ async def futures_coin_create_order(self, **params):
1192
+ return await self._request_futures_coin_api("post", "order", True, data=params)
1193
+
1194
+ async def futures_coin_place_batch_order(self, **params):
1195
+ query_string = urlencode(params)
1196
+ query_string = query_string.replace("%27", "%22")
1197
+ params["batchOrders"] = query_string[12:]
1198
+
1199
+ return await self._request_futures_coin_api("post", "batchOrders", True, data=params)
1200
+
1201
+ async def futures_coin_get_order(self, **params):
1202
+ return await self._request_futures_coin_api("get", "order", True, data=params)
1203
+
1204
+ async def futures_coin_get_open_orders(self, **params):
1205
+ return await self._request_futures_coin_api("get", "openOrders", True, data=params)
1206
+
1207
+ async def futures_coin_get_all_orders(self, **params):
1208
+ return await self._request_futures_coin_api("get", "allOrders", signed=True, data=params)
1209
+
1210
+ async def futures_coin_cancel_order(self, **params):
1211
+ return await self._request_futures_coin_api("delete", "order", signed=True, data=params)
1212
+
1213
+ async def futures_coin_cancel_all_open_orders(self, **params):
1214
+ return await self._request_futures_coin_api("delete", "allOpenOrders", signed=True, data=params)
1215
+
1216
+ async def futures_coin_cancel_orders(self, **params):
1217
+ return await self._request_futures_coin_api("delete", "batchOrders", True, data=params)
1218
+
1219
+ async def futures_coin_account_balance(self, **params):
1220
+ return await self._request_futures_coin_api("get", "balance", signed=True, data=params)
1221
+
1222
+ async def futures_coin_account(self, **params):
1223
+ return await self._request_futures_coin_api("get", "account", signed=True, data=params)
1224
+
1225
+ async def futures_coin_change_leverage(self, **params):
1226
+ return await self._request_futures_coin_api("post", "leverage", signed=True, data=params)
1227
+
1228
+ async def futures_coin_change_margin_type(self, **params):
1229
+ return await self._request_futures_coin_api("post", "marginType", signed=True, data=params)
1230
+
1231
+ async def futures_coin_change_position_margin(self, **params):
1232
+ return await self._request_futures_coin_api("post", "positionMargin", True, data=params)
1233
+
1234
+ async def futures_coin_position_margin_history(self, **params):
1235
+ return await self._request_futures_coin_api("get", "positionMargin/history", True, data=params)
1236
+
1237
+ async def futures_coin_position_information(self, **params):
1238
+ return await self._request_futures_coin_api("get", "positionRisk", True, data=params)
1239
+
1240
+ async def futures_coin_account_trades(self, **params):
1241
+ return await self._request_futures_coin_api("get", "userTrades", True, data=params)
1242
+
1243
+ async def futures_coin_income_history(self, **params):
1244
+ return await self._request_futures_coin_api("get", "income", True, data=params)
1245
+
1246
+ async def futures_coin_change_position_mode(self, **params):
1247
+ return await self._request_futures_coin_api("post", "positionSide/dual", True, data=params)
1248
+
1249
+ async def futures_coin_get_position_mode(self, **params):
1250
+ return await self._request_futures_coin_api("get", "positionSide/dual", True, data=params)
1251
+
1252
+ async def futures_coin_stream_get_listen_key(self):
1253
+ res = await self._request_futures_coin_api("post", "listenKey", signed=False, data={})
1254
+ return res["listenKey"]
1255
+
1256
+ async def futures_coin_stream_keepalive(self):
1257
+ return await self._request_futures_coin_api("put", "listenKey", signed=False, data={})
1258
+
1259
+ async def futures_coin_stream_close(self):
1260
+ return await self._request_futures_coin_api("delete", "listenKey", signed=False, data={})
1261
+
1262
+ async def get_all_coins_info(self, **params):
1263
+ return await self._request_margin_api("get", "capital/config/getall", True, data=params)
1264
+
1265
+ async def get_account_snapshot(self, **params):
1266
+ return await self._request_margin_api("get", "accountSnapshot", True, data=params)
1267
+
1268
+ async def disable_fast_withdraw_switch(self, **params):
1269
+ return await self._request_margin_api("post", "disableFastWithdrawSwitch", True, data=params)
1270
+
1271
+ async def enable_fast_withdraw_switch(self, **params):
1272
+ return await self._request_margin_api("post", "enableFastWithdrawSwitch", True, data=params)
1273
+
1274
+ """
1275
+ ====================================================================================================================
1276
+ Options API
1277
+ ====================================================================================================================
1278
+ """
1279
+
1280
+ # Quoting interface endpoints
1281
+
1282
+ async def options_ping(self):
1283
+ return await self._request_options_api("get", "ping")
1284
+
1285
+ async def options_time(self):
1286
+ return await self._request_options_api("get", "time")
1287
+
1288
+ async def options_info(self):
1289
+ return await self._request_options_api("get", "optionInfo")
1290
+
1291
+ async def options_exchange_info(self):
1292
+ return await self._request_options_api("get", "exchangeInfo")
1293
+
1294
+ async def options_index_price(self, **params):
1295
+ return await self._request_options_api("get", "index", data=params)
1296
+
1297
+ async def options_price(self, **params):
1298
+ return await self._request_options_api("get", "ticker", data=params)
1299
+
1300
+ async def options_mark_price(self, **params):
1301
+ return await self._request_options_api("get", "mark", data=params)
1302
+
1303
+ async def options_order_book(self, **params):
1304
+ return await self._request_options_api("get", "depth", data=params)
1305
+
1306
+ async def options_klines(self, **params):
1307
+ return await self._request_options_api("get", "klines", data=params)
1308
+
1309
+ async def options_recent_trades(self, **params):
1310
+ return await self._request_options_api("get", "trades", data=params)
1311
+
1312
+ async def options_historical_trades(self, **params):
1313
+ return await self._request_options_api("get", "historicalTrades", data=params)
1314
+
1315
+ # Account and trading interface endpoints
1316
+
1317
+ async def options_account_info(self, **params):
1318
+ return await self._request_options_api("get", "account", signed=True, data=params)
1319
+
1320
+ async def options_funds_transfer(self, **params):
1321
+ return await self._request_options_api("post", "transfer", signed=True, data=params)
1322
+
1323
+ async def options_positions(self, **params):
1324
+ return await self._request_options_api("get", "position", signed=True, data=params)
1325
+
1326
+ async def options_bill(self, **params):
1327
+ return await self._request_options_api("post", "bill", signed=True, data=params)
1328
+
1329
+ async def options_place_order(self, **params):
1330
+ return await self._request_options_api("post", "order", signed=True, data=params)
1331
+
1332
+ async def options_place_batch_order(self, **params):
1333
+ return await self._request_options_api("post", "batchOrders", signed=True, data=params)
1334
+
1335
+ async def options_cancel_order(self, **params):
1336
+ return await self._request_options_api("delete", "order", signed=True, data=params)
1337
+
1338
+ async def options_cancel_batch_order(self, **params):
1339
+ return await self._request_options_api("delete", "batchOrders", signed=True, data=params)
1340
+
1341
+ async def options_cancel_all_orders(self, **params):
1342
+ return await self._request_options_api("delete", "allOpenOrders", signed=True, data=params)
1343
+
1344
+ async def options_query_order(self, **params):
1345
+ return await self._request_options_api("get", "order", signed=True, data=params)
1346
+
1347
+ async def options_query_pending_orders(self, **params):
1348
+ return await self._request_options_api("get", "openOrders", signed=True, data=params)
1349
+
1350
+ async def options_query_order_history(self, **params):
1351
+ return await self._request_options_api("get", "historyOrders", signed=True, data=params)
1352
+
1353
+ async def options_user_trades(self, **params):
1354
+ return await self._request_options_api("get", "userTrades", signed=True, data=params)
1355
+
1356
+ # Fiat Endpoints
1357
+
1358
+ async def get_fiat_deposit_withdraw_history(self, **params):
1359
+ return await self._request_margin_api("get", "fiat/orders", signed=True, data=params)
1360
+
1361
+ async def get_fiat_payments_history(self, **params):
1362
+ return await self._request_margin_api("get", "fiat/payments", signed=True, data=params)
1363
+
1364
+ # Portfolio Margin Endpoints
1365
+ async def portfolio_margin_ping(self):
1366
+ return await self._request_portfolio_margin_api("get", "ping")
1367
+
1368
+ async def portfolio_margin_new_um_order(self, **params):
1369
+ return await self._request_portfolio_margin_api("post", "um/order", signed=True, data=params)
1370
+
1371
+ async def portfolio_margin_new_cm_order(self, **params):
1372
+ return await self._request_portfolio_margin_api("post", "cm/order", signed=True, data=params)
1373
+
1374
+ async def portfolio_margin_new_margin_order(self, **params):
1375
+ return await self._request_portfolio_margin_api("post", "margin/order", signed=True, data=params)
1376
+
1377
+ async def portfolio_margin_margin_account_borrow(self, **params):
1378
+ return await self._request_portfolio_margin_api("post", "marginLoan", signed=True, data=params)
1379
+
1380
+ async def portfolio_margin_margin_account_repay(self, **params):
1381
+ return await self._request_portfolio_margin_api("post", "repayLoan", signed=True, data=params)
1382
+
1383
+ async def portfolio_margin_margin_account_new_oco(self, **params):
1384
+ return await self._request_portfolio_margin_api("post", "margin/order/oco", signed=True, data=params)
1385
+
1386
+ async def portfolio_margin_new_um_conditional_order(self, **params):
1387
+ return await self._request_portfolio_margin_api("post", "um/conditional/order", signed=True, data=params)
1388
+
1389
+ async def portfolio_margin_new_cm_conditional_order(self, **params):
1390
+ return await self._request_portfolio_margin_api("post", "cm/conditional/order", signed=True, data=params)
1391
+
1392
+ async def portfolio_margin_cancel_um_order(self, **params):
1393
+ return await self._request_portfolio_margin_api("delete", "um/order", signed=True, data=params)
1394
+
1395
+ async def portfolio_margin_cancel_all_um_orders(self, **params):
1396
+ return await self._request_portfolio_margin_api("delete", "um/allOpenOrders", signed=True, data=params)
1397
+
1398
+ async def portfolio_margin_cancel_cm_order(self, **params):
1399
+ return await self._request_portfolio_margin_api("delete", "cm/order", signed=True, data=params)
1400
+
1401
+ async def portfolio_margin_cancel_all_cm_orders(self, **params):
1402
+ return await self._request_portfolio_margin_api("delete", "cm/allOpenOrders", signed=True, data=params)
1403
+
1404
+ async def portfolio_margin_cancel_margin_account_order(self, **params):
1405
+ return await self._request_portfolio_margin_api("delete", "margin/order", signed=True, data=params)
1406
+
1407
+ async def portfolio_margin_cancel_margin_account_all_orders(self, **params):
1408
+ return await self._request_portfolio_margin_api("delete", "margin/allOpenOrders", signed=True, data=params)
1409
+
1410
+ async def portfolio_margin_cancel_margin_oco_orders(self, **params):
1411
+ return await self._request_portfolio_margin_api("delete", "margin/orderList", signed=True, data=params)
1412
+
1413
+ async def portfolio_margin_cancel_um_conditional_order(self, **params):
1414
+ return await self._request_portfolio_margin_api("delete", "um/conditional/order", signed=True, data=params)
1415
+
1416
+ async def portfolio_margin_cancel_all_um_conditional_orders(self, **params):
1417
+ return await self._request_portfolio_margin_api(
1418
+ "delete", "um/conditional/allOpenOrders", signed=True, data=params
1419
+ )
1420
+
1421
+ async def portfolio_margin_cancel_cm_conditional_order(self, **params):
1422
+ return await self._request_portfolio_margin_api("delete", "cm/conditional/order", signed=True, data=params)
1423
+
1424
+ async def portfolio_margin_cancel_all_cm_conditional_orders(self, **params):
1425
+ return await self._request_portfolio_margin_api(
1426
+ "delete", "cm/conditional/allOpenOrders", signed=True, data=params
1427
+ )
1428
+
1429
+ async def portfolio_margin_query_um_order(self, **params):
1430
+ return await self._request_portfolio_margin_api("get", "um/order", signed=True, data=params)
1431
+
1432
+ async def portfolio_margin_query_current_um_open_order(self, **params):
1433
+ return await self._request_portfolio_margin_api("get", "um/openOrder", signed=True, data=params)
1434
+
1435
+ async def portfolio_margin_query_all_current_um_open_orders(self, **params):
1436
+ return await self._request_portfolio_margin_api("get", "um/openOrders", signed=True, data=params)
1437
+
1438
+ async def portfolio_margin_query_all_um_orders(self, **params):
1439
+ return await self._request_portfolio_margin_api("get", "um/allOrders", signed=True, data=params)
1440
+
1441
+ async def portfolio_margin_query_cm_order(self, **params):
1442
+ return await self._request_portfolio_margin_api("get", "cm/order", signed=True, data=params)
1443
+
1444
+ async def portfolio_margin_query_current_cm_open_order(self, **params):
1445
+ return await self._request_portfolio_margin_api("get", "cm/openOrder", signed=True, data=params)
1446
+
1447
+ async def portfolio_margin_query_all_current_cm_open_orders(self, **params):
1448
+ return await self._request_portfolio_margin_api("get", "cm/openOrders", signed=True, data=params)
1449
+
1450
+ async def portfolio_margin_query_all_cm_orders(self, **params):
1451
+ return await self._request_portfolio_margin_api("get", "cm/allOrders", signed=True, data=params)
1452
+
1453
+ async def portfolio_margin_query_current_um_open_conditional_order(self, **params):
1454
+ return await self._request_portfolio_margin_api("get", "um/conditional/openOrder", signed=True, data=params)
1455
+
1456
+ async def portfolio_margin_query_all_current_um_open_conditional_order(self, **params):
1457
+ return await self._request_portfolio_margin_api("get", "um/conditional/openOrders", signed=True, data=params)
1458
+
1459
+ async def portfolio_margin_query_um_conditional_order_history(self, **params):
1460
+ return await self._request_portfolio_margin_api("get", "um/conditional/orderHistory", signed=True, data=params)
1461
+
1462
+ async def portfolio_margin_query_all_um_conditional_orders(self, **params):
1463
+ return await self._request_portfolio_margin_api("get", "um/conditional/allOrders", signed=True, data=params)
1464
+
1465
+ async def portfolio_margin_query_current_cm_open_conditional_order(self, **params):
1466
+ return await self._request_portfolio_margin_api("get", "cm/conditional/openOrder", signed=True, data=params)
1467
+
1468
+ async def portfolio_margin_query_all_current_cm_open_conditional_order(self, **params):
1469
+ return await self._request_portfolio_margin_api("get", "cm/conditional/openOrders", signed=True, data=params)
1470
+
1471
+ async def portfolio_margin_query_cm_conditional_order_history(self, **params):
1472
+ return await self._request_portfolio_margin_api("get", "cm/conditional/orderHistory", signed=True, data=params)
1473
+
1474
+ async def portfolio_margin_query_all_cm_conditional_orders(self, **params):
1475
+ return await self._request_portfolio_margin_api("get", "cm/conditional/allOrders", signed=True, data=params)
1476
+
1477
+ async def portfolio_margin_query_margin_account_order(self, **params):
1478
+ return await self._request_portfolio_margin_api("get", "margin/order", signed=True, data=params)
1479
+
1480
+ async def portfolio_margin_query_current_margin_open_order(self, **params):
1481
+ return await self._request_portfolio_margin_api("get", "margin/openOrders", signed=True, data=params)
1482
+
1483
+ async def portfolio_margin_query_all_margin_account_orders(self, **params):
1484
+ return await self._request_portfolio_margin_api("get", "margin/allOrders", signed=True, data=params)
1485
+
1486
+ async def portfolio_margin_query_margin_account_oco(self, **params):
1487
+ return await self._request_portfolio_margin_api("get", "margin/orderList", signed=True, data=params)
1488
+
1489
+ async def portfolio_margin_query_margin_account_all_oco(self, **params):
1490
+ return await self._request_portfolio_margin_api("get", "margin/allOrderList", signed=True, data=params)
1491
+
1492
+ async def portfolio_margin_query_margin_account_open_oco(self, **params):
1493
+ return await self._request_portfolio_margin_api("get", "margin/openOrderList", signed=True, data=params)
1494
+
1495
+ async def portfolio_margin_margin_account_trade_list(self, **params):
1496
+ return await self._request_portfolio_margin_api("get", "margin/myTrades", signed=True, data=params)
1497
+
1498
+ async def portfolio_margin_balance(self, **params):
1499
+ return await self._request_portfolio_margin_api("get", "balance", signed=True, data=params)
1500
+
1501
+ async def portfolio_margin_account(self, **params):
1502
+ return await self._request_portfolio_margin_api("get", "account", signed=True, data=params)
1503
+
1504
+ async def portfolio_margin_max_borrowable(self, **params):
1505
+ return await self._request_portfolio_margin_api("get", "margin/maxBorrowable", signed=True, data=params)
1506
+
1507
+ async def portfolio_margin_max_withdraw(self, **params):
1508
+ return await self._request_portfolio_margin_api("get", "margin/maxWithdraw", signed=True, data=params)
1509
+
1510
+ async def portfolio_margin_um_position_information(self, **params):
1511
+ return await self._request_portfolio_margin_api("get", "um/positionRisk", signed=True, data=params)
1512
+
1513
+ async def portfolio_margin_cm_position_information(self, **params):
1514
+ return await self._request_portfolio_margin_api("get", "cm/positionRisk", signed=True, data=params)
1515
+
1516
+ async def portfolio_margin_um_leverage(self, **params):
1517
+ return await self._request_portfolio_margin_api("post", "um/leverage", signed=True, data=params)
1518
+
1519
+ async def portfolio_margin_cm_leverage(self, **params):
1520
+ return await self._request_portfolio_margin_api("post", "cm/leverage", signed=True, data=params)
1521
+
1522
+ async def portfolio_margin_change_um_position_mode(self, **params):
1523
+ return await self._request_portfolio_margin_api("post", "um/positionSide/dual", signed=True, data=params)
1524
+
1525
+ async def portfolio_margin_change_cm_position_mode(self, **params):
1526
+ return await self._request_portfolio_margin_api("post", "cm/positionSide/dual", signed=True, data=params)
1527
+
1528
+ async def portfolio_margin_um_position_mode(self, **params):
1529
+ return await self._request_portfolio_margin_api("get", "um/positionSide/dual", signed=True, data=params)
1530
+
1531
+ async def portfolio_margin_cm_position_mode(self, **params):
1532
+ return await self._request_portfolio_margin_api("get", "cm/positionSide/dual", signed=True, data=params)
1533
+
1534
+ async def portfolio_margin_um_account_trade_list(self, **params):
1535
+ return await self._request_portfolio_margin_api("get", "um/userTrades", signed=True, data=params)
1536
+
1537
+ async def portfolio_margin_cm_account_trade_list(self, **params):
1538
+ return await self._request_portfolio_margin_api("get", "cm/userTrades", signed=True, data=params)
1539
+
1540
+ async def portfolio_margin_um_leverage_bracket(self, **params):
1541
+ return await self._request_portfolio_margin_api("get", "um/leverageBracket", signed=True, data=params)
1542
+
1543
+ async def portfolio_margin_cm_leverage_bracket(self, **params):
1544
+ return await self._request_portfolio_margin_api("get", "cm/leverageBracket", signed=True, data=params)
1545
+
1546
+ async def portfolio_margin_user_force_orders(self, **params):
1547
+ return await self._request_portfolio_margin_api("get", "margin/forceOrders", signed=True, data=params)
1548
+
1549
+ async def portfolio_margin_um_force_orders(self, **params):
1550
+ return await self._request_portfolio_margin_api("get", "um/forceOrders", signed=True, data=params)
1551
+
1552
+ async def portfolio_margin_cm_force_orders(self, **params):
1553
+ return await self._request_portfolio_margin_api("get", "cm/forceOrders", signed=True, data=params)
1554
+
1555
+ async def portfolio_margin_um_trading_quantitative_rules(self, **params):
1556
+ return await self._request_portfolio_margin_api("get", "um/apiTradingStatus", signed=True, data=params)
1557
+
1558
+ async def portfolio_margin_um_commission_rate(self, **params):
1559
+ return await self._request_portfolio_margin_api("get", "um/commissionRate", signed=True, data=params)
1560
+
1561
+ async def portfolio_margin_cm_commission_rate(self, **params):
1562
+ return await self._request_portfolio_margin_api("get", "cm/commissionRate", signed=True, data=params)
1563
+
1564
+ async def portfolio_margin_margin_loan_record(self, **params):
1565
+ return await self._request_portfolio_margin_api("get", "margin/marginLoan", signed=True, data=params)
1566
+
1567
+ async def portfolio_margin_margin_repay_record(self, **params):
1568
+ return await self._request_portfolio_margin_api("get", "margin/repayLoan", signed=True, data=params)
1569
+
1570
+ async def portfolio_margin_margin_interest_history(self, **params):
1571
+ return await self._request_portfolio_margin_api("get", "margin/marginInterestHistory", signed=True, data=params)
1572
+
1573
+ async def portfolio_margin_negative_balance_interest_history(self, **params):
1574
+ return await self._request_portfolio_margin_api("get", "portfolio/interest-history", signed=True, data=params)
1575
+
1576
+ async def portfolio_margin_fund_auto_collection(self, **params):
1577
+ return await self._request_portfolio_margin_api("post", "auto-collection", signed=True, data=params)
1578
+
1579
+ async def portfolio_margin_fund_collection_by_asset(self, **params):
1580
+ return await self._request_portfolio_margin_api("post", "asset-collection", signed=True, data=params)
1581
+
1582
+ async def portfolio_margin_bnb_transfer(self, **params):
1583
+ return await self._request_portfolio_margin_api("post", "bnb-transfer", signed=True, data=params)
1584
+
1585
+ async def portfolio_margin_um_income_history(self, **params):
1586
+ return await self._request_portfolio_margin_api("get", "um/income", signed=True, data=params)
1587
+
1588
+ async def portfolio_margin_cm_income_history(self, **params):
1589
+ return await self._request_portfolio_margin_api("get", "cm/income", signed=True, data=params)
1590
+
1591
+ async def portfolio_margin_um_account_detail(self, **params):
1592
+ return await self._request_portfolio_margin_api("get", "um/account", signed=True, data=params)
1593
+
1594
+ async def portfolio_margin_cm_account_detail(self, **params):
1595
+ return await self._request_portfolio_margin_api("get", "cm/account", signed=True, data=params)
1596
+
1597
+ async def portfolio_margin_change_auto_repay_futures_status(self, **params):
1598
+ return await self._request_portfolio_margin_api("post", "repay-futures-switch", signed=True, data=params)
1599
+
1600
+ async def portfolio_margin_get_auto_repay_futures_status(self, **params):
1601
+ return await self._request_portfolio_margin_api("get", "repay-futures-switch", signed=True, data=params)
1602
+
1603
+ async def portfolio_margin_repay_futures_negative_balance(self, **params):
1604
+ return await self._request_portfolio_margin_api(
1605
+ "post", "repay-futures-negative-balance", signed=True, data=params
1606
+ )
1607
+
1608
+ async def portfolio_margin_um_position_adl_quantile(self, **params):
1609
+ return await self._request_portfolio_margin_api("get", "um/adlQuantile", signed=True, data=params)
1610
+
1611
+ async def portfolio_margin_cm_position_adl_quantile(self, **params):
1612
+ return await self._request_portfolio_margin_api("get", "cm/adlQuantile", signed=True, data=params)
1613
+
1614
+ async def portfolio_margin_stream_get_listen_key(self) -> str:
1615
+ res = await self._request_portfolio_margin_api("post", "listenKey", signed=False, data={})
1616
+ return res["listenKey"]
1617
+
1618
+ async def portfolio_margin_stream_keepalive(self) -> dict:
1619
+ """
1620
+ @return: empty dict {}
1621
+ """
1622
+ return await self._request_portfolio_margin_api("put", "listenKey", signed=False, data={})
1623
+
1624
+ async def portfolio_margin_stream_close(self) -> dict:
1625
+ """
1626
+ @return: empty dict {}
1627
+ """
1628
+ return await self._request_portfolio_margin_api("delete", "listenKey", signed=False, data={})
1629
+
1630
+ # C2C Endpoints
1631
+
1632
+ async def get_c2c_trade_history(self, **params):
1633
+ return await self._request_margin_api("get", "c2c/orderMatch/listUserOrderHistory", signed=True, data=params)
1634
+
1635
+ # Crypto Loans Endpoints
1636
+
1637
+ async def get_crypto_loans_income_history(self, **params):
1638
+ return await self._request_margin_api("get", "loan/income", signed=True, data=params)
1639
+
1640
+ async def borrow_crypto_loans(self, **params):
1641
+ return await self._request_margin_api("post", "loan/borrow", signed=True, data=params)
1642
+
1643
+ async def get_loan_borrow_history(self, **params):
1644
+ return await self._request_margin_api("get", "loan/borrow/history", signed=True, data=params)
1645
+
1646
+ async def get_loan_ongoing_orders(self, **params):
1647
+ return await self._request_margin_api("get", "loan/ongoing/orders", signed=True, data=params)
1648
+
1649
+ async def repay_crypto_loans(self, **params):
1650
+ return await self._request_margin_api("post", "loan/repay", signed=True, data=params)
1651
+
1652
+ async def get_loan_repayment_history(self, **params):
1653
+ return await self._request_margin_api("get", "loan/repay/history", signed=True, data=params)
1654
+
1655
+ async def crypto_loan_adjust_ltv(self, **params):
1656
+ return await self._request_margin_api("post", "loan/adjust/ltv", signed=True, data=params)
1657
+
1658
+ async def get_loan_ltv_adjustments_history(self, **params):
1659
+ return await self._request_margin_api("get", "loan/ltv/adjustments/history", signed=True, data=params)
1660
+
1661
+ async def get_loanable_assets_data(self, **params):
1662
+ return await self._request_margin_api("get", "loan/loanable/data", signed=True, data=params)
1663
+
1664
+ async def get_collateral_assets_data(self, **params):
1665
+ return await self._request_margin_api("get", "loan/collateral/data", signed=True, data=params)
1666
+
1667
+ async def get_collateral_repay_rate(self, **params):
1668
+ return await self._request_margin_api("get", "loan/repay/collateral/rate", signed=True, data=params)
1669
+
1670
+ async def customize_crypto_loan_margin_call(self, **params):
1671
+ return await self._request_margin_api("post", "loan/customize/margin_call", signed=True, data=params)