ccxt 4.3.58__py2.py3-none-any.whl → 4.3.60__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.

Potentially problematic release.


This version of ccxt might be problematic. Click here for more details.

Files changed (84) hide show
  1. ccxt/__init__.py +5 -5
  2. ccxt/abstract/bingx.py +1 -1
  3. ccxt/abstract/bitmart.py +1 -0
  4. ccxt/abstract/btcbox.py +1 -0
  5. ccxt/abstract/upbit.py +3 -0
  6. ccxt/abstract/xt.py +1 -0
  7. ccxt/async_support/__init__.py +5 -5
  8. ccxt/async_support/base/exchange.py +1 -1
  9. ccxt/async_support/binance.py +91 -2
  10. ccxt/async_support/bingx.py +448 -123
  11. ccxt/async_support/bitfinex.py +38 -4
  12. ccxt/async_support/bitget.py +1 -1
  13. ccxt/async_support/bitmart.py +1 -0
  14. ccxt/async_support/bitso.py +4 -1
  15. ccxt/async_support/btcbox.py +145 -8
  16. ccxt/async_support/bybit.py +3 -5
  17. ccxt/async_support/cex.py +1 -1
  18. ccxt/async_support/coinsph.py +1 -1
  19. ccxt/async_support/cryptocom.py +11 -5
  20. ccxt/async_support/deribit.py +15 -1
  21. ccxt/async_support/digifinex.py +30 -7
  22. ccxt/async_support/gate.py +17 -18
  23. ccxt/async_support/htx.py +7 -7
  24. ccxt/async_support/hyperliquid.py +107 -3
  25. ccxt/async_support/kraken.py +2 -2
  26. ccxt/async_support/mexc.py +11 -11
  27. ccxt/async_support/novadax.py +1 -1
  28. ccxt/async_support/okcoin.py +1 -1
  29. ccxt/async_support/okx.py +11 -2
  30. ccxt/async_support/phemex.py +1 -1
  31. ccxt/async_support/probit.py +1 -1
  32. ccxt/async_support/timex.py +16 -2
  33. ccxt/async_support/tokocrypto.py +1 -1
  34. ccxt/async_support/upbit.py +139 -45
  35. ccxt/async_support/xt.py +71 -8
  36. ccxt/base/errors.py +23 -23
  37. ccxt/base/exchange.py +9 -9
  38. ccxt/binance.py +91 -2
  39. ccxt/bingx.py +448 -123
  40. ccxt/bitfinex.py +38 -4
  41. ccxt/bitget.py +1 -1
  42. ccxt/bitmart.py +1 -0
  43. ccxt/bitso.py +4 -1
  44. ccxt/btcbox.py +145 -8
  45. ccxt/bybit.py +3 -5
  46. ccxt/cex.py +1 -1
  47. ccxt/coinsph.py +1 -1
  48. ccxt/cryptocom.py +11 -5
  49. ccxt/deribit.py +15 -1
  50. ccxt/digifinex.py +30 -7
  51. ccxt/gate.py +17 -18
  52. ccxt/htx.py +7 -7
  53. ccxt/hyperliquid.py +107 -3
  54. ccxt/kraken.py +2 -2
  55. ccxt/mexc.py +11 -11
  56. ccxt/novadax.py +1 -1
  57. ccxt/okcoin.py +1 -1
  58. ccxt/okx.py +11 -2
  59. ccxt/phemex.py +1 -1
  60. ccxt/pro/__init__.py +3 -1
  61. ccxt/pro/binance.py +11 -13
  62. ccxt/pro/bingx.py +11 -8
  63. ccxt/pro/bitmart.py +2 -2
  64. ccxt/pro/bitopro.py +1 -1
  65. ccxt/pro/cex.py +1 -1
  66. ccxt/pro/coincheck.py +1 -1
  67. ccxt/pro/coinone.py +1 -1
  68. ccxt/pro/hyperliquid.py +1 -1
  69. ccxt/pro/kucoin.py +35 -3
  70. ccxt/pro/phemex.py +1 -1
  71. ccxt/pro/xt.py +1046 -0
  72. ccxt/probit.py +1 -1
  73. ccxt/test/tests_async.py +2 -2
  74. ccxt/test/tests_helpers.py +1 -1
  75. ccxt/test/tests_sync.py +2 -2
  76. ccxt/timex.py +16 -2
  77. ccxt/tokocrypto.py +1 -1
  78. ccxt/upbit.py +139 -45
  79. ccxt/xt.py +71 -8
  80. {ccxt-4.3.58.dist-info → ccxt-4.3.60.dist-info}/METADATA +5 -5
  81. {ccxt-4.3.58.dist-info → ccxt-4.3.60.dist-info}/RECORD +84 -83
  82. {ccxt-4.3.58.dist-info → ccxt-4.3.60.dist-info}/LICENSE.txt +0 -0
  83. {ccxt-4.3.58.dist-info → ccxt-4.3.60.dist-info}/WHEEL +0 -0
  84. {ccxt-4.3.58.dist-info → ccxt-4.3.60.dist-info}/top_level.txt +0 -0
ccxt/probit.py CHANGED
@@ -14,13 +14,13 @@ from ccxt.base.errors import ArgumentsRequired
14
14
  from ccxt.base.errors import BadRequest
15
15
  from ccxt.base.errors import BadSymbol
16
16
  from ccxt.base.errors import MarketClosed
17
- from ccxt.base.errors import BadResponse
18
17
  from ccxt.base.errors import InsufficientFunds
19
18
  from ccxt.base.errors import InvalidAddress
20
19
  from ccxt.base.errors import InvalidOrder
21
20
  from ccxt.base.errors import DDoSProtection
22
21
  from ccxt.base.errors import RateLimitExceeded
23
22
  from ccxt.base.errors import ExchangeNotAvailable
23
+ from ccxt.base.errors import BadResponse
24
24
  from ccxt.base.decimal_to_precision import TRUNCATE
25
25
  from ccxt.base.decimal_to_precision import TICK_SIZE
26
26
  from ccxt.base.precise import Precise
ccxt/test/tests_async.py CHANGED
@@ -3,7 +3,7 @@
3
3
  import asyncio
4
4
 
5
5
 
6
- from tests_helpers import get_cli_arg_value, dump, exit_script, get_test_files, init_exchange, set_exchange_prop, call_method, exception_message, io_file_exists, io_file_read, baseMainTestClass, AuthenticationError, NotSupported, OperationFailed, OnMaintenance, ExchangeNotAvailable, ProxyError, get_exchange_prop, close, json_parse, json_stringify, is_null_value, io_dir_read, convert_ascii, call_exchange_method_dynamically, set_fetch_response, call_exchange_method_dynamically_sync # noqa: F401
6
+ from tests_helpers import get_cli_arg_value, dump, exit_script, get_test_files, init_exchange, set_exchange_prop, call_method, exception_message, io_file_exists, io_file_read, baseMainTestClass, AuthenticationError, NotSupported, OperationFailed, OnMaintenance, ExchangeNotAvailable, InvalidProxySettings, get_exchange_prop, close, json_parse, json_stringify, is_null_value, io_dir_read, convert_ascii, call_exchange_method_dynamically, set_fetch_response, call_exchange_method_dynamically_sync # noqa: F401
7
7
 
8
8
  class testMainClass(baseMainTestClass):
9
9
  def parse_cli_args(self):
@@ -827,7 +827,7 @@ class testMainClass(baseMainTestClass):
827
827
  else:
828
828
  call_exchange_method_dynamically_sync(exchange, method, self.sanitize_data_input(data['input']))
829
829
  except Exception as e:
830
- if not (isinstance(e, ProxyError)):
830
+ if not (isinstance(e, InvalidProxySettings)):
831
831
  raise e
832
832
  output = exchange.last_request_body
833
833
  request_url = exchange.last_request_url
@@ -25,7 +25,7 @@ import ccxt.pro as ccxtpro # noqa: E402
25
25
  # from typing import Optional
26
26
  # from typing import List
27
27
  from ccxt.base.errors import NotSupported # noqa: F401
28
- from ccxt.base.errors import ProxyError # noqa: F401
28
+ from ccxt.base.errors import InvalidProxySettings # noqa: F401
29
29
  from ccxt.base.errors import OperationFailed # noqa: F401
30
30
  # from ccxt.base.errors import ExchangeError
31
31
  from ccxt.base.errors import ExchangeNotAvailable # noqa: F401
ccxt/test/tests_sync.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- from tests_helpers import get_cli_arg_value, dump, exit_script, get_test_files, init_exchange, set_exchange_prop, call_method, exception_message, io_file_exists, io_file_read, baseMainTestClass, AuthenticationError, NotSupported, OperationFailed, OnMaintenance, ExchangeNotAvailable, ProxyError, get_exchange_prop, close, json_parse, json_stringify, is_null_value, io_dir_read, convert_ascii, call_exchange_method_dynamically, set_fetch_response, call_exchange_method_dynamically_sync # noqa: F401
3
+ from tests_helpers import get_cli_arg_value, dump, exit_script, get_test_files, init_exchange, set_exchange_prop, call_method, exception_message, io_file_exists, io_file_read, baseMainTestClass, AuthenticationError, NotSupported, OperationFailed, OnMaintenance, ExchangeNotAvailable, InvalidProxySettings, get_exchange_prop, close, json_parse, json_stringify, is_null_value, io_dir_read, convert_ascii, call_exchange_method_dynamically, set_fetch_response, call_exchange_method_dynamically_sync # noqa: F401
4
4
 
5
5
  class testMainClass(baseMainTestClass):
6
6
  def parse_cli_args(self):
@@ -824,7 +824,7 @@ class testMainClass(baseMainTestClass):
824
824
  else:
825
825
  call_exchange_method_dynamically_sync(exchange, method, self.sanitize_data_input(data['input']))
826
826
  except Exception as e:
827
- if not (isinstance(e, ProxyError)):
827
+ if not (isinstance(e, InvalidProxySettings)):
828
828
  raise e
829
829
  output = exchange.last_request_body
830
830
  request_url = exchange.last_request_url
ccxt/timex.py CHANGED
@@ -843,7 +843,8 @@ class timex(Exchange, ImplicitAPI):
843
843
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
844
844
  """
845
845
  self.load_markets()
846
- return self.cancel_orders([id], symbol, params)
846
+ orders = self.cancel_orders([id], symbol, params)
847
+ return self.safe_dict(orders, 0)
847
848
 
848
849
  def cancel_orders(self, ids, symbol: Str = None, params={}):
849
850
  """
@@ -883,7 +884,20 @@ class timex(Exchange, ImplicitAPI):
883
884
  # ],
884
885
  # "unchangedOrders": ["string"],
885
886
  # }
886
- return response
887
+ #
888
+ changedOrders = self.safe_list(response, 'changedOrders', [])
889
+ unchangedOrders = self.safe_list(response, 'unchangedOrders', [])
890
+ orders = []
891
+ for i in range(0, len(changedOrders)):
892
+ newOrder = self.safe_dict(changedOrders[i], 'newOrder')
893
+ orders.append(self.parse_order(newOrder))
894
+ for i in range(0, len(unchangedOrders)):
895
+ orders.append(self.safe_order({
896
+ 'info': unchangedOrders[i],
897
+ 'id': unchangedOrders[i],
898
+ 'status': 'unchanged',
899
+ }))
900
+ return orders
887
901
 
888
902
  def fetch_order(self, id: str, symbol: Str = None, params={}):
