ccxt 4.3.14__py2.py3-none-any.whl → 4.3.16__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 (70) hide show
  1. ccxt/__init__.py +2 -1
  2. ccxt/abstract/luno.py +2 -0
  3. ccxt/alpaca.py +1 -0
  4. ccxt/ascendex.py +1 -0
  5. ccxt/async_support/__init__.py +2 -1
  6. ccxt/async_support/alpaca.py +1 -0
  7. ccxt/async_support/ascendex.py +1 -0
  8. ccxt/async_support/base/exchange.py +18 -13
  9. ccxt/async_support/binance.py +5 -3
  10. ccxt/async_support/bingx.py +2 -0
  11. ccxt/async_support/bitmex.py +1 -0
  12. ccxt/async_support/bybit.py +7 -6
  13. ccxt/async_support/coinbaseinternational.py +1 -0
  14. ccxt/async_support/coinex.py +35 -33
  15. ccxt/async_support/coinmetro.py +1 -0
  16. ccxt/async_support/cryptocom.py +3 -1
  17. ccxt/async_support/currencycom.py +1 -0
  18. ccxt/async_support/deribit.py +1 -0
  19. ccxt/async_support/gate.py +1 -0
  20. ccxt/async_support/gemini.py +1 -0
  21. ccxt/async_support/hitbtc.py +2 -0
  22. ccxt/async_support/hollaex.py +1 -0
  23. ccxt/async_support/hyperliquid.py +4 -0
  24. ccxt/async_support/idex.py +1 -0
  25. ccxt/async_support/krakenfutures.py +1 -0
  26. ccxt/async_support/luno.py +2 -0
  27. ccxt/async_support/ndax.py +1 -0
  28. ccxt/async_support/okx.py +1 -0
  29. ccxt/async_support/phemex.py +2 -1
  30. ccxt/async_support/poloniex.py +1 -0
  31. ccxt/async_support/probit.py +1 -0
  32. ccxt/async_support/wavesexchange.py +1 -0
  33. ccxt/async_support/woo.py +1 -0
  34. ccxt/async_support/zaif.py +1 -1
  35. ccxt/base/errors.py +6 -0
  36. ccxt/base/exchange.py +24 -19
  37. ccxt/binance.py +5 -3
  38. ccxt/bingx.py +2 -0
  39. ccxt/bitmex.py +1 -0
  40. ccxt/bybit.py +7 -6
  41. ccxt/coinbaseinternational.py +1 -0
  42. ccxt/coinex.py +35 -33
  43. ccxt/coinmetro.py +1 -0
  44. ccxt/cryptocom.py +3 -1
  45. ccxt/currencycom.py +1 -0
  46. ccxt/deribit.py +1 -0
  47. ccxt/gate.py +1 -0
  48. ccxt/gemini.py +1 -0
  49. ccxt/hitbtc.py +2 -0
  50. ccxt/hollaex.py +1 -0
  51. ccxt/hyperliquid.py +4 -0
  52. ccxt/idex.py +1 -0
  53. ccxt/krakenfutures.py +1 -0
  54. ccxt/luno.py +2 -0
  55. ccxt/ndax.py +1 -0
  56. ccxt/okx.py +1 -0
  57. ccxt/phemex.py +2 -1
  58. ccxt/poloniex.py +1 -0
  59. ccxt/pro/__init__.py +1 -1
  60. ccxt/pro/hitbtc.py +1 -1
  61. ccxt/pro/independentreserve.py +3 -3
  62. ccxt/pro/poloniex.py +3 -3
  63. ccxt/probit.py +1 -0
  64. ccxt/wavesexchange.py +1 -0
  65. ccxt/woo.py +1 -0
  66. ccxt/zaif.py +1 -1
  67. {ccxt-4.3.14.dist-info → ccxt-4.3.16.dist-info}/METADATA +4 -4
  68. {ccxt-4.3.14.dist-info → ccxt-4.3.16.dist-info}/RECORD +70 -70
  69. {ccxt-4.3.14.dist-info → ccxt-4.3.16.dist-info}/WHEEL +0 -0
  70. {ccxt-4.3.14.dist-info → ccxt-4.3.16.dist-info}/top_level.txt +0 -0
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.14'
7
+ __version__ = '4.3.16'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -3092,15 +3092,15 @@ class Exchange(object):
3092
3092
  # timestamp and symbol operations don't belong in safeTicker
3093
3093
  # they should be done in the derived classes
3094
3094
  return self.extend(ticker, {
3095
- 'bid': self.parse_number(self.omit_zero(self.safe_number(ticker, 'bid'))),
3095
+ 'bid': self.parse_number(self.omit_zero(self.safe_string(ticker, 'bid'))),
3096
3096
  'bidVolume': self.safe_number(ticker, 'bidVolume'),
3097
- 'ask': self.parse_number(self.omit_zero(self.safe_number(ticker, 'ask'))),
3097
+ 'ask': self.parse_number(self.omit_zero(self.safe_string(ticker, 'ask'))),
3098
3098
  'askVolume': self.safe_number(ticker, 'askVolume'),
3099
3099
  'high': self.parse_number(self.omit_zero(self.safe_string(ticker, 'high'))),
3100
- 'low': self.parse_number(self.omit_zero(self.safe_number(ticker, 'low'))),
3101
- 'open': self.parse_number(self.omit_zero(self.parse_number(open))),
3102
- 'close': self.parse_number(self.omit_zero(self.parse_number(close))),
3103
- 'last': self.parse_number(self.omit_zero(self.parse_number(last))),
3100
+ 'low': self.parse_number(self.omit_zero(self.safe_string(ticker, 'low'))),
3101
+ 'open': self.parse_number(self.omit_zero(open)),
3102
+ 'close': self.parse_number(self.omit_zero(close)),
3103
+ 'last': self.parse_number(self.omit_zero(last)),
3104
3104
  'change': self.parse_number(change),
3105
3105
  'percentage': self.parse_number(percentage),
3106
3106
  'average': self.parse_number(average),
@@ -5468,18 +5468,19 @@ class Exchange(object):
5468
5468
  maxRetries = None
5469
5469
  maxRetries, params = self.handle_option_and_params(params, method, 'maxRetries', 3)
5470
5470
  errors = 0
5471
- try:
5472
- if timeframe and method != 'fetchFundingRateHistory':
5473
- return getattr(self, method)(symbol, timeframe, since, limit, params)
5474
- else:
5475
- return getattr(self, method)(symbol, since, limit, params)
5476
- except Exception as e:
5477
- if isinstance(e, RateLimitExceeded):
5478
- raise e # if we are rate limited, we should not retry and fail fast
5479
- errors += 1
5480
- if errors > maxRetries:
5481
- raise e
5482
- return None
5471
+ while(errors <= maxRetries):
5472
+ try:
5473
+ if timeframe and method != 'fetchFundingRateHistory':
5474
+ return getattr(self, method)(symbol, timeframe, since, limit, params)
5475
+ else:
5476
+ return getattr(self, method)(symbol, since, limit, params)
5477
+ except Exception as e:
5478
+ if isinstance(e, RateLimitExceeded):
5479
+ raise e # if we are rate limited, we should not retry and fail fast
5480
+ errors += 1
5481
+ if errors > maxRetries:
5482
+ raise e
5483
+ return []
5483
5484
 
5484
5485
  def fetch_paginated_call_deterministic(self, method: str, symbol: Str = None, since: Int = None, limit: Int = None, timeframe: Str = None, params={}, maxEntriesPerRequest=None):
5485
5486
  maxCalls = None
@@ -5492,6 +5493,8 @@ class Exchange(object):
5492
5493
  currentSince = current - (maxCalls * step) - 1
5493
5494
  if since is not None:
5494
5495
  currentSince = max(currentSince, since)
5496
+ else:
5497
+ currentSince = max(currentSince, 1241440531000) # avoid timestamps older than 2009
5495
5498
  until = self.safe_integer_2(params, 'until', 'till') # do not omit it here
5496
5499
  if until is not None:
5497
5500
  requiredCalls = int(math.ceil((until - since)) / step)
@@ -5500,6 +5503,8 @@ class Exchange(object):
5500
5503
  for i in range(0, maxCalls):
5501
5504
  if (until is not None) and (currentSince >= until):
5502
5505
  break
5506
+ if currentSince >= current:
5507
+ break
5503
5508
  tasks.append(self.safe_deterministic_call(method, symbol, currentSince, maxEntriesPerRequest, timeframe, params))
5504
5509
  currentSince = self.sum(currentSince, step) - 1
5505
5510
  results = tasks
ccxt/binance.py CHANGED
@@ -18,6 +18,7 @@ from ccxt.base.errors import BadRequest
18
18
  from ccxt.base.errors import BadSymbol
19
19
  from ccxt.base.errors import OperationRejected
20
20
  from ccxt.base.errors import MarginModeAlreadySet
21
+ from ccxt.base.errors import MarketClosed
21
22
  from ccxt.base.errors import BadResponse
22
23
  from ccxt.base.errors import InsufficientFunds
23
24
  from ccxt.base.errors import InvalidOrder
@@ -176,6 +177,7 @@ class binance(Exchange, ImplicitAPI):
176
177
  'reduceMargin': True,
177
178
  'repayCrossMargin': True,
178
179
  'repayIsolatedMargin': True,
180
+ 'sandbox': True,
179
181
  'setLeverage': True,
180
182
  'setMargin': False,
181
183
  'setMarginMode': True,
@@ -2418,7 +2420,7 @@ class binance(Exchange, ImplicitAPI):
2418
2420
  'Rest API trading is not enabled.': PermissionDenied,
2419
2421
  'This account may not place or cancel orders.': PermissionDenied,
2420
2422
  "You don't have permission.": PermissionDenied, # {"msg":"You don't have permission.","success":false}
2421
- 'Market is closed.': OperationRejected, # {"code":-1013,"msg":"Market is closed."}
2423
+ 'Market is closed.': MarketClosed, # {"code":-1013,"msg":"Market is closed."}
2422
2424
  'Too many requests. Please try again later.': RateLimitExceeded, # {"msg":"Too many requests. Please try again later.","success":false}
2423
2425
  'This action is disabled on self account.': AccountSuspended, # {"code":-2011,"msg":"This action is disabled on self account."}
2424
2426
  'Limit orders require GTC for self phase.': BadRequest,
@@ -3885,8 +3887,8 @@ class binance(Exchange, ImplicitAPI):
3885
3887
  """
3886
3888
  fetches the last price for multiple markets
3887
3889
  :see: https://binance-docs.github.io/apidocs/spot/en/#symbol-price-ticker # spot
3888
- :see: https://binance-docs.github.io/apidocs/future/en/#symbol-price-ticker # swap
3889
- :see: https://binance-docs.github.io/apidocs/delivery/en/#symbol-price-ticker # future
3890
+ :see: https://binance-docs.github.io/apidocs/futures/en/#symbol-price-ticker # swap
3891
+ :see: https://binance-docs.github.io/apidocs/delivery/en/#symbol-price-tickers # future
3890
3892
  :param str[]|None symbols: unified symbols of the markets to fetch the last prices
3891
3893
  :param dict [params]: extra parameters specific to the exchange API endpoint
3892
3894
  :param str [params.subType]: "linear" or "inverse"
ccxt/bingx.py CHANGED
@@ -97,6 +97,7 @@ class bingx(Exchange, ImplicitAPI):
97
97
  'fetchTransfers': True,
98
98
  'fetchWithdrawals': True,
99
99
  'reduceMargin': True,
100
+ 'sandbox': True,
100
101
  'setLeverage': True,
101
102
  'setMargin': True,
102
103
  'setMarginMode': True,
@@ -400,6 +401,7 @@ class bingx(Exchange, ImplicitAPI):
400
401
  '100202': InsufficientFunds,
401
402
  '100204': BadRequest,
402
403
  '100400': BadRequest,
404
+ '100410': OperationFailed, # {"code":100410,"msg":"The current system is busy, please try again later"}
403
405
  '100421': BadSymbol, # {"code":100421,"msg":"This pair is currently restricted from API trading","debugMsg":""}
404
406
  '100440': ExchangeError,
405
407
  '100500': OperationFailed, # {"code":100500,"msg":"The current system is busy, please try again later","debugMsg":""}
ccxt/bitmex.py CHANGED
@@ -100,6 +100,7 @@ class bitmex(Exchange, ImplicitAPI):
100
100
  'fetchTransfer': False,
101
101
  'fetchTransfers': False,
102
102
  'reduceMargin': None,
103
+ 'sandbox': True,
103
104
  'setLeverage': True,
104
105
  'setMargin': None,
105
106
  'setMarginMode': True,
ccxt/bybit.py CHANGED
@@ -133,6 +133,7 @@ class bybit(Exchange, ImplicitAPI):
133
133
  'fetchVolatilityHistory': True,
134
134
  'fetchWithdrawals': True,
135
135
  'repayCrossMargin': True,
136
+ 'sandbox': True,
136
137
  'setLeverage': True,
137
138
  'setMarginMode': True,
138
139
  'setPositionMode': True,
@@ -6267,19 +6268,19 @@ class bybit(Exchange, ImplicitAPI):
6267
6268
  isUsdcSettled = market['settle'] == 'USDC'
6268
6269
  # engage in leverage setting
6269
6270
  # we reuse the code here instead of having two methods
6270
- leverage = self.number_to_string(leverage)
6271
+ leverageString = self.number_to_string(leverage)
6271
6272
  request = {
6272
6273
  'symbol': market['id'],
6273
- 'buyLeverage': leverage,
6274
- 'sellLeverage': leverage,
6274
+ 'buyLeverage': leverageString,
6275
+ 'sellLeverage': leverageString,
6275
6276
  }
6276
6277
  response = None
6277
6278
  if isUsdcSettled and not isUnifiedAccount:
6278
- request['leverage'] = leverage
6279
+ request['leverage'] = leverageString
6279
6280
  response = self.privatePostPerpetualUsdcOpenapiPrivateV1PositionLeverageSave(self.extend(request, params))
6280
6281
  else:
6281
- request['buyLeverage'] = leverage
6282
- request['sellLeverage'] = leverage
6282
+ request['buyLeverage'] = leverageString
6283
+ request['sellLeverage'] = leverageString
6283
6284
  if market['linear']:
6284
6285
  request['category'] = 'linear'
6285
6286
  elif market['inverse']:
@@ -113,6 +113,7 @@ class coinbaseinternational(Exchange, ImplicitAPI):
113
113
  'fetchTradingFees': False,
114
114
  'fetchWithdrawals': True,
115
115
  'reduceMargin': False,
116
+ 'sandbox': True,
116
117
  'setLeverage': False,
117
118
  'setMargin': True,
118
119
  'setMarginMode': False,
ccxt/coinex.py CHANGED
@@ -3487,48 +3487,49 @@ class coinex(Exchange, ImplicitAPI):
3487
3487
  def create_deposit_address(self, code: str, params={}):
3488
3488
  """
3489
3489
  create a currency deposit address
3490
- :see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot002_account019_update_deposit_address
3490
+ :see: https://docs.coinex.com/api/v2/assets/deposit-withdrawal/http/update-deposit-address
3491
3491
  :param str code: unified currency code of the currency for the deposit address
3492
3492
  :param dict [params]: extra parameters specific to the exchange API endpoint
3493
+ :param str [params.network]: the blockchain network to create a deposit address on
3493
3494
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
3494
3495
  """
3495
3496
  self.load_markets()
3496
3497
  currency = self.currency(code)
3498
+ network = self.safe_string_2(params, 'chain', 'network')
3499
+ if network is None:
3500
+ raise ArgumentsRequired(self.id + ' createDepositAddress() requires a network parameter')
3501
+ params = self.omit(params, 'network')
3497
3502
  request = {
3498
- 'coin_type': currency['id'],
3503
+ 'ccy': currency['id'],
3504
+ 'chain': self.network_code_to_id(network, currency['code']),
3499
3505
  }
3500
- if 'network' in params:
3501
- network = self.safe_string(params, 'network')
3502
- params = self.omit(params, 'network')
3503
- request['smart_contract_name'] = network
3504
- response = self.v1PrivatePutBalanceDepositAddressCoinType(self.extend(request, params))
3506
+ response = self.v2PrivatePostAssetsRenewalDepositAddress(self.extend(request, params))
3505
3507
  #
3506
3508
  # {
3507
3509
  # "code": 0,
3508
3510
  # "data": {
3509
- # "coin_address": "TV639dSpb9iGRtoFYkCp4AoaaDYKrK1pw5",
3510
- # "is_bitcoin_cash": False
3511
+ # "address": "0x321bd6479355142334f45653ad5d8b76105a1234",
3512
+ # "memo": ""
3511
3513
  # },
3512
- # "message": "Success"
3514
+ # "message": "OK"
3513
3515
  # }
3516
+ #
3514
3517
  data = self.safe_dict(response, 'data', {})
3515
3518
  return self.parse_deposit_address(data, currency)
3516
3519
 
3517
3520
  def fetch_deposit_address(self, code: str, params={}):
3518
3521
  """
3519
3522
  fetch the deposit address for a currency associated with self account
3520
- :see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot002_account020_query_deposit_address
3523
+ :see: https://docs.coinex.com/api/v2/assets/deposit-withdrawal/http/get-deposit-address
3521
3524
  :param str code: unified currency code
3522
3525
  :param dict [params]: extra parameters specific to the exchange API endpoint
3526
+ :param str [params.network]: the blockchain network to create a deposit address on
3523
3527
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
3524
3528
  """
3525
3529
  self.load_markets()
3526
3530
  currency = self.currency(code)
3527
- request = {
3528
- 'coin_type': currency['id'],
3529
- }
3530
- networks = self.safe_value(currency, 'networks', {})
3531
- network = self.safe_string(params, 'network')
3531
+ networks = self.safe_dict(currency, 'networks', {})
3532
+ network = self.safe_string_2(params, 'network', 'chain')
3532
3533
  params = self.omit(params, 'network')
3533
3534
  networksKeys = list(networks.keys())
3534
3535
  numOfNetworks = len(networksKeys)
@@ -3537,23 +3538,24 @@ class coinex(Exchange, ImplicitAPI):
3537
3538
  raise ArgumentsRequired(self.id + ' fetchDepositAddress() ' + code + ' requires a network parameter')
3538
3539
  if not (network in networks):
3539
3540
  raise ExchangeError(self.id + ' fetchDepositAddress() ' + network + ' network not supported for ' + code)
3540
- if network is not None:
3541
- request['smart_contract_name'] = network
3542
- response = self.v1PrivateGetBalanceDepositAddressCoinType(self.extend(request, params))
3541
+ request = {
3542
+ 'ccy': currency['id'],
3543
+ 'chain': network,
3544
+ }
3545
+ response = self.v2PrivateGetAssetsDepositAddress(self.extend(request, params))
3543
3546
  #
3544
- # {
3545
- # "code": 0,
3546
- # "data": {
3547
- # "coin_address": "1P1JqozxioQwaqPwgMAQdNDYNyaVSqgARq",
3548
- # # coin_address: "xxxxxxxxxxxxxx:yyyyyyyyy", # with embedded tag/memo
3549
- # "is_bitcoin_cash": False
3550
- # },
3551
- # "message": "Success"
3552
- # }
3547
+ # {
3548
+ # "code": 0,
3549
+ # "data": {
3550
+ # "address": "0x321bd6479355142334f45653ad5d8b76105a1234",
3551
+ # "memo": ""
3552
+ # },
3553
+ # "message": "OK"
3554
+ # }
3553
3555
  #
3554
- data = self.safe_value(response, 'data', {})
3556
+ data = self.safe_dict(response, 'data', {})
3555
3557
  depositAddress = self.parse_deposit_address(data, currency)
3556
- options = self.safe_value(self.options, 'fetchDepositAddress', {})
3558
+ options = self.safe_dict(self.options, 'fetchDepositAddress', {})
3557
3559
  fillResponseFromRequest = self.safe_bool(options, 'fillResponseFromRequest', True)
3558
3560
  if fillResponseFromRequest:
3559
3561
  depositAddress['network'] = self.safe_network_code(network, currency)
@@ -3577,11 +3579,11 @@ class coinex(Exchange, ImplicitAPI):
3577
3579
  def parse_deposit_address(self, depositAddress, currency: Currency = None):
3578
3580
  #
3579
3581
  # {
3580
- # "coin_address": "1P1JqozxioQwaqPwgMAQdNDYNyaVSqgARq",
3581
- # "is_bitcoin_cash": False
3582
+ # "address": "1P1JqozxioQwaqPwgMAQdNDYNyaVSqgARq",
3583
+ # "memo": ""
3582
3584
  # }
3583
3585
  #
3584
- coinAddress = self.safe_string(depositAddress, 'coin_address')
3586
+ coinAddress = self.safe_string(depositAddress, 'address')
3585
3587
  parts = coinAddress.split(':')
3586
3588
  address = None
3587
3589
  tag = None
ccxt/coinmetro.py CHANGED
@@ -122,6 +122,7 @@ class coinmetro(Exchange, ImplicitAPI):
122
122
  'reduceMargin': False,
123
123
  'repayCrossMargin': False,
124
124
  'repayIsolatedMargin': False,
125
+ 'sandbox': True,
125
126
  'setLeverage': False,
126
127
  'setMargin': False,
127
128
  'setMarginMode': False,
ccxt/cryptocom.py CHANGED
@@ -117,6 +117,7 @@ class cryptocom(Exchange, ImplicitAPI):
117
117
  'reduceMargin': False,
118
118
  'repayCrossMargin': False,
119
119
  'repayIsolatedMargin': False,
120
+ 'sandbox': True,
120
121
  'setLeverage': False,
121
122
  'setMarginMode': False,
122
123
  'setPositionMode': False,
@@ -509,7 +510,8 @@ class cryptocom(Exchange, ImplicitAPI):
509
510
  strike = self.safe_string(market, 'strike')
510
511
  marginBuyEnabled = self.safe_value(market, 'margin_buy_enabled')
511
512
  marginSellEnabled = self.safe_value(market, 'margin_sell_enabled')
512
- expiry = self.omit_zero(self.safe_integer(market, 'expiry_timestamp_ms'))
513
+ expiryString = self.omit_zero(self.safe_string(market, 'expiry_timestamp_ms'))
514
+ expiry = int(expiryString) if (expiryString is not None) else None
513
515
  symbol = base + '/' + quote
514
516
  type = None
515
517
  contract = None
ccxt/currencycom.py CHANGED
@@ -114,6 +114,7 @@ class currencycom(Exchange, ImplicitAPI):
114
114
  'fetchWithdrawal': None,
115
115
  'fetchWithdrawals': True,
116
116
  'reduceMargin': None,
117
+ 'sandbox': True,
117
118
  'setLeverage': None,
118
119
  'setMarginMode': None,
119
120
  'setPositionMode': None,
ccxt/deribit.py CHANGED
@@ -107,6 +107,7 @@ class deribit(Exchange, ImplicitAPI):
107
107
  'fetchVolatilityHistory': True,
108
108
  'fetchWithdrawal': False,
109
109
  'fetchWithdrawals': True,
110
+ 'sandbox': True,
110
111
  'transfer': True,
111
112
  'withdraw': True,
112
113
  },
ccxt/gate.py CHANGED
@@ -175,6 +175,7 @@ class gate(Exchange, ImplicitAPI):
175
175
  'reduceMargin': True,
176
176
  'repayCrossMargin': True,
177
177
  'repayIsolatedMargin': True,
178
+ 'sandbox': True,
178
179
  'setLeverage': True,
179
180
  'setMarginMode': False,
180
181
  'setPositionMode': True,
ccxt/gemini.py CHANGED
@@ -95,6 +95,7 @@ class gemini(Exchange, ImplicitAPI):
95
95
  'fetchTransactions': 'emulated',
96
96
  'postOnly': True,
97
97
  'reduceMargin': False,
98
+ 'sandbox': True,
98
99
  'setLeverage': False,
99
100
  'setMarginMode': False,
100
101
  'setPositionMode': False,
ccxt/hitbtc.py CHANGED
@@ -108,6 +108,7 @@ class hitbtc(Exchange, ImplicitAPI):
108
108
  'fetchTransactions': 'emulated',
109
109
  'fetchWithdrawals': True,
110
110
  'reduceMargin': True,
111
+ 'sandbox': True,
111
112
  'setLeverage': True,
112
113
  'setMargin': False,
113
114
  'setMarginMode': False,
@@ -632,6 +633,7 @@ class hitbtc(Exchange, ImplicitAPI):
632
633
  'accountsByType': {
633
634
  'spot': 'spot',
634
635
  'funding': 'wallet',
636
+ 'swap': 'derivatives',
635
637
  'future': 'derivatives',
636
638
  },
637
639
  'withdraw': {
ccxt/hollaex.py CHANGED
@@ -96,6 +96,7 @@ class hollaex(Exchange, ImplicitAPI):
96
96
  'fetchWithdrawal': True,
97
97
  'fetchWithdrawals': True,
98
98
  'reduceMargin': False,
99
+ 'sandbox': True,
99
100
  'setLeverage': False,
100
101
  'setMarginMode': False,
101
102
  'setPositionMode': False,
ccxt/hyperliquid.py CHANGED
@@ -113,6 +113,7 @@ class hyperliquid(Exchange, ImplicitAPI):
113
113
  'reduceMargin': True,
114
114
  'repayCrossMargin': False,
115
115
  'repayIsolatedMargin': False,
116
+ 'sandbox': True,
116
117
  'setLeverage': True,
117
118
  'setMarginMode': True,
118
119
  'setPositionMode': False,
@@ -442,6 +443,9 @@ class hyperliquid(Exchange, ImplicitAPI):
442
443
  for i in range(0, len(meta)):
443
444
  market = self.safe_dict(meta, i, {})
444
445
  marketName = self.safe_string(market, 'name')
446
+ if marketName.find('/') < 0:
447
+ # there are some weird spot markets in testnet, eg @2
448
+ continue
445
449
  marketParts = marketName.split('/')
446
450
  baseName = self.safe_string(marketParts, 0)
447
451
  quoteId = self.safe_string(marketParts, 1)
ccxt/idex.py CHANGED
@@ -106,6 +106,7 @@ class idex(Exchange, ImplicitAPI):
106
106
  'fetchWithdrawal': True,
107
107
  'fetchWithdrawals': True,
108
108
  'reduceMargin': False,
109
+ 'sandbox': True,
109
110
  'setLeverage': False,
110
111
  'setMarginMode': False,
111
112
  'setPositionMode': False,
ccxt/krakenfutures.py CHANGED
@@ -86,6 +86,7 @@ class krakenfutures(Exchange, ImplicitAPI):
86
86
  'fetchPremiumIndexOHLCV': False,
87
87
  'fetchTickers': True,
88
88
  'fetchTrades': True,
89
+ 'sandbox': True,
89
90
  'setLeverage': True,
90
91
  'setMarginMode': False,
91
92
  'transfer': True,
ccxt/luno.py CHANGED
@@ -150,6 +150,7 @@ class luno(Exchange, ImplicitAPI):
150
150
  'withdrawals': 1,
151
151
  'send': 1,
152
152
  'oauth2/grant': 1,
153
+ 'beneficiaries': 1,
153
154
  # POST /api/exchange/1/move
154
155
  },
155
156
  'put': {
@@ -157,6 +158,7 @@ class luno(Exchange, ImplicitAPI):
157
158
  },
158
159
  'delete': {
159
160
  'withdrawals/{id}': 1,
161
+ 'beneficiaries/{id}': 1,
160
162
  },
161
163
  },
162
164
  },
ccxt/ndax.py CHANGED
@@ -91,6 +91,7 @@ class ndax(Exchange, ImplicitAPI):
91
91
  'fetchTradingFees': False,
92
92
  'fetchWithdrawals': True,
93
93
  'reduceMargin': False,
94
+ 'sandbox': True,
94
95
  'setLeverage': False,
95
96
  'setMarginMode': False,
96
97
  'setPositionMode': False,
ccxt/okx.py CHANGED
@@ -161,6 +161,7 @@ class okx(Exchange, ImplicitAPI):
161
161
  'fetchWithdrawalWhitelist': False,
162
162
  'reduceMargin': True,
163
163
  'repayCrossMargin': True,
164
+ 'sandbox': True,
164
165
  'setLeverage': True,
165
166
  'setMargin': False,
166
167
  'setMarginMode': True,
ccxt/phemex.py CHANGED
@@ -96,6 +96,7 @@ class phemex(Exchange, ImplicitAPI):
96
96
  'fetchTransfers': True,
97
97
  'fetchWithdrawals': True,
98
98
  'reduceMargin': False,
99
+ 'sandbox': True,
99
100
  'setLeverage': True,
100
101
  'setMargin': True,
101
102
  'setMarginMode': True,
@@ -2299,7 +2300,7 @@ class phemex(Exchange, ImplicitAPI):
2299
2300
  if lastTradeTimestamp == 0:
2300
2301
  lastTradeTimestamp = None
2301
2302
  timeInForce = self.parse_time_in_force(self.safe_string(order, 'timeInForce'))
2302
- stopPrice = self.omit_zero(self.safe_number_2(order, 'stopPx', 'stopPxRp'))
2303
+ stopPrice = self.omit_zero(self.safe_string_2(order, 'stopPx', 'stopPxRp'))
2303
2304
  postOnly = (timeInForce == 'PO')
2304
2305
  reduceOnly = self.safe_value(order, 'reduceOnly')
2305
2306
  execInst = self.safe_string(order, 'execInst')
ccxt/poloniex.py CHANGED
@@ -84,6 +84,7 @@ class poloniex(Exchange, ImplicitAPI):
84
84
  'fetchTransfer': False,
85
85
  'fetchTransfers': False,
86
86
  'fetchWithdrawals': True,
87
+ 'sandbox': True,
87
88
  'transfer': True,
88
89
  'withdraw': True,
89
90
  },
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.14'
7
+ __version__ = '4.3.16'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/hitbtc.py CHANGED
@@ -1123,7 +1123,7 @@ class hitbtc(ccxt.async_support.hitbtc):
1123
1123
  # "id": 1700233093414
1124
1124
  # }
1125
1125
  #
1126
- messageHash = self.safe_integer(message, 'id')
1126
+ messageHash = self.safe_string(message, 'id')
1127
1127
  result = self.safe_value(message, 'result', {})
1128
1128
  if isinstance(result, list):
1129
1129
  parsedOrders = []
@@ -135,9 +135,9 @@ class independentreserve(ccxt.async_support.independentreserve):
135
135
  symbol = market['symbol']
136
136
  if limit is None:
137
137
  limit = 100
138
- limit = self.number_to_string(limit)
139
- url = self.urls['api']['ws'] + '/orderbook/' + limit + '?subscribe=' + market['base'] + '-' + market['quote']
140
- messageHash = 'orderbook:' + symbol + ':' + limit
138
+ limitString = self.number_to_string(limit)
139
+ url = self.urls['api']['ws'] + '/orderbook/' + limitString + '?subscribe=' + market['base'] + '-' + market['quote']
140
+ messageHash = 'orderbook:' + symbol + ':' + limitString
141
141
  subscription = {
142
142
  'receivedSnapshot': False,
143
143
  }
ccxt/pro/poloniex.py CHANGED
@@ -298,7 +298,7 @@ class poloniex(ccxt.async_support.poloniex):
298
298
  # }]
299
299
  # }
300
300
  #
301
- messageHash = self.safe_integer(message, 'id')
301
+ messageHash = self.safe_string(message, 'id')
302
302
  data = self.safe_value(message, 'data', [])
303
303
  orders = []
304
304
  for i in range(0, len(data)):
@@ -606,8 +606,8 @@ class poloniex(ccxt.async_support.poloniex):
606
606
  'type': self.safe_string_lower(trade, 'type'),
607
607
  'side': self.safe_string_lower_2(trade, 'takerSide', 'side'),
608
608
  'takerOrMaker': takerMaker,
609
- 'price': self.omit_zero(self.safe_number_2(trade, 'tradePrice', 'price')),
610
- 'amount': self.omit_zero(self.safe_number_2(trade, 'filledQuantity', 'quantity')),
609
+ 'price': self.omit_zero(self.safe_string_2(trade, 'tradePrice', 'price')),
610
+ 'amount': self.omit_zero(self.safe_string_2(trade, 'filledQuantity', 'quantity')),
611
611
  'cost': self.safe_string_2(trade, 'amount', 'filledAmount'),
612
612
  'fee': {
613
613
  'rate': None,
ccxt/probit.py CHANGED
@@ -101,6 +101,7 @@ class probit(Exchange, ImplicitAPI):
101
101
  'fetchWithdrawal': False,
102
102
  'fetchWithdrawals': True,
103
103
  'reduceMargin': False,
104
+ 'sandbox': True,
104
105
  'setLeverage': False,
105
106
  'setMarginMode': False,
106
107
  'setPositionMode': False,
ccxt/wavesexchange.py CHANGED
@@ -92,6 +92,7 @@ class wavesexchange(Exchange, ImplicitAPI):
92
92
  'fetchTransfer': False,
93
93
  'fetchTransfers': False,
94
94
  'reduceMargin': False,
95
+ 'sandbox': True,
95
96
  'setLeverage': False,
96
97
  'setMarginMode': False,
97
98
  'setPositionMode': False,
ccxt/woo.py CHANGED
@@ -113,6 +113,7 @@ class woo(Exchange, ImplicitAPI):
113
113
  'fetchTransfers': True,
114
114
  'fetchWithdrawals': True,
115
115
  'reduceMargin': False,
116
+ 'sandbox': True,
116
117
  'setLeverage': True,
117
118
  'setMargin': False,
118
119
  'setPositionMode': True,
ccxt/zaif.py CHANGED
@@ -649,7 +649,7 @@ class zaif(Exchange, ImplicitAPI):
649
649
  }
650
650
 
651
651
  def custom_nonce(self):
652
- num = (self.milliseconds() / str(1000))
652
+ num = self.number_to_string(self.milliseconds() / 1000)
653
653
  nonce = float(num)
654
654
  return format(nonce, '.8f')
655
655
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ccxt
3
- Version: 4.3.14
3
+ Version: 4.3.16
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
@@ -262,13 +262,13 @@ console.log(version, Object.keys(exchanges));
262
262
 
263
263
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
264
264
 
265
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.14/dist/ccxt.browser.js
266
- * unpkg: https://unpkg.com/ccxt@4.3.14/dist/ccxt.browser.js
265
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.16/dist/ccxt.browser.js
266
+ * unpkg: https://unpkg.com/ccxt@4.3.16/dist/ccxt.browser.js
267
267
 
268
268
  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.
269
269
 
270
270
  ```HTML
271
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.14/dist/ccxt.browser.js"></script>
271
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.16/dist/ccxt.browser.js"></script>
272
272
  ```
273
273
 
274
274
  Creates a global `ccxt` object: