ccxt 4.4.34__py2.py3-none-any.whl → 4.4.36__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 +3 -1
- ccxt/abstract/bingx.py +1 -0
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitpanda.py +0 -12
- ccxt/abstract/bitrue.py +3 -3
- ccxt/abstract/bybit.py +15 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/gate.py +14 -0
- ccxt/abstract/gateio.py +14 -0
- ccxt/abstract/okx.py +1 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/xt.py +5 -5
- ccxt/async_support/__init__.py +3 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/bingx.py +324 -138
- ccxt/async_support/bitfinex2.py +18 -13
- ccxt/async_support/bitmex.py +104 -2
- ccxt/async_support/bitopro.py +21 -4
- ccxt/async_support/bitrue.py +2 -2
- ccxt/async_support/bitso.py +2 -1
- ccxt/async_support/btcmarkets.py +3 -3
- ccxt/async_support/btcturk.py +19 -19
- ccxt/async_support/bybit.py +21 -1
- ccxt/async_support/defx.py +1981 -0
- ccxt/async_support/deribit.py +27 -12
- ccxt/async_support/gate.py +156 -39
- ccxt/async_support/htx.py +11 -2
- ccxt/async_support/hyperliquid.py +68 -11
- ccxt/async_support/idex.py +3 -4
- ccxt/async_support/kraken.py +97 -90
- ccxt/async_support/kucoin.py +1 -1
- ccxt/async_support/okx.py +1 -0
- ccxt/async_support/onetrading.py +47 -369
- ccxt/async_support/xt.py +10 -10
- ccxt/base/exchange.py +2 -1
- ccxt/bingx.py +324 -138
- ccxt/bitfinex2.py +18 -13
- ccxt/bitmex.py +104 -2
- ccxt/bitopro.py +21 -4
- ccxt/bitrue.py +2 -2
- ccxt/bitso.py +2 -1
- ccxt/btcmarkets.py +3 -3
- ccxt/btcturk.py +19 -19
- ccxt/bybit.py +21 -1
- ccxt/defx.py +1980 -0
- ccxt/deribit.py +27 -12
- ccxt/gate.py +156 -39
- ccxt/htx.py +11 -2
- ccxt/hyperliquid.py +68 -11
- ccxt/idex.py +3 -4
- ccxt/kraken.py +97 -90
- ccxt/kucoin.py +1 -1
- ccxt/okx.py +1 -0
- ccxt/onetrading.py +47 -369
- ccxt/pro/__init__.py +3 -1
- ccxt/pro/bitrue.py +13 -11
- ccxt/pro/defx.py +832 -0
- ccxt/pro/probit.py +54 -66
- ccxt/test/tests_async.py +44 -3
- ccxt/test/tests_sync.py +44 -3
- ccxt/xt.py +10 -10
- {ccxt-4.4.34.dist-info → ccxt-4.4.36.dist-info}/METADATA +7 -6
- {ccxt-4.4.34.dist-info → ccxt-4.4.36.dist-info}/RECORD +67 -63
- {ccxt-4.4.34.dist-info → ccxt-4.4.36.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.34.dist-info → ccxt-4.4.36.dist-info}/WHEEL +0 -0
- {ccxt-4.4.34.dist-info → ccxt-4.4.36.dist-info}/top_level.txt +0 -0
ccxt/pro/probit.py
CHANGED
@@ -41,15 +41,6 @@ class probit(ccxt.async_support.probit):
|
|
41
41
|
'filter': 'order_books_l2',
|
42
42
|
'interval': 100, # or 500
|
43
43
|
},
|
44
|
-
'watchTrades': {
|
45
|
-
'filter': 'recent_trades',
|
46
|
-
},
|
47
|
-
'watchTicker': {
|
48
|
-
'filter': 'ticker',
|
49
|
-
},
|
50
|
-
'watchOrders': {
|
51
|
-
'channel': 'open_order',
|
52
|
-
},
|
53
44
|
},
|
54
45
|
'streaming': {
|
55
46
|
},
|
@@ -66,13 +57,7 @@ class probit(ccxt.async_support.probit):
|
|
66
57
|
"""
|
67
58
|
await self.authenticate(params)
|
68
59
|
messageHash = 'balance'
|
69
|
-
|
70
|
-
subscribe: dict = {
|
71
|
-
'type': 'subscribe',
|
72
|
-
'channel': 'balance',
|
73
|
-
}
|
74
|
-
request = self.extend(subscribe, params)
|
75
|
-
return await self.watch(url, messageHash, request, messageHash)
|
60
|
+
return await self.subscribe_private(messageHash, 'balance', params)
|
76
61
|
|
77
62
|
def handle_balance(self, client: Client, message):
|
78
63
|
#
|
@@ -130,9 +115,8 @@ class probit(ccxt.async_support.probit):
|
|
130
115
|
:param int [params.interval]: Unit time to synchronize market information(ms). Available units: 100, 500
|
131
116
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
132
117
|
"""
|
133
|
-
|
134
|
-
|
135
|
-
return await self.subscribe_order_book(symbol, 'ticker', filter, params)
|
118
|
+
channel = 'ticker'
|
119
|
+
return await self.subscribe_public('watchTicker', symbol, 'ticker', channel, params)
|
136
120
|
|
137
121
|
def handle_ticker(self, client: Client, message):
|
138
122
|
#
|
@@ -175,9 +159,8 @@ class probit(ccxt.async_support.probit):
|
|
175
159
|
:param int [params.interval]: Unit time to synchronize market information(ms). Available units: 100, 500
|
176
160
|
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
177
161
|
"""
|
178
|
-
|
179
|
-
|
180
|
-
trades = await self.subscribe_order_book(symbol, 'trades', filter, params)
|
162
|
+
channel = 'recent_trades'
|
163
|
+
trades = await self.subscribe_public('watchTrades', symbol, 'trades', channel, params)
|
181
164
|
if self.newUpdates:
|
182
165
|
limit = trades.getLimit(symbol, limit)
|
183
166
|
return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
|
@@ -207,10 +190,11 @@ class probit(ccxt.async_support.probit):
|
|
207
190
|
symbol = self.safe_symbol(marketId)
|
208
191
|
market = self.safe_market(marketId)
|
209
192
|
trades = self.safe_value(message, 'recent_trades', [])
|
210
|
-
|
193
|
+
if self.safe_bool(message, 'reset', False):
|
194
|
+
return # see comment in handleMessage
|
211
195
|
messageHash = 'trades:' + symbol
|
212
196
|
stored = self.safe_value(self.trades, symbol)
|
213
|
-
if stored is None
|
197
|
+
if stored is None:
|
214
198
|
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
215
199
|
stored = ArrayCache(limit)
|
216
200
|
self.trades[symbol] = stored
|
@@ -235,19 +219,11 @@ class probit(ccxt.async_support.probit):
|
|
235
219
|
"""
|
236
220
|
await self.load_markets()
|
237
221
|
await self.authenticate(params)
|
238
|
-
messageHash = '
|
222
|
+
messageHash = 'trades'
|
239
223
|
if symbol is not None:
|
240
|
-
|
241
|
-
symbol = market['symbol']
|
224
|
+
symbol = self.safe_symbol(symbol)
|
242
225
|
messageHash = messageHash + ':' + symbol
|
243
|
-
|
244
|
-
channel = 'trade_history'
|
245
|
-
message: dict = {
|
246
|
-
'type': 'subscribe',
|
247
|
-
'channel': channel,
|
248
|
-
}
|
249
|
-
request = self.extend(message, params)
|
250
|
-
trades = await self.watch(url, messageHash, request, channel)
|
226
|
+
trades = await self.subscribe_private(messageHash, 'trade_history', params)
|
251
227
|
if self.newUpdates:
|
252
228
|
limit = trades.getLimit(symbol, limit)
|
253
229
|
return self.filter_by_symbol_since_limit(trades, symbol, since, limit, True)
|
@@ -276,10 +252,11 @@ class probit(ccxt.async_support.probit):
|
|
276
252
|
length = len(rawTrades)
|
277
253
|
if length == 0:
|
278
254
|
return
|
279
|
-
|
280
|
-
|
255
|
+
if self.safe_bool(message, 'reset', False):
|
256
|
+
return # see comment in handleMessage
|
257
|
+
messageHash = 'trades'
|
281
258
|
stored = self.myTrades
|
282
|
-
if
|
259
|
+
if stored is None:
|
283
260
|
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
284
261
|
stored = ArrayCacheBySymbolById(limit)
|
285
262
|
self.myTrades = stored
|
@@ -287,9 +264,15 @@ class probit(ccxt.async_support.probit):
|
|
287
264
|
tradeSymbols: dict = {}
|
288
265
|
for j in range(0, len(trades)):
|
289
266
|
trade = trades[j]
|
267
|
+
# don't include 'executed' state, because it's just blanket state of the trade, emited before actual trade event
|
268
|
+
if self.safe_string(trade['info'], 'status') == 'executed':
|
269
|
+
continue
|
290
270
|
tradeSymbols[trade['symbol']] = True
|
291
271
|
stored.append(trade)
|
292
272
|
unique = list(tradeSymbols.keys())
|
273
|
+
uniqueLength = len(unique)
|
274
|
+
if uniqueLength == 0:
|
275
|
+
return
|
293
276
|
for i in range(0, len(unique)):
|
294
277
|
symbol = unique[i]
|
295
278
|
symbolSpecificMessageHash = messageHash + ':' + symbol
|
@@ -310,20 +293,11 @@ class probit(ccxt.async_support.probit):
|
|
310
293
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
311
294
|
"""
|
312
295
|
await self.authenticate(params)
|
313
|
-
url = self.urls['api']['ws']
|
314
296
|
messageHash = 'orders'
|
315
297
|
if symbol is not None:
|
316
|
-
|
317
|
-
symbol = market['symbol']
|
298
|
+
symbol = self.safe_symbol(symbol)
|
318
299
|
messageHash = messageHash + ':' + symbol
|
319
|
-
|
320
|
-
channel, params = self.handle_option_and_params(params, 'watchOrders', 'channel', 'open_order')
|
321
|
-
subscribe: dict = {
|
322
|
-
'type': 'subscribe',
|
323
|
-
'channel': channel,
|
324
|
-
}
|
325
|
-
request = self.extend(subscribe, params)
|
326
|
-
orders = await self.watch(url, messageHash, request, channel)
|
300
|
+
orders = await self.subscribe_private(messageHash, 'open_order', params)
|
327
301
|
if self.newUpdates:
|
328
302
|
limit = orders.getLimit(symbol, limit)
|
329
303
|
return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
|
@@ -388,39 +362,49 @@ class probit(ccxt.async_support.probit):
|
|
388
362
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
389
363
|
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
390
364
|
"""
|
391
|
-
|
392
|
-
|
393
|
-
orderbook = await self.
|
365
|
+
channel = None
|
366
|
+
channel, params = self.handle_option_and_params(params, 'watchOrderBook', 'filter', 'order_books')
|
367
|
+
orderbook = await self.subscribe_public('watchOrderBook', symbol, 'orderbook', channel, params)
|
394
368
|
return orderbook.limit()
|
395
369
|
|
396
|
-
async def
|
370
|
+
async def subscribe_private(self, messageHash, channel, params):
|
371
|
+
url = self.urls['api']['ws']
|
372
|
+
subscribe: dict = {
|
373
|
+
'type': 'subscribe',
|
374
|
+
'channel': channel,
|
375
|
+
}
|
376
|
+
request = self.extend(subscribe, params)
|
377
|
+
subscribeHash = messageHash
|
378
|
+
return await self.watch(url, messageHash, request, subscribeHash)
|
379
|
+
|
380
|
+
async def subscribe_public(self, methodName: str, symbol: str, dataType, filter, params={}):
|
397
381
|
await self.load_markets()
|
398
382
|
market = self.market(symbol)
|
399
383
|
symbol = market['symbol']
|
400
384
|
url = self.urls['api']['ws']
|
401
385
|
client = self.client(url)
|
402
|
-
|
403
|
-
|
404
|
-
subscriptionHash = 'marketdata:' + symbol
|
405
|
-
messageHash = messageHash + ':' + symbol
|
386
|
+
subscribeHash = 'marketdata:' + symbol
|
387
|
+
messageHash = dataType + ':' + symbol
|
406
388
|
filters = {}
|
407
|
-
if
|
389
|
+
if subscribeHash in client.subscriptions:
|
408
390
|
# already subscribed
|
409
|
-
filters = client.subscriptions[
|
391
|
+
filters = client.subscriptions[subscribeHash]
|
410
392
|
if not (filter in filters):
|
411
393
|
# resubscribe
|
412
|
-
del client.subscriptions[
|
394
|
+
del client.subscriptions[subscribeHash]
|
413
395
|
filters[filter] = True
|
414
396
|
keys = list(filters.keys())
|
415
|
-
|
397
|
+
interval = None
|
398
|
+
interval, params = self.handle_option_and_params(params, methodName, 'interval', 100)
|
399
|
+
request: dict = {
|
400
|
+
'type': 'subscribe',
|
416
401
|
'channel': 'marketdata',
|
417
|
-
'interval': interval,
|
418
402
|
'market_id': market['id'],
|
419
|
-
'type': 'subscribe',
|
420
403
|
'filter': keys,
|
404
|
+
'interval': interval,
|
421
405
|
}
|
422
|
-
request = self.extend(
|
423
|
-
return await self.watch(url, messageHash, request,
|
406
|
+
request = self.extend(request, params)
|
407
|
+
return await self.watch(url, messageHash, request, subscribeHash, filters)
|
424
408
|
|
425
409
|
def handle_order_book(self, client: Client, message, orderBook):
|
426
410
|
#
|
@@ -493,7 +477,8 @@ class probit(ccxt.async_support.probit):
|
|
493
477
|
result = self.safe_string(message, 'result')
|
494
478
|
future = client.subscriptions['authenticated']
|
495
479
|
if result == 'ok':
|
496
|
-
|
480
|
+
messageHash = 'authenticated'
|
481
|
+
client.resolve(message, messageHash)
|
497
482
|
else:
|
498
483
|
future.reject(message)
|
499
484
|
del client.subscriptions['authenticated']
|
@@ -521,6 +506,9 @@ class probit(ccxt.async_support.probit):
|
|
521
506
|
# }
|
522
507
|
# }
|
523
508
|
#
|
509
|
+
# Note about 'reset' field
|
510
|
+
# 'reset': True field - it happens once after initial subscription, which just returns old items by the moment of subscription(like "fetchMyTrades" does)
|
511
|
+
#
|
524
512
|
errorCode = self.safe_string(message, 'errorCode')
|
525
513
|
if errorCode is not None:
|
526
514
|
self.handle_error_message(client, message)
|
ccxt/test/tests_async.py
CHANGED
@@ -714,7 +714,7 @@ class testMainClass:
|
|
714
714
|
result[key] = value
|
715
715
|
return result
|
716
716
|
|
717
|
-
def
|
717
|
+
def assert_new_and_stored_output_inner(self, exchange, skip_keys, new_output, stored_output, strict_type_check=True, asserting_key=None):
|
718
718
|
if is_null_value(new_output) and is_null_value(stored_output):
|
719
719
|
return True
|
720
720
|
if not new_output and not stored_output:
|
@@ -796,6 +796,25 @@ class testMainClass:
|
|
796
796
|
self.assert_static_error(numeric_new_output == numeric_stored_output, message_error, stored_output, new_output, asserting_key)
|
797
797
|
return True # c# requ
|
798
798
|
|
799
|
+
def assert_new_and_stored_output(self, exchange, skip_keys, new_output, stored_output, strict_type_check=True, asserting_key=None):
|
800
|
+
try:
|
801
|
+
return self.assert_new_and_stored_output_inner(exchange, skip_keys, new_output, stored_output, strict_type_check, asserting_key)
|
802
|
+
except Exception as e:
|
803
|
+
if self.info:
|
804
|
+
error_message = self.var_to_string(new_output) + '(calculated)' + ' != ' + self.var_to_string(stored_output) + '(stored)'
|
805
|
+
dump('[TEST_FAILURE_DETAIL]' + error_message)
|
806
|
+
raise e
|
807
|
+
|
808
|
+
def var_to_string(self, obj=None):
|
809
|
+
new_string = None
|
810
|
+
if obj is None:
|
811
|
+
new_string = 'undefined'
|
812
|
+
elif is_null_value(obj):
|
813
|
+
new_string = 'null'
|
814
|
+
else:
|
815
|
+
new_string = json_stringify(obj)
|
816
|
+
return new_string
|
817
|
+
|
799
818
|
def assert_static_request_output(self, exchange, type, skip_keys, stored_url, request_url, stored_output, new_output):
|
800
819
|
if stored_url != request_url:
|
801
820
|
# remove the host part from the url
|
@@ -1064,7 +1083,15 @@ class testMainClass:
|
|
1064
1083
|
promises.append(self.test_exchange_request_statically(exchange_name, exchange_data, test_name))
|
1065
1084
|
else:
|
1066
1085
|
promises.append(self.test_exchange_response_statically(exchange_name, exchange_data, test_name))
|
1067
|
-
|
1086
|
+
try:
|
1087
|
+
await asyncio.gather(*promises)
|
1088
|
+
except Exception as e:
|
1089
|
+
if type == 'request':
|
1090
|
+
self.request_tests_failed = True
|
1091
|
+
else:
|
1092
|
+
self.response_tests_failed = True
|
1093
|
+
error_message = '[' + self.lang + '][STATIC_REQUEST]' + '[' + exchange.id + ']' + str(e)
|
1094
|
+
dump('[TEST_FAILURE]' + error_message)
|
1068
1095
|
if self.request_tests_failed or self.response_tests_failed:
|
1069
1096
|
exit_script(1)
|
1070
1097
|
else:
|
@@ -1082,7 +1109,7 @@ class testMainClass:
|
|
1082
1109
|
# -----------------------------------------------------------------------------
|
1083
1110
|
# --- Init of brokerId tests functions-----------------------------------------
|
1084
1111
|
# -----------------------------------------------------------------------------
|
1085
|
-
promises = [self.test_binance(), self.test_okx(), self.test_cryptocom(), self.test_bybit(), self.test_kucoin(), self.test_kucoinfutures(), self.test_bitget(), self.test_mexc(), self.test_htx(), self.test_woo(), self.test_bitmart(), self.test_coinex(), self.test_bingx(), self.test_phemex(), self.test_blofin(), self.test_hyperliquid(), self.test_coinbaseinternational(), self.test_coinbase_advanced(), self.test_woofi_pro(), self.test_oxfun(), self.test_xt(), self.test_vertex(), self.test_paradex(), self.test_hashkey(), self.test_coincatch()]
|
1112
|
+
promises = [self.test_binance(), self.test_okx(), self.test_cryptocom(), self.test_bybit(), self.test_kucoin(), self.test_kucoinfutures(), self.test_bitget(), self.test_mexc(), self.test_htx(), self.test_woo(), self.test_bitmart(), self.test_coinex(), self.test_bingx(), self.test_phemex(), self.test_blofin(), self.test_hyperliquid(), self.test_coinbaseinternational(), self.test_coinbase_advanced(), self.test_woofi_pro(), self.test_oxfun(), self.test_xt(), self.test_vertex(), self.test_paradex(), self.test_hashkey(), self.test_coincatch(), self.test_defx()]
|
1086
1113
|
await asyncio.gather(*promises)
|
1087
1114
|
success_message = '[' + self.lang + '][TEST_SUCCESS] brokerId tests passed.'
|
1088
1115
|
dump('[INFO]' + success_message)
|
@@ -1558,3 +1585,17 @@ class testMainClass:
|
|
1558
1585
|
if not is_sync():
|
1559
1586
|
await close(exchange)
|
1560
1587
|
return True
|
1588
|
+
|
1589
|
+
async def test_defx(self):
|
1590
|
+
exchange = self.init_offline_exchange('defx')
|
1591
|
+
req_headers = None
|
1592
|
+
try:
|
1593
|
+
await exchange.create_order('DOGE/USDC:USDC', 'limit', 'buy', 100, 1)
|
1594
|
+
except Exception as e:
|
1595
|
+
# we expect an error here, we're only interested in the headers
|
1596
|
+
req_headers = exchange.last_request_headers
|
1597
|
+
id = 'ccxt'
|
1598
|
+
assert req_headers['X-DEFX-SOURCE'] == id, 'defx - id: ' + id + ' not in headers.'
|
1599
|
+
if not is_sync():
|
1600
|
+
await close(exchange)
|
1601
|
+
return True
|
ccxt/test/tests_sync.py
CHANGED
@@ -711,7 +711,7 @@ class testMainClass:
|
|
711
711
|
result[key] = value
|
712
712
|
return result
|
713
713
|
|
714
|
-
def
|
714
|
+
def assert_new_and_stored_output_inner(self, exchange, skip_keys, new_output, stored_output, strict_type_check=True, asserting_key=None):
|
715
715
|
if is_null_value(new_output) and is_null_value(stored_output):
|
716
716
|
return True
|
717
717
|
if not new_output and not stored_output:
|
@@ -793,6 +793,25 @@ class testMainClass:
|
|
793
793
|
self.assert_static_error(numeric_new_output == numeric_stored_output, message_error, stored_output, new_output, asserting_key)
|
794
794
|
return True # c# requ
|
795
795
|
|
796
|
+
def assert_new_and_stored_output(self, exchange, skip_keys, new_output, stored_output, strict_type_check=True, asserting_key=None):
|
797
|
+
try:
|
798
|
+
return self.assert_new_and_stored_output_inner(exchange, skip_keys, new_output, stored_output, strict_type_check, asserting_key)
|
799
|
+
except Exception as e:
|
800
|
+
if self.info:
|
801
|
+
error_message = self.var_to_string(new_output) + '(calculated)' + ' != ' + self.var_to_string(stored_output) + '(stored)'
|
802
|
+
dump('[TEST_FAILURE_DETAIL]' + error_message)
|
803
|
+
raise e
|
804
|
+
|
805
|
+
def var_to_string(self, obj=None):
|
806
|
+
new_string = None
|
807
|
+
if obj is None:
|
808
|
+
new_string = 'undefined'
|
809
|
+
elif is_null_value(obj):
|
810
|
+
new_string = 'null'
|
811
|
+
else:
|
812
|
+
new_string = json_stringify(obj)
|
813
|
+
return new_string
|
814
|
+
|
796
815
|
def assert_static_request_output(self, exchange, type, skip_keys, stored_url, request_url, stored_output, new_output):
|
797
816
|
if stored_url != request_url:
|
798
817
|
# remove the host part from the url
|
@@ -1061,7 +1080,15 @@ class testMainClass:
|
|
1061
1080
|
promises.append(self.test_exchange_request_statically(exchange_name, exchange_data, test_name))
|
1062
1081
|
else:
|
1063
1082
|
promises.append(self.test_exchange_response_statically(exchange_name, exchange_data, test_name))
|
1064
|
-
|
1083
|
+
try:
|
1084
|
+
(promises)
|
1085
|
+
except Exception as e:
|
1086
|
+
if type == 'request':
|
1087
|
+
self.request_tests_failed = True
|
1088
|
+
else:
|
1089
|
+
self.response_tests_failed = True
|
1090
|
+
error_message = '[' + self.lang + '][STATIC_REQUEST]' + '[' + exchange.id + ']' + str(e)
|
1091
|
+
dump('[TEST_FAILURE]' + error_message)
|
1065
1092
|
if self.request_tests_failed or self.response_tests_failed:
|
1066
1093
|
exit_script(1)
|
1067
1094
|
else:
|
@@ -1079,7 +1106,7 @@ class testMainClass:
|
|
1079
1106
|
# -----------------------------------------------------------------------------
|
1080
1107
|
# --- Init of brokerId tests functions-----------------------------------------
|
1081
1108
|
# -----------------------------------------------------------------------------
|
1082
|
-
promises = [self.test_binance(), self.test_okx(), self.test_cryptocom(), self.test_bybit(), self.test_kucoin(), self.test_kucoinfutures(), self.test_bitget(), self.test_mexc(), self.test_htx(), self.test_woo(), self.test_bitmart(), self.test_coinex(), self.test_bingx(), self.test_phemex(), self.test_blofin(), self.test_hyperliquid(), self.test_coinbaseinternational(), self.test_coinbase_advanced(), self.test_woofi_pro(), self.test_oxfun(), self.test_xt(), self.test_vertex(), self.test_paradex(), self.test_hashkey(), self.test_coincatch()]
|
1109
|
+
promises = [self.test_binance(), self.test_okx(), self.test_cryptocom(), self.test_bybit(), self.test_kucoin(), self.test_kucoinfutures(), self.test_bitget(), self.test_mexc(), self.test_htx(), self.test_woo(), self.test_bitmart(), self.test_coinex(), self.test_bingx(), self.test_phemex(), self.test_blofin(), self.test_hyperliquid(), self.test_coinbaseinternational(), self.test_coinbase_advanced(), self.test_woofi_pro(), self.test_oxfun(), self.test_xt(), self.test_vertex(), self.test_paradex(), self.test_hashkey(), self.test_coincatch(), self.test_defx()]
|
1083
1110
|
(promises)
|
1084
1111
|
success_message = '[' + self.lang + '][TEST_SUCCESS] brokerId tests passed.'
|
1085
1112
|
dump('[INFO]' + success_message)
|
@@ -1555,3 +1582,17 @@ class testMainClass:
|
|
1555
1582
|
if not is_sync():
|
1556
1583
|
close(exchange)
|
1557
1584
|
return True
|
1585
|
+
|
1586
|
+
def test_defx(self):
|
1587
|
+
exchange = self.init_offline_exchange('defx')
|
1588
|
+
req_headers = None
|
1589
|
+
try:
|
1590
|
+
exchange.create_order('DOGE/USDC:USDC', 'limit', 'buy', 100, 1)
|
1591
|
+
except Exception as e:
|
1592
|
+
# we expect an error here, we're only interested in the headers
|
1593
|
+
req_headers = exchange.last_request_headers
|
1594
|
+
id = 'ccxt'
|
1595
|
+
assert req_headers['X-DEFX-SOURCE'] == id, 'defx - id: ' + id + ' not in headers.'
|
1596
|
+
if not is_sync():
|
1597
|
+
close(exchange)
|
1598
|
+
return True
|
ccxt/xt.py
CHANGED
@@ -156,16 +156,16 @@ class xt(Exchange, ImplicitAPI):
|
|
156
156
|
'spot': {
|
157
157
|
'get': {
|
158
158
|
'currencies': 1,
|
159
|
-
'depth':
|
160
|
-
'kline':
|
161
|
-
'symbol': 1, #
|
162
|
-
'ticker': 1, #
|
163
|
-
'ticker/book': 1, #
|
164
|
-
'ticker/price': 1, #
|
165
|
-
'ticker/24h': 1, #
|
159
|
+
'depth': 10,
|
160
|
+
'kline': 1,
|
161
|
+
'symbol': 1, # 1 for a single symbol
|
162
|
+
'ticker': 1, # 1 for a single symbol
|
163
|
+
'ticker/book': 1, # 1 for a single symbol
|
164
|
+
'ticker/price': 1, # 1 for a single symbol
|
165
|
+
'ticker/24h': 1, # 1 for a single symbol
|
166
166
|
'time': 1,
|
167
|
-
'trade/history':
|
168
|
-
'trade/recent':
|
167
|
+
'trade/history': 1,
|
168
|
+
'trade/recent': 1,
|
169
169
|
'wallet/support/currency': 1,
|
170
170
|
},
|
171
171
|
},
|
@@ -235,7 +235,7 @@ class xt(Exchange, ImplicitAPI):
|
|
235
235
|
},
|
236
236
|
'post': {
|
237
237
|
'order': 0.2,
|
238
|
-
'withdraw':
|
238
|
+
'withdraw': 10,
|
239
239
|
'balance/transfer': 1,
|
240
240
|
'balance/account/transfer': 1,
|
241
241
|
'ws-token': 1,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ccxt
|
3
|
-
Version: 4.4.
|
3
|
+
Version: 4.4.36
|
4
4
|
Summary: A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges
|
5
5
|
Home-page: https://ccxt.com
|
6
6
|
Author: Igor Kroitor
|
@@ -50,7 +50,7 @@ Requires-Dist: mypy (==1.6.1) ; extra == 'type'
|
|
50
50
|
|
51
51
|
# CCXT – CryptoCurrency eXchange Trading Library
|
52
52
|
|
53
|
-
[](https://travis-ci.com/ccxt/ccxt) [](https://npmjs.com/package/ccxt) [](https://pypi.python.org/pypi/ccxt) [](https://www.npmjs.com/package/ccxt) [](https://discord.gg/ccxt) [](https://travis-ci.com/ccxt/ccxt) [](https://npmjs.com/package/ccxt) [](https://pypi.python.org/pypi/ccxt) [](https://www.npmjs.com/package/ccxt) [](https://discord.gg/ccxt) [](https://github.com/ccxt/ccxt/wiki/Exchange-Markets) [](https://twitter.com/ccxt_official)
|
54
54
|
|
55
55
|
A JavaScript / Python / PHP / C# library for cryptocurrency trading and e-commerce with support for many bitcoin/ether/altcoin exchange markets and merchant APIs.
|
56
56
|
|
@@ -108,7 +108,7 @@ Current feature list:
|
|
108
108
|
|
109
109
|
## Supported Cryptocurrency Exchanges
|
110
110
|
|
111
|
-
The CCXT library currently supports the following
|
111
|
+
The CCXT library currently supports the following 106 cryptocurrency exchange markets and trading APIs:
|
112
112
|
|
113
113
|
| logo | id | name | ver | type | certified | pro |
|
114
114
|
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------|----------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------:|------|-----------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------|
|
@@ -161,6 +161,7 @@ The CCXT library currently supports the following 105 cryptocurrency exchange ma
|
|
161
161
|
| [](https://www.coinspot.com.au/register?code=PJURCU) | coinspot | [CoinSpot](https://www.coinspot.com.au/register?code=PJURCU) | [](https://www.coinspot.com.au/api) | cex | | |
|
162
162
|
| [](https://crypto.com/exch/kdacthrnxt) | cryptocom | [Crypto.com](https://crypto.com/exch/kdacthrnxt) | [](https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html) | cex | [](https://github.com/ccxt/ccxt/wiki/Certification) | [](https://ccxt.pro) |
|
163
163
|
| [](https://currency.com/trading/signup?c=362jaimv&pid=referral) | currencycom | [Currency.com](https://currency.com/trading/signup?c=362jaimv&pid=referral) | [](https://currency.com/api) | cex | | [](https://ccxt.pro) |
|
164
|
+
| [](https://app.defx.com/join/6I2CZ7) | defx | [Defx X](https://app.defx.com/join/6I2CZ7) | [](https://docs.defx.com/docs) | dex | | |
|
164
165
|
| [](https://www.delta.exchange/app/signup/?code=IULYNB) | delta | [Delta Exchange](https://www.delta.exchange/app/signup/?code=IULYNB) | [](https://docs.delta.exchange) | cex | | |
|
165
166
|
| [](https://www.deribit.com/reg-1189.4038) | deribit | [Deribit](https://www.deribit.com/reg-1189.4038) | [](https://docs.deribit.com/v2) | cex | | [](https://ccxt.pro) |
|
166
167
|
| [](https://www.digifinex.com/en-ww/from/DhOzBg?channelCode=ljaUPp) | digifinex | [DigiFinex](https://www.digifinex.com/en-ww/from/DhOzBg?channelCode=ljaUPp) | [](https://docs.digifinex.com) | cex | | |
|
@@ -274,13 +275,13 @@ console.log(version, Object.keys(exchanges));
|
|
274
275
|
|
275
276
|
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
|
276
277
|
|
277
|
-
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.
|
278
|
-
* unpkg: https://unpkg.com/ccxt@4.4.
|
278
|
+
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.36/dist/ccxt.browser.min.js
|
279
|
+
* unpkg: https://unpkg.com/ccxt@4.4.36/dist/ccxt.browser.min.js
|
279
280
|
|
280
281
|
CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
|
281
282
|
|
282
283
|
```HTML
|
283
|
-
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.4.
|
284
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.4.36/dist/ccxt.browser.min.js"></script>
|
284
285
|
```
|
285
286
|
|
286
287
|
Creates a global `ccxt` object:
|