889
903
  """
ccxt/tokocrypto.py CHANGED
@@ -17,7 +17,6 @@ from ccxt.base.errors import ArgumentsRequired
17
17
  from ccxt.base.errors import BadRequest
18
18
  from ccxt.base.errors import BadSymbol
19
19
  from ccxt.base.errors import MarginModeAlreadySet
20
- from ccxt.base.errors import BadResponse
21
20
  from ccxt.base.errors import InsufficientFunds
22
21
  from ccxt.base.errors import InvalidOrder
23
22
  from ccxt.base.errors import OrderNotFound
@@ -30,6 +29,7 @@ from ccxt.base.errors import ExchangeNotAvailable
30
29
  from ccxt.base.errors import OnMaintenance
31
30
  from ccxt.base.errors import InvalidNonce
32
31
  from ccxt.base.errors import RequestTimeout
32
+ from ccxt.base.errors import BadResponse
33
33
  from ccxt.base.decimal_to_precision import TRUNCATE
34
34
  from ccxt.base.decimal_to_precision import TICK_SIZE
35
35
  from ccxt.base.precise import Precise
ccxt/upbit.py CHANGED
@@ -134,6 +134,9 @@ class upbit(Exchange, ImplicitAPI):
134
134
  'orders/chance',
135
135
  'order',
136
136
  'orders',
137
+ 'orders/closed',
138
+ 'orders/open',
139
+ 'orders/uuids',
137
140
  'withdraws',
138
141
  'withdraw',
139
142
  'withdraws/chance',
@@ -1392,6 +1395,28 @@ class upbit(Exchange, ImplicitAPI):
1392
1395
  # ],
1393
1396
  # }
1394
1397
  #
1398
+ # fetchOpenOrders, fetchClosedOrders, fetchCanceledOrders
1399
+ #
1400
+ # {
1401
+ # "uuid": "637fd66-d019-4d77-bee6-8e0cff28edd9",
1402
+ # "side": "ask",
1403
+ # "ord_type": "limit",
1404
+ # "price": "1.5",
1405
+ # "state": "wait",
1406
+ # "market": "SGD-XRP",
1407
+ # "created_at": "2024-06-05T09:37:10Z",
1408
+ # "volume": "10",
1409
+ # "remaining_volume": "10",
1410
+ # "reserved_fee": "0",
1411
+ # "remaining_fee": "0",
1412
+ # "paid_fee": "0",
1413
+ # "locked": "10",
1414
+ # "executed_volume": "0",
1415
+ # "executed_funds": "0",
1416
+ # "trades_count": 0,
1417
+ # "time_in_force": "ioc"
1418
+ # }
1419
+ #
1395
1420
  id = self.safe_string(order, 'uuid')
1396
1421
  side = self.safe_string(order, 'side')
1397
1422
  if side == 'bid':
@@ -1453,7 +1478,7 @@ class upbit(Exchange, ImplicitAPI):
1453
1478
  'lastTradeTimestamp': lastTradeTimestamp,
1454
1479
  'symbol': market['symbol'],
1455
1480
  'type': type,
1456
- 'timeInForce': None,
1481
+ 'timeInForce': self.safe_string_upper(order, 'time_in_force'),
1457
1482
  'postOnly': None,
1458
1483
  'side': side,
1459
1484
  'price': price,
@@ -1469,77 +1494,149 @@ class upbit(Exchange, ImplicitAPI):
1469
1494
  'trades': trades,
1470
1495
  })
1471
1496
 
1472
- def fetch_orders_by_state(self, state, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1497
+ def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1498
+ """
1499
+ fetch all unfilled currently open orders
1500
+ :see: https://global-docs.upbit.com/reference/open-order
1501
+ :param str symbol: unified market symbol
1502
+ :param int [since]: the earliest time in ms to fetch open orders for
1503
+ :param int [limit]: the maximum number of open order structures to retrieve
1504
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1505
+ :param str [params.state]: default is 'wait', set to 'watch' for stop limit orders
1506
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1507
+ """
1473
1508
  self.load_markets()
1474
- request: dict = {
1475
- # 'market': self.market_id(symbol),
1476
- 'state': state,
1477
- # 'page': 1,
1478
- # 'order_by': 'asc',
1479
- }
1509
+ request: dict = {}
1480
1510
  market = None
1481
1511
  if symbol is not None:
1482
1512
  market = self.market(symbol)
1483
1513
  request['market'] = market['id']
1484
- response = self.privateGetOrders(self.extend(request, params))
1514
+ if limit is not None:
1515
+ request['limit'] = limit
1516
+ response = self.privateGetOrdersOpen(self.extend(request, params))
1485
1517
  #
1486
1518
  # [
1487
1519
  # {
1488
- # "uuid": "a08f09b1-1718-42e2-9358-f0e5e083d3ee",
1489
- # "side": "bid",
1520
+ # "uuid": "637fd66-d019-4d77-bee6-8e0cff28edd9",
1521
+ # "side": "ask",
1490
1522
  # "ord_type": "limit",
1491
- # "price": "17417000.0",
1492
- # "state": "done",
1493
- # "market": "KRW-BTC",
1494
- # "created_at": "2018-04-05T14:09:14+09:00",
1495
- # "volume": "1.0",
1496
- # "remaining_volume": "0.0",
1497
- # "reserved_fee": "26125.5",
1498
- # "remaining_fee": "25974.0",
1499
- # "paid_fee": "151.5",
1500
- # "locked": "17341974.0",
1501
- # "executed_volume": "1.0",
1502
- # "trades_count":2
1503
- # },
1523
+ # "price": "1.5",
1524
+ # "state": "wait",
1525
+ # "market": "SGD-XRP",
1526
+ # "created_at": "2024-06-05T09:37:10Z",
1527
+ # "volume": "10",
1528
+ # "remaining_volume": "10",
1529
+ # "reserved_fee": "0",
1530
+ # "remaining_fee": "0",
1531
+ # "paid_fee": "0",
1532
+ # "locked": "10",
1533
+ # "executed_volume": "0",
1534
+ # "executed_funds": "0",
1535
+ # "trades_count": 0
1536
+ # }
1504
1537
  # ]
1505
1538
  #
1506
1539
  return self.parse_orders(response, market, since, limit)
1507
1540
 
1508
- def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1509
- """
1510
- :see: https://docs.upbit.com/reference/%EC%A3%BC%EB%AC%B8-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%A1%B0%ED%9A%8C
1511
- fetch all unfilled currently open orders
1512
- :param str symbol: unified market symbol
1513
- :param int [since]: the earliest time in ms to fetch open orders for
1514
- :param int [limit]: the maximum number of open orders structures to retrieve
1515
- :param dict [params]: extra parameters specific to the exchange API endpoint
1516
- :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1517
- """
1518
- return self.fetch_orders_by_state('wait', symbol, since, limit, params)
1519
-
1520
1541
  def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1521
1542
  """
1522
- :see: https://docs.upbit.com/reference/%EC%A3%BC%EB%AC%B8-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%A1%B0%ED%9A%8C
1523
1543
  fetches information on multiple closed orders made by the user
1544
+ :see: https://global-docs.upbit.com/reference/closed-order
1524
1545
  :param str symbol: unified market symbol of the market orders were made in
1525
1546
  :param int [since]: the earliest time in ms to fetch orders for
1526
1547
  :param int [limit]: the maximum number of order structures to retrieve
1527
1548
  :param dict [params]: extra parameters specific to the exchange API endpoint
1549
+ :param int [params.until]: timestamp in ms of the latest order
1528
1550
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1529
1551
  """
1530
- return self.fetch_orders_by_state('done', symbol, since, limit, params)
1552
+ self.load_markets()
1553
+ request: dict = {
1554
+ 'state': 'done',
1555
+ }
1556
+ market = None
1557
+ if symbol is not None:
1558
+ market = self.market(symbol)
1559
+ request['market'] = market['id']
1560
+ if since is not None:
1561
+ request['start_time'] = since
1562
+ if limit is not None:
1563
+ request['limit'] = limit
1564
+ request, params = self.handle_until_option('end_time', request, params)
1565
+ response = self.privateGetOrdersClosed(self.extend(request, params))
1566
+ #
1567
+ # [
1568
+ # {
1569
+ # "uuid": "637fd66-d019-4d77-bee6-8e0cff28edd9",
1570
+ # "side": "ask",
1571
+ # "ord_type": "limit",
1572
+ # "price": "1.5",
1573
+ # "state": "done",
1574
+ # "market": "SGD-XRP",
1575
+ # "created_at": "2024-06-05T09:37:10Z",
1576
+ # "volume": "10",
1577
+ # "remaining_volume": "10",
1578
+ # "reserved_fee": "0",
1579
+ # "remaining_fee": "0",
1580
+ # "paid_fee": "0",
1581
+ # "locked": "10",
1582
+ # "executed_volume": "0",
1583
+ # "executed_funds": "0",
1584
+ # "trades_count": 0,
1585
+ # "time_in_force": "ioc"
1586
+ # }
1587
+ # ]
1588
+ #
1589
+ return self.parse_orders(response, market, since, limit)
1531
1590
 
1532
1591
  def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1533
1592
  """
1534
- :see: https://docs.upbit.com/reference/%EC%A3%BC%EB%AC%B8-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%A1%B0%ED%9A%8C
1535
1593
  fetches information on multiple canceled orders made by the user
1594
+ :see: https://global-docs.upbit.com/reference/closed-order
1536
1595
  :param str symbol: unified market symbol of the market orders were made in
1537
1596
  :param int [since]: timestamp in ms of the earliest order, default is None
1538
1597
  :param int [limit]: max number of orders to return, default is None
1539
1598
  :param dict [params]: extra parameters specific to the exchange API endpoint
1599
+ :param int [params.until]: timestamp in ms of the latest order
1540
1600
  :returns dict: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1541
1601
  """
1542
- return self.fetch_orders_by_state('cancel', symbol, since, limit, params)
1602
+ self.load_markets()
1603
+ request: dict = {
1604
+ 'state': 'cancel',
1605
+ }
1606
+ market = None
1607
+ if symbol is not None:
1608
+ market = self.market(symbol)
1609
+ request['market'] = market['id']
1610
+ if since is not None:
1611
+ request['start_time'] = since
1612
+ if limit is not None:
1613
+ request['limit'] = limit
1614
+ request, params = self.handle_until_option('end_time', request, params)
1615
+ response = self.privateGetOrdersClosed(self.extend(request, params))
1616
+ #
1617
+ # [
1618
+ # {
1619
+ # "uuid": "637fd66-d019-4d77-bee6-8e0cff28edd9",
1620
+ # "side": "ask",
1621
+ # "ord_type": "limit",
1622
+ # "price": "1.5",
1623
+ # "state": "cancel",
1624
+ # "market": "SGD-XRP",
1625
+ # "created_at": "2024-06-05T09:37:10Z",
1626
+ # "volume": "10",
1627
+ # "remaining_volume": "10",
1628
+ # "reserved_fee": "0",
1629
+ # "remaining_fee": "0",
1630
+ # "paid_fee": "0",
1631
+ # "locked": "10",
1632
+ # "executed_volume": "0",
1633
+ # "executed_funds": "0",
1634
+ # "trades_count": 0,
1635
+ # "time_in_force": "ioc"
1636
+ # }
1637
+ # ]
1638
+ #
1639
+ return self.parse_orders(response, market, since, limit)
1543
1640
 
1544
1641
  def fetch_order(self, id: str, symbol: Str = None, params={}):
1545
1642
  """
