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.
Files changed (67) hide show
  1. ccxt/__init__.py +3 -1
  2. ccxt/abstract/bingx.py +1 -0
  3. ccxt/abstract/bitopro.py +1 -0
  4. ccxt/abstract/bitpanda.py +0 -12
  5. ccxt/abstract/bitrue.py +3 -3
  6. ccxt/abstract/bybit.py +15 -0
  7. ccxt/abstract/defx.py +69 -0
  8. ccxt/abstract/deribit.py +1 -0
  9. ccxt/abstract/gate.py +14 -0
  10. ccxt/abstract/gateio.py +14 -0
  11. ccxt/abstract/okx.py +1 -0
  12. ccxt/abstract/onetrading.py +0 -12
  13. ccxt/abstract/xt.py +5 -5
  14. ccxt/async_support/__init__.py +3 -1
  15. ccxt/async_support/base/exchange.py +1 -1
  16. ccxt/async_support/bingx.py +324 -138
  17. ccxt/async_support/bitfinex2.py +18 -13
  18. ccxt/async_support/bitmex.py +104 -2
  19. ccxt/async_support/bitopro.py +21 -4
  20. ccxt/async_support/bitrue.py +2 -2
  21. ccxt/async_support/bitso.py +2 -1
  22. ccxt/async_support/btcmarkets.py +3 -3
  23. ccxt/async_support/btcturk.py +19 -19
  24. ccxt/async_support/bybit.py +21 -1
  25. ccxt/async_support/defx.py +1981 -0
  26. ccxt/async_support/deribit.py +27 -12
  27. ccxt/async_support/gate.py +156 -39
  28. ccxt/async_support/htx.py +11 -2
  29. ccxt/async_support/hyperliquid.py +68 -11
  30. ccxt/async_support/idex.py +3 -4
  31. ccxt/async_support/kraken.py +97 -90
  32. ccxt/async_support/kucoin.py +1 -1
  33. ccxt/async_support/okx.py +1 -0
  34. ccxt/async_support/onetrading.py +47 -369
  35. ccxt/async_support/xt.py +10 -10
  36. ccxt/base/exchange.py +2 -1
  37. ccxt/bingx.py +324 -138
  38. ccxt/bitfinex2.py +18 -13
  39. ccxt/bitmex.py +104 -2
  40. ccxt/bitopro.py +21 -4
  41. ccxt/bitrue.py +2 -2
  42. ccxt/bitso.py +2 -1
  43. ccxt/btcmarkets.py +3 -3
  44. ccxt/btcturk.py +19 -19
  45. ccxt/bybit.py +21 -1
  46. ccxt/defx.py +1980 -0
  47. ccxt/deribit.py +27 -12
  48. ccxt/gate.py +156 -39
  49. ccxt/htx.py +11 -2
  50. ccxt/hyperliquid.py +68 -11
  51. ccxt/idex.py +3 -4
  52. ccxt/kraken.py +97 -90
  53. ccxt/kucoin.py +1 -1
  54. ccxt/okx.py +1 -0
  55. ccxt/onetrading.py +47 -369
  56. ccxt/pro/__init__.py +3 -1
  57. ccxt/pro/bitrue.py +13 -11
  58. ccxt/pro/defx.py +832 -0
  59. ccxt/pro/probit.py +54 -66
  60. ccxt/test/tests_async.py +44 -3
  61. ccxt/test/tests_sync.py +44 -3
  62. ccxt/xt.py +10 -10
  63. {ccxt-4.4.34.dist-info → ccxt-4.4.36.dist-info}/METADATA +7 -6
  64. {ccxt-4.4.34.dist-info → ccxt-4.4.36.dist-info}/RECORD +67 -63
  65. {ccxt-4.4.34.dist-info → ccxt-4.4.36.dist-info}/LICENSE.txt +0 -0
  66. {ccxt-4.4.34.dist-info → ccxt-4.4.36.dist-info}/WHEEL +0 -0
  67. {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
- url = self.urls['api']['ws']
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
- filter = None
134
- filter, params = self.handle_option_and_params(params, 'watchTicker', 'filter', 'ticker')
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
- filter = None
179
- filter, params = self.handle_option_and_params(params, 'watchTrades', 'filter', 'recent_trades')
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
- reset = self.safe_bool(message, 'reset', False)
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 or reset:
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 = 'myTrades'
222
+ messageHash = 'trades'
239
223
  if symbol is not None:
240
- market = self.market(symbol)
241
- symbol = market['symbol']
224
+ symbol = self.safe_symbol(symbol)
242
225
  messageHash = messageHash + ':' + symbol
243
- url = self.urls['api']['ws']
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
- reset = self.safe_bool(message, 'reset', False)
280
- messageHash = 'myTrades'
255
+ if self.safe_bool(message, 'reset', False):
256
+ return # see comment in handleMessage
257
+ messageHash = 'trades'
281
258
  stored = self.myTrades
282
- if (stored is None) or reset:
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
- market = self.market(symbol)
317
- symbol = market['symbol']
298
+ symbol = self.safe_symbol(symbol)
318
299
  messageHash = messageHash + ':' + symbol
319
- channel = None
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
- filter = None
392
- filter, params = self.handle_option_and_params(params, 'watchOrderBook', 'filter', 'order_books')
393
- orderbook = await self.subscribe_order_book(symbol, 'orderbook', filter, params)
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 subscribe_order_book(self, symbol: str, messageHash, filter, params={}):
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
- interval = None
403
- interval, params = self.handle_option_and_params(params, 'watchOrderBook', 'interval', 100)
404
- subscriptionHash = 'marketdata:' + symbol
405
- messageHash = messageHash + ':' + symbol
386
+ subscribeHash = 'marketdata:' + symbol
387
+ messageHash = dataType + ':' + symbol
406
388
  filters = {}
407
- if subscriptionHash in client.subscriptions:
389
+ if subscribeHash in client.subscriptions:
408
390
  # already subscribed
409
- filters = client.subscriptions[subscriptionHash]
391
+ filters = client.subscriptions[subscribeHash]
410
392
  if not (filter in filters):
411
393
  # resubscribe
412
- del client.subscriptions[subscriptionHash]
394
+ del client.subscriptions[subscribeHash]
413
395
  filters[filter] = True
414
396
  keys = list(filters.keys())
415
- message: dict = {
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(message, params)
423
- return await self.watch(url, messageHash, request, messageHash, filters)
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
- future.resolve(True)
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 assert_new_and_stored_output(self, exchange, skip_keys, new_output, stored_output, strict_type_check=True, asserting_key=None):
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
- await asyncio.gather(*promises)
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 assert_new_and_stored_output(self, exchange, skip_keys, new_output, stored_output, strict_type_check=True, asserting_key=None):
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
- (promises)
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': 0.05,
160
- 'kline': 0.1,
161
- 'symbol': 1, # 0.1 for a single symbol
162
- 'ticker': 1, # 0.1 for a single symbol
163
- 'ticker/book': 1, # 0.1 for a single symbol
164
- 'ticker/price': 1, # 0.1 for a single symbol
165
- 'ticker/24h': 1, # 0.1 for a single symbol
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': 0.1,
168
- 'trade/recent': 0.1,
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': 1,
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.34
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
- [![Build Status](https://img.shields.io/travis/com/ccxt/ccxt)](https://travis-ci.com/ccxt/ccxt) [![npm](https://img.shields.io/npm/v/ccxt.svg)](https://npmjs.com/package/ccxt) [![PyPI](https://img.shields.io/pypi/v/ccxt.svg)](https://pypi.python.org/pypi/ccxt) [![NPM Downloads](https://img.shields.io/npm/dy/ccxt.svg)](https://www.npmjs.com/package/ccxt) [![Discord](https://img.shields.io/discord/690203284119617602?logo=discord&logoColor=white)](https://discord.gg/ccxt) [![Supported Exchanges](https://img.shields.io/badge/exchanges-110-blue.svg)](https://github.com/ccxt/ccxt/wiki/Exchange-Markets) [![Twitter Follow](https://img.shields.io/twitter/follow/ccxt_official.svg?style=social&label=CCXT)](https://twitter.com/ccxt_official)
53
+ [![Build Status](https://img.shields.io/travis/com/ccxt/ccxt)](https://travis-ci.com/ccxt/ccxt) [![npm](https://img.shields.io/npm/v/ccxt.svg)](https://npmjs.com/package/ccxt) [![PyPI](https://img.shields.io/pypi/v/ccxt.svg)](https://pypi.python.org/pypi/ccxt) [![NPM Downloads](https://img.shields.io/npm/dy/ccxt.svg)](https://www.npmjs.com/package/ccxt) [![Discord](https://img.shields.io/discord/690203284119617602?logo=discord&logoColor=white)](https://discord.gg/ccxt) [![Supported Exchanges](https://img.shields.io/badge/exchanges-111-blue.svg)](https://github.com/ccxt/ccxt/wiki/Exchange-Markets) [![Twitter Follow](https://img.shields.io/twitter/follow/ccxt_official.svg?style=social&label=CCXT)](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 105 cryptocurrency exchange markets and trading APIs:
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
  | [![coinspot](https://user-images.githubusercontent.com/1294454/28208429-3cacdf9a-6896-11e7-854e-4c79a772a30f.jpg)](https://www.coinspot.com.au/register?code=PJURCU) | coinspot | [CoinSpot](https://www.coinspot.com.au/register?code=PJURCU) | [![API Version *](https://img.shields.io/badge/*-lightgray)](https://www.coinspot.com.au/api) | cex | | |
162
162
  | [![cryptocom](https://user-images.githubusercontent.com/1294454/147792121-38ed5e36-c229-48d6-b49a-48d05fc19ed4.jpeg)](https://crypto.com/exch/kdacthrnxt) | cryptocom | [Crypto.com](https://crypto.com/exch/kdacthrnxt) | [![API Version 2](https://img.shields.io/badge/2-lightgray)](https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html) | cex | [![CCXT Certified](https://img.shields.io/badge/CCXT-Certified-green.svg)](https://github.com/ccxt/ccxt/wiki/Certification) | [![CCXT Pro](https://img.shields.io/badge/CCXT-Pro-black)](https://ccxt.pro) |
163
163
  | [![currencycom](https://user-images.githubusercontent.com/1294454/83718672-36745c00-a63e-11ea-81a9-677b1f789a4d.jpg)](https://currency.com/trading/signup?c=362jaimv&pid=referral) | currencycom | [Currency.com](https://currency.com/trading/signup?c=362jaimv&pid=referral) | [![API Version 2](https://img.shields.io/badge/2-lightgray)](https://currency.com/api) | cex | | [![CCXT Pro](https://img.shields.io/badge/CCXT-Pro-black)](https://ccxt.pro) |
164
+ | [![defx](https://github.com/user-attachments/assets/4e92bace-d7a9-45ea-92be-122168dc87e4)](https://app.defx.com/join/6I2CZ7) | defx | [Defx X](https://app.defx.com/join/6I2CZ7) | [![API Version 1](https://img.shields.io/badge/1-lightgray)](https://docs.defx.com/docs) | dex | | |
164
165
  | [![delta](https://user-images.githubusercontent.com/1294454/99450025-3be60a00-2931-11eb-9302-f4fd8d8589aa.jpg)](https://www.delta.exchange/app/signup/?code=IULYNB) | delta | [Delta Exchange](https://www.delta.exchange/app/signup/?code=IULYNB) | [![API Version 2](https://img.shields.io/badge/2-lightgray)](https://docs.delta.exchange) | cex | | |
165
166
  | [![deribit](https://user-images.githubusercontent.com/1294454/41933112-9e2dd65a-798b-11e8-8440-5bab2959fcb8.jpg)](https://www.deribit.com/reg-1189.4038) | deribit | [Deribit](https://www.deribit.com/reg-1189.4038) | [![API Version 2](https://img.shields.io/badge/2-lightgray)](https://docs.deribit.com/v2) | cex | | [![CCXT Pro](https://img.shields.io/badge/CCXT-Pro-black)](https://ccxt.pro) |
166
167
  | [![digifinex](https://user-images.githubusercontent.com/51840849/87443315-01283a00-c5fe-11ea-8628-c2a0feaf07ac.jpg)](https://www.digifinex.com/en-ww/from/DhOzBg?channelCode=ljaUPp) | digifinex | [DigiFinex](https://www.digifinex.com/en-ww/from/DhOzBg?channelCode=ljaUPp) | [![API Version 3](https://img.shields.io/badge/3-lightgray)](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.34/dist/ccxt.browser.min.js
278
- * unpkg: https://unpkg.com/ccxt@4.4.34/dist/ccxt.browser.min.js
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.34/dist/ccxt.browser.min.js"></script>
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: