ccxt 4.3.88__py2.py3-none-any.whl → 4.3.90__py2.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.
- ccxt/__init__.py +1 -1
- ccxt/ace.py +1 -0
- ccxt/alpaca.py +3 -2
- ccxt/ascendex.py +102 -116
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ace.py +1 -0
- ccxt/async_support/alpaca.py +3 -2
- ccxt/async_support/ascendex.py +102 -116
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/bigone.py +1 -0
- ccxt/async_support/bingx.py +30 -17
- ccxt/async_support/bit2c.py +1 -0
- ccxt/async_support/bitbank.py +1 -0
- ccxt/async_support/bitfinex.py +1 -0
- ccxt/async_support/bitfinex2.py +21 -22
- ccxt/async_support/bitflyer.py +1 -0
- ccxt/async_support/bitget.py +3 -2
- ccxt/async_support/bitmart.py +4 -8
- ccxt/async_support/bitmex.py +1 -0
- ccxt/async_support/bitopro.py +1 -0
- ccxt/async_support/bitrue.py +62 -71
- ccxt/async_support/bitso.py +1 -0
- ccxt/async_support/bitstamp.py +1 -0
- ccxt/async_support/bitvavo.py +1 -0
- ccxt/async_support/blockchaincom.py +1 -0
- ccxt/async_support/btcalpha.py +1 -0
- ccxt/async_support/btcbox.py +1 -0
- ccxt/async_support/btcmarkets.py +1 -0
- ccxt/async_support/bybit.py +2 -0
- ccxt/async_support/cex.py +1 -0
- ccxt/async_support/coinbaseexchange.py +1 -0
- ccxt/async_support/coinbaseinternational.py +2 -1
- ccxt/async_support/coinex.py +1 -16
- ccxt/async_support/cryptocom.py +0 -12
- ccxt/async_support/hitbtc.py +1 -0
- ccxt/async_support/huobijp.py +0 -8
- ccxt/async_support/kraken.py +48 -48
- ccxt/async_support/latoken.py +1 -0
- ccxt/async_support/mexc.py +1 -61
- ccxt/async_support/okcoin.py +4 -9
- ccxt/async_support/okx.py +1 -8
- ccxt/async_support/onetrading.py +1 -0
- ccxt/async_support/phemex.py +1 -0
- ccxt/async_support/poloniexfutures.py +1 -0
- ccxt/async_support/probit.py +1 -0
- ccxt/async_support/vertex.py +1 -0
- ccxt/async_support/whitebit.py +5 -3
- ccxt/async_support/woo.py +1 -0
- ccxt/async_support/woofipro.py +1 -0
- ccxt/base/exchange.py +6 -4
- ccxt/bigone.py +1 -0
- ccxt/bingx.py +30 -17
- ccxt/bit2c.py +1 -0
- ccxt/bitbank.py +1 -0
- ccxt/bitfinex.py +1 -0
- ccxt/bitfinex2.py +21 -22
- ccxt/bitflyer.py +1 -0
- ccxt/bitget.py +3 -2
- ccxt/bitmart.py +4 -8
- ccxt/bitmex.py +1 -0
- ccxt/bitopro.py +1 -0
- ccxt/bitrue.py +62 -71
- ccxt/bitso.py +1 -0
- ccxt/bitstamp.py +1 -0
- ccxt/bitvavo.py +1 -0
- ccxt/blockchaincom.py +1 -0
- ccxt/btcalpha.py +1 -0
- ccxt/btcbox.py +1 -0
- ccxt/btcmarkets.py +1 -0
- ccxt/bybit.py +2 -0
- ccxt/cex.py +1 -0
- ccxt/coinbaseexchange.py +1 -0
- ccxt/coinbaseinternational.py +2 -1
- ccxt/coinex.py +1 -16
- ccxt/cryptocom.py +0 -12
- ccxt/hitbtc.py +1 -0
- ccxt/huobijp.py +0 -8
- ccxt/kraken.py +48 -48
- ccxt/latoken.py +1 -0
- ccxt/mexc.py +1 -61
- ccxt/okcoin.py +4 -9
- ccxt/okx.py +1 -8
- ccxt/onetrading.py +1 -0
- ccxt/phemex.py +1 -0
- ccxt/poloniexfutures.py +1 -0
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +280 -0
- ccxt/pro/bingx.py +235 -85
- ccxt/pro/bithumb.py +4 -0
- ccxt/pro/bitvavo.py +1 -0
- ccxt/pro/bybit.py +253 -2
- ccxt/pro/cex.py +1 -0
- ccxt/pro/coinex.py +941 -662
- ccxt/pro/lbank.py +1 -2
- ccxt/pro/okx.py +142 -2
- ccxt/probit.py +1 -0
- ccxt/vertex.py +1 -0
- ccxt/whitebit.py +5 -3
- ccxt/woo.py +1 -0
- ccxt/woofipro.py +1 -0
- {ccxt-4.3.88.dist-info → ccxt-4.3.90.dist-info}/METADATA +4 -4
- {ccxt-4.3.88.dist-info → ccxt-4.3.90.dist-info}/RECORD +105 -105
- {ccxt-4.3.88.dist-info → ccxt-4.3.90.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.3.88.dist-info → ccxt-4.3.90.dist-info}/WHEEL +0 -0
- {ccxt-4.3.88.dist-info → ccxt-4.3.90.dist-info}/top_level.txt +0 -0
ccxt/pro/bingx.py
CHANGED
@@ -37,7 +37,8 @@ class bingx(ccxt.async_support.bingx):
|
|
37
37
|
'api': {
|
38
38
|
'ws': {
|
39
39
|
'spot': 'wss://open-api-ws.bingx.com/market',
|
40
|
-
'
|
40
|
+
'linear': 'wss://open-api-swap.bingx.com/swap-market',
|
41
|
+
'inverse': 'wss://open-api-cswap-ws.bingx.com/market',
|
41
42
|
},
|
42
43
|
},
|
43
44
|
},
|
@@ -95,17 +96,24 @@ class bingx(ccxt.async_support.bingx):
|
|
95
96
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
96
97
|
"""
|
97
98
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
99
|
+
:see: https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#Subscribe%20to%2024-hour%20Price%20Change
|
98
100
|
:see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20to%2024-hour%20price%20changes
|
101
|
+
:see: https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%2024-Hour%20Price%20Change
|
99
102
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
100
103
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
101
104
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
102
105
|
"""
|
103
106
|
await self.load_markets()
|
104
107
|
market = self.market(symbol)
|
105
|
-
marketType
|
106
|
-
|
107
|
-
|
108
|
-
|
108
|
+
marketType = None
|
109
|
+
subType = None
|
110
|
+
url = None
|
111
|
+
marketType, params = self.handle_market_type_and_params('watchTicker', market, params)
|
112
|
+
subType, params = self.handle_sub_type_and_params('watchTicker', market, params, 'linear')
|
113
|
+
if marketType == 'swap':
|
114
|
+
url = self.safe_string(self.urls['api']['ws'], subType)
|
115
|
+
else:
|
116
|
+
url = self.safe_string(self.urls['api']['ws'], marketType)
|
109
117
|
subscriptionHash = market['id'] + '@ticker'
|
110
118
|
messageHash = self.get_message_hash('ticker', market['symbol'])
|
111
119
|
uuid = self.uuid()
|
@@ -115,7 +123,7 @@ class bingx(ccxt.async_support.bingx):
|
|
115
123
|
}
|
116
124
|
if marketType == 'swap':
|
117
125
|
request['reqType'] = 'sub'
|
118
|
-
return await self.watch(url, messageHash, self.extend(request,
|
126
|
+
return await self.watch(url, messageHash, self.extend(request, params), subscriptionHash)
|
119
127
|
|
120
128
|
def handle_ticker(self, client: Client, message):
|
121
129
|
#
|
@@ -247,12 +255,16 @@ class bingx(ccxt.async_support.bingx):
|
|
247
255
|
symbols = self.market_symbols(symbols, None, True, True, False)
|
248
256
|
firstMarket = None
|
249
257
|
marketType = None
|
258
|
+
subType = None
|
250
259
|
symbolsDefined = (symbols is not None)
|
251
260
|
if symbolsDefined:
|
252
261
|
firstMarket = self.market(symbols[0])
|
253
262
|
marketType, params = self.handle_market_type_and_params('watchTickers', firstMarket, params)
|
263
|
+
subType, params = self.handle_sub_type_and_params('watchTickers', firstMarket, params, 'linear')
|
254
264
|
if marketType == 'spot':
|
255
265
|
raise NotSupported(self.id + ' watchTickers is not supported for spot markets yet')
|
266
|
+
if subType == 'inverse':
|
267
|
+
raise NotSupported(self.id + ' watchTickers is not supported for inverse markets yet')
|
256
268
|
messageHashes = []
|
257
269
|
subscriptionHashes = ['all@ticker']
|
258
270
|
if symbolsDefined:
|
@@ -262,7 +274,7 @@ class bingx(ccxt.async_support.bingx):
|
|
262
274
|
messageHashes.append(self.get_message_hash('ticker', market['symbol']))
|
263
275
|
else:
|
264
276
|
messageHashes.append(self.get_message_hash('ticker'))
|
265
|
-
url = self.safe_string(self.urls['api']['ws'],
|
277
|
+
url = self.safe_string(self.urls['api']['ws'], subType)
|
266
278
|
uuid = self.uuid()
|
267
279
|
request: dict = {
|
268
280
|
'id': uuid,
|
@@ -289,12 +301,16 @@ class bingx(ccxt.async_support.bingx):
|
|
289
301
|
symbols = self.market_symbols(symbols, None, True, True, False)
|
290
302
|
firstMarket = None
|
291
303
|
marketType = None
|
304
|
+
subType = None
|
292
305
|
symbolsDefined = (symbols is not None)
|
293
306
|
if symbolsDefined:
|
294
307
|
firstMarket = self.market(symbols[0])
|
295
308
|
marketType, params = self.handle_market_type_and_params('watchOrderBookForSymbols', firstMarket, params)
|
309
|
+
subType, params = self.handle_sub_type_and_params('watchOrderBookForSymbols', firstMarket, params, 'linear')
|
296
310
|
if marketType == 'spot':
|
297
311
|
raise NotSupported(self.id + ' watchOrderBookForSymbols is not supported for spot markets yet')
|
312
|
+
if subType == 'inverse':
|
313
|
+
raise NotSupported(self.id + ' watchOrderBookForSymbols is not supported for inverse markets yet')
|
298
314
|
limit = self.get_order_book_limit_by_market_type(marketType, limit)
|
299
315
|
interval = None
|
300
316
|
interval, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'interval', 500)
|
@@ -309,7 +325,7 @@ class bingx(ccxt.async_support.bingx):
|
|
309
325
|
messageHashes.append(self.get_message_hash('orderbook', market['symbol']))
|
310
326
|
else:
|
311
327
|
messageHashes.append(self.get_message_hash('orderbook'))
|
312
|
-
url = self.safe_string(self.urls['api']['ws'],
|
328
|
+
url = self.safe_string(self.urls['api']['ws'], subType)
|
313
329
|
uuid = self.uuid()
|
314
330
|
request: dict = {
|
315
331
|
'id': uuid,
|
@@ -329,6 +345,7 @@ class bingx(ccxt.async_support.bingx):
|
|
329
345
|
async def watch_ohlcv_for_symbols(self, symbolsAndTimeframes: List[List[str]], since: Int = None, limit: Int = None, params={}):
|
330
346
|
"""
|
331
347
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
348
|
+
:see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20K-Line%20Data%20of%20all%20trading%20pairs
|
332
349
|
:param str[][] symbolsAndTimeframes: array of arrays containing unified symbols and timeframes to fetch OHLCV data for, example [['BTC/USDT', '1m'], ['LTC/USDT', '5m']]
|
333
350
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
334
351
|
:param int [limit]: the maximum amount of candles to fetch
|
@@ -341,14 +358,19 @@ class bingx(ccxt.async_support.bingx):
|
|
341
358
|
await self.load_markets()
|
342
359
|
messageHashes = []
|
343
360
|
marketType = None
|
361
|
+
subType = None
|
344
362
|
chosenTimeframe = None
|
363
|
+
firstMarket = None
|
345
364
|
if symbolsLength != 0:
|
346
365
|
symbols = self.get_list_from_object_values(symbolsAndTimeframes, 0)
|
347
366
|
symbols = self.market_symbols(symbols, None, True, True, False)
|
348
367
|
firstMarket = self.market(symbols[0])
|
349
|
-
|
350
|
-
|
351
|
-
|
368
|
+
marketType, params = self.handle_market_type_and_params('watchOHLCVForSymbols', firstMarket, params)
|
369
|
+
subType, params = self.handle_sub_type_and_params('watchOHLCVForSymbols', firstMarket, params, 'linear')
|
370
|
+
if marketType == 'spot':
|
371
|
+
raise NotSupported(self.id + ' watchOHLCVForSymbols is not supported for spot markets yet')
|
372
|
+
if subType == 'inverse':
|
373
|
+
raise NotSupported(self.id + ' watchOHLCVForSymbols is not supported for inverse markets yet')
|
352
374
|
marketOptions = self.safe_dict(self.options, marketType)
|
353
375
|
timeframes = self.safe_dict(marketOptions, 'timeframes', {})
|
354
376
|
for i in range(0, len(symbolsAndTimeframes)):
|
@@ -363,7 +385,7 @@ class bingx(ccxt.async_support.bingx):
|
|
363
385
|
raise BadRequest(self.id + ' watchOHLCVForSymbols requires all timeframes to be the same')
|
364
386
|
messageHashes.append(self.get_message_hash('ohlcv', market['symbol'], chosenTimeframe))
|
365
387
|
subscriptionHash = 'all@kline_' + chosenTimeframe
|
366
|
-
url = self.safe_string(self.urls['api']['ws'],
|
388
|
+
url = self.safe_string(self.urls['api']['ws'], subType)
|
367
389
|
uuid = self.uuid()
|
368
390
|
request: dict = {
|
369
391
|
'id': uuid,
|
@@ -404,8 +426,9 @@ class bingx(ccxt.async_support.bingx):
|
|
404
426
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
405
427
|
"""
|
406
428
|
watches information on multiple trades made in a market
|
407
|
-
:see: https://bingx-api.github.io/docs/#/
|
408
|
-
:see: https://bingx-api.github.io/docs/#/
|
429
|
+
:see: https://bingx-api.github.io/docs/#/spot/socket/market.html#Subscribe%20to%20tick-by-tick
|
430
|
+
:see: https://bingx-api.github.io/docs/#/swapV2/socket/market.html#Subscribe%20the%20Latest%20Trade%20Detail
|
431
|
+
:see: https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscription%20transaction%20by%20transaction
|
409
432
|
:param str symbol: unified market symbol of the market orders were made in
|
410
433
|
:param int [since]: the earliest time in ms to fetch orders for
|
411
434
|
:param int [limit]: the maximum number of order structures to retrieve
|
@@ -414,11 +437,16 @@ class bingx(ccxt.async_support.bingx):
|
|
414
437
|
"""
|
415
438
|
await self.load_markets()
|
416
439
|
market = self.market(symbol)
|
440
|
+
symbol = market['symbol']
|
417
441
|
marketType = None
|
442
|
+
subType = None
|
443
|
+
url = None
|
418
444
|
marketType, params = self.handle_market_type_and_params('watchTrades', market, params)
|
419
|
-
|
420
|
-
if
|
421
|
-
|
445
|
+
subType, params = self.handle_sub_type_and_params('watchTrades', market, params, 'linear')
|
446
|
+
if marketType == 'swap':
|
447
|
+
url = self.safe_string(self.urls['api']['ws'], subType)
|
448
|
+
else:
|
449
|
+
url = self.safe_string(self.urls['api']['ws'], marketType)
|
422
450
|
rawHash = market['id'] + '@trade'
|
423
451
|
messageHash = 'trade::' + symbol
|
424
452
|
uuid = self.uuid()
|
@@ -435,8 +463,7 @@ class bingx(ccxt.async_support.bingx):
|
|
435
463
|
|
436
464
|
def handle_trades(self, client: Client, message):
|
437
465
|
#
|
438
|
-
# spot
|
439
|
-
# first snapshot
|
466
|
+
# spot: first snapshot
|
440
467
|
#
|
441
468
|
# {
|
442
469
|
# "id": "d83b78ce-98be-4dc2-b847-12fe471b5bc5",
|
@@ -445,7 +472,7 @@ class bingx(ccxt.async_support.bingx):
|
|
445
472
|
# "timestamp": 1690214699854
|
446
473
|
# }
|
447
474
|
#
|
448
|
-
# subsequent updates
|
475
|
+
# spot: subsequent updates
|
449
476
|
#
|
450
477
|
# {
|
451
478
|
# "code": 0,
|
@@ -463,9 +490,7 @@ class bingx(ccxt.async_support.bingx):
|
|
463
490
|
# "success": True
|
464
491
|
# }
|
465
492
|
#
|
466
|
-
#
|
467
|
-
# swap
|
468
|
-
# first snapshot
|
493
|
+
# linear swap: first snapshot
|
469
494
|
#
|
470
495
|
# {
|
471
496
|
# "id": "2aed93b1-6e1e-4038-aeba-f5eeaec2ca48",
|
@@ -475,8 +500,7 @@ class bingx(ccxt.async_support.bingx):
|
|
475
500
|
# "data": null
|
476
501
|
# }
|
477
502
|
#
|
478
|
-
# subsequent updates
|
479
|
-
#
|
503
|
+
# linear swap: subsequent updates
|
480
504
|
#
|
481
505
|
# {
|
482
506
|
# "code": 0,
|
@@ -493,6 +517,32 @@ class bingx(ccxt.async_support.bingx):
|
|
493
517
|
# ]
|
494
518
|
# }
|
495
519
|
#
|
520
|
+
# inverse swap: first snapshot
|
521
|
+
#
|
522
|
+
# {
|
523
|
+
# "code": 0,
|
524
|
+
# "id": "a2e482ca-f71b-42f8-a83a-8ff85a713e64",
|
525
|
+
# "msg": "SUCCESS",
|
526
|
+
# "timestamp": 1722920589426
|
527
|
+
# }
|
528
|
+
#
|
529
|
+
# inverse swap: subsequent updates
|
530
|
+
#
|
531
|
+
# {
|
532
|
+
# "code": 0,
|
533
|
+
# "dataType": "BTC-USD@trade",
|
534
|
+
# "data": {
|
535
|
+
# "e": "trade",
|
536
|
+
# "E": 1722920589665,
|
537
|
+
# "s": "BTC-USD",
|
538
|
+
# "t": "39125001",
|
539
|
+
# "p": "55360.0",
|
540
|
+
# "q": "1",
|
541
|
+
# "T": 1722920589582,
|
542
|
+
# "m": False
|
543
|
+
# }
|
544
|
+
# }
|
545
|
+
#
|
496
546
|
data = self.safe_value(message, 'data', [])
|
497
547
|
rawHash = self.safe_string(message, 'dataType')
|
498
548
|
marketId = rawHash.split('@')[0]
|
@@ -520,6 +570,7 @@ class bingx(ccxt.async_support.bingx):
|
|
520
570
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
521
571
|
:see: https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#Subscribe%20Market%20Depth%20Data
|
522
572
|
:see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20Market%20Depth%20Data
|
573
|
+
:see: https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%20Limited%20Depth
|
523
574
|
:param str symbol: unified symbol of the market to fetch the order book for
|
524
575
|
:param int [limit]: the maximum amount of order book entries to return
|
525
576
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -527,17 +578,23 @@ class bingx(ccxt.async_support.bingx):
|
|
527
578
|
"""
|
528
579
|
await self.load_markets()
|
529
580
|
market = self.market(symbol)
|
530
|
-
marketType
|
581
|
+
marketType = None
|
582
|
+
subType = None
|
583
|
+
url = None
|
584
|
+
marketType, params = self.handle_market_type_and_params('watchOrderBook', market, params)
|
585
|
+
subType, params = self.handle_sub_type_and_params('watchOrderBook', market, params, 'linear')
|
586
|
+
if marketType == 'swap':
|
587
|
+
url = self.safe_string(self.urls['api']['ws'], subType)
|
588
|
+
else:
|
589
|
+
url = self.safe_string(self.urls['api']['ws'], marketType)
|
531
590
|
limit = self.get_order_book_limit_by_market_type(marketType, limit)
|
532
591
|
channelName = 'depth' + str(limit)
|
533
|
-
url = self.safe_value(self.urls['api']['ws'], marketType)
|
534
|
-
if url is None:
|
535
|
-
raise BadRequest(self.id + ' watchOrderBook is not supported for ' + marketType + ' markets.')
|
536
592
|
interval = None
|
537
593
|
if marketType != 'spot':
|
538
|
-
|
539
|
-
|
540
|
-
|
594
|
+
if not market['inverse']:
|
595
|
+
interval, params = self.handle_option_and_params(params, 'watchOrderBook', 'interval', 500)
|
596
|
+
self.check_required_argument('watchOrderBook', interval, 'interval', [100, 200, 500, 1000])
|
597
|
+
channelName = channelName + '@' + str(interval) + 'ms'
|
541
598
|
subscriptionHash = market['id'] + '@' + channelName
|
542
599
|
messageHash = self.get_message_hash('orderbook', market['symbol'])
|
543
600
|
uuid = self.uuid()
|
@@ -547,24 +604,30 @@ class bingx(ccxt.async_support.bingx):
|
|
547
604
|
}
|
548
605
|
if marketType == 'swap':
|
549
606
|
request['reqType'] = 'sub'
|
550
|
-
subscriptionArgs: dict = {
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
607
|
+
subscriptionArgs: dict = {}
|
608
|
+
if market['inverse']:
|
609
|
+
subscriptionArgs = {
|
610
|
+
'count': limit,
|
611
|
+
'params': params,
|
612
|
+
}
|
613
|
+
else:
|
614
|
+
subscriptionArgs = {
|
615
|
+
'level': limit,
|
616
|
+
'interval': interval,
|
617
|
+
'params': params,
|
618
|
+
}
|
619
|
+
orderbook = await self.watch(url, messageHash, self.deep_extend(request, params), subscriptionHash, subscriptionArgs)
|
556
620
|
return orderbook.limit()
|
557
621
|
|
558
622
|
def handle_delta(self, bookside, delta):
|
559
|
-
price = self.
|
560
|
-
amount = self.
|
623
|
+
price = self.safe_float_2(delta, 0, 'p')
|
624
|
+
amount = self.safe_float_2(delta, 1, 'a')
|
561
625
|
bookside.store(price, amount)
|
562
626
|
|
563
627
|
def handle_order_book(self, client: Client, message):
|
564
628
|
#
|
565
629
|
# spot
|
566
630
|
#
|
567
|
-
#
|
568
631
|
# {
|
569
632
|
# "code": 0,
|
570
633
|
# "dataType": "BTC-USDT@depth20",
|
@@ -582,8 +645,7 @@ class bingx(ccxt.async_support.bingx):
|
|
582
645
|
# "success": True
|
583
646
|
# }
|
584
647
|
#
|
585
|
-
# swap
|
586
|
-
#
|
648
|
+
# linear swap
|
587
649
|
#
|
588
650
|
# {
|
589
651
|
# "code": 0,
|
@@ -601,6 +663,28 @@ class bingx(ccxt.async_support.bingx):
|
|
601
663
|
# }
|
602
664
|
# }
|
603
665
|
#
|
666
|
+
# inverse swap
|
667
|
+
#
|
668
|
+
# {
|
669
|
+
# "code": 0,
|
670
|
+
# "dataType": "BTC-USD@depth100",
|
671
|
+
# "data": {
|
672
|
+
# {
|
673
|
+
# "symbol": "BTC-USD",
|
674
|
+
# "bids": [
|
675
|
+
# {"p": "58074.2", "a": "1.422318", "v": "826.0"},
|
676
|
+
# ...
|
677
|
+
# ],
|
678
|
+
# "asks": [
|
679
|
+
# {"p": "62878.0", "a": "0.001590", "v": "1.0"},
|
680
|
+
# ...
|
681
|
+
# ],
|
682
|
+
# "aggPrecision": "0.1",
|
683
|
+
# "timestamp": 1723705093529
|
684
|
+
# }
|
685
|
+
# }
|
686
|
+
# }
|
687
|
+
#
|
604
688
|
data = self.safe_dict(message, 'data', {})
|
605
689
|
dataType = self.safe_string(message, 'dataType')
|
606
690
|
parts = dataType.split('@')
|
@@ -618,7 +702,11 @@ class bingx(ccxt.async_support.bingx):
|
|
618
702
|
limit = self.safe_integer(subscription, 'limit')
|
619
703
|
self.orderbooks[symbol] = self.order_book({}, limit)
|
620
704
|
orderbook = self.orderbooks[symbol]
|
621
|
-
snapshot =
|
705
|
+
snapshot = None
|
706
|
+
if market['inverse']:
|
707
|
+
snapshot = self.parse_order_book(data, symbol, None, 'bids', 'asks', 'p', 'a')
|
708
|
+
else:
|
709
|
+
snapshot = self.parse_order_book(data, symbol, None, 'bids', 'asks', 0, 1)
|
622
710
|
orderbook.reset(snapshot)
|
623
711
|
self.orderbooks[symbol] = orderbook
|
624
712
|
messageHash = self.get_message_hash('orderbook', symbol)
|
@@ -641,8 +729,10 @@ class bingx(ccxt.async_support.bingx):
|
|
641
729
|
# }
|
642
730
|
#
|
643
731
|
# for spot, opening-time(t) is used instead of closing-time(T), to be compatible with fetchOHLCV
|
644
|
-
# for swap,(T) is the opening time
|
732
|
+
# for linear swap,(T) is the opening time
|
645
733
|
timestamp = 't' if (market['spot']) else 'T'
|
734
|
+
if market['swap']:
|
735
|
+
timestamp = 't' if (market['inverse']) else 'T'
|
646
736
|
return [
|
647
737
|
self.safe_integer(ohlcv, timestamp),
|
648
738
|
self.safe_number(ohlcv, 'o'),
|
@@ -654,7 +744,7 @@ class bingx(ccxt.async_support.bingx):
|
|
654
744
|
|
655
745
|
def handle_ohlcv(self, client: Client, message):
|
656
746
|
#
|
657
|
-
# spot
|
747
|
+
# spot:
|
658
748
|
#
|
659
749
|
# {
|
660
750
|
# "code": 0,
|
@@ -680,7 +770,8 @@ class bingx(ccxt.async_support.bingx):
|
|
680
770
|
# "success": True
|
681
771
|
# }
|
682
772
|
#
|
683
|
-
# swap
|
773
|
+
# linear swap:
|
774
|
+
#
|
684
775
|
# {
|
685
776
|
# "code": 0,
|
686
777
|
# "dataType": "BTC-USDT@kline_1m",
|
@@ -697,13 +788,26 @@ class bingx(ccxt.async_support.bingx):
|
|
697
788
|
# ]
|
698
789
|
# }
|
699
790
|
#
|
791
|
+
# inverse swap:
|
792
|
+
#
|
793
|
+
# {
|
794
|
+
# "code": 0,
|
795
|
+
# "timestamp": 1723769354547,
|
796
|
+
# "dataType": "BTC-USD@kline_1m",
|
797
|
+
# "data": {
|
798
|
+
# "t": 1723769340000,
|
799
|
+
# "o": 57485.1,
|
800
|
+
# "c": 57468,
|
801
|
+
# "l": 57464.9,
|
802
|
+
# "h": 57485.1,
|
803
|
+
# "a": 0.189663,
|
804
|
+
# "v": 109,
|
805
|
+
# "u": 92,
|
806
|
+
# "s": "BTC-USD"
|
807
|
+
# }
|
808
|
+
# }
|
809
|
+
#
|
700
810
|
isSwap = client.url.find('swap') >= 0
|
701
|
-
candles = None
|
702
|
-
if isSwap:
|
703
|
-
candles = self.safe_list(message, 'data', [])
|
704
|
-
else:
|
705
|
-
data = self.safe_dict(message, 'data', {})
|
706
|
-
candles = [self.safe_dict(data, 'K', {})]
|
707
811
|
dataType = self.safe_string(message, 'dataType')
|
708
812
|
parts = dataType.split('@')
|
709
813
|
firstPart = parts[0]
|
@@ -711,6 +815,15 @@ class bingx(ccxt.async_support.bingx):
|
|
711
815
|
marketId = self.safe_string(message, 's', firstPart)
|
712
816
|
marketType = 'swap' if isSwap else 'spot'
|
713
817
|
market = self.safe_market(marketId, None, None, marketType)
|
818
|
+
candles = None
|
819
|
+
if isSwap:
|
820
|
+
if market['inverse']:
|
821
|
+
candles = [self.safe_dict(message, 'data', {})]
|
822
|
+
else:
|
823
|
+
candles = self.safe_list(message, 'data', [])
|
824
|
+
else:
|
825
|
+
data = self.safe_dict(message, 'data', {})
|
826
|
+
candles = [self.safe_dict(data, 'K', {})]
|
714
827
|
symbol = market['symbol']
|
715
828
|
self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
|
716
829
|
rawTimeframe = dataType.split('_')[1]
|
@@ -740,6 +853,7 @@ class bingx(ccxt.async_support.bingx):
|
|
740
853
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
741
854
|
:see: https://bingx-api.github.io/docs/#/en-us/spot/socket/market.html#K-line%20Streams
|
742
855
|
:see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/market.html#Subscribe%20K-Line%20Data
|
856
|
+
:see: https://bingx-api.github.io/docs/#/en-us/cswap/socket/market.html#Subscribe%20to%20Latest%20Trading%20Pair%20K-Line
|
743
857
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
744
858
|
:param str timeframe: the length of time each candle represents
|
745
859
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
@@ -749,8 +863,15 @@ class bingx(ccxt.async_support.bingx):
|
|
749
863
|
"""
|
750
864
|
await self.load_markets()
|
751
865
|
market = self.market(symbol)
|
752
|
-
marketType
|
753
|
-
|
866
|
+
marketType = None
|
867
|
+
subType = None
|
868
|
+
url = None
|
869
|
+
marketType, params = self.handle_market_type_and_params('watchOHLCV', market, params)
|
870
|
+
subType, params = self.handle_sub_type_and_params('watchOHLCV', market, params, 'linear')
|
871
|
+
if marketType == 'swap':
|
872
|
+
url = self.safe_string(self.urls['api']['ws'], subType)
|
873
|
+
else:
|
874
|
+
url = self.safe_string(self.urls['api']['ws'], marketType)
|
754
875
|
if url is None:
|
755
876
|
raise BadRequest(self.id + ' watchOHLCV is not supported for ' + marketType + ' markets.')
|
756
877
|
options = self.safe_value(self.options, marketType, {})
|
@@ -766,10 +887,10 @@ class bingx(ccxt.async_support.bingx):
|
|
766
887
|
if marketType == 'swap':
|
767
888
|
request['reqType'] = 'sub'
|
768
889
|
subscriptionArgs: dict = {
|
769
|
-
'
|
890
|
+
'interval': rawTimeframe,
|
770
891
|
'params': params,
|
771
892
|
}
|
772
|
-
result = await self.watch(url, messageHash, self.extend(request,
|
893
|
+
result = await self.watch(url, messageHash, self.extend(request, params), subscriptionHash, subscriptionArgs)
|
773
894
|
ohlcv = result[2]
|
774
895
|
if self.newUpdates:
|
775
896
|
limit = ohlcv.getLimit(symbol, limit)
|
@@ -777,11 +898,12 @@ class bingx(ccxt.async_support.bingx):
|
|
777
898
|
|
778
899
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
779
900
|
"""
|
780
|
-
:see: https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20order%20update%20data
|
781
|
-
:see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
|
782
901
|
watches information on multiple orders made by the user
|
783
|
-
:
|
784
|
-
:
|
902
|
+
:see: https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20order%20update%20data
|
903
|
+
:see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Order%20update%20push
|
904
|
+
:see: https://bingx-api.github.io/docs/#/en-us/cswap/socket/account.html#Order%20update%20push
|
905
|
+
:param str [symbol]: unified market symbol of the market orders are made in
|
906
|
+
:param int [since]: the earliest time in ms to watch orders for
|
785
907
|
:param int [limit]: the maximum number of order structures to retrieve
|
786
908
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
787
909
|
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
@@ -789,11 +911,13 @@ class bingx(ccxt.async_support.bingx):
|
|
789
911
|
await self.load_markets()
|
790
912
|
await self.authenticate()
|
791
913
|
type = None
|
914
|
+
subType = None
|
792
915
|
market = None
|
793
916
|
if symbol is not None:
|
794
917
|
market = self.market(symbol)
|
795
918
|
symbol = market['symbol']
|
796
919
|
type, params = self.handle_market_type_and_params('watchOrders', market, params)
|
920
|
+
subType, params = self.handle_sub_type_and_params('watchOrders', market, params, 'linear')
|
797
921
|
isSpot = (type == 'spot')
|
798
922
|
spotHash = 'spot:private'
|
799
923
|
swapHash = 'swap:private'
|
@@ -803,14 +927,21 @@ class bingx(ccxt.async_support.bingx):
|
|
803
927
|
messageHash = spotMessageHash if isSpot else swapMessageHash
|
804
928
|
if market is not None:
|
805
929
|
messageHash += ':' + symbol
|
806
|
-
url = self.urls['api']['ws'][type] + '?listenKey=' + self.options['listenKey']
|
807
|
-
request = None
|
808
930
|
uuid = self.uuid()
|
809
|
-
|
931
|
+
baseUrl = None
|
932
|
+
request = None
|
933
|
+
if type == 'swap':
|
934
|
+
if subType == 'inverse':
|
935
|
+
raise NotSupported(self.id + ' watchOrders is not supported for inverse swap markets yet')
|
936
|
+
baseUrl = self.safe_string(self.urls['api']['ws'], subType)
|
937
|
+
else:
|
938
|
+
baseUrl = self.safe_string(self.urls['api']['ws'], type)
|
810
939
|
request = {
|
811
940
|
'id': uuid,
|
941
|
+
'reqType': 'sub',
|
812
942
|
'dataType': 'spot.executionReport',
|
813
943
|
}
|
944
|
+
url = baseUrl + '?listenKey=' + self.options['listenKey']
|
814
945
|
orders = await self.watch(url, messageHash, request, subscriptionHash)
|
815
946
|
if self.newUpdates:
|
816
947
|
limit = orders.getLimit(symbol, limit)
|
@@ -818,40 +949,50 @@ class bingx(ccxt.async_support.bingx):
|
|
818
949
|
|
819
950
|
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
820
951
|
"""
|
821
|
-
:see: https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20order%20update%20data
|
822
|
-
:see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
|
823
952
|
watches information on multiple trades made by the user
|
824
|
-
:
|
825
|
-
:
|
826
|
-
:
|
953
|
+
:see: https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20order%20update%20data
|
954
|
+
:see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Order%20update%20push
|
955
|
+
:see: https://bingx-api.github.io/docs/#/en-us/cswap/socket/account.html#Order%20update%20push
|
956
|
+
:param str [symbol]: unified market symbol of the market the trades are made in
|
957
|
+
:param int [since]: the earliest time in ms to watch trades for
|
958
|
+
:param int [limit]: the maximum number of trade structures to retrieve
|
827
959
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
828
960
|
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
829
961
|
"""
|
830
962
|
await self.load_markets()
|
831
963
|
await self.authenticate()
|
832
964
|
type = None
|
965
|
+
subType = None
|
833
966
|
market = None
|
834
967
|
if symbol is not None:
|
835
968
|
market = self.market(symbol)
|
836
969
|
symbol = market['symbol']
|
837
|
-
type, params = self.handle_market_type_and_params('
|
970
|
+
type, params = self.handle_market_type_and_params('watchMyTrades', market, params)
|
971
|
+
subType, params = self.handle_sub_type_and_params('watchMyTrades', market, params, 'linear')
|
838
972
|
isSpot = (type == 'spot')
|
839
|
-
|
840
|
-
|
841
|
-
subscriptionHash =
|
973
|
+
spotHash = 'spot:private'
|
974
|
+
swapHash = 'swap:private'
|
975
|
+
subscriptionHash = spotHash if isSpot else swapHash
|
842
976
|
spotMessageHash = 'spot:mytrades'
|
843
977
|
swapMessageHash = 'swap:mytrades'
|
844
978
|
messageHash = spotMessageHash if isSpot else swapMessageHash
|
845
979
|
if market is not None:
|
846
980
|
messageHash += ':' + symbol
|
847
|
-
url = self.urls['api']['ws'][type] + '?listenKey=' + self.options['listenKey']
|
848
|
-
request = None
|
849
981
|
uuid = self.uuid()
|
850
|
-
|
982
|
+
baseUrl = None
|
983
|
+
request = None
|
984
|
+
if type == 'swap':
|
985
|
+
if subType == 'inverse':
|
986
|
+
raise NotSupported(self.id + ' watchMyTrades is not supported for inverse swap markets yet')
|
987
|
+
baseUrl = self.safe_string(self.urls['api']['ws'], subType)
|
988
|
+
else:
|
989
|
+
baseUrl = self.safe_string(self.urls['api']['ws'], type)
|
851
990
|
request = {
|
852
991
|
'id': uuid,
|
992
|
+
'reqType': 'sub',
|
853
993
|
'dataType': 'spot.executionReport',
|
854
994
|
}
|
995
|
+
url = baseUrl + '?listenKey=' + self.options['listenKey']
|
855
996
|
trades = await self.watch(url, messageHash, request, subscriptionHash)
|
856
997
|
if self.newUpdates:
|
857
998
|
limit = trades.getLimit(symbol, limit)
|
@@ -859,16 +1000,19 @@ class bingx(ccxt.async_support.bingx):
|
|
859
1000
|
|
860
1001
|
async def watch_balance(self, params={}) -> Balances:
|
861
1002
|
"""
|
1003
|
+
query for balance and get the amount of funds available for trading or funds locked in orders
|
862
1004
|
:see: https://bingx-api.github.io/docs/#/en-us/spot/socket/account.html#Subscription%20account%20balance%20push
|
863
1005
|
:see: https://bingx-api.github.io/docs/#/en-us/swapV2/socket/account.html#Account%20balance%20and%20position%20update%20push
|
864
|
-
|
1006
|
+
:see: https://bingx-api.github.io/docs/#/en-us/cswap/socket/account.html#Account%20balance%20and%20position%20update%20push
|
865
1007
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
866
1008
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
867
1009
|
"""
|
868
1010
|
await self.load_markets()
|
869
1011
|
await self.authenticate()
|
870
1012
|
type = None
|
1013
|
+
subType = None
|
871
1014
|
type, params = self.handle_market_type_and_params('watchBalance', None, params)
|
1015
|
+
subType, params = self.handle_sub_type_and_params('watchBalance', None, params, 'linear')
|
872
1016
|
isSpot = (type == 'spot')
|
873
1017
|
spotSubHash = 'spot:balance'
|
874
1018
|
swapSubHash = 'swap:private'
|
@@ -876,16 +1020,22 @@ class bingx(ccxt.async_support.bingx):
|
|
876
1020
|
swapMessageHash = 'swap:balance'
|
877
1021
|
messageHash = spotMessageHash if isSpot else swapMessageHash
|
878
1022
|
subscriptionHash = spotSubHash if isSpot else swapSubHash
|
879
|
-
url = self.urls['api']['ws'][type] + '?listenKey=' + self.options['listenKey']
|
880
1023
|
request = None
|
1024
|
+
baseUrl = None
|
881
1025
|
uuid = self.uuid()
|
882
|
-
if type == '
|
1026
|
+
if type == 'swap':
|
1027
|
+
if subType == 'inverse':
|
1028
|
+
raise NotSupported(self.id + ' watchBalance is not supported for inverse swap markets yet')
|
1029
|
+
baseUrl = self.safe_string(self.urls['api']['ws'], subType)
|
1030
|
+
else:
|
1031
|
+
baseUrl = self.safe_string(self.urls['api']['ws'], type)
|
883
1032
|
request = {
|
884
1033
|
'id': uuid,
|
885
1034
|
'dataType': 'ACCOUNT_UPDATE',
|
886
1035
|
}
|
1036
|
+
url = baseUrl + '?listenKey=' + self.options['listenKey']
|
887
1037
|
client = self.client(url)
|
888
|
-
self.set_balance_cache(client, type, subscriptionHash, params)
|
1038
|
+
self.set_balance_cache(client, type, subType, subscriptionHash, params)
|
889
1039
|
fetchBalanceSnapshot = None
|
890
1040
|
awaitBalanceSnapshot = None
|
891
1041
|
fetchBalanceSnapshot, params = self.handle_option_and_params(params, 'watchBalance', 'fetchBalanceSnapshot', True)
|
@@ -894,7 +1044,7 @@ class bingx(ccxt.async_support.bingx):
|
|
894
1044
|
await client.future(type + ':fetchBalanceSnapshot')
|
895
1045
|
return await self.watch(url, messageHash, request, subscriptionHash)
|
896
1046
|
|
897
|
-
def set_balance_cache(self, client: Client, type, subscriptionHash, params):
|
1047
|
+
def set_balance_cache(self, client: Client, type, subType, subscriptionHash, params):
|
898
1048
|
if subscriptionHash in client.subscriptions:
|
899
1049
|
return
|
900
1050
|
fetchBalanceSnapshot = self.handle_option_and_params(params, 'watchBalance', 'fetchBalanceSnapshot', True)
|
@@ -902,12 +1052,12 @@ class bingx(ccxt.async_support.bingx):
|
|
902
1052
|
messageHash = type + ':fetchBalanceSnapshot'
|
903
1053
|
if not (messageHash in client.futures):
|
904
1054
|
client.future(messageHash)
|
905
|
-
self.spawn(self.load_balance_snapshot, client, messageHash, type)
|
1055
|
+
self.spawn(self.load_balance_snapshot, client, messageHash, type, subType)
|
906
1056
|
else:
|
907
1057
|
self.balance[type] = {}
|
908
1058
|
|
909
|
-
async def load_balance_snapshot(self, client, messageHash, type):
|
910
|
-
response = await self.fetch_balance({'type': type})
|
1059
|
+
async def load_balance_snapshot(self, client, messageHash, type, subType):
|
1060
|
+
response = await self.fetch_balance({'type': type, 'subType': subType})
|
911
1061
|
self.balance[type] = self.extend(response, self.safe_value(self.balance, type, {}))
|
912
1062
|
# don't remove the future from the .futures cache
|
913
1063
|
future = client.futures[messageHash]
|
@@ -941,7 +1091,7 @@ class bingx(ccxt.async_support.bingx):
|
|
941
1091
|
try:
|
942
1092
|
await self.userAuthPrivatePutUserDataStream({'listenKey': listenKey}) # self.extend the expiry
|
943
1093
|
except Exception as error:
|
944
|
-
types = ['spot', '
|
1094
|
+
types = ['spot', 'linear', 'inverse']
|
945
1095
|
for i in range(0, len(types)):
|
946
1096
|
type = types[i]
|
947
1097
|
url = self.urls['api']['ws'][type] + '?listenKey=' + listenKey
|