@@ -1793,11 +1890,8 @@ class upbit(Exchange, ImplicitAPI):
1793
1890
  if (method != 'GET') and (method != 'DELETE'):
1794
1891
  body = self.json(params)
1795
1892
  headers['Content-Type'] = 'application/json'
1796
- if hasQuery:
1797
- auth = self.urlencode(query)
1798
- else:
1799
- if hasQuery:
1800
- auth = self.urlencode(self.keysort(query))
1893
+ if hasQuery:
1894
+ auth = self.urlencode(query)
1801
1895
  if auth is not None:
1802
1896
  hash = self.hash(self.encode(auth), 'sha512')
1803
1897
  request['query_hash'] = hash
ccxt/xt.py CHANGED
@@ -39,7 +39,7 @@ class xt(Exchange, ImplicitAPI):
39
39
  'rateLimit': 100,
40
40
  'version': 'v4',
41
41
  'certified': False,
42
- 'pro': False,
42
+ 'pro': True,
43
43
  'has': {
44
44
  'CORS': False,
45
45
  'spot': True,
@@ -234,6 +234,7 @@ class xt(Exchange, ImplicitAPI):
234
234
  'withdraw': 1,
235
235
  'balance/transfer': 1,
236
236
  'balance/account/transfer': 1,
237
+ 'ws-token': 1,
237
238
  },
