ccxt 4.4.53__py2.py3-none-any.whl → 4.4.58__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 (68) hide show
  1. ccxt/__init__.py +1 -3
  2. ccxt/abstract/xt.py +1 -0
  3. ccxt/ascendex.py +2 -0
  4. ccxt/async_support/__init__.py +1 -3
  5. ccxt/async_support/ascendex.py +2 -0
  6. ccxt/async_support/base/exchange.py +5 -5
  7. ccxt/async_support/binance.py +39 -9
  8. ccxt/async_support/bitget.py +6 -1
  9. ccxt/async_support/bitmart.py +13 -3
  10. ccxt/async_support/blofin.py +1 -2
  11. ccxt/async_support/bybit.py +16 -3
  12. ccxt/async_support/coinbase.py +9 -2
  13. ccxt/async_support/coinbaseinternational.py +2 -2
  14. ccxt/async_support/coinex.py +1 -1
  15. ccxt/async_support/deribit.py +8 -25
  16. ccxt/async_support/exmo.py +1 -1
  17. ccxt/async_support/hyperliquid.py +11 -6
  18. ccxt/async_support/kraken.py +1 -1
  19. ccxt/async_support/timex.py +12 -2
  20. ccxt/async_support/vertex.py +1 -1
  21. ccxt/async_support/whitebit.py +2 -1
  22. ccxt/async_support/woofipro.py +2 -2
  23. ccxt/async_support/xt.py +54 -1
  24. ccxt/base/errors.py +0 -6
  25. ccxt/base/exchange.py +6 -6
  26. ccxt/binance.py +39 -9
  27. ccxt/bitget.py +6 -1
  28. ccxt/bitmart.py +13 -3
  29. ccxt/blofin.py +1 -2
  30. ccxt/bybit.py +16 -3
  31. ccxt/coinbase.py +9 -2
  32. ccxt/coinbaseinternational.py +2 -2
  33. ccxt/coinex.py +1 -1
  34. ccxt/deribit.py +8 -25
  35. ccxt/exmo.py +1 -1
  36. ccxt/hyperliquid.py +11 -6
  37. ccxt/kraken.py +1 -1
  38. ccxt/pro/__init__.py +1 -1
  39. ccxt/pro/binance.py +2 -2
  40. ccxt/pro/bitget.py +3 -3
  41. ccxt/pro/bybit.py +11 -3
  42. ccxt/pro/cex.py +1 -1
  43. ccxt/pro/coincatch.py +3 -3
  44. ccxt/pro/mexc.py +6 -4
  45. ccxt/pro/okx.py +1 -1
  46. ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
  47. ccxt/static_dependencies/ethereum/account/py.typed +0 -0
  48. ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
  49. ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
  50. ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
  51. ccxt/static_dependencies/lark/py.typed +0 -0
  52. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  53. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  54. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  55. ccxt/test/tests_init.py +2 -2
  56. ccxt/timex.py +12 -2
  57. ccxt/vertex.py +1 -1
  58. ccxt/whitebit.py +2 -1
  59. ccxt/woofipro.py +2 -2
  60. ccxt/xt.py +54 -1
  61. {ccxt-4.4.53.dist-info → ccxt-4.4.58.dist-info}/METADATA +9 -12
  62. {ccxt-4.4.53.dist-info → ccxt-4.4.58.dist-info}/RECORD +65 -59
  63. ccxt/abstract/lykke.py +0 -29
  64. ccxt/async_support/lykke.py +0 -1374
  65. ccxt/lykke.py +0 -1374
  66. {ccxt-4.4.53.dist-info → ccxt-4.4.58.dist-info}/LICENSE.txt +0 -0
  67. {ccxt-4.4.53.dist-info → ccxt-4.4.58.dist-info}/WHEEL +0 -0
  68. {ccxt-4.4.53.dist-info → ccxt-4.4.58.dist-info}/top_level.txt +0 -0
ccxt/hyperliquid.py CHANGED
@@ -203,7 +203,7 @@ class hyperliquid(Exchange, ImplicitAPI):
203
203
  'broad': {
204
204
  'Price must be divisible by tick size.': InvalidOrder,
205
205
  'Order must have minimum value of $10': InvalidOrder,
206
- 'Insufficient margin to place order.': InvalidOrder,
206
+ 'Insufficient margin to place order.': InsufficientFunds,
207
207
  'Reduce only order would increase position.': InvalidOrder,
208
208
  'Post only order would have immediately matched,': InvalidOrder,
209
209
  'Order could not immediately match against any resting orders.': InvalidOrder,
@@ -601,7 +601,9 @@ class hyperliquid(Exchange, ImplicitAPI):
601
601
  amountPrecisionStr = self.safe_string(innerBaseTokenInfo, 'szDecimals')
602
602
  amountPrecision = int(amountPrecisionStr)
603
603
  price = self.safe_number(extraData, 'midPx')
604
- pricePrecision = self.calculate_price_precision(price, amountPrecision, 8)
604
+ pricePrecision = 0
605
+ if price is not None:
606
+ pricePrecision = self.calculate_price_precision(price, amountPrecision, 8)
605
607
  pricePrecisionStr = self.number_to_string(pricePrecision)
606
608
  # quotePrecision = self.parse_number(self.parse_precision(self.safe_string(innerQuoteTokenInfo, 'szDecimals')))
607
609
  baseId = self.number_to_string(index + 10000)
@@ -698,7 +700,9 @@ class hyperliquid(Exchange, ImplicitAPI):
698
700
  amountPrecisionStr = self.safe_string(market, 'szDecimals')
699
701
  amountPrecision = int(amountPrecisionStr)
700
702
  price = self.safe_number(market, 'markPx', 0)
701
- pricePrecision = self.calculate_price_precision(price, amountPrecision, 6)
703
+ pricePrecision = 0
704
+ if price is not None:
705
+ pricePrecision = self.calculate_price_precision(price, amountPrecision, 6)
702
706
  pricePrecisionStr = self.number_to_string(pricePrecision)
703
707
  isDelisted = self.safe_bool(market, 'isDelisted')
704
708
  active = True
@@ -2706,7 +2710,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2706
2710
  if self.in_array(fromAccount, ['spot', 'swap', 'perp']):
2707
2711
  # handle swap <> spot account transfer
2708
2712
  if not self.in_array(toAccount, ['spot', 'swap', 'perp']):
2709
- raise NotSupported(self.id + 'transfer() only support spot <> swap transfer')
2713
+ raise NotSupported(self.id + ' transfer() only support spot <> swap transfer')
2710
2714
  strAmount = self.number_to_string(amount)
2711
2715
  vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
2712
2716
  params = self.omit(params, 'vaultAddress')
@@ -2741,7 +2745,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2741
2745
  if code is not None:
2742
2746
  code = code.upper()
2743
2747
  if code != 'USDC':
2744
- raise NotSupported(self.id + 'transfer() only support USDC')
2748
+ raise NotSupported(self.id + ' transfer() only support USDC')
2745
2749
  payload: dict = {
2746
2750
  'hyperliquidChain': 'Testnet' if isSandboxMode else 'Mainnet',
2747
2751
  'destination': toAccount,
@@ -2804,7 +2808,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2804
2808
  if code is not None:
2805
2809
  code = code.upper()
2806
2810
  if code != 'USDC':
2807
- raise NotSupported(self.id + 'withdraw() only support USDC')
2811
+ raise NotSupported(self.id + ' withdraw() only support USDC')
2808
2812
  vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
2809
2813
  params = self.omit(params, 'vaultAddress')
2810
2814
  nonce = self.milliseconds()
@@ -3264,6 +3268,7 @@ class hyperliquid(Exchange, ImplicitAPI):
3264
3268
  # status: 'ok',
3265
3269
  # response: {type: 'order', data: {statuses: [{error: 'Insufficient margin to place order. asset=4'}]}}
3266
3270
  # }
3271
+ # {"status":"ok","response":{"type":"order","data":{"statuses":[{"error":"Insufficient margin to place order. asset=84"}]}}}
3267
3272
  #
3268
3273
  status = self.safe_string(response, 'status', '')
3269
3274
  message = None
ccxt/kraken.py CHANGED
@@ -2365,7 +2365,7 @@ class kraken(Exchange, ImplicitAPI):
2365
2365
  :returns dict: the api result
2366
2366
  """
2367
2367
  if timeout > 86400000:
2368
- raise BadRequest(self.id + 'cancelAllOrdersAfter timeout should be less than 86400000 milliseconds')
2368
+ raise BadRequest(self.id + ' cancelAllOrdersAfter timeout should be less than 86400000 milliseconds')
2369
2369
  self.load_markets()
2370
2370
  request: dict = {
2371
2371
  'timeout': (self.parse_to_int(timeout / 1000)) if (timeout > 0) else 0,
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.53'
7
+ __version__ = '4.4.58'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/binance.py CHANGED
@@ -247,7 +247,7 @@ class binance(ccxt.async_support.binance):
247
247
  type = None
248
248
  type, params = self.handle_market_type_and_params('watchLiquidationsForSymbols', firstMarket, params)
249
249
  if type == 'spot':
250
- raise BadRequest(self.id + 'watchLiquidationsForSymbols is not supported for spot symbols')
250
+ raise BadRequest(self.id + ' watchLiquidationsForSymbols is not supported for spot symbols')
251
251
  subType = None
252
252
  subType, params = self.handle_sub_type_and_params('watchLiquidationsForSymbols', firstMarket, params)
253
253
  if self.isLinear(type, subType):
@@ -3705,7 +3705,7 @@ class binance(ccxt.async_support.binance):
3705
3705
  payload['limit'] = limit
3706
3706
  fromId = self.safe_integer(params, 'fromId')
3707
3707
  if fromId is not None and since is not None:
3708
- raise BadRequest(self.id + 'fetchMyTradesWs does not support fetching by both fromId and since parameters at the same time')
3708
+ raise BadRequest(self.id + ' fetchMyTradesWs does not support fetching by both fromId and since parameters at the same time')
3709
3709
  message: dict = {
3710
3710
  'id': messageHash,
3711
3711
  'method': 'myTrades',
ccxt/pro/bitget.py CHANGED
@@ -1916,7 +1916,7 @@ class bitget(ccxt.async_support.bitget):
1916
1916
  del client.subscriptions[subMessageHash]
1917
1917
  if messageHash in client.subscriptions:
1918
1918
  del client.subscriptions[messageHash]
1919
- error = UnsubscribeError(self.id + 'orderbook ' + symbol)
1919
+ error = UnsubscribeError(self.id + ' orderbook ' + symbol)
1920
1920
  client.reject(error, subMessageHash)
1921
1921
  client.resolve(True, messageHash)
1922
1922
 
@@ -1938,7 +1938,7 @@ class bitget(ccxt.async_support.bitget):
1938
1938
  del client.subscriptions[subMessageHash]
1939
1939
  if messageHash in client.subscriptions:
1940
1940
  del client.subscriptions[messageHash]
1941
- error = UnsubscribeError(self.id + 'trades ' + symbol)
1941
+ error = UnsubscribeError(self.id + ' trades ' + symbol)
1942
1942
  client.reject(error, subMessageHash)
1943
1943
  client.resolve(True, messageHash)
1944
1944
 
@@ -1960,7 +1960,7 @@ class bitget(ccxt.async_support.bitget):
1960
1960
  del client.subscriptions[subMessageHash]
1961
1961
  if messageHash in client.subscriptions:
1962
1962
  del client.subscriptions[messageHash]
1963
- error = UnsubscribeError(self.id + 'ticker ' + symbol)
1963
+ error = UnsubscribeError(self.id + ' ticker ' + symbol)
1964
1964
  client.reject(error, subMessageHash)
1965
1965
  client.resolve(True, messageHash)
1966
1966
 
ccxt/pro/bybit.py CHANGED
@@ -833,11 +833,19 @@ class bybit(ccxt.async_support.bybit):
833
833
  market = self.market(symbols[0])
834
834
  if limit is None:
835
835
  limit = 50 if (market['spot']) else 500
836
+ if market['option']:
837
+ limit = 100
836
838
  else:
837
839
  if not market['spot']:
838
- # bybit only support limit 1, 50, 200, 500 for contract
839
- if (limit != 1) and (limit != 50) and (limit != 200) and (limit != 500):
840
- raise BadRequest(self.id + ' watchOrderBookForSymbols() can only use limit 1, 50, 200 and 500.')
840
+ if market['option']:
841
+ if (limit != 25) and (limit != 100):
842
+ raise BadRequest(self.id + ' watchOrderBookForSymbols() can only use limit 25 and 100 for option markets.')
843
+ elif (limit != 1) and (limit != 50) and (limit != 200) and (limit != 500):
844
+ # bybit only support limit 1, 50, 200, 500 for contract
845
+ raise BadRequest(self.id + ' watchOrderBookForSymbols() can only use limit 1, 50, 200 and 500 for swap and future markets.')
846
+ else:
847
+ if (limit != 1) and (limit != 50) and (limit != 200):
848
+ raise BadRequest(self.id + ' watchOrderBookForSymbols() can only use limit 1,50, and 200 for spot markets.')
841
849
  topics = []
842
850
  messageHashes = []
843
851
  for i in range(0, len(symbols)):
ccxt/pro/cex.py CHANGED
@@ -1188,7 +1188,7 @@ class cex(ccxt.async_support.cex):
1188
1188
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1189
1189
  """
1190
1190
  if symbol is None:
1191
- raise ArgumentsRequired(self.id + 'fetchOpenOrdersWs requires a symbol.')
1191
+ raise ArgumentsRequired(self.id + ' fetchOpenOrdersWs requires a symbol.')
1192
1192
  await self.load_markets()
1193
1193
  await self.authenticate()
1194
1194
  market = self.market(symbol)
ccxt/pro/coincatch.py CHANGED
@@ -1403,7 +1403,7 @@ class coincatch(ccxt.async_support.coincatch):
1403
1403
  del client.subscriptions[subMessageHash]
1404
1404
  if messageHash in client.subscriptions:
1405
1405
  del client.subscriptions[messageHash]
1406
- error = UnsubscribeError(self.id + 'orderbook ' + symbol)
1406
+ error = UnsubscribeError(self.id + ' orderbook ' + symbol)
1407
1407
  client.reject(error, subMessageHash)
1408
1408
  client.resolve(True, messageHash)
1409
1409
 
@@ -1422,7 +1422,7 @@ class coincatch(ccxt.async_support.coincatch):
1422
1422
  del client.subscriptions[subMessageHash]
1423
1423
  if messageHash in client.subscriptions:
1424
1424
  del client.subscriptions[messageHash]
1425
- error = UnsubscribeError(self.id + 'trades ' + symbol)
1425
+ error = UnsubscribeError(self.id + ' trades ' + symbol)
1426
1426
  client.reject(error, subMessageHash)
1427
1427
  client.resolve(True, messageHash)
1428
1428
 
@@ -1441,7 +1441,7 @@ class coincatch(ccxt.async_support.coincatch):
1441
1441
  del client.subscriptions[subMessageHash]
1442
1442
  if messageHash in client.subscriptions:
1443
1443
  del client.subscriptions[messageHash]
1444
- error = UnsubscribeError(self.id + 'ticker ' + symbol)
1444
+ error = UnsubscribeError(self.id + ' ticker ' + symbol)
1445
1445
  client.reject(error, subMessageHash)
1446
1446
  client.resolve(True, messageHash)
1447
1447
 
ccxt/pro/mexc.py CHANGED
@@ -225,7 +225,7 @@ class mexc(ccxt.async_support.mexc):
225
225
  topics = []
226
226
  if not miniTicker:
227
227
  if symbols is None:
228
- raise ArgumentsRequired(self.id + 'watchTickers required symbols argument for the bookTicker channel')
228
+ raise ArgumentsRequired(self.id + ' watchTickers required symbols argument for the bookTicker channel')
229
229
  marketIds = self.market_ids(symbols)
230
230
  for i in range(0, len(marketIds)):
231
231
  marketId = marketIds[i]
@@ -406,12 +406,12 @@ class mexc(ccxt.async_support.mexc):
406
406
  symbols = self.market_symbols(symbols, None, True, False, True)
407
407
  marketType = None
408
408
  if symbols is None:
409
- raise ArgumentsRequired(self.id + 'watchBidsAsks required symbols argument')
409
+ raise ArgumentsRequired(self.id + ' watchBidsAsks required symbols argument')
410
410
  markets = self.markets_for_symbols(symbols)
411
411
  marketType, params = self.handle_market_type_and_params('watchBidsAsks', markets[0], params)
412
412
  isSpot = marketType == 'spot'
413
413
  if not isSpot:
414
- raise NotSupported(self.id + 'watchBidsAsks only support spot market')
414
+ raise NotSupported(self.id + ' watchBidsAsks only support spot market')
415
415
  messageHashes = []
416
416
  topics = []
417
417
  for i in range(0, len(symbols)):
@@ -446,7 +446,9 @@ class mexc(ccxt.async_support.mexc):
446
446
  # }
447
447
  #
448
448
  parsedTicker = self.parse_ws_bid_ask(message)
449
- symbol = parsedTicker['symbol']
449
+ symbol = self.safe_string(parsedTicker, 'symbol')
450
+ if symbol is None:
451
+ return
450
452
  self.bidsasks[symbol] = parsedTicker
451
453
  messageHash = 'bidask:' + symbol
452
454
  client.resolve(parsedTicker, messageHash)
ccxt/pro/okx.py CHANGED
@@ -2076,7 +2076,7 @@ class okx(ccxt.async_support.okx):
2076
2076
  await self.authenticate()
2077
2077
  market = self.market(symbol)
2078
2078
  if market['type'] != 'option':
2079
- raise BadRequest(self.id + 'cancelAllOrdersWs is only applicable to Option in Portfolio Margin mode, and MMP privilege is required.')
2079
+ raise BadRequest(self.id + ' cancelAllOrdersWs is only applicable to Option in Portfolio Margin mode, and MMP privilege is required.')
2080
2080
  url = self.get_url('private', 'private')
2081
2081
  messageHash = self.request_id()
2082
2082
  request: dict = {
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
ccxt/test/tests_init.py CHANGED
@@ -18,7 +18,7 @@ if sys.platform == 'win32':
18
18
  # ########### args ###########
19
19
  isWs = get_cli_arg_value('--ws')
20
20
  isBaseTests = get_cli_arg_value('--baseTests')
21
- run_all = get_cli_arg_value('--all')
21
+ runAll = get_cli_arg_value('--all')
22
22
 
23
23
  # ###### base tests #######
24
24
  if (isBaseTests):
@@ -27,7 +27,7 @@ if (isBaseTests):
27
27
  else:
28
28
  base_tests_init()
29
29
  print('base tests passed!')
30
- if not run_all:
30
+ if not runAll:
31
31
  exit(0)
32
32
 
33
33
  # ###### exchange tests #######
ccxt/timex.py CHANGED
@@ -729,6 +729,7 @@ class timex(Exchange, ImplicitAPI):
729
729
  :param int [since]: timestamp in ms of the earliest candle to fetch
730
730
  :param int [limit]: the maximum amount of candles to fetch
731
731
  :param dict [params]: extra parameters specific to the exchange API endpoint
732
+ :param int [params.until]: timestamp in ms of the latest candle to fetch
732
733
  :returns int[][]: A list of candles ordered, open, high, low, close, volume
733
734
  """
734
735
  self.load_markets()
@@ -739,15 +740,24 @@ class timex(Exchange, ImplicitAPI):
739
740
  }
740
741
  # if since and limit are not specified
741
742
  duration = self.parse_timeframe(timeframe)
743
+ until = self.safe_integer(params, 'until')
742
744
  if limit is None:
743
745
  limit = 1000 # exchange provides tens of thousands of data, but we set generous default value
744
746
  if since is not None:
745
747
  request['from'] = self.iso8601(since)
746
- request['till'] = self.iso8601(self.sum(since, self.sum(limit, 1) * duration * 1000))
748
+ if until is None:
749
+ request['till'] = self.iso8601(self.sum(since, self.sum(limit, 1) * duration * 1000))
750
+ else:
751
+ request['till'] = self.iso8601(until)
752
+ elif until is not None:
753
+ request['till'] = self.iso8601(until)
754
+ fromTimestamp = until - self.sum(limit, 1) * duration * 1000
755
+ request['from'] = self.iso8601(fromTimestamp)
747
756
  else:
748
757
  now = self.milliseconds()
749
758
  request['till'] = self.iso8601(now)
750
- request['from'] = self.iso8601(now - limit * duration * 1000 - 1)
759
+ request['from'] = self.iso8601(now - self.sum(limit, 1) * duration * 1000 - 1)
760
+ params = self.omit(params, 'until')
751
761
  response = self.publicGetCandles(self.extend(request, params))
752
762
  #
753
763
  # [
ccxt/vertex.py CHANGED
@@ -1523,7 +1523,7 @@ class vertex(Exchange, ImplicitAPI):
1523
1523
  marketId = base + '/' + quote
1524
1524
  if base.find('PERP') > 0:
1525
1525
  marketId = marketId.replace('-PERP', '') + ':USDC'
1526
- market = self.market(marketId)
1526
+ market = self.safe_market(marketId, market)
1527
1527
  last = self.safe_string(ticker, 'last_price')
1528
1528
  return self.safe_ticker({
1529
1529
  'symbol': market['symbol'],
ccxt/whitebit.py CHANGED
@@ -2626,12 +2626,13 @@ class whitebit(Exchange, ImplicitAPI):
2626
2626
  # For cases where we have a meaningful status
2627
2627
  # {"response":null,"status":422,"errors":{"orderId":["Finished order id 435453454535 not found on your account"]},"notification":null,"warning":"Finished order id 435453454535 not found on your account","_token":null}
2628
2628
  status = self.safe_string(response, 'status')
2629
+ errors = self.safe_value(response, 'errors')
2629
2630
  # {"code":10,"message":"Unauthorized request."}
2630
2631
  message = self.safe_string(response, 'message')
2631
2632
  # For these cases where we have a generic code variable error key
2632
2633
  # {"code":0,"message":"Validation failed","errors":{"amount":["Amount must be greater than 0"]}}
2633
2634
  codeNew = self.safe_integer(response, 'code')
2634
- hasErrorStatus = status is not None and status != '200'
2635
+ hasErrorStatus = status is not None and status != '200' and errors is not None
2635
2636
  if hasErrorStatus or codeNew is not None:
2636
2637
  feedback = self.id + ' ' + body
2637
2638
  errorInfo = message
ccxt/woofipro.py CHANGED
@@ -1507,7 +1507,7 @@ class woofipro(Exchange, ImplicitAPI):
1507
1507
  takeProfit = self.safe_value(orderParams, 'takeProfit')
1508
1508
  isConditional = triggerPrice is not None or stopLoss is not None or takeProfit is not None or (self.safe_value(orderParams, 'childOrders') is not None)
1509
1509
  if isConditional:
1510
- raise NotSupported(self.id + 'createOrders() only support non-stop order')
1510
+ raise NotSupported(self.id + ' createOrders() only support non-stop order')
1511
1511
  orderRequest = self.create_order_request(marketId, type, side, amount, price, orderParams)
1512
1512
  ordersRequests.append(orderRequest)
1513
1513
  request: dict = {
@@ -2355,7 +2355,7 @@ class woofipro(Exchange, ImplicitAPI):
2355
2355
  if code is not None:
2356
2356
  code = code.upper()
2357
2357
  if code != 'USDC':
2358
- raise NotSupported(self.id + 'withdraw() only support USDC')
2358
+ raise NotSupported(self.id + ' withdraw() only support USDC')
2359
2359
  currency = self.currency(code)
2360
2360
  verifyingContractAddress = self.safe_string(self.options, 'verifyingContractAddress')
2361
2361
  chainId = self.safe_string(params, 'chainId')
ccxt/xt.py CHANGED
@@ -128,7 +128,7 @@ class xt(Exchange, ImplicitAPI):
128
128
  'repayMargin': False,
129
129
  'setLeverage': True,
130
130
  'setMargin': False,
131
- 'setMarginMode': False,
131
+ 'setMarginMode': True,
132
132
  'setPositionMode': False,
133
133
  'signIn': False,
134
134
  'transfer': True,
@@ -286,6 +286,7 @@ class xt(Exchange, ImplicitAPI):
286
286
  'future/user/v1/position/margin': 1,
287
287
  'future/user/v1/user/collection/add': 1,
288
288
  'future/user/v1/user/collection/cancel': 1,
289
+ 'future/user/v1/position/change-type': 1,
289
290
  },
290
291
  },
291
292
  'inverse': {
@@ -531,10 +532,12 @@ class xt(Exchange, ImplicitAPI):
531
532
  'TRANSFER_012': PermissionDenied, # Currency transfer prohibited
532
533
  'symbol_not_support_trading_via_api': BadSymbol, # {"returnCode":1,"msgInfo":"failure","error":{"code":"symbol_not_support_trading_via_api","msg":"The symbol does not support trading via API"},"result":null}
533
534
  'open_order_min_nominal_value_limit': InvalidOrder, # {"returnCode":1,"msgInfo":"failure","error":{"code":"open_order_min_nominal_value_limit","msg":"Exceeds the minimum notional value of a single order"},"result":null}
535
+ 'insufficient_balance': InsufficientFunds,
534
536
  },
535
537
  'broad': {
536
538
  'The symbol does not support trading via API': BadSymbol, # {"returnCode":1,"msgInfo":"failure","error":{"code":"symbol_not_support_trading_via_api","msg":"The symbol does not support trading via API"},"result":null}
537
539
  'Exceeds the minimum notional value of a single order': InvalidOrder, # {"returnCode":1,"msgInfo":"failure","error":{"code":"open_order_min_nominal_value_limit","msg":"Exceeds the minimum notional value of a single order"},"result":null}
540
+ 'insufficient balance': InsufficientFunds,
538
541
  },
539
542
  },
540
543
  'timeframes': {
@@ -4616,6 +4619,53 @@ class xt(Exchange, ImplicitAPI):
4616
4619
  'status': None,
4617
4620
  }
4618
4621
 
4622
+ def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
4623
+ """
4624
+ set margin mode to 'cross' or 'isolated'
4625
+
4626
+ https://doc.xt.com/#futures_userchangePositionType
4627
+
4628
+ :param str marginMode: 'cross' or 'isolated'
4629
+ :param str [symbol]: required
4630
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4631
+ :param str [params.positionSide]: *required* "long" or "short"
4632
+ :returns dict: response from the exchange
4633
+ """
4634
+ if symbol is None:
4635
+ raise ArgumentsRequired(self.id + ' setMarginMode() requires a symbol argument')
4636
+ self.load_markets()
4637
+ market = self.market(symbol)
4638
+ if market['spot']:
4639
+ raise BadSymbol(self.id + ' setMarginMode() supports contract markets only')
4640
+ marginMode = marginMode.lower()
4641
+ if marginMode != 'isolated' and marginMode != 'cross':
4642
+ raise BadRequest(self.id + ' setMarginMode() marginMode argument should be isolated or cross')
4643
+ if marginMode == 'cross':
4644
+ marginMode = 'CROSSED'
4645
+ else:
4646
+ marginMode = 'ISOLATED'
4647
+ posSide = self.safe_string_upper(params, 'positionSide')
4648
+ if posSide is None:
4649
+ raise ArgumentsRequired(self.id + ' setMarginMode() requires a positionSide parameter, either "LONG" or "SHORT"')
4650
+ request: dict = {
4651
+ 'positionType': marginMode,
4652
+ 'positionSide': posSide,
4653
+ 'symbol': market['id'],
4654
+ }
4655
+ response = self.privateLinearPostFutureUserV1PositionChangeType(self.extend(request, params))
4656
+ #
4657
+ # {
4658
+ # "error": {
4659
+ # "code": "",
4660
+ # "msg": ""
4661
+ # },
4662
+ # "msgInfo": "",
4663
+ # "result": {},
4664
+ # "returnCode": 0
4665
+ # }
4666
+ #
4667
+ return response # unify return type
4668
+
4619
4669
  def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
4620
4670
  #
4621
4671
  # spot: error
@@ -4666,6 +4716,9 @@ class xt(Exchange, ImplicitAPI):
4666
4716
  # "result": {}
4667
4717
  # }
4668
4718
  #
4719
+ # {"returnCode":1,"msgInfo":"failure","error":{"code":"insufficient_balance","msg":"insufficient balance","args":[]},"result":null}
4720
+ #
4721
+ #
4669
4722
  status = self.safe_string_upper_2(response, 'msgInfo', 'mc')
4670
4723
  if status is not None and status != 'SUCCESS':
4671
4724
  feedback = self.id + ' ' + body
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ccxt
3
- Version: 4.4.53
3
+ Version: 4.4.58
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
@@ -49,7 +49,7 @@ Requires-Dist: mypy==1.6.1; extra == "type"
49
49
 
50
50
  # CCXT – CryptoCurrency eXchange Trading Library
51
51
 
52
- [![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-112-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)
52
+ [![NPM Downloads](https://img.shields.io/npm/dy/ccxt.svg)](https://www.npmjs.com/package/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) [![NuGet version](https://img.shields.io/nuget/v/ccxt)](https://www.nuget.org/packages/ccxt) [![GoDoc](https://pkg.go.dev/badge/github.com/ccxt/ccxt/go/v4?utm_source=godoc)](https://godoc.org/github.com/ccxt/ccxt/go/v4) [![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) [![Follow CCXT at x.com](https://img.shields.io/twitter/follow/ccxt_official.svg?style=social&label=CCXT)](https://x.com/ccxt_official)
53
53
 
54
54
  A JavaScript / Python / PHP / C# / Go library for cryptocurrency trading and e-commerce with support for many bitcoin/ether/altcoin exchange markets and merchant APIs.
55
55
 
@@ -110,7 +110,7 @@ Current feature list:
110
110
 
111
111
  ## Supported Cryptocurrency Exchanges
112
112
 
113
- The CCXT library currently supports the following 107 cryptocurrency exchange markets and trading APIs:
113
+ The CCXT library currently supports the following 106 cryptocurrency exchange markets and trading APIs:
114
114
 
115
115
  | logo | id | name | ver | type | certified | pro |
116
116
  |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------|----------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------:|--------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------|
@@ -189,7 +189,6 @@ The CCXT library currently supports the following 107 cryptocurrency exchange ma
189
189
  | [![latoken](https://user-images.githubusercontent.com/1294454/61511972-24c39f00-aa01-11e9-9f7c-471f1d6e5214.jpg)](https://latoken.com/invite?r=mvgp2djk) | latoken | [Latoken](https://latoken.com/invite?r=mvgp2djk) | [![API Version 2](https://img.shields.io/badge/2-lightgray)](https://api.latoken.com) | ![CEX – Centralized EXchange](https://img.shields.io/badge/CEX-green.svg "CEX – Centralized EXchange") | | |
190
190
  | [![lbank](https://user-images.githubusercontent.com/1294454/38063602-9605e28a-3302-11e8-81be-64b1e53c4cfb.jpg)](https://www.lbank.com/login/?icode=7QCY) | lbank | [LBank](https://www.lbank.com/login/?icode=7QCY) | [![API Version 2](https://img.shields.io/badge/2-lightgray)](https://www.lbank.com/en-US/docs/index.html) | ![CEX – Centralized EXchange](https://img.shields.io/badge/CEX-green.svg "CEX – Centralized EXchange") | | [![CCXT Pro](https://img.shields.io/badge/CCXT-Pro-black)](https://ccxt.pro) |
191
191
  | [![luno](https://user-images.githubusercontent.com/1294454/27766607-8c1a69d8-5ede-11e7-930c-540b5eb9be24.jpg)](https://www.luno.com/invite/44893A) | luno | [luno](https://www.luno.com/invite/44893A) | [![API Version 1](https://img.shields.io/badge/1-lightgray)](https://www.luno.com/en/api) | ![CEX – Centralized EXchange](https://img.shields.io/badge/CEX-green.svg "CEX – Centralized EXchange") | | [![CCXT Pro](https://img.shields.io/badge/CCXT-Pro-black)](https://ccxt.pro) |
192
- | [![lykke](https://user-images.githubusercontent.com/1294454/155840500-1ea4fdf0-47c0-4daa-9597-c6c1cd51b9ec.jpg)](https://www.lykke.com) | lykke | [Lykke](https://www.lykke.com) | [![API Version 2](https://img.shields.io/badge/2-lightgray)](https://hft-apiv2.lykke.com/swagger/ui/index.html) | ![CEX – Centralized EXchange](https://img.shields.io/badge/CEX-green.svg "CEX – Centralized EXchange") | | |
193
192
  | [![mercado](https://user-images.githubusercontent.com/1294454/27837060-e7c58714-60ea-11e7-9192-f05e86adb83f.jpg)](https://www.mercadobitcoin.com.br) | mercado | [Mercado Bitcoin](https://www.mercadobitcoin.com.br) | [![API Version 3](https://img.shields.io/badge/3-lightgray)](https://www.mercadobitcoin.com.br/api-doc) | ![CEX – Centralized EXchange](https://img.shields.io/badge/CEX-green.svg "CEX – Centralized EXchange") | | |
194
193
  | [![mexc](https://user-images.githubusercontent.com/1294454/137283979-8b2a818d-8633-461b-bfca-de89e8c446b2.jpg)](https://www.mexc.com/register?inviteCode=mexc-1FQ1GNu1) | mexc | [MEXC Global](https://www.mexc.com/register?inviteCode=mexc-1FQ1GNu1) | [![API Version 3](https://img.shields.io/badge/3-lightgray)](https://mexcdevelop.github.io/apidocs/) | ![CEX – Centralized EXchange](https://img.shields.io/badge/CEX-green.svg "CEX – Centralized EXchange") | [![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) |
195
194
  | [![myokx](https://user-images.githubusercontent.com/1294454/152485636-38b19e4a-bece-4dec-979a-5982859ffc04.jpg)](https://www.my.okx.com/join/CCXT2023) | myokx | [MyOKX (EEA)](https://www.my.okx.com/join/CCXT2023) | [![API Version 5](https://img.shields.io/badge/5-lightgray)](https://my.okx.com/docs-v5/en/#overview) | ![CEX – Centralized EXchange](https://img.shields.io/badge/CEX-green.svg "CEX – Centralized EXchange") | | [![CCXT Pro](https://img.shields.io/badge/CCXT-Pro-black)](https://ccxt.pro) |
@@ -236,7 +235,7 @@ The easiest way to install the CCXT library is to use a package manager:
236
235
  - [ccxt in **PyPI**](https://pypi.python.org/pypi/ccxt) (Python 3.7.0+)
237
236
  - [ccxt in **Packagist/Composer**](https://packagist.org/packages/ccxt/ccxt) (PHP 8.1+)
238
237
  - [ccxt in **Nuget**](https://www.nuget.org/packages/ccxt) (netstandard 2.0)
239
- - [ccxt in **GO**](https://pkg.go.dev/github.com/ccxt/ccxt)
238
+ - [ccxt in **GO**](https://pkg.go.dev/github.com/ccxt/ccxt/go/v4)
240
239
 
241
240
  This library is shipped as an all-in-one module implementation with minimalistic dependencies and requirements:
242
241
 
@@ -281,13 +280,13 @@ console.log(version, Object.keys(exchanges));
281
280
 
282
281
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
283
282
 
284
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.53/dist/ccxt.browser.min.js
285
- * unpkg: https://unpkg.com/ccxt@4.4.53/dist/ccxt.browser.min.js
283
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.58/dist/ccxt.browser.min.js
284
+ * unpkg: https://unpkg.com/ccxt@4.4.58/dist/ccxt.browser.min.js
286
285
 
287
286
  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.
288
287
 
289
288
  ```HTML
290
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.4.53/dist/ccxt.browser.min.js"></script>
289
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.4.58/dist/ccxt.browser.min.js"></script>
291
290
  ```
292
291
 
293
292
  Creates a global `ccxt` object:
@@ -350,12 +349,10 @@ Console.WriteLine(ccxt.Exchanges) // check this later
350
349
 
351
350
  ### Go
352
351
 
353
- *warning* GO isn't publicly released yet, for now you need to build it from source (it will be officially released soon)
354
-
355
- [ccxt in GO with] (https://pkg.go.dev/github.com/ccxt/ccxt)
352
+ [ccxt in GO with **PKG**](https://pkg.go.dev/github.com/ccxt/ccxt/go/v4)
356
353
 
357
354
  ```shell
358
- go get github.com/ccxt/ccxt/go/v4/go
355
+ go get github.com/ccxt/ccxt/go/v4
359
356
  ```
360
357
 
361
358
  ```Go