walrasquant-lib 0.4.20__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.
Files changed (105) hide show
  1. walrasquant/__init__.py +7 -0
  2. walrasquant/aggregation.py +449 -0
  3. walrasquant/backends/__init__.py +5 -0
  4. walrasquant/backends/db.py +109 -0
  5. walrasquant/backends/db_memory.py +61 -0
  6. walrasquant/backends/db_postgresql.py +321 -0
  7. walrasquant/backends/db_sqlite.py +310 -0
  8. walrasquant/base/__init__.py +24 -0
  9. walrasquant/base/api_client.py +46 -0
  10. walrasquant/base/connector.py +863 -0
  11. walrasquant/base/ems.py +794 -0
  12. walrasquant/base/exchange.py +213 -0
  13. walrasquant/base/oms.py +428 -0
  14. walrasquant/base/retry.py +220 -0
  15. walrasquant/base/sms.py +545 -0
  16. walrasquant/base/ws_client.py +408 -0
  17. walrasquant/config.py +284 -0
  18. walrasquant/constants.py +413 -0
  19. walrasquant/core/__init__.py +0 -0
  20. walrasquant/core/cache.py +688 -0
  21. walrasquant/core/clock.py +59 -0
  22. walrasquant/core/connection.py +41 -0
  23. walrasquant/core/entity.py +504 -0
  24. walrasquant/core/nautilius_core.py +103 -0
  25. walrasquant/core/registry.py +41 -0
  26. walrasquant/engine.py +745 -0
  27. walrasquant/error.py +34 -0
  28. walrasquant/exchange/__init__.py +13 -0
  29. walrasquant/exchange/base_factory.py +172 -0
  30. walrasquant/exchange/binance/__init__.py +30 -0
  31. walrasquant/exchange/binance/connector.py +1093 -0
  32. walrasquant/exchange/binance/constants.py +934 -0
  33. walrasquant/exchange/binance/ems.py +140 -0
  34. walrasquant/exchange/binance/error.py +48 -0
  35. walrasquant/exchange/binance/exchange.py +144 -0
  36. walrasquant/exchange/binance/factory.py +115 -0
  37. walrasquant/exchange/binance/oms.py +1807 -0
  38. walrasquant/exchange/binance/rest_api.py +1653 -0
  39. walrasquant/exchange/binance/schema.py +1063 -0
  40. walrasquant/exchange/binance/websockets.py +389 -0
  41. walrasquant/exchange/bitget/__init__.py +28 -0
  42. walrasquant/exchange/bitget/connector.py +578 -0
  43. walrasquant/exchange/bitget/constants.py +392 -0
  44. walrasquant/exchange/bitget/ems.py +202 -0
  45. walrasquant/exchange/bitget/error.py +36 -0
  46. walrasquant/exchange/bitget/exchange.py +128 -0
  47. walrasquant/exchange/bitget/factory.py +135 -0
  48. walrasquant/exchange/bitget/oms.py +1619 -0
  49. walrasquant/exchange/bitget/rest_api.py +610 -0
  50. walrasquant/exchange/bitget/schema.py +885 -0
  51. walrasquant/exchange/bitget/websockets.py +753 -0
  52. walrasquant/exchange/bybit/__init__.py +32 -0
  53. walrasquant/exchange/bybit/connector.py +819 -0
  54. walrasquant/exchange/bybit/constants.py +479 -0
  55. walrasquant/exchange/bybit/ems.py +93 -0
  56. walrasquant/exchange/bybit/error.py +36 -0
  57. walrasquant/exchange/bybit/exchange.py +108 -0
  58. walrasquant/exchange/bybit/factory.py +128 -0
  59. walrasquant/exchange/bybit/oms.py +1195 -0
  60. walrasquant/exchange/bybit/rest_api.py +570 -0
  61. walrasquant/exchange/bybit/schema.py +867 -0
  62. walrasquant/exchange/bybit/websockets.py +307 -0
  63. walrasquant/exchange/hyperliquid/__init__.py +28 -0
  64. walrasquant/exchange/hyperliquid/connector.py +370 -0
  65. walrasquant/exchange/hyperliquid/constants.py +371 -0
  66. walrasquant/exchange/hyperliquid/ems.py +156 -0
  67. walrasquant/exchange/hyperliquid/error.py +48 -0
  68. walrasquant/exchange/hyperliquid/exchange.py +120 -0
  69. walrasquant/exchange/hyperliquid/factory.py +135 -0
  70. walrasquant/exchange/hyperliquid/oms.py +1081 -0
  71. walrasquant/exchange/hyperliquid/rest_api.py +348 -0
  72. walrasquant/exchange/hyperliquid/schema.py +583 -0
  73. walrasquant/exchange/hyperliquid/websockets.py +592 -0
  74. walrasquant/exchange/okx/__init__.py +25 -0
  75. walrasquant/exchange/okx/connector.py +931 -0
  76. walrasquant/exchange/okx/constants.py +518 -0
  77. walrasquant/exchange/okx/ems.py +144 -0
  78. walrasquant/exchange/okx/error.py +66 -0
  79. walrasquant/exchange/okx/exchange.py +102 -0
  80. walrasquant/exchange/okx/factory.py +138 -0
  81. walrasquant/exchange/okx/oms.py +1199 -0
  82. walrasquant/exchange/okx/rest_api.py +799 -0
  83. walrasquant/exchange/okx/schema.py +1449 -0
  84. walrasquant/exchange/okx/websockets.py +420 -0
  85. walrasquant/exchange/registry.py +201 -0
  86. walrasquant/execution/__init__.py +24 -0
  87. walrasquant/execution/algorithm.py +968 -0
  88. walrasquant/execution/algorithms/__init__.py +3 -0
  89. walrasquant/execution/algorithms/twap.py +392 -0
  90. walrasquant/execution/config.py +34 -0
  91. walrasquant/execution/constants.py +27 -0
  92. walrasquant/execution/schema.py +62 -0
  93. walrasquant/indicator.py +382 -0
  94. walrasquant/push.py +77 -0
  95. walrasquant/schema.py +755 -0
  96. walrasquant/strategy.py +1805 -0
  97. walrasquant/tools/__init__.py +0 -0
  98. walrasquant/tools/pm2_wrapper.py +1016 -0
  99. walrasquant/web/__init__.py +26 -0
  100. walrasquant/web/app.py +157 -0
  101. walrasquant/web/server.py +92 -0
  102. walrasquant_lib-0.4.20.dist-info/METADATA +162 -0
  103. walrasquant_lib-0.4.20.dist-info/RECORD +105 -0
  104. walrasquant_lib-0.4.20.dist-info/WHEEL +4 -0
  105. walrasquant_lib-0.4.20.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,1653 @@
1
+ import hmac
2
+ import hashlib
3
+ import msgspec
4
+
5
+ from typing import Any
6
+ from urllib.parse import urljoin, urlencode
7
+ import asyncio
8
+ import aiohttp
9
+ import yarl
10
+
11
+ from walrasquant.base import ApiClient, RetryManager
12
+ from walrasquant.exchange.binance.schema import (
13
+ BinanceOrder,
14
+ BinanceListenKey,
15
+ BinanceSpotAccountInfo,
16
+ BinanceFuturesAccountInfo,
17
+ BinanceResponseKline,
18
+ BinanceFuturesModifyOrderResponse,
19
+ BinanceCancelAllOrdersResponse,
20
+ BinanceFundingRateResponse,
21
+ BinancePortfolioMarginBalance,
22
+ BinancePortfolioMarginPositionRisk,
23
+ BinanceIndexResponseKline,
24
+ BinanceBatchOrderResponse,
25
+ BinanceFuture24hrTicker,
26
+ BinanceSpot24hrTicker,
27
+ BinanceDepthSnapshotData,
28
+ BinanceBnbTransferResponse,
29
+ )
30
+ from walrasquant.exchange.binance.constants import (
31
+ BinanceAccountType,
32
+ BinanceRateLimiter,
33
+ )
34
+ from walrasquant.exchange.binance.error import BinanceClientError, BinanceServerError
35
+ from walrasquant.core.nautilius_core import hmac_signature, LiveClock
36
+
37
+
38
+ class BinanceApiClient(ApiClient):
39
+ _limiter: BinanceRateLimiter
40
+
41
+ def __init__(
42
+ self,
43
+ clock: LiveClock,
44
+ api_key: str | None = None,
45
+ secret: str | None = None,
46
+ testnet: bool = False,
47
+ timeout: int = 10,
48
+ enable_rate_limit: bool = True,
49
+ max_retries: int = 0,
50
+ delay_initial_ms: int = 100,
51
+ delay_max_ms: int = 800,
52
+ backoff_factor: int = 2,
53
+ ):
54
+ super().__init__(
55
+ clock=clock,
56
+ api_key=api_key,
57
+ secret=secret,
58
+ timeout=timeout,
59
+ rate_limiter=BinanceRateLimiter(enable_rate_limit),
60
+ retry_manager=RetryManager(
61
+ max_retries=max_retries,
62
+ delay_initial_ms=delay_initial_ms,
63
+ delay_max_ms=delay_max_ms,
64
+ backoff_factor=backoff_factor,
65
+ exc_types=(BinanceClientError, BinanceServerError),
66
+ retry_check=lambda e: e.code in [-1000, -1001],
67
+ ),
68
+ )
69
+ self._headers = {
70
+ "Content-Type": "application/json",
71
+ "User-Agent": "TradingBot/1.0",
72
+ }
73
+
74
+ if api_key:
75
+ self._headers["X-MBX-APIKEY"] = api_key
76
+
77
+ self._testnet = testnet
78
+ self._msg_encoder = msgspec.json.Encoder()
79
+ self._msg_decoder = msgspec.json.Decoder()
80
+ self._order_decoder = msgspec.json.Decoder(BinanceOrder)
81
+ self._spot_account_decoder = msgspec.json.Decoder(BinanceSpotAccountInfo)
82
+ self._futures_account_decoder = msgspec.json.Decoder(BinanceFuturesAccountInfo)
83
+ self._listen_key_decoder = msgspec.json.Decoder(BinanceListenKey)
84
+ self._kline_response_decoder = msgspec.json.Decoder(list[BinanceResponseKline])
85
+ self._index_kline_response_decoder = msgspec.json.Decoder(
86
+ list[BinanceIndexResponseKline]
87
+ )
88
+ self._futures_modify_order_decoder = msgspec.json.Decoder(
89
+ BinanceFuturesModifyOrderResponse
90
+ )
91
+ self._cancel_all_orders_decoder = msgspec.json.Decoder(
92
+ BinanceCancelAllOrdersResponse
93
+ )
94
+ self._funding_rate_decoder = msgspec.json.Decoder(
95
+ list[BinanceFundingRateResponse]
96
+ )
97
+ self._portfolio_margin_balance_decoder = msgspec.json.Decoder(
98
+ list[BinancePortfolioMarginBalance]
99
+ )
100
+ self._portfolio_margin_position_risk_decoder = msgspec.json.Decoder(
101
+ list[BinancePortfolioMarginPositionRisk]
102
+ )
103
+ self._batch_order_decoder = msgspec.json.Decoder(
104
+ list[BinanceBatchOrderResponse]
105
+ )
106
+ self._single_future_24hr_ticker_decoder = msgspec.json.Decoder(
107
+ BinanceFuture24hrTicker
108
+ )
109
+ self._future_24hr_ticker_decoder = msgspec.json.Decoder(
110
+ list[BinanceFuture24hrTicker]
111
+ )
112
+ self._single_spot_24hr_ticker_decoder = msgspec.json.Decoder(
113
+ BinanceSpot24hrTicker
114
+ )
115
+ self._spot_24hr_ticker_decoder = msgspec.json.Decoder(
116
+ list[BinanceSpot24hrTicker]
117
+ )
118
+ self._depth_snapshot_decoder = msgspec.json.Decoder(BinanceDepthSnapshotData)
119
+ self._bnb_transfer_decoder = msgspec.json.Decoder(BinanceBnbTransferResponse)
120
+
121
+ def _generate_signature(self, query: str) -> str:
122
+ secret = self._secret
123
+ if secret is None:
124
+ raise ValueError("secret is required for signed Binance requests")
125
+ signature = hmac.new(
126
+ secret.encode("utf-8"), query.encode("utf-8"), hashlib.sha256
127
+ ).hexdigest()
128
+ return signature
129
+
130
+ def _generate_signature_v2(self, query: str) -> str:
131
+ secret = self._secret
132
+ if secret is None:
133
+ raise ValueError("secret is required for signed Binance requests")
134
+ signature = hmac_signature(secret, query)
135
+ return signature
136
+
137
+ async def _fetch(
138
+ self,
139
+ method: str,
140
+ base_url: str,
141
+ endpoint: str,
142
+ payload: dict[str, Any] | None = None,
143
+ signed: bool = False,
144
+ required_timestamp: bool = True,
145
+ ) -> Any:
146
+ retry_manager = self._retry_manager
147
+ if retry_manager is None:
148
+ raise ValueError("retry_manager is not configured")
149
+ return await retry_manager.run(
150
+ name=f"{method} {endpoint}",
151
+ func=self._fetch_async,
152
+ method=method,
153
+ base_url=base_url,
154
+ endpoint=endpoint,
155
+ payload=payload,
156
+ signed=signed,
157
+ required_timestamp=required_timestamp,
158
+ )
159
+
160
+ async def _fetch_async(
161
+ self,
162
+ method: str,
163
+ base_url: str,
164
+ endpoint: str,
165
+ payload: dict[str, Any] | None = None,
166
+ signed: bool = False,
167
+ required_timestamp: bool = True,
168
+ ) -> Any:
169
+ await self._init_session()
170
+ session = self._session
171
+ if session is None:
172
+ raise ValueError("HTTP session initialization failed")
173
+
174
+ url = urljoin(base_url, endpoint)
175
+ params = payload or {}
176
+ if required_timestamp:
177
+ params["timestamp"] = self._clock.timestamp_ms()
178
+ query = urlencode(params)
179
+
180
+ if signed:
181
+ signature = self._generate_signature_v2(query)
182
+ query += f"&signature={signature}"
183
+
184
+ # if method == "GET":
185
+ url = f"{url}?{query}"
186
+ data = None
187
+ # else:
188
+ # data = payload
189
+ self._log.debug(f"Request: {url}")
190
+
191
+ try:
192
+ async with session.request(
193
+ method=method,
194
+ url=yarl.URL(url, encoded=True),
195
+ headers=self._headers,
196
+ data=data,
197
+ ) as response:
198
+ raw = await response.read()
199
+ if response.status >= 400:
200
+ try:
201
+ error_msg = self._msg_decoder.decode(raw) if raw else {}
202
+ except msgspec.DecodeError:
203
+ error_msg = raw.decode()
204
+
205
+ if response.status >= 500:
206
+ msg = (
207
+ error_msg.get("msg", str(error_msg))
208
+ if isinstance(error_msg, dict)
209
+ else str(error_msg)
210
+ )
211
+ raise BinanceServerError(
212
+ code=int(response.status),
213
+ message=msg,
214
+ )
215
+ else:
216
+ if not isinstance(error_msg, dict):
217
+ raise BinanceClientError(
218
+ code=int(response.status),
219
+ message=str(error_msg),
220
+ )
221
+ raise BinanceClientError(
222
+ code=int(error_msg.get("code", response.status)),
223
+ message=error_msg.get("msg", "Unknown error"),
224
+ )
225
+ return raw
226
+ except asyncio.TimeoutError as e:
227
+ self._log.error(f"Timeout {method} {url} {e}")
228
+ raise
229
+ except aiohttp.ClientError as e:
230
+ self._log.error(f"Request Error {method} {url} {e}")
231
+ raise
232
+ except Exception as e:
233
+ self._log.error(f"Error {method} {url} {e}")
234
+ raise
235
+
236
+ def _get_base_url(self, account_type: BinanceAccountType) -> str:
237
+ if account_type == BinanceAccountType.SPOT:
238
+ if self._testnet:
239
+ return BinanceAccountType.SPOT_TESTNET.base_url
240
+ return BinanceAccountType.SPOT.base_url
241
+ elif account_type == BinanceAccountType.MARGIN:
242
+ return BinanceAccountType.MARGIN.base_url
243
+ elif account_type == BinanceAccountType.ISOLATED_MARGIN:
244
+ return BinanceAccountType.ISOLATED_MARGIN.base_url
245
+ elif account_type == BinanceAccountType.USD_M_FUTURE:
246
+ if self._testnet:
247
+ return BinanceAccountType.USD_M_FUTURE_TESTNET.base_url
248
+ return BinanceAccountType.USD_M_FUTURE.base_url
249
+ elif account_type == BinanceAccountType.COIN_M_FUTURE:
250
+ if self._testnet:
251
+ return BinanceAccountType.COIN_M_FUTURE_TESTNET.base_url
252
+ return BinanceAccountType.COIN_M_FUTURE.base_url
253
+ elif account_type == BinanceAccountType.PORTFOLIO_MARGIN:
254
+ return BinanceAccountType.PORTFOLIO_MARGIN.base_url
255
+ raise ValueError(f"Unsupported Binance account type: {account_type}")
256
+
257
+ async def put_dapi_v1_listen_key(self):
258
+ """
259
+ https://developers.binance.com/docs/derivatives/coin-margined-futures/user-data-streams/Keepalive-User-Data-Stream
260
+ """
261
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
262
+ end_point = "/dapi/v1/listenKey"
263
+ await self._limiter.dapi_weight_limit(cost=1)
264
+ raw = await self._fetch("PUT", base_url, end_point, required_timestamp=False)
265
+ return self._msg_decoder.decode(raw)
266
+
267
+ async def post_dapi_v1_listen_key(self):
268
+ """
269
+ https://developers.binance.com/docs/derivatives/coin-margined-futures/user-data-streams/Start-User-Data-Stream
270
+ """
271
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
272
+ end_point = "/dapi/v1/listenKey"
273
+ await self._limiter.dapi_weight_limit(cost=1)
274
+ raw = await self._fetch("POST", base_url, end_point, required_timestamp=False)
275
+ return self._listen_key_decoder.decode(raw)
276
+
277
+ async def post_api_v3_user_data_stream(self) -> BinanceListenKey:
278
+ """
279
+ https://developers.binance.com/docs/binance-spot-api-docs/rest-api/user-data-stream-endpoints-deprecated
280
+ """
281
+ base_url = self._get_base_url(BinanceAccountType.SPOT)
282
+ end_point = "/api/v3/userDataStream"
283
+ await self._limiter.api_weight_limit(cost=2)
284
+ raw = await self._fetch("POST", base_url, end_point, required_timestamp=False)
285
+ return self._listen_key_decoder.decode(raw)
286
+
287
+ async def put_api_v3_user_data_stream(self, listen_key: str):
288
+ """
289
+ https://developers.binance.com/docs/binance-spot-api-docs/user-data-stream
290
+ """
291
+ base_url = self._get_base_url(BinanceAccountType.SPOT)
292
+ end_point = "/api/v3/userDataStream"
293
+ await self._limiter.api_weight_limit(cost=2)
294
+ raw = await self._fetch(
295
+ "PUT",
296
+ base_url,
297
+ end_point,
298
+ payload={"listenKey": listen_key},
299
+ required_timestamp=False,
300
+ )
301
+ return self._msg_decoder.decode(raw)
302
+
303
+ async def post_sapi_v1_user_data_stream(self) -> BinanceListenKey:
304
+ """
305
+ https://developers.binance.com/docs/margin_trading/trade-data-stream/Start-Margin-User-Data-Stream
306
+ """
307
+ base_url = self._get_base_url(BinanceAccountType.MARGIN)
308
+ end_point = "/sapi/v1/userDataStream"
309
+ await self._limiter.api_weight_limit(cost=1)
310
+ raw = await self._fetch("POST", base_url, end_point, required_timestamp=False)
311
+ return self._listen_key_decoder.decode(raw)
312
+
313
+ async def put_sapi_v1_user_data_stream(self, listen_key: str):
314
+ """
315
+ https://developers.binance.com/docs/margin_trading/trade-data-stream/Keepalive-Margin-User-Data-Stream
316
+ """
317
+ base_url = self._get_base_url(BinanceAccountType.MARGIN)
318
+ end_point = "/sapi/v1/userDataStream"
319
+ await self._limiter.api_weight_limit(cost=1)
320
+ raw = await self._fetch(
321
+ "PUT",
322
+ base_url,
323
+ end_point,
324
+ payload={"listenKey": listen_key},
325
+ required_timestamp=False,
326
+ )
327
+ return self._msg_decoder.decode(raw)
328
+
329
+ async def post_sapi_v1_user_data_stream_isolated(
330
+ self, symbol: str
331
+ ) -> BinanceListenKey:
332
+ """
333
+ https://developers.binance.com/docs/margin_trading/trade-data-stream/Start-Isolated-Margin-User-Data-Stream
334
+ """
335
+ base_url = self._get_base_url(BinanceAccountType.ISOLATED_MARGIN)
336
+ end_point = "/sapi/v1/userDataStream/isolated"
337
+ await self._limiter.api_weight_limit(cost=1)
338
+ raw = await self._fetch(
339
+ "POST",
340
+ base_url,
341
+ end_point,
342
+ payload={"symbol": symbol},
343
+ required_timestamp=False,
344
+ )
345
+ return self._listen_key_decoder.decode(raw)
346
+
347
+ async def put_sapi_v1_user_data_stream_isolated(self, symbol: str, listen_key: str):
348
+ """
349
+ https://developers.binance.com/docs/margin_trading/trade-data-stream/Keepalive-Isolated-Margin-User-Data-Stream
350
+ """
351
+ base_url = self._get_base_url(BinanceAccountType.ISOLATED_MARGIN)
352
+ end_point = "/sapi/v1/userDataStream/isolated"
353
+ await self._limiter.api_weight_limit(cost=1)
354
+ raw = await self._fetch(
355
+ "PUT",
356
+ base_url,
357
+ end_point,
358
+ payload={"symbol": symbol, "listenKey": listen_key},
359
+ required_timestamp=False,
360
+ )
361
+ return self._msg_decoder.decode(raw)
362
+
363
+ async def post_fapi_v1_listen_key(self) -> BinanceListenKey:
364
+ """
365
+ https://developers.binance.com/docs/derivatives/usds-margined-futures/user-data-streams/Start-User-Data-Stream
366
+ """
367
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
368
+ end_point = "/fapi/v1/listenKey"
369
+ await self._limiter.fapi_weight_limit(cost=1)
370
+ raw = await self._fetch("POST", base_url, end_point, required_timestamp=False)
371
+ return self._listen_key_decoder.decode(raw)
372
+
373
+ async def put_fapi_v1_listen_key(self):
374
+ """
375
+ https://developers.binance.com/docs/derivatives/usds-margined-futures/user-data-streams/Keepalive-User-Data-Stream
376
+ """
377
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
378
+ end_point = "/fapi/v1/listenKey"
379
+ await self._limiter.fapi_weight_limit(cost=1)
380
+ raw = await self._fetch("PUT", base_url, end_point, required_timestamp=False)
381
+ return self._msg_decoder.decode(raw)
382
+
383
+ async def post_papi_v1_listen_key(self) -> BinanceListenKey:
384
+ """
385
+ https://developers.binance.com/docs/derivatives/portfolio-margin/user-data-streams/Start-User-Data-Stream
386
+ """
387
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
388
+ end_point = "/papi/v1/listenKey"
389
+ await self._limiter.papi_weight_limit(cost=1)
390
+ raw = await self._fetch("POST", base_url, end_point, required_timestamp=False)
391
+ return self._listen_key_decoder.decode(raw)
392
+
393
+ async def put_papi_v1_listen_key(self):
394
+ """
395
+ https://developers.binance.com/docs/derivatives/portfolio-margin/user-data-streams/Keepalive-User-Data-Stream
396
+ """
397
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
398
+ end_point = "/papi/v1/listenKey"
399
+ await self._limiter.papi_weight_limit(cost=1)
400
+ raw = await self._fetch("PUT", base_url, end_point, required_timestamp=False)
401
+ return self._msg_decoder.decode(raw)
402
+
403
+ async def post_sapi_v1_margin_order(
404
+ self,
405
+ symbol: str,
406
+ side: str,
407
+ type: str,
408
+ **kwargs,
409
+ ) -> BinanceOrder:
410
+ """
411
+ https://developers.binance.com/docs/margin_trading/trade/Margin-Account-New-Order
412
+ """
413
+ base_url = self._get_base_url(BinanceAccountType.MARGIN)
414
+ end_point = "/sapi/v1/margin/order"
415
+ await self._limiter.api_order_limit(cost=6)
416
+ data = {
417
+ "symbol": symbol,
418
+ "side": side,
419
+ "type": type,
420
+ **kwargs,
421
+ }
422
+ raw = await self._fetch("POST", base_url, end_point, payload=data, signed=True)
423
+ return self._order_decoder.decode(raw)
424
+
425
+ async def post_api_v3_order(
426
+ self,
427
+ symbol: str,
428
+ side: str,
429
+ type: str,
430
+ **kwargs,
431
+ ) -> BinanceOrder:
432
+ """
433
+ https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#new-order-trade
434
+ """
435
+ base_url = self._get_base_url(BinanceAccountType.SPOT)
436
+ end_point = "/api/v3/order"
437
+ await self._limiter.api_order_limit(cost=1)
438
+ data = {
439
+ "symbol": symbol,
440
+ "side": side,
441
+ "type": type,
442
+ **kwargs,
443
+ }
444
+ raw = await self._fetch("POST", base_url, end_point, payload=data, signed=True)
445
+ return self._order_decoder.decode(raw)
446
+
447
+ async def post_fapi_v1_order(
448
+ self,
449
+ symbol: str,
450
+ side: str,
451
+ type: str,
452
+ **kwargs,
453
+ ) -> BinanceOrder:
454
+ """
455
+ https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api
456
+ """
457
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
458
+ end_point = "/fapi/v1/order"
459
+ await self._limiter.fapi_order_limit()
460
+ data = {
461
+ "symbol": symbol,
462
+ "side": side,
463
+ "type": type,
464
+ **kwargs,
465
+ }
466
+ raw = await self._fetch("POST", base_url, end_point, payload=data, signed=True)
467
+ return self._order_decoder.decode(raw)
468
+
469
+ async def post_dapi_v1_order(
470
+ self,
471
+ symbol: str,
472
+ side: str,
473
+ type: str,
474
+ **kwargs,
475
+ ) -> BinanceOrder:
476
+ """
477
+ https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api
478
+ """
479
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
480
+ end_point = "/dapi/v1/order"
481
+ await self._limiter.dapi_order_limit()
482
+ data = {
483
+ "symbol": symbol,
484
+ "side": side,
485
+ "type": type,
486
+ **kwargs,
487
+ }
488
+ raw = await self._fetch("POST", base_url, end_point, payload=data, signed=True)
489
+ return self._order_decoder.decode(raw)
490
+
491
+ async def post_papi_v1_bnb_transfer(
492
+ self,
493
+ amount: str,
494
+ transferSide: str,
495
+ **kwargs,
496
+ ) -> BinanceBnbTransferResponse:
497
+ """
498
+ Transfer BNB in and out of UM.
499
+ https://developers.binance.com/docs/derivatives/portfolio-margin/transfer/BNB-Transfer
500
+ POST /papi/v1/bnb-transfer
501
+ Weight: 750 — max 10 calls per 10 minutes
502
+ transferSide: "TO_UM" or "FROM_UM"
503
+ """
504
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
505
+ end_point = "/papi/v1/bnb-transfer"
506
+ await self._limiter.papi_weight_limit(750)
507
+ data = {"amount": amount, "transferSide": transferSide, **kwargs}
508
+ raw = await self._fetch("POST", base_url, end_point, payload=data, signed=True)
509
+ return self._bnb_transfer_decoder.decode(raw)
510
+
511
+ async def post_papi_v1_um_order(
512
+ self,
513
+ symbol: str,
514
+ side: str,
515
+ type: str,
516
+ **kwargs,
517
+ ) -> BinanceOrder:
518
+ """
519
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade
520
+ """
521
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
522
+ end_point = "/papi/v1/um/order"
523
+ await self._limiter.papi_order_limit(cost=1)
524
+ data = {
525
+ "symbol": symbol,
526
+ "side": side,
527
+ "type": type,
528
+ **kwargs,
529
+ }
530
+ raw = await self._fetch("POST", base_url, end_point, payload=data, signed=True)
531
+ return self._order_decoder.decode(raw)
532
+
533
+ async def post_papi_v1_cm_order(
534
+ self,
535
+ symbol: str,
536
+ side: str,
537
+ type: str,
538
+ **kwargs,
539
+ ) -> BinanceOrder:
540
+ """
541
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/New-CM-Order
542
+ """
543
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
544
+ end_point = "/papi/v1/cm/order"
545
+ await self._limiter.papi_order_limit(cost=1)
546
+ data = {
547
+ "symbol": symbol,
548
+ "side": side,
549
+ "type": type,
550
+ **kwargs,
551
+ }
552
+ raw = await self._fetch("POST", base_url, end_point, payload=data, signed=True)
553
+ return self._order_decoder.decode(raw)
554
+
555
+ async def post_papi_v1_margin_order(
556
+ self,
557
+ symbol: str,
558
+ side: str,
559
+ type: str,
560
+ **kwargs,
561
+ ) -> BinanceOrder:
562
+ """
563
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/New-Margin-Order
564
+ """
565
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
566
+ end_point = "/papi/v1/margin/order"
567
+ await self._limiter.papi_order_limit(cost=1)
568
+ data = {
569
+ "symbol": symbol,
570
+ "side": side,
571
+ "type": type,
572
+ **kwargs,
573
+ }
574
+ raw = await self._fetch("POST", base_url, end_point, payload=data, signed=True)
575
+ return self._order_decoder.decode(raw)
576
+
577
+ async def delete_api_v3_order(
578
+ self, symbol: str, origClientOrderId: str, **kwargs
579
+ ) -> BinanceOrder:
580
+ """
581
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-UM-Order
582
+ """
583
+ base_url = self._get_base_url(BinanceAccountType.SPOT)
584
+ end_point = "/api/v3/order"
585
+ data = {
586
+ "symbol": symbol,
587
+ "origClientOrderId": origClientOrderId,
588
+ **kwargs,
589
+ }
590
+ raw = await self._fetch(
591
+ "DELETE", base_url, end_point, payload=data, signed=True
592
+ )
593
+ return self._order_decoder.decode(raw)
594
+
595
+ async def delete_sapi_v1_margin_order(
596
+ self, symbol: str, origClientOrderId: str, **kwargs
597
+ ) -> BinanceOrder:
598
+ """
599
+ https://developers.binance.com/docs/margin_trading/trade/Margin-Account-Cancel-Order
600
+ """
601
+ base_url = self._get_base_url(BinanceAccountType.MARGIN)
602
+ end_point = "/sapi/v1/margin/order"
603
+ data = {
604
+ "symbol": symbol,
605
+ "origClientOrderId": origClientOrderId,
606
+ **kwargs,
607
+ }
608
+ raw = await self._fetch(
609
+ "DELETE", base_url, end_point, payload=data, signed=True
610
+ )
611
+ return self._order_decoder.decode(raw)
612
+
613
+ async def delete_sapi_v1_margin_open_orders(self, symbol: str, **kwargs):
614
+ """
615
+ https://developers.binance.com/docs/margin_trading/trade/Margin-Account-Cancel-All-Open-Orders
616
+ DELETE /sapi/v1/margin/openOrders
617
+ """
618
+ base_url = self._get_base_url(BinanceAccountType.MARGIN)
619
+ end_point = "/sapi/v1/margin/openOrders"
620
+ data = {
621
+ "symbol": symbol,
622
+ **kwargs,
623
+ }
624
+ raw = await self._fetch(
625
+ "DELETE", base_url, end_point, payload=data, signed=True
626
+ )
627
+ return self._msg_decoder.decode(raw)
628
+
629
+ async def delete_fapi_v1_order(
630
+ self, symbol: str, origClientOrderId: str, **kwargs
631
+ ) -> BinanceOrder:
632
+ """
633
+ https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Cancel-Order
634
+ """
635
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
636
+ end_point = "/fapi/v1/order"
637
+ data = {
638
+ "symbol": symbol,
639
+ "origClientOrderId": origClientOrderId,
640
+ **kwargs,
641
+ }
642
+ raw = await self._fetch(
643
+ "DELETE", base_url, end_point, payload=data, signed=True
644
+ )
645
+ return self._order_decoder.decode(raw)
646
+
647
+ async def delete_dapi_v1_order(
648
+ self, symbol: str, origClientOrderId: str, **kwargs
649
+ ) -> BinanceOrder:
650
+ """
651
+ https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Cancel-Order
652
+ """
653
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
654
+ end_point = "/dapi/v1/order"
655
+ data = {
656
+ "symbol": symbol,
657
+ "origClientOrderId": origClientOrderId,
658
+ **kwargs,
659
+ }
660
+ raw = await self._fetch(
661
+ "DELETE", base_url, end_point, payload=data, signed=True
662
+ )
663
+ return self._order_decoder.decode(raw)
664
+
665
+ async def delete_papi_v1_um_order(
666
+ self, symbol: str, origClientOrderId: str, **kwargs
667
+ ) -> BinanceOrder:
668
+ """
669
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-UM-Order
670
+ """
671
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
672
+ end_point = "/papi/v1/um/order"
673
+ data = {
674
+ "symbol": symbol,
675
+ "origClientOrderId": origClientOrderId,
676
+ **kwargs,
677
+ }
678
+ raw = await self._fetch(
679
+ "DELETE", base_url, end_point, payload=data, signed=True
680
+ )
681
+ return self._order_decoder.decode(raw)
682
+
683
+ async def delete_papi_v1_cm_order(
684
+ self, symbol: str, origClientOrderId: str, **kwargs
685
+ ) -> BinanceOrder:
686
+ """
687
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-CM-Order
688
+ """
689
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
690
+ end_point = "/papi/v1/cm/order"
691
+ data = {
692
+ "symbol": symbol,
693
+ "origClientOrderId": origClientOrderId,
694
+ **kwargs,
695
+ }
696
+ raw = await self._fetch(
697
+ "DELETE", base_url, end_point, payload=data, signed=True
698
+ )
699
+ return self._order_decoder.decode(raw)
700
+
701
+ async def delete_papi_v1_margin_order(
702
+ self, symbol: str, origClientOrderId: str, **kwargs
703
+ ) -> BinanceOrder:
704
+ """
705
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-Margin-Account-Order
706
+ """
707
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
708
+ end_point = "/papi/v1/margin/order"
709
+ data = {
710
+ "symbol": symbol,
711
+ "origClientOrderId": origClientOrderId,
712
+ **kwargs,
713
+ }
714
+ raw = await self._fetch(
715
+ "DELETE", base_url, end_point, payload=data, signed=True
716
+ )
717
+ return self._order_decoder.decode(raw)
718
+
719
+ async def get_api_v3_order(
720
+ self, symbol: str, origClientOrderId: str, **kwargs
721
+ ) -> BinanceOrder:
722
+ """
723
+ https://developers.binance.com/docs/binance-spot-api-docs/rest-api/account-endpoints#query-order-user_data
724
+ """
725
+ base_url = self._get_base_url(BinanceAccountType.SPOT)
726
+ end_point = "/api/v3/order"
727
+ await self._limiter.api_weight_limit(4)
728
+ data = {
729
+ "symbol": symbol,
730
+ "origClientOrderId": origClientOrderId,
731
+ **kwargs,
732
+ }
733
+ raw = await self._fetch("GET", base_url, end_point, payload=data, signed=True)
734
+ return self._order_decoder.decode(raw)
735
+
736
+ async def get_sapi_v1_margin_order(
737
+ self, symbol: str, origClientOrderId: str, **kwargs
738
+ ) -> BinanceOrder:
739
+ """
740
+ https://developers.binance.com/docs/margin_trading/trade/Query-Margin-Account-Order
741
+ """
742
+ base_url = self._get_base_url(BinanceAccountType.MARGIN)
743
+ end_point = "/sapi/v1/margin/order"
744
+ await self._limiter.api_weight_limit(10)
745
+ data = {
746
+ "symbol": symbol,
747
+ "origClientOrderId": origClientOrderId,
748
+ **kwargs,
749
+ }
750
+ raw = await self._fetch("GET", base_url, end_point, payload=data, signed=True)
751
+ return self._order_decoder.decode(raw)
752
+
753
+ async def get_fapi_v1_order(
754
+ self, symbol: str, origClientOrderId: str, **kwargs
755
+ ) -> BinanceOrder:
756
+ """
757
+ https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Query-Order
758
+ """
759
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
760
+ end_point = "/fapi/v1/order"
761
+ await self._limiter.fapi_weight_limit(1)
762
+ data = {
763
+ "symbol": symbol,
764
+ "origClientOrderId": origClientOrderId,
765
+ **kwargs,
766
+ }
767
+ raw = await self._fetch("GET", base_url, end_point, payload=data, signed=True)
768
+ return self._order_decoder.decode(raw)
769
+
770
+ async def get_dapi_v1_order(
771
+ self, symbol: str, origClientOrderId: str, **kwargs
772
+ ) -> BinanceOrder:
773
+ """
774
+ https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Query-Order
775
+ """
776
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
777
+ end_point = "/dapi/v1/order"
778
+ await self._limiter.dapi_weight_limit(1)
779
+ data = {
780
+ "symbol": symbol,
781
+ "origClientOrderId": origClientOrderId,
782
+ **kwargs,
783
+ }
784
+ raw = await self._fetch("GET", base_url, end_point, payload=data, signed=True)
785
+ return self._order_decoder.decode(raw)
786
+
787
+ async def get_papi_v1_um_order(
788
+ self, symbol: str, origClientOrderId: str, **kwargs
789
+ ) -> BinanceOrder:
790
+ """
791
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-UM-Order
792
+ """
793
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
794
+ end_point = "/papi/v1/um/order"
795
+ await self._limiter.papi_weight_limit(1)
796
+ data = {
797
+ "symbol": symbol,
798
+ "origClientOrderId": origClientOrderId,
799
+ **kwargs,
800
+ }
801
+ raw = await self._fetch("GET", base_url, end_point, payload=data, signed=True)
802
+ return self._order_decoder.decode(raw)
803
+
804
+ async def get_papi_v1_cm_order(
805
+ self, symbol: str, origClientOrderId: str, **kwargs
806
+ ) -> BinanceOrder:
807
+ """
808
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-CM-Order
809
+ """
810
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
811
+ end_point = "/papi/v1/cm/order"
812
+ await self._limiter.papi_weight_limit(1)
813
+ data = {
814
+ "symbol": symbol,
815
+ "origClientOrderId": origClientOrderId,
816
+ **kwargs,
817
+ }
818
+ raw = await self._fetch("GET", base_url, end_point, payload=data, signed=True)
819
+ return self._order_decoder.decode(raw)
820
+
821
+ async def get_papi_v1_margin_order(
822
+ self, symbol: str, origClientOrderId: str, **kwargs
823
+ ) -> BinanceOrder:
824
+ """
825
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Query-Margin-Order
826
+ """
827
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
828
+ end_point = "/papi/v1/margin/order"
829
+ await self._limiter.papi_weight_limit(10)
830
+ data = {
831
+ "symbol": symbol,
832
+ "origClientOrderId": origClientOrderId,
833
+ **kwargs,
834
+ }
835
+ raw = await self._fetch("GET", base_url, end_point, payload=data, signed=True)
836
+ return self._order_decoder.decode(raw)
837
+
838
+ async def get_api_v3_account(self) -> BinanceSpotAccountInfo:
839
+ """
840
+ https://developers.binance.com/docs/binance-spot-api-docs/rest-api/account-endpoints#account-information-user_data
841
+ """
842
+ base_url = self._get_base_url(BinanceAccountType.SPOT)
843
+ end_point = "/api/v3/account"
844
+ await self._limiter.api_weight_limit(20)
845
+ raw = await self._fetch_async("GET", base_url, end_point, signed=True)
846
+ return self._spot_account_decoder.decode(raw)
847
+
848
+ async def get_fapi_v2_account(self) -> BinanceFuturesAccountInfo:
849
+ """
850
+ https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Account-Information-V2
851
+ """
852
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
853
+ end_point = "/fapi/v2/account"
854
+ await self._limiter.fapi_weight_limit(5)
855
+ raw = await self._fetch_async("GET", base_url, end_point, signed=True)
856
+ return self._futures_account_decoder.decode(raw)
857
+
858
+ async def get_dapi_v1_account(self) -> BinanceFuturesAccountInfo:
859
+ """
860
+ https://developers.binance.com/docs/derivatives/coin-margined-futures/account/rest-api/Account-Information
861
+ """
862
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
863
+ end_point = "/dapi/v1/account"
864
+ await self._limiter.dapi_weight_limit(5)
865
+ raw = await self._fetch_async("GET", base_url, end_point, signed=True)
866
+ return self._futures_account_decoder.decode(raw)
867
+
868
+ async def get_papi_v1_balance(self) -> list[BinancePortfolioMarginBalance]:
869
+ """
870
+ https://developers.binance.com/docs/derivatives/portfolio-margin/account
871
+ """
872
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
873
+ end_point = "/papi/v1/balance"
874
+ await self._limiter.papi_weight_limit(20)
875
+ raw = await self._fetch_async("GET", base_url, end_point, signed=True)
876
+ return self._portfolio_margin_balance_decoder.decode(raw)
877
+
878
+ async def get_papi_v1_um_position_risk(
879
+ self,
880
+ ) -> list[BinancePortfolioMarginPositionRisk]:
881
+ """
882
+ https://developers.binance.com/docs/derivatives/portfolio-margin/account/Query-UM-Position-Information
883
+ /papi/v1/um/positionRisk
884
+ """
885
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
886
+ end_point = "/papi/v1/um/positionRisk"
887
+ await self._limiter.papi_weight_limit(5)
888
+ raw = await self._fetch_async("GET", base_url, end_point, signed=True)
889
+ return self._portfolio_margin_position_risk_decoder.decode(raw)
890
+
891
+ async def get_papi_v1_cm_position_risk(
892
+ self,
893
+ ) -> list[BinancePortfolioMarginPositionRisk]:
894
+ """
895
+ https://developers.binance.com/docs/derivatives/portfolio-margin/account/Query-CM-Position-Information
896
+ /papi/v1/cm/positionRisk
897
+ """
898
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
899
+ end_point = "/papi/v1/cm/positionRisk"
900
+ await self._limiter.papi_weight_limit(1)
901
+ raw = await self._fetch_async("GET", base_url, end_point, signed=True)
902
+ return self._portfolio_margin_position_risk_decoder.decode(raw)
903
+
904
+ async def get_fapi_v1_klines(
905
+ self,
906
+ symbol: str,
907
+ interval: str,
908
+ startTime: int | None = None,
909
+ endTime: int | None = None,
910
+ limit: int | None = None,
911
+ ):
912
+ """
913
+ https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Kline-Candlestick-Data
914
+ """
915
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
916
+ end_point = "/fapi/v1/klines"
917
+ if limit is None: # default limit is 500
918
+ cost = 5
919
+ elif limit < 100:
920
+ cost = 1
921
+ elif limit < 500:
922
+ cost = 2
923
+ elif limit < 1000:
924
+ cost = 5
925
+ else:
926
+ cost = 10
927
+
928
+ await self._limiter.fapi_weight_limit(cost)
929
+
930
+ data: dict[str, int | str] = {
931
+ "symbol": symbol,
932
+ "interval": interval,
933
+ }
934
+
935
+ if startTime is not None:
936
+ data["startTime"] = startTime
937
+ if endTime is not None:
938
+ data["endTime"] = endTime
939
+ if limit is not None:
940
+ data["limit"] = limit
941
+
942
+ raw = await self._fetch_async(
943
+ "GET", base_url, end_point, payload=data, required_timestamp=False
944
+ )
945
+ return self._kline_response_decoder.decode(raw)
946
+
947
+ async def get_dapi_v1_klines(
948
+ self,
949
+ symbol: str,
950
+ interval: str,
951
+ startTime: int | None = None,
952
+ endTime: int | None = None,
953
+ limit: int | None = None,
954
+ ):
955
+ """
956
+ https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Kline-Candlestick-Data
957
+ """
958
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
959
+ end_point = "/dapi/v1/klines"
960
+
961
+ if limit is None: # default limit is 500
962
+ cost = 5
963
+ elif limit < 100:
964
+ cost = 1
965
+ elif limit < 500:
966
+ cost = 2
967
+ elif limit < 1000:
968
+ cost = 5
969
+ else:
970
+ cost = 10
971
+
972
+ await self._limiter.dapi_weight_limit(cost)
973
+
974
+ data = {
975
+ "symbol": symbol,
976
+ "interval": interval,
977
+ "startTime": startTime,
978
+ "endTime": endTime,
979
+ "limit": limit,
980
+ }
981
+ data = {k: v for k, v in data.items() if v is not None}
982
+ raw = await self._fetch_async(
983
+ "GET", base_url, end_point, payload=data, required_timestamp=False
984
+ )
985
+ return self._kline_response_decoder.decode(raw)
986
+
987
+ async def get_fapi_v1_index_price_klines(
988
+ self,
989
+ pair: str,
990
+ interval: str,
991
+ startTime: int | None = None,
992
+ endTime: int | None = None,
993
+ limit: int | None = None,
994
+ ):
995
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
996
+ end_point = "/fapi/v1/indexPriceKlines"
997
+ if limit is None: # default limit is 500
998
+ cost = 5
999
+ elif limit < 100:
1000
+ cost = 1
1001
+ elif limit < 500:
1002
+ cost = 2
1003
+ elif limit < 1000:
1004
+ cost = 5
1005
+ else:
1006
+ cost = 10
1007
+
1008
+ await self._limiter.fapi_weight_limit(cost)
1009
+ data = {
1010
+ "pair": pair,
1011
+ "interval": interval,
1012
+ "startTime": startTime,
1013
+ "endTime": endTime,
1014
+ "limit": limit,
1015
+ }
1016
+ data = {k: v for k, v in data.items() if v is not None}
1017
+ raw = await self._fetch_async(
1018
+ "GET", base_url, end_point, payload=data, required_timestamp=False
1019
+ )
1020
+ return self._index_kline_response_decoder.decode(raw)
1021
+
1022
+ async def get_dapi_v1_index_price_klines(
1023
+ self,
1024
+ pair: str,
1025
+ interval: str,
1026
+ startTime: int | None = None,
1027
+ endTime: int | None = None,
1028
+ limit: int | None = None,
1029
+ ):
1030
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
1031
+ end_point = "/dapi/v1/indexPriceKlines"
1032
+ if limit is None: # default limit is 500
1033
+ cost = 5
1034
+ elif limit < 100:
1035
+ cost = 1
1036
+ elif limit < 500:
1037
+ cost = 2
1038
+ elif limit < 1000:
1039
+ cost = 5
1040
+ else:
1041
+ cost = 10
1042
+
1043
+ await self._limiter.dapi_weight_limit(cost)
1044
+ data = {
1045
+ "pair": pair,
1046
+ "interval": interval,
1047
+ "startTime": startTime,
1048
+ "endTime": endTime,
1049
+ "limit": limit,
1050
+ }
1051
+ data = {k: v for k, v in data.items() if v is not None}
1052
+ raw = await self._fetch_async(
1053
+ "GET", base_url, end_point, payload=data, required_timestamp=False
1054
+ )
1055
+ return self._index_kline_response_decoder.decode(raw)
1056
+
1057
+ async def get_api_v3_klines(
1058
+ self,
1059
+ symbol: str,
1060
+ interval: str,
1061
+ startTime: int | None = None,
1062
+ endTime: int | None = None,
1063
+ limit: int | None = None,
1064
+ ):
1065
+ """
1066
+ https://developers.binance.com/docs/binance-spot-api-docs/rest-api/market-data-endpoints#klinecandlestick-data
1067
+
1068
+ [
1069
+ [
1070
+ 1499040000000, // Kline open time
1071
+ "0.01634790", // Open price
1072
+ "0.80000000", // High price
1073
+ "0.01575800", // Low price
1074
+ "0.01577100", // Close price
1075
+ "148976.11427815", // Volume
1076
+ 1499644799999, // Kline Close time
1077
+ "2434.19055334", // Quote asset volume
1078
+ 308, // Number of trades
1079
+ "1756.87402397", // Taker buy base asset volume
1080
+ "28.46694368", // Taker buy quote asset volume
1081
+ "0" // Unused field, ignore.
1082
+ ]
1083
+ ]
1084
+ """
1085
+ base_url = self._get_base_url(BinanceAccountType.SPOT)
1086
+ end_point = "/api/v3/klines"
1087
+ data: dict[str, str | int] = {
1088
+ "symbol": symbol,
1089
+ "interval": interval,
1090
+ }
1091
+
1092
+ await self._limiter.api_weight_limit(2)
1093
+
1094
+ if startTime is not None:
1095
+ data["startTime"] = startTime
1096
+ if endTime is not None:
1097
+ data["endTime"] = endTime
1098
+ if limit is not None:
1099
+ data["limit"] = limit
1100
+
1101
+ raw = await self._fetch_async(
1102
+ "GET", base_url, end_point, payload=data, required_timestamp=False
1103
+ )
1104
+ return self._kline_response_decoder.decode(raw)
1105
+
1106
+ async def put_fapi_v1_order(
1107
+ self,
1108
+ symbol: str,
1109
+ side: str,
1110
+ quantity: str,
1111
+ price: str,
1112
+ orderId: int | None = None,
1113
+ origClientOrderId: str | None = None,
1114
+ priceMatch: str | None = None,
1115
+ ):
1116
+ """
1117
+ https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Modify-Order
1118
+ """
1119
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
1120
+ end_point = "/fapi/v1/order"
1121
+ await self._limiter.fapi_order_limit()
1122
+ data = {
1123
+ "symbol": symbol,
1124
+ "side": side,
1125
+ "quantity": quantity,
1126
+ "price": price,
1127
+ "orderId": orderId,
1128
+ "origClientOrderId": origClientOrderId,
1129
+ "priceMatch": priceMatch,
1130
+ }
1131
+ data = {k: v for k, v in data.items() if v is not None}
1132
+ raw = await self._fetch("PUT", base_url, end_point, payload=data, signed=True)
1133
+ return self._futures_modify_order_decoder.decode(raw)
1134
+
1135
+ async def put_dapi_v1_order(
1136
+ self,
1137
+ symbol: str,
1138
+ side: str,
1139
+ quantity: str,
1140
+ price: str,
1141
+ orderId: int | None = None,
1142
+ origClientOrderId: str | None = None,
1143
+ priceMatch: str | None = None,
1144
+ ):
1145
+ """
1146
+ https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Modify-Order
1147
+ """
1148
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
1149
+ end_point = "/dapi/v1/order"
1150
+ await self._limiter.dapi_order_limit()
1151
+ data = {
1152
+ "symbol": symbol,
1153
+ "side": side,
1154
+ "quantity": quantity,
1155
+ "price": price,
1156
+ "orderId": orderId,
1157
+ "origClientOrderId": origClientOrderId,
1158
+ "priceMatch": priceMatch,
1159
+ }
1160
+ data = {k: v for k, v in data.items() if v is not None}
1161
+ raw = await self._fetch("PUT", base_url, end_point, payload=data, signed=True)
1162
+ return self._futures_modify_order_decoder.decode(raw)
1163
+
1164
+ async def put_papi_v1_cm_order(
1165
+ self,
1166
+ symbol: str,
1167
+ side: str,
1168
+ quantity: str,
1169
+ price: str,
1170
+ orderId: int | None = None,
1171
+ origClientOrderId: str | None = None,
1172
+ priceMatch: str | None = None,
1173
+ ):
1174
+ """
1175
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Modify-CM-Order
1176
+ """
1177
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
1178
+ end_point = "/papi/v1/cm/order"
1179
+ await self._limiter.papi_order_limit(cost=1)
1180
+ data = {
1181
+ "symbol": symbol,
1182
+ "side": side,
1183
+ "quantity": quantity,
1184
+ "price": price,
1185
+ "orderId": orderId,
1186
+ "origClientOrderId": origClientOrderId,
1187
+ "priceMatch": priceMatch,
1188
+ }
1189
+ data = {k: v for k, v in data.items() if v is not None}
1190
+ raw = await self._fetch("PUT", base_url, end_point, payload=data, signed=True)
1191
+ return self._futures_modify_order_decoder.decode(raw)
1192
+
1193
+ async def put_papi_v1_um_order(
1194
+ self,
1195
+ symbol: str,
1196
+ side: str,
1197
+ quantity: str,
1198
+ price: str,
1199
+ orderId: int | None = None,
1200
+ origClientOrderId: str | None = None,
1201
+ priceMatch: str | None = None,
1202
+ ):
1203
+ """
1204
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Modify-UM-Order
1205
+ """
1206
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
1207
+ end_point = "/papi/v1/um/order"
1208
+ await self._limiter.papi_order_limit(cost=1)
1209
+ data = {
1210
+ "symbol": symbol,
1211
+ "side": side,
1212
+ "quantity": quantity,
1213
+ "price": price,
1214
+ "orderId": orderId,
1215
+ "origClientOrderId": origClientOrderId,
1216
+ "priceMatch": priceMatch,
1217
+ }
1218
+ data = {k: v for k, v in data.items() if v is not None}
1219
+ raw = await self._fetch("PUT", base_url, end_point, payload=data, signed=True)
1220
+ return self._futures_modify_order_decoder.decode(raw)
1221
+
1222
+ async def delete_fapi_v1_all_open_orders(self, symbol: str):
1223
+ """
1224
+ DELETE /fapi/v1/allOpenOrders
1225
+ https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Cancel-All-Open-Orders
1226
+ """
1227
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
1228
+ end_point = "/fapi/v1/allOpenOrders"
1229
+ data = {
1230
+ "symbol": symbol,
1231
+ }
1232
+ raw = await self._fetch(
1233
+ "DELETE", base_url, end_point, payload=data, signed=True
1234
+ )
1235
+ return self._msg_decoder.decode(raw)
1236
+
1237
+ async def delete_dapi_v1_all_open_orders(self, symbol: str):
1238
+ """
1239
+ DELETE /dapi/v1/allOpenOrders
1240
+ https://developers.binance.com/docs/derivatives/coin-margined-futures/trade/rest-api/Cancel-All-Open-Orders
1241
+ """
1242
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
1243
+ end_point = "/dapi/v1/allOpenOrders"
1244
+ data = {
1245
+ "symbol": symbol,
1246
+ }
1247
+ raw = await self._fetch(
1248
+ "DELETE", base_url, end_point, payload=data, signed=True
1249
+ )
1250
+ return self._msg_decoder.decode(raw)
1251
+
1252
+ async def delete_papi_v1_um_all_open_orders(self, symbol: str):
1253
+ """
1254
+ DELETE /papi/v1/um/allOpenOrders
1255
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-All-UM-Open-Orders
1256
+ """
1257
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
1258
+ end_point = "/papi/v1/um/allOpenOrders"
1259
+ data = {
1260
+ "symbol": symbol,
1261
+ }
1262
+ raw = await self._fetch(
1263
+ "DELETE", base_url, end_point, payload=data, signed=True
1264
+ )
1265
+ return self._msg_decoder.decode(raw)
1266
+
1267
+ async def delete_papi_v1_cm_all_open_orders(self, symbol: str):
1268
+ """
1269
+ DELETE /papi/v1/cm/allOpenOrders
1270
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-All-CM-Open-Orders
1271
+ """
1272
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
1273
+ end_point = "/papi/v1/cm/allOpenOrders"
1274
+ data = {
1275
+ "symbol": symbol,
1276
+ }
1277
+ raw = await self._fetch(
1278
+ "DELETE", base_url, end_point, payload=data, signed=True
1279
+ )
1280
+ return self._msg_decoder.decode(raw)
1281
+
1282
+ async def delete_papi_v1_margin_all_open_orders(self, symbol: str):
1283
+ """
1284
+ DELETE /papi/v1/margin/allOpenOrders
1285
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Cancel-Margin-Account-All-Open-Orders-on-a-Symbol
1286
+ """
1287
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
1288
+ end_point = "/papi/v1/margin/allOpenOrders"
1289
+ data = {
1290
+ "symbol": symbol,
1291
+ }
1292
+ raw = await self._fetch(
1293
+ "DELETE", base_url, end_point, payload=data, signed=True
1294
+ )
1295
+ return self._msg_decoder.decode(raw)
1296
+
1297
+ async def delete_api_v3_open_orders(self, symbol: str):
1298
+ """
1299
+ DELETE /api/v3/openOrders
1300
+ """
1301
+ base_url = self._get_base_url(BinanceAccountType.SPOT)
1302
+ end_point = "/api/v3/openOrders"
1303
+ data = {
1304
+ "symbol": symbol,
1305
+ }
1306
+ raw = await self._fetch(
1307
+ "DELETE", base_url, end_point, payload=data, signed=True
1308
+ )
1309
+ return self._msg_decoder.decode(raw)
1310
+
1311
+ async def get_fapi_v1_funding_rate(
1312
+ self,
1313
+ symbol: str,
1314
+ startTime: int | None = None,
1315
+ endTime: int | None = None,
1316
+ limit: int | None = None,
1317
+ ):
1318
+ """
1319
+ GET /fapi/v1/fundingRate
1320
+ """
1321
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
1322
+ end_point = "/fapi/v1/fundingRate"
1323
+ data = {
1324
+ "symbol": symbol,
1325
+ "startTime": startTime,
1326
+ "endTime": endTime,
1327
+ "limit": limit,
1328
+ }
1329
+ data = {k: v for k, v in data.items() if v is not None}
1330
+ raw = await self._fetch("GET", base_url, end_point, payload=data)
1331
+ return self._funding_rate_decoder.decode(raw)
1332
+
1333
+ async def get_dapi_v1_funding_rate(
1334
+ self,
1335
+ symbol: str,
1336
+ startTime: int | None = None,
1337
+ endTime: int | None = None,
1338
+ limit: int | None = None,
1339
+ ):
1340
+ """
1341
+ GET /dapi/v1/fundingRate
1342
+ """
1343
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
1344
+ end_point = "/dapi/v1/fundingRate"
1345
+ data = {
1346
+ "symbol": symbol,
1347
+ "startTime": startTime,
1348
+ "endTime": endTime,
1349
+ "limit": limit,
1350
+ }
1351
+ data = {k: v for k, v in data.items() if v is not None}
1352
+ raw = await self._fetch("GET", base_url, end_point, payload=data)
1353
+ return self._funding_rate_decoder.decode(raw)
1354
+
1355
+ async def get_fapi_v1_positionSide_dual(self):
1356
+ """
1357
+ GET /fapi/v1/positionSide/dual
1358
+ https://developers.binance.com/docs/derivatives/usds-margined-futures/account/rest-api/Get-Current-Position-Mode
1359
+ """
1360
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
1361
+ end_point = "/fapi/v1/positionSide/dual"
1362
+ await self._limiter.fapi_weight_limit(30)
1363
+ raw = await self._fetch_async("GET", base_url, end_point, signed=True)
1364
+ return self._msg_decoder.decode(raw)
1365
+
1366
+ async def get_dapi_v1_positionSide_dual(self):
1367
+ """
1368
+ GET /dapi/v1/positionSide/dual
1369
+ """
1370
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
1371
+ end_point = "/dapi/v1/positionSide/dual"
1372
+ await self._limiter.dapi_weight_limit(30)
1373
+ raw = await self._fetch_async("GET", base_url, end_point, signed=True)
1374
+ return self._msg_decoder.decode(raw)
1375
+
1376
+ async def get_papi_v1_um_positionSide_dual(self):
1377
+ """
1378
+ GET /papi/v1/um/positionSide/dual
1379
+ https://developers.binance.com/docs/derivatives/portfolio-margin/account/Get-UM-Current-Position-Mode
1380
+ """
1381
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
1382
+ end_point = "/papi/v1/um/positionSide/dual"
1383
+ await self._limiter.papi_weight_limit(30)
1384
+ raw = await self._fetch_async("GET", base_url, end_point, signed=True)
1385
+ return self._msg_decoder.decode(raw)
1386
+
1387
+ async def get_papi_v1_cm_positionSide_dual(self):
1388
+ """
1389
+ GET /papi/v1/cm/positionSide/dual
1390
+ """
1391
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
1392
+ end_point = "/papi/v1/cm/positionSide/dual"
1393
+ await self._limiter.papi_weight_limit(30)
1394
+ raw = await self._fetch_async("GET", base_url, end_point, signed=True)
1395
+ return self._msg_decoder.decode(raw)
1396
+
1397
+ async def post_fapi_v1_batch_orders(
1398
+ self,
1399
+ batch_orders: list[dict],
1400
+ ):
1401
+ """
1402
+ POST /fapi/v1/batchOrders
1403
+ https://developers.binance.com/docs/zh-CN/derivatives/usds-margined-futures/trade/rest-api/Place-Multiple-Orders
1404
+ """
1405
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
1406
+ end_point = "/fapi/v1/batchOrders"
1407
+ await self._limiter.fapi_order_limit(cost=5, order_sec_cost=1, order_min_cost=5)
1408
+ data = {
1409
+ "batchOrders": self._msg_encoder.encode(batch_orders),
1410
+ }
1411
+ raw = await self._fetch("POST", base_url, end_point, payload=data, signed=True)
1412
+ return self._batch_order_decoder.decode(raw)
1413
+
1414
+ async def post_dapi_v1_batch_orders(
1415
+ self,
1416
+ batch_orders: list[dict],
1417
+ ):
1418
+ """
1419
+ POST /dapi/v1/batchOrders
1420
+ https://developers.binance.com/docs/zh-CN/derivatives/coin-margined-futures/trade/rest-api/Place-Multiple-Orders
1421
+ """
1422
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
1423
+ end_point = "/dapi/v1/batchOrders"
1424
+ await self._limiter.dapi_order_limit(cost=5)
1425
+ data = {
1426
+ "batchOrders": self._msg_encoder.encode(batch_orders),
1427
+ }
1428
+ raw = await self._fetch("POST", base_url, end_point, payload=data, signed=True)
1429
+ return self._batch_order_decoder.decode(raw)
1430
+
1431
+ async def delete_fapi_v1_batch_orders(
1432
+ self, symbol: str, origClientOrderIdList: list[str]
1433
+ ) -> list[BinanceBatchOrderResponse]:
1434
+ """DELETE /fapi/v1/batchOrders — cancel up to 10 orders, same symbol"""
1435
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
1436
+ endpoint = "/fapi/v1/batchOrders"
1437
+ payload = {
1438
+ "symbol": symbol,
1439
+ "origClientOrderIdList": self._msg_encoder.encode(origClientOrderIdList),
1440
+ }
1441
+ raw = await self._fetch(
1442
+ "DELETE", base_url, endpoint, payload=payload, signed=True
1443
+ )
1444
+ return self._batch_order_decoder.decode(raw)
1445
+
1446
+ async def delete_dapi_v1_batch_orders(
1447
+ self, symbol: str, origClientOrderIdList: list[str]
1448
+ ) -> list[BinanceBatchOrderResponse]:
1449
+ """DELETE /dapi/v1/batchOrders — cancel up to 10 orders, same symbol"""
1450
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
1451
+ endpoint = "/dapi/v1/batchOrders"
1452
+ payload = {
1453
+ "symbol": symbol,
1454
+ "origClientOrderIdList": self._msg_encoder.encode(origClientOrderIdList),
1455
+ }
1456
+ raw = await self._fetch(
1457
+ "DELETE", base_url, endpoint, payload=payload, signed=True
1458
+ )
1459
+ return self._batch_order_decoder.decode(raw)
1460
+
1461
+ async def get_fapi_v1_ticker_24hr(
1462
+ self, symbol: str | None = None
1463
+ ) -> list[BinanceFuture24hrTicker]:
1464
+ """
1465
+ GET /fapi/v1/ticker/24hr
1466
+
1467
+ 24hr ticker price change statistics.
1468
+
1469
+ Request Weight:
1470
+ - 1 for a single symbol
1471
+ - 40 when the symbol parameter is omitted
1472
+
1473
+ Args:
1474
+ symbol: Symbol name (optional)
1475
+
1476
+ Returns:
1477
+ list[BinanceFuture24hrTicker]: List of 24hr ticker data
1478
+ """
1479
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
1480
+ end_point = "/fapi/v1/ticker/24hr"
1481
+
1482
+ payload = {}
1483
+ if symbol:
1484
+ payload["symbol"] = symbol
1485
+ cost = 1
1486
+ else:
1487
+ cost = 40
1488
+
1489
+ await self._limiter.fapi_weight_limit(cost)
1490
+
1491
+ raw = await self._fetch_async(
1492
+ "GET", base_url, end_point, payload=payload, signed=False
1493
+ )
1494
+ if symbol:
1495
+ return [self._single_future_24hr_ticker_decoder.decode(raw)]
1496
+ return self._future_24hr_ticker_decoder.decode(raw)
1497
+
1498
+ async def get_dapi_v1_ticker_24hr(
1499
+ self, symbol: str | None = None, pair: str | None = None
1500
+ ) -> list[BinanceFuture24hrTicker]:
1501
+ """
1502
+ GET /dapi/v1/ticker/24hr
1503
+
1504
+ 24hr ticker price change statistics.
1505
+
1506
+ Request Weight:
1507
+ - 1 for a single symbol
1508
+ - 40 when the symbol parameter is omitted
1509
+
1510
+ Args:
1511
+ symbol: Symbol name (optional)
1512
+ pair: Pair name (optional)
1513
+
1514
+ Returns:
1515
+ list[BinanceFuture24hrTicker]: List of 24hr ticker data
1516
+ """
1517
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
1518
+ end_point = "/dapi/v1/ticker/24hr"
1519
+
1520
+ payload = {}
1521
+ if symbol:
1522
+ payload["symbol"] = symbol
1523
+ cost = 1
1524
+ elif pair:
1525
+ payload["pair"] = pair
1526
+ cost = 1
1527
+ else:
1528
+ cost = 40
1529
+
1530
+ await self._limiter.dapi_weight_limit(cost)
1531
+
1532
+ raw = await self._fetch_async(
1533
+ "GET", base_url, end_point, payload=payload, signed=False
1534
+ )
1535
+ return self._future_24hr_ticker_decoder.decode(raw)
1536
+
1537
+ async def get_api_v3_ticker_24hr(
1538
+ self, symbol: str | None = None, symbols: str | None = None
1539
+ ) -> list[BinanceSpot24hrTicker]:
1540
+ """
1541
+ GET /api/v3/ticker/24hr
1542
+
1543
+ 24hr ticker price change statistics.
1544
+
1545
+ Request Weight:
1546
+ - 1 for a single symbol
1547
+ - 2 for a symbols parameter
1548
+ - 40 when no parameters are sent
1549
+
1550
+ Args:
1551
+ symbol: Symbol name (optional)
1552
+ symbols: Array of symbols (optional, format: ["BTCUSDT","BNBUSDT"])
1553
+
1554
+ Returns:
1555
+ list[BinanceSpot24hrTicker]: List of 24hr ticker data
1556
+ """
1557
+ base_url = self._get_base_url(BinanceAccountType.SPOT)
1558
+ end_point = "/api/v3/ticker/24hr"
1559
+
1560
+ payload = {}
1561
+ if symbol:
1562
+ payload["symbol"] = symbol
1563
+ cost = 1
1564
+ elif symbols:
1565
+ payload["symbols"] = symbols
1566
+ cost = 2
1567
+ else:
1568
+ cost = 40
1569
+
1570
+ await self._limiter.api_weight_limit(cost)
1571
+
1572
+ raw = await self._fetch_async(
1573
+ "GET", base_url, end_point, payload=payload, signed=False
1574
+ )
1575
+ if symbol:
1576
+ return [self._single_spot_24hr_ticker_decoder.decode(raw)]
1577
+ return self._spot_24hr_ticker_decoder.decode(raw)
1578
+
1579
+ async def fapi_v1_adl_quantile(self):
1580
+ """
1581
+ GET /fapi/v1/adlQuantile
1582
+ https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/ADL-Quantile
1583
+ """
1584
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
1585
+ end_point = "/fapi/v1/adlQuantile"
1586
+ await self._limiter.fapi_weight_limit(5)
1587
+ raw = await self._fetch_async("GET", base_url, end_point, signed=True)
1588
+ return self._msg_decoder.decode(raw)
1589
+
1590
+ async def papi_v1_um_adl_quantile(self):
1591
+ """
1592
+ GET /papi/v1/adlQuantile
1593
+ https://developers.binance.com/docs/derivatives/portfolio-margin/trade/UM-Position-ADL-Quantile-Estimation
1594
+ """
1595
+ base_url = self._get_base_url(BinanceAccountType.PORTFOLIO_MARGIN)
1596
+ end_point = "/papi/v1/um/adlQuantile"
1597
+ await self._limiter.papi_weight_limit(5)
1598
+ raw = await self._fetch_async("GET", base_url, end_point, signed=True)
1599
+ return self._msg_decoder.decode(raw)
1600
+
1601
+ async def get_api_v3_depth(
1602
+ self, symbol: str, limit: int = 1000
1603
+ ) -> BinanceDepthSnapshotData:
1604
+ """
1605
+ https://developers.binance.com/docs/binance-spot-api-docs/rest-api/public-api-endpoints#order-book
1606
+ """
1607
+ base_url = self._get_base_url(BinanceAccountType.SPOT)
1608
+ end_point = "/api/v3/depth"
1609
+ await self._limiter.api_weight_limit(cost=10)
1610
+ raw = await self._fetch(
1611
+ "GET",
1612
+ base_url,
1613
+ end_point,
1614
+ payload={"symbol": symbol, "limit": limit},
1615
+ required_timestamp=False,
1616
+ )
1617
+ return self._depth_snapshot_decoder.decode(raw)
1618
+
1619
+ async def get_fapi_v1_depth(
1620
+ self, symbol: str, limit: int = 1000
1621
+ ) -> BinanceDepthSnapshotData:
1622
+ """
1623
+ https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Order-Book
1624
+ """
1625
+ base_url = self._get_base_url(BinanceAccountType.USD_M_FUTURE)
1626
+ end_point = "/fapi/v1/depth"
1627
+ await self._limiter.fapi_weight_limit(cost=10)
1628
+ raw = await self._fetch(
1629
+ "GET",
1630
+ base_url,
1631
+ end_point,
1632
+ payload={"symbol": symbol, "limit": limit},
1633
+ required_timestamp=False,
1634
+ )
1635
+ return self._depth_snapshot_decoder.decode(raw)
1636
+
1637
+ async def get_dapi_v1_depth(
1638
+ self, symbol: str, limit: int = 1000
1639
+ ) -> BinanceDepthSnapshotData:
1640
+ """
1641
+ https://developers.binance.com/docs/derivatives/coin-margined-futures/market-data/rest-api/Order-Book
1642
+ """
1643
+ base_url = self._get_base_url(BinanceAccountType.COIN_M_FUTURE)
1644
+ end_point = "/dapi/v1/depth"
1645
+ await self._limiter.dapi_weight_limit(cost=10)
1646
+ raw = await self._fetch(
1647
+ "GET",
1648
+ base_url,
1649
+ end_point,
1650
+ payload={"symbol": symbol, "limit": limit},
1651
+ required_timestamp=False,
1652
+ )
1653
+ return self._depth_snapshot_decoder.decode(raw)