238
239
  'delete': {
239
240
  'batch-order': 1,
@@ -834,7 +835,7 @@ class xt(Exchange, ImplicitAPI):
834
835
  'name': self.safe_string(entry, 'fullName'),
835
836
  'active': active,
836
837
  'fee': self.parse_number(minWithdrawFeeString),
837
- 'precision': None,
838
+ 'precision': minPrecision,
838
839
  'deposit': deposit,
839
840
  'withdraw': withdraw,
840
841
  'networks': networks,
@@ -1435,8 +1436,12 @@ class xt(Exchange, ImplicitAPI):
1435
1436
  orderBook = self.safe_value(response, 'result', {})
1436
1437
  timestamp = self.safe_integer_2(orderBook, 'timestamp', 't')
1437
1438
  if market['spot']:
1438
- return self.parse_order_book(orderBook, symbol, timestamp)
1439
- return self.parse_order_book(orderBook, symbol, timestamp, 'b', 'a')
1439
+ ob = self.parse_order_book(orderBook, symbol, timestamp)
1440
+ ob['nonce'] = self.safe_integer(orderBook, 'lastUpdateId')
1441
+ return ob
1442
+ swapOb = self.parse_order_book(orderBook, symbol, timestamp, 'b', 'a')
1443
+ swapOb['nonce'] = self.safe_integer_2(orderBook, 'u', 'lastUpdateId')
1444
+ return swapOb
1440
1445
 
1441
1446
  def fetch_ticker(self, symbol: str, params={}):
1442
1447
  """
@@ -1679,8 +1684,9 @@ class xt(Exchange, ImplicitAPI):
1679
1684
  #
1680
1685
  marketId = self.safe_string(ticker, 's')
1681
1686
  marketType = market['type'] if (market is not None) else None
1687
+ hasSpotKeys = ('cv' in ticker) or ('aq' in ticker)
1682
1688
  if marketType is None:
1683
- marketType = ('cv' in ticker) or 'spot' if ('aq' in ticker) else 'contract'
1689
+ marketType = 'spot' if hasSpotKeys else 'contract'
1684
1690
  market = self.safe_market(marketId, market, '_', marketType)
1685
1691
  symbol = market['symbol']
1686
1692
  timestamp = self.safe_integer(ticker, 't')
@@ -1888,6 +1894,29 @@ class xt(Exchange, ImplicitAPI):
1888
1894
  # "b": True
1889
1895
  # }
1890
1896
  #
1897
+ # spot: watchMyTrades
1898
+ #
1899
+ # {
1900
+ # "s": "btc_usdt", # symbol
1901
+ # "t": 1656043204763, # time
1902
+ # "i": "6316559590087251233", # tradeId
1903
+ # "oi": "6216559590087220004", # orderId
1904
+ # "p": "30000", # trade price
1905
+ # "q": "3", # qty quantity
1906
+ # "v": "90000" # volume trade amount
1907
+ # }
1908
+ #
1909
+ # spot: watchTrades
1910
+ #
1911
+ # {
1912
+ # s: 'btc_usdt',
1913
+ # i: '228825383103928709',
1914
+ # t: 1684258222702,
1915
+ # p: '27003.65',
1916
+ # q: '0.000796',
1917
+ # b: True
1918
+ # }
1919
+ #
1891
1920
  # swap and future: fetchTrades
1892
1921
  #
1893
1922
  # {
@@ -1932,19 +1961,53 @@ class xt(Exchange, ImplicitAPI):
1932
1961
  # "takerMaker": "TAKER"
1933
1962
  # }
1934
1963
  #
1964
+ # contract watchMyTrades
1965
+ #
1966
+ # {
1967
+ # "symbol": 'btc_usdt',
1968
+ # "orderSide": 'SELL',
1969
+ # "positionSide": 'LONG',
1970
+ # "orderId": '231485367663419328',
1971
+ # "price": '27152.7',
1972
+ # "quantity": '33',
1973
+ # "marginUnfrozen": '2.85318000',
1974
+ # "timestamp": 1684892412565
1975
+ # }
1976
+ #
1977
+ # watchMyTrades(ws, swap)
1978
+ #
1979
+ # {
1980
+ # 'fee': '0.04080840',
1981
+ # 'isMaker': False,
1982
+ # 'marginUnfrozen': '0.75711984',
1983
+ # 'orderId': '376172779053188416',
1984
+ # 'orderSide': 'BUY',
1985
+ # 'positionSide': 'LONG',
1986
+ # 'price': '3400.70',
1987
+ # 'quantity': '2',
1988
+ # 'symbol': 'eth_usdt',
1989
+ # 'timestamp': 1719388579622
1990
+ # }
1991
+ #
1935
1992
  marketId = self.safe_string_2(trade, 's', 'symbol')
1936
1993
  marketType = market['type'] if (market is not None) else None
1994
+ hasSpotKeys = ('b' in trade) or ('bizType' in trade) or ('oi' in trade)
1937
1995
  if marketType is None:
1938
- marketType = ('b' in trade) or 'spot' if ('bizType' in trade) else 'contract'
1996
+ marketType = 'spot' if hasSpotKeys else 'contract'
1939
1997
  market = self.safe_market(marketId, market, '_', marketType)
1940
1998
  bidOrAsk = self.safe_string(trade, 'm')
1941
1999
  side = self.safe_string_lower(trade, 'orderSide')
1942
2000
  if bidOrAsk is not None:
1943
2001
  side = 'buy' if (bidOrAsk == 'BID') else 'sell'
1944
2002
  buyerMaker = self.safe_value(trade, 'b')
2003
+ if buyerMaker is not None:
2004
+ side = 'buy'
1945
2005
  takerOrMaker = self.safe_string_lower(trade, 'takerMaker')
1946
2006
  if buyerMaker is not None:
1947
2007
  takerOrMaker = 'maker' if buyerMaker else 'taker'
2008
+ isMaker = self.safe_bool(trade, 'isMaker')
2009
+ if isMaker is not None:
2010
+ takerOrMaker = 'maker' if isMaker else 'taker'
1948
2011
  timestamp = self.safe_integer_n(trade, ['t', 'time', 'timestamp'])
1949
2012
  quantity = self.safe_string_2(trade, 'q', 'quantity')
1950
2013
  amount = None
@@ -1961,7 +2024,7 @@ class xt(Exchange, ImplicitAPI):
1961
2024
  'timestamp': timestamp,
1962
2025
  'datetime': self.iso8601(timestamp),
1963
2026
  'symbol': market['symbol'],
1964
- 'order': self.safe_string(trade, 'orderId'),
2027
+ 'order': self.safe_string_2(trade, 'orderId', 'oi'),
1965
2028
  'type': self.safe_string_lower(trade, 'orderType'),
1966
2029
  'side': side,
1967
2030
  'takerOrMaker': takerOrMaker,
@@ -4418,7 +4481,7 @@ class xt(Exchange, ImplicitAPI):
4418
4481
  body['clientMedia'] = id
4419
4482
  else:
4420
4483
  body['media'] = id
4421
- isUndefinedBody = ((method == 'GET') or (path == 'order/{orderId}'))
4484
+ isUndefinedBody = ((method == 'GET') or (path == 'order/{orderId}') or (path == 'ws-token'))
4422
4485
  body = None if isUndefinedBody else self.json(body)
4423
4486
  payloadString = None
4424
4487
  if (endpoint == 'spot') or (endpoint == 'user'):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ccxt
3
- Version: 4.3.58
3
+ Version: 4.3.60
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
@@ -207,7 +207,7 @@ The CCXT library currently supports the following 101 cryptocurrency exchange ma
207
207
  | [![whitebit](https://user-images.githubusercontent.com/1294454/66732963-8eb7dd00-ee66-11e9-849b-10d9282bb9e0.jpg)](https://whitebit.com/referral/d9bdf40e-28f2-4b52-b2f9-cd1415d82963) | whitebit | [WhiteBit](https://whitebit.com/referral/d9bdf40e-28f2-4b52-b2f9-cd1415d82963) | [![API Version 4](https://img.shields.io/badge/4-lightgray)](https://github.com/whitebit-exchange/api-docs) | cex | | [![CCXT Pro](https://img.shields.io/badge/CCXT-Pro-black)](https://ccxt.pro) |
208
208
  | [![woo](https://user-images.githubusercontent.com/1294454/150730761-1a00e5e0-d28c-480f-9e65-089ce3e6ef3b.jpg)](https://x.woo.org/register?ref=YWOWC96B) | woo | [WOO X](https://x.woo.org/register?ref=YWOWC96B) | [![API Version 1](https://img.shields.io/badge/1-lightgray)](https://docs.woo.org/) | 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) |
209
209
  | [![woofipro](https://github.com/ccxt/ccxt/assets/43336371/b1e7b348-a0fc-4605-8b7f-91176958fd69)](https://dex.woo.org/en/trade?ref=CCXT) | woofipro | [WOOFI PRO](https://dex.woo.org/en/trade?ref=CCXT) | [![API Version 1](https://img.shields.io/badge/1-lightgray)](https://orderly.network/docs/build-on-evm/building-on-evm) | dex | [![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) |
210
- | [![xt](https://user-images.githubusercontent.com/14319357/232636712-466df2fc-560a-4ca4-aab2-b1d954a58e24.jpg)](https://www.xt.com/en/accounts/register?ref=9PTM9VW) | xt | [XT](https://www.xt.com/en/accounts/register?ref=9PTM9VW) | [![API Version 4](https://img.shields.io/badge/4-lightgray)](https://doc.xt.com/) | cex | | |
210
+ | [![xt](https://user-images.githubusercontent.com/14319357/232636712-466df2fc-560a-4ca4-aab2-b1d954a58e24.jpg)](https://www.xt.com/en/accounts/register?ref=9PTM9VW) | xt | [XT](https://www.xt.com/en/accounts/register?ref=9PTM9VW) | [![API Version 4](https://img.shields.io/badge/4-lightgray)](https://doc.xt.com/) | cex | | [![CCXT Pro](https://img.shields.io/badge/CCXT-Pro-black)](https://ccxt.pro) |
211
211
  | [![yobit](https://user-images.githubusercontent.com/1294454/27766910-cdcbfdae-5eea-11e7-9859-03fea873272d.jpg)](https://www.yobit.net) | yobit | [YoBit](https://www.yobit.net) | [![API Version 3](https://img.shields.io/badge/3-lightgray)](https://www.yobit.net/en/api/) | cex | | |
212
212
  | [![zaif](https://user-images.githubusercontent.com/1294454/27766927-39ca2ada-5eeb-11e7-972f-1b4199518ca6.jpg)](https://zaif.jp) | zaif | [Zaif](https://zaif.jp) | [![API Version 1](https://img.shields.io/badge/1-lightgray)](https://techbureau-api-document.readthedocs.io/ja/latest/index.html) | cex | | |
213
213
  | [![zonda](https://user-images.githubusercontent.com/1294454/159202310-a0e38007-5e7c-4ba9-a32f-c8263a0291fe.jpg)](https://auth.zondaglobal.com/ref/jHlbB4mIkdS1) | zonda | [Zonda](https://auth.zondaglobal.com/ref/jHlbB4mIkdS1) | [![API Version *](https://img.shields.io/badge/*-lightgray)](https://docs.zondacrypto.exchange/) | cex | | |
@@ -268,13 +268,13 @@ console.log(version, Object.keys(exchanges));
268
268
 
269
269
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
270
270
 
271
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.58/dist/ccxt.browser.min.js
272
- * unpkg: https://unpkg.com/ccxt@4.3.58/dist/ccxt.browser.min.js
271
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.60/dist/ccxt.browser.min.js
272
+ * unpkg: https://unpkg.com/ccxt@4.3.60/dist/ccxt.browser.min.js
273
273
 
274
274
  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.
275
275
 
276
276
  ```HTML
277
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.58/dist/ccxt.browser.min.js"></script>
277
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.60/dist/ccxt.browser.min.js"></script>
278
278
  ```
279
279
 
280
280
  Creates a global `ccxt` object: