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

ccxt/__init__.py CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.3.16'
25
+ __version__ = '4.3.17'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.16'
7
+ __version__ = '4.3.17'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.3.16'
5
+ __version__ = '4.3.17'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -2612,7 +2612,7 @@ class binance(Exchange, ImplicitAPI):
2612
2612
  :param dict [params]: extra parameters specific to the exchange API endpoint
2613
2613
  :returns dict: an associative dictionary of currencies
2614
2614
  """
2615
- fetchCurrenciesEnabled = self.safe_value(self.options, 'fetchCurrencies')
2615
+ fetchCurrenciesEnabled = self.safe_bool(self.options, 'fetchCurrencies')
2616
2616
  if not fetchCurrenciesEnabled:
2617
2617
  return None
2618
2618
  # self endpoint requires authentication
@@ -4399,7 +4399,7 @@ class binance(Exchange, ImplicitAPI):
4399
4399
  market = self.safe_market(marketId, market, None, marketType)
4400
4400
  symbol = market['symbol']
4401
4401
  side = None
4402
- buyerMaker = self.safe_value_2(trade, 'm', 'isBuyerMaker')
4402
+ buyerMaker = self.safe_bool_2(trade, 'm', 'isBuyerMaker')
4403
4403
  takerOrMaker = None
4404
4404
  if buyerMaker is not None:
4405
4405
  side = 'sell' if buyerMaker else 'buy' # self is reversed intentionally
@@ -4675,14 +4675,14 @@ class binance(Exchange, ImplicitAPI):
4675
4675
  uppercaseType = 'STOP_LOSS'
4676
4676
  elif uppercaseType == 'LIMIT':
4677
4677
  uppercaseType = 'STOP_LOSS_LIMIT'
4678
- validOrderTypes = self.safe_value(market['info'], 'orderTypes')
4678
+ validOrderTypes = self.safe_list(market['info'], 'orderTypes')
4679
4679
  if not self.in_array(uppercaseType, validOrderTypes):
4680
4680
  if initialUppercaseType != uppercaseType:
4681
4681
  raise InvalidOrder(self.id + ' stopPrice parameter is not allowed for ' + symbol + ' ' + type + ' orders')
4682
4682
  else:
4683
4683
  raise InvalidOrder(self.id + ' ' + type + ' is not a valid order type for the ' + symbol + ' market')
4684
4684
  if clientOrderId is None:
4685
- broker = self.safe_value(self.options, 'broker')
4685
+ broker = self.safe_dict(self.options, 'broker')
4686
4686
  if broker is not None:
4687
4687
  brokerId = self.safe_string(broker, 'spot')
4688
4688
  if brokerId is not None:
@@ -7150,7 +7150,7 @@ class binance(Exchange, ImplicitAPI):
7150
7150
  if until is not None:
7151
7151
  request['endTime'] = until
7152
7152
  raw = await self.sapiGetFiatOrders(self.extend(request, params))
7153
- response = self.safe_value(raw, 'data')
7153
+ response = self.safe_list(raw, 'data', [])
7154
7154
  # {
7155
7155
  # "code": "000000",
7156
7156
  # "message": "success",
@@ -7252,7 +7252,7 @@ class binance(Exchange, ImplicitAPI):
7252
7252
  if since is not None:
7253
7253
  request['beginTime'] = since
7254
7254
  raw = await self.sapiGetFiatOrders(self.extend(request, params))
7255
- response = self.safe_value(raw, 'data')
7255
+ response = self.safe_list(raw, 'data', [])
7256
7256
  # {
7257
7257
  # "code": "000000",
7258
7258
  # "message": "success",
@@ -7459,7 +7459,7 @@ class binance(Exchange, ImplicitAPI):
7459
7459
  txType = self.safe_string(transaction, 'transactionType')
7460
7460
  if txType is not None:
7461
7461
  type = 'deposit' if (txType == '0') else 'withdrawal'
7462
- legalMoneyCurrenciesById = self.safe_value(self.options, 'legalMoneyCurrenciesById')
7462
+ legalMoneyCurrenciesById = self.safe_dict(self.options, 'legalMoneyCurrenciesById')
7463
7463
  code = self.safe_string(legalMoneyCurrenciesById, code, code)
7464
7464
  status = self.parse_transaction_status_by_type(self.safe_string(transaction, 'status'), type)
7465
7465
  amount = self.safe_number(transaction, 'amount')
@@ -7773,7 +7773,7 @@ class binance(Exchange, ImplicitAPI):
7773
7773
  if subLevel is not None:
7774
7774
  topLevel = topLevel + '/' + subLevel
7775
7775
  impliedNetwork = self.safe_string(reverseNetworks, topLevel)
7776
- impliedNetworks = self.safe_value(self.options, 'impliedNetworks', {
7776
+ impliedNetworks = self.safe_dict(self.options, 'impliedNetworks', {
7777
7777
  'ETH': {'ERC20': 'ETH'},
7778
7778
  'TRX': {'TRC20': 'TRX'},
7779
7779
  })
@@ -8981,7 +8981,7 @@ class binance(Exchange, ImplicitAPI):
8981
8981
  await self.load_markets()
8982
8982
  # by default cache the leverage bracket
8983
8983
  # it contains useful stuff like the maintenance margin and initial margin for positions
8984
- leverageBrackets = self.safe_value(self.options, 'leverageBrackets')
8984
+ leverageBrackets = self.safe_dict(self.options, 'leverageBrackets', {})
8985
8985
  if (leverageBrackets is None) or (reload):
8986
8986
  defaultType = self.safe_string(self.options, 'defaultType', 'future')
8987
8987
  type = self.safe_string(params, 'type', defaultType)
@@ -1470,6 +1470,7 @@ class bybit(Exchange, ImplicitAPI):
1470
1470
  # "quoteCoin": "USDT",
1471
1471
  # "innovation": "0",
1472
1472
  # "status": "Trading",
1473
+ # "marginTrading": "both",
1473
1474
  # "lotSizeFilter": {
1474
1475
  # "basePrecision": "0.000001",
1475
1476
  # "quotePrecision": "0.00000001",
@@ -1506,7 +1507,9 @@ class bybit(Exchange, ImplicitAPI):
1506
1507
  lotSizeFilter = self.safe_dict(market, 'lotSizeFilter')
1507
1508
  priceFilter = self.safe_dict(market, 'priceFilter')
1508
1509
  quotePrecision = self.safe_number(lotSizeFilter, 'quotePrecision')
1509
- result.append({
1510
+ marginTrading = self.safe_string(market, 'marginTrading', 'none')
1511
+ allowsMargin = marginTrading != 'none'
1512
+ result.append(self.safe_market_structure({
1510
1513
  'id': id,
1511
1514
  'symbol': symbol,
1512
1515
  'base': base,
@@ -1517,7 +1520,7 @@ class bybit(Exchange, ImplicitAPI):
1517
1520
  'settleId': None,
1518
1521
  'type': 'spot',
1519
1522
  'spot': True,
1520
- 'margin': None,
1523
+ 'margin': allowsMargin,
1521
1524
  'swap': False,
1522
1525
  'future': False,
1523
1526
  'option': False,
@@ -1556,7 +1559,7 @@ class bybit(Exchange, ImplicitAPI):
1556
1559
  },
1557
1560
  'created': None,
1558
1561
  'info': market,
1559
- })
1562
+ }))
1560
1563
  return result
1561
1564
 
1562
1565
  async def fetch_future_markets(self, params):
@@ -1669,7 +1672,7 @@ class bybit(Exchange, ImplicitAPI):
1669
1672
  if expiry is not None:
1670
1673
  symbol = symbol + '-' + self.yymmdd(expiry)
1671
1674
  contractSize = self.safe_number_2(lotSizeFilter, 'minTradingQty', 'minOrderQty') if inverse else self.parse_number('1')
1672
- result.append({
1675
+ result.append(self.safe_market_structure({
1673
1676
  'id': id,
1674
1677
  'symbol': symbol,
1675
1678
  'base': base,
@@ -1719,7 +1722,7 @@ class bybit(Exchange, ImplicitAPI):
1719
1722
  },
1720
1723
  'created': self.safe_integer(market, 'launchTime'),
1721
1724
  'info': market,
1722
- })
1725
+ }))
1723
1726
  return result
1724
1727
 
1725
1728
  async def fetch_option_markets(self, params):
@@ -1797,7 +1800,7 @@ class bybit(Exchange, ImplicitAPI):
1797
1800
  optionLetter = self.safe_string(splitId, 3)
1798
1801
  isActive = (status == 'Trading')
1799
1802
  if isActive or (self.options['loadAllOptions']) or (self.options['loadExpiredOptions']):
1800
- result.append({
1803
+ result.append(self.safe_market_structure({
1801
1804
  'id': id,
1802
1805
  'symbol': base + '/' + quote + ':' + settle + '-' + self.yymmdd(expiry) + '-' + strike + '-' + optionLetter,
1803
1806
  'base': base,
@@ -1847,7 +1850,7 @@ class bybit(Exchange, ImplicitAPI):
1847
1850
  },
1848
1851
  'created': self.safe_integer(market, 'launchTime'),
1849
1852
  'info': market,
1850
- })
1853
+ }))
1851
1854
  return result
1852
1855
 
1853
1856
  def parse_ticker(self, ticker, market: Market = None) -> Ticker:
ccxt/async_support/okx.py CHANGED
@@ -26,6 +26,7 @@ from ccxt.base.errors import CancelPending
26
26
  from ccxt.base.errors import ContractUnavailable
27
27
  from ccxt.base.errors import NotSupported
28
28
  from ccxt.base.errors import NetworkError
29
+ from ccxt.base.errors import DDoSProtection
29
30
  from ccxt.base.errors import RateLimitExceeded
30
31
  from ccxt.base.errors import ExchangeNotAvailable
31
32
  from ccxt.base.errors import OnMaintenance
@@ -913,7 +914,24 @@ class okx(Exchange, ImplicitAPI):
913
914
  '60017': BadRequest, # Invalid url path
914
915
  '60018': BadRequest, # The {0} {1} {2} {3} {4} does not exist
915
916
  '60019': BadRequest, # Invalid op {op}
917
+ '60020': ExchangeError, # APIKey subscription amount exceeds the limit
918
+ '60021': AccountNotEnabled, # This operation does not support multiple accounts login
919
+ '60022': AuthenticationError, # Bulk login partially succeeded
920
+ '60023': DDoSProtection, # Bulk login requests too frequent
921
+ '60024': AuthenticationError, # Wrong passphrase
922
+ '60025': ExchangeError, # Token subscription amount exceeds the limit
923
+ '60026': AuthenticationError, # Batch login by APIKey and token simultaneously is not supported
924
+ '60027': ArgumentsRequired, # Parameter {0} can not be empty
925
+ '60028': NotSupported, # The current operation is not supported by self URL
926
+ '60029': AccountNotEnabled, # Only users who are VIP5 and above in trading fee tier are allowed to subscribe to books-l2-tbt channel
927
+ '60030': AccountNotEnabled, # Only users who are VIP4 and above in trading fee tier are allowed to subscribe to books50-l2-tbt channel
928
+ '60031': AuthenticationError, # The WebSocket endpoint does not support multiple account batch login,
929
+ '60032': AuthenticationError, # API key doesn't exist,
916
930
  '63999': ExchangeError, # Internal system error
931
+ '64000': BadRequest, # Subscription parameter uly is unavailable anymore, please replace uly with instFamily. More details can refer to: https://www.okx.com/help-center/changes-to-v5-api-websocket-subscription-parameter-and-url,
932
+ '64001': BadRequest, # This channel has been migrated to the business URL. Please subscribe using the new URL. More details can refer to: https://www.okx.com/help-center/changes-to-v5-api-websocket-subscription-parameter-and-url,
933
+ '64002': BadRequest, # This channel is not supported by business URL. Please use "/private" URL(for private channels), or "/public" URL(for public channels). More details can refer to: https://www.okx.com/help-center/changes-to-v5-api-websocket-subscription-parameter-and-url,
934
+ '64003': AccountNotEnabled, # Your trading fee tier doesnt meet the requirement to access self channel
917
935
  '70010': BadRequest, # Timestamp parameters need to be in Unix timestamp format in milliseconds.
918
936
  '70013': BadRequest, # endTs needs to be bigger than or equal to beginTs.
919
937
  '70016': BadRequest, # Please specify your instrument settings for at least one instType.
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.16'
7
+ __version__ = '4.3.17'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
ccxt/binance.py CHANGED
@@ -2611,7 +2611,7 @@ class binance(Exchange, ImplicitAPI):
2611
2611
  :param dict [params]: extra parameters specific to the exchange API endpoint
2612
2612
  :returns dict: an associative dictionary of currencies
2613
2613
  """
2614
- fetchCurrenciesEnabled = self.safe_value(self.options, 'fetchCurrencies')
2614
+ fetchCurrenciesEnabled = self.safe_bool(self.options, 'fetchCurrencies')
2615
2615
  if not fetchCurrenciesEnabled:
2616
2616
  return None
2617
2617
  # self endpoint requires authentication
@@ -4398,7 +4398,7 @@ class binance(Exchange, ImplicitAPI):
4398
4398
  market = self.safe_market(marketId, market, None, marketType)
4399
4399
  symbol = market['symbol']
4400
4400
  side = None
4401
- buyerMaker = self.safe_value_2(trade, 'm', 'isBuyerMaker')
4401
+ buyerMaker = self.safe_bool_2(trade, 'm', 'isBuyerMaker')
4402
4402
  takerOrMaker = None
4403
4403
  if buyerMaker is not None:
4404
4404
  side = 'sell' if buyerMaker else 'buy' # self is reversed intentionally
@@ -4674,14 +4674,14 @@ class binance(Exchange, ImplicitAPI):
4674
4674
  uppercaseType = 'STOP_LOSS'
4675
4675
  elif uppercaseType == 'LIMIT':
4676
4676
  uppercaseType = 'STOP_LOSS_LIMIT'
4677
- validOrderTypes = self.safe_value(market['info'], 'orderTypes')
4677
+ validOrderTypes = self.safe_list(market['info'], 'orderTypes')
4678
4678
  if not self.in_array(uppercaseType, validOrderTypes):
4679
4679
  if initialUppercaseType != uppercaseType:
4680
4680
  raise InvalidOrder(self.id + ' stopPrice parameter is not allowed for ' + symbol + ' ' + type + ' orders')
4681
4681
  else:
4682
4682
  raise InvalidOrder(self.id + ' ' + type + ' is not a valid order type for the ' + symbol + ' market')
4683
4683
  if clientOrderId is None:
4684
- broker = self.safe_value(self.options, 'broker')
4684
+ broker = self.safe_dict(self.options, 'broker')
4685
4685
  if broker is not None:
4686
4686
  brokerId = self.safe_string(broker, 'spot')
4687
4687
  if brokerId is not None:
@@ -7149,7 +7149,7 @@ class binance(Exchange, ImplicitAPI):
7149
7149
  if until is not None:
7150
7150
  request['endTime'] = until
7151
7151
  raw = self.sapiGetFiatOrders(self.extend(request, params))
7152
- response = self.safe_value(raw, 'data')
7152
+ response = self.safe_list(raw, 'data', [])
7153
7153
  # {
7154
7154
  # "code": "000000",
7155
7155
  # "message": "success",
@@ -7251,7 +7251,7 @@ class binance(Exchange, ImplicitAPI):
7251
7251
  if since is not None:
7252
7252
  request['beginTime'] = since
7253
7253
  raw = self.sapiGetFiatOrders(self.extend(request, params))
7254
- response = self.safe_value(raw, 'data')
7254
+ response = self.safe_list(raw, 'data', [])
7255
7255
  # {
7256
7256
  # "code": "000000",
7257
7257
  # "message": "success",
@@ -7458,7 +7458,7 @@ class binance(Exchange, ImplicitAPI):
7458
7458
  txType = self.safe_string(transaction, 'transactionType')
7459
7459
  if txType is not None:
7460
7460
  type = 'deposit' if (txType == '0') else 'withdrawal'
7461
- legalMoneyCurrenciesById = self.safe_value(self.options, 'legalMoneyCurrenciesById')
7461
+ legalMoneyCurrenciesById = self.safe_dict(self.options, 'legalMoneyCurrenciesById')
7462
7462
  code = self.safe_string(legalMoneyCurrenciesById, code, code)
7463
7463
  status = self.parse_transaction_status_by_type(self.safe_string(transaction, 'status'), type)
7464
7464
  amount = self.safe_number(transaction, 'amount')
@@ -7772,7 +7772,7 @@ class binance(Exchange, ImplicitAPI):
7772
7772
  if subLevel is not None:
7773
7773
  topLevel = topLevel + '/' + subLevel
7774
7774
  impliedNetwork = self.safe_string(reverseNetworks, topLevel)
7775
- impliedNetworks = self.safe_value(self.options, 'impliedNetworks', {
7775
+ impliedNetworks = self.safe_dict(self.options, 'impliedNetworks', {
7776
7776
  'ETH': {'ERC20': 'ETH'},
7777
7777
  'TRX': {'TRC20': 'TRX'},
7778
7778
  })
@@ -8980,7 +8980,7 @@ class binance(Exchange, ImplicitAPI):
8980
8980
  self.load_markets()
8981
8981
  # by default cache the leverage bracket
8982
8982
  # it contains useful stuff like the maintenance margin and initial margin for positions
8983
- leverageBrackets = self.safe_value(self.options, 'leverageBrackets')
8983
+ leverageBrackets = self.safe_dict(self.options, 'leverageBrackets', {})
8984
8984
  if (leverageBrackets is None) or (reload):
8985
8985
  defaultType = self.safe_string(self.options, 'defaultType', 'future')
8986
8986
  type = self.safe_string(params, 'type', defaultType)
ccxt/bybit.py CHANGED
@@ -1469,6 +1469,7 @@ class bybit(Exchange, ImplicitAPI):
1469
1469
  # "quoteCoin": "USDT",
1470
1470
  # "innovation": "0",
1471
1471
  # "status": "Trading",
1472
+ # "marginTrading": "both",
1472
1473
  # "lotSizeFilter": {
1473
1474
  # "basePrecision": "0.000001",
1474
1475
  # "quotePrecision": "0.00000001",
@@ -1505,7 +1506,9 @@ class bybit(Exchange, ImplicitAPI):
1505
1506
  lotSizeFilter = self.safe_dict(market, 'lotSizeFilter')
1506
1507
  priceFilter = self.safe_dict(market, 'priceFilter')
1507
1508
  quotePrecision = self.safe_number(lotSizeFilter, 'quotePrecision')
1508
- result.append({
1509
+ marginTrading = self.safe_string(market, 'marginTrading', 'none')
1510
+ allowsMargin = marginTrading != 'none'
1511
+ result.append(self.safe_market_structure({
1509
1512
  'id': id,
1510
1513
  'symbol': symbol,
1511
1514
  'base': base,
@@ -1516,7 +1519,7 @@ class bybit(Exchange, ImplicitAPI):
1516
1519
  'settleId': None,
1517
1520
  'type': 'spot',
1518
1521
  'spot': True,
1519
- 'margin': None,
1522
+ 'margin': allowsMargin,
1520
1523
  'swap': False,
1521
1524
  'future': False,
1522
1525
  'option': False,
@@ -1555,7 +1558,7 @@ class bybit(Exchange, ImplicitAPI):
1555
1558
  },
1556
1559
  'created': None,
1557
1560
  'info': market,
1558
- })
1561
+ }))
1559
1562
  return result
1560
1563
 
1561
1564
  def fetch_future_markets(self, params):
@@ -1668,7 +1671,7 @@ class bybit(Exchange, ImplicitAPI):
1668
1671
  if expiry is not None:
1669
1672
  symbol = symbol + '-' + self.yymmdd(expiry)
1670
1673
  contractSize = self.safe_number_2(lotSizeFilter, 'minTradingQty', 'minOrderQty') if inverse else self.parse_number('1')
1671
- result.append({
1674
+ result.append(self.safe_market_structure({
1672
1675
  'id': id,
1673
1676
  'symbol': symbol,
1674
1677
  'base': base,
@@ -1718,7 +1721,7 @@ class bybit(Exchange, ImplicitAPI):
1718
1721
  },
1719
1722
  'created': self.safe_integer(market, 'launchTime'),
1720
1723
  'info': market,
1721
- })
1724
+ }))
1722
1725
  return result
1723
1726
 
1724
1727
  def fetch_option_markets(self, params):
@@ -1796,7 +1799,7 @@ class bybit(Exchange, ImplicitAPI):
1796
1799
  optionLetter = self.safe_string(splitId, 3)
1797
1800
  isActive = (status == 'Trading')
1798
1801
  if isActive or (self.options['loadAllOptions']) or (self.options['loadExpiredOptions']):
1799
- result.append({
1802
+ result.append(self.safe_market_structure({
1800
1803
  'id': id,
1801
1804
  'symbol': base + '/' + quote + ':' + settle + '-' + self.yymmdd(expiry) + '-' + strike + '-' + optionLetter,
1802
1805
  'base': base,
@@ -1846,7 +1849,7 @@ class bybit(Exchange, ImplicitAPI):
1846
1849
  },
1847
1850
  'created': self.safe_integer(market, 'launchTime'),
1848
1851
  'info': market,
1849
- })
1852
+ }))
1850
1853
  return result
1851
1854
 
1852
1855
  def parse_ticker(self, ticker, market: Market = None) -> Ticker:
ccxt/okx.py CHANGED
@@ -25,6 +25,7 @@ from ccxt.base.errors import CancelPending
25
25
  from ccxt.base.errors import ContractUnavailable
26
26
  from ccxt.base.errors import NotSupported
27
27
  from ccxt.base.errors import NetworkError
28
+ from ccxt.base.errors import DDoSProtection
28
29
  from ccxt.base.errors import RateLimitExceeded
29
30
  from ccxt.base.errors import ExchangeNotAvailable
30
31
  from ccxt.base.errors import OnMaintenance
@@ -912,7 +913,24 @@ class okx(Exchange, ImplicitAPI):
912
913
  '60017': BadRequest, # Invalid url path
913
914
  '60018': BadRequest, # The {0} {1} {2} {3} {4} does not exist
914
915
  '60019': BadRequest, # Invalid op {op}
916
+ '60020': ExchangeError, # APIKey subscription amount exceeds the limit
917
+ '60021': AccountNotEnabled, # This operation does not support multiple accounts login
918
+ '60022': AuthenticationError, # Bulk login partially succeeded
919
+ '60023': DDoSProtection, # Bulk login requests too frequent
920
+ '60024': AuthenticationError, # Wrong passphrase
921
+ '60025': ExchangeError, # Token subscription amount exceeds the limit
922
+ '60026': AuthenticationError, # Batch login by APIKey and token simultaneously is not supported
923
+ '60027': ArgumentsRequired, # Parameter {0} can not be empty
924
+ '60028': NotSupported, # The current operation is not supported by self URL
925
+ '60029': AccountNotEnabled, # Only users who are VIP5 and above in trading fee tier are allowed to subscribe to books-l2-tbt channel
926
+ '60030': AccountNotEnabled, # Only users who are VIP4 and above in trading fee tier are allowed to subscribe to books50-l2-tbt channel
927
+ '60031': AuthenticationError, # The WebSocket endpoint does not support multiple account batch login,
928
+ '60032': AuthenticationError, # API key doesn't exist,
915
929
  '63999': ExchangeError, # Internal system error
930
+ '64000': BadRequest, # Subscription parameter uly is unavailable anymore, please replace uly with instFamily. More details can refer to: https://www.okx.com/help-center/changes-to-v5-api-websocket-subscription-parameter-and-url,
931
+ '64001': BadRequest, # This channel has been migrated to the business URL. Please subscribe using the new URL. More details can refer to: https://www.okx.com/help-center/changes-to-v5-api-websocket-subscription-parameter-and-url,
932
+ '64002': BadRequest, # This channel is not supported by business URL. Please use "/private" URL(for private channels), or "/public" URL(for public channels). More details can refer to: https://www.okx.com/help-center/changes-to-v5-api-websocket-subscription-parameter-and-url,
933
+ '64003': AccountNotEnabled, # Your trading fee tier doesnt meet the requirement to access self channel
916
934
  '70010': BadRequest, # Timestamp parameters need to be in Unix timestamp format in milliseconds.
917
935
  '70013': BadRequest, # endTs needs to be bigger than or equal to beginTs.
918
936
  '70016': BadRequest, # Please specify your instrument settings for at least one instType.
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.16'
7
+ __version__ = '4.3.17'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/bitfinex2.py CHANGED
@@ -642,6 +642,8 @@ class bitfinex2(ccxt.async_support.bitfinex2):
642
642
  responseChecksum = self.safe_integer(message, 2)
643
643
  if responseChecksum != localChecksum:
644
644
  error = InvalidNonce(self.id + ' invalid checksum')
645
+ del client.subscriptions[messageHash]
646
+ del self.orderbooks[symbol]
645
647
  client.reject(error, messageHash)
646
648
 
647
649
  async def watch_balance(self, params={}) -> Balances:
ccxt/pro/bitget.py CHANGED
@@ -541,7 +541,10 @@ class bitget(ccxt.async_support.bitget):
541
541
  responseChecksum = self.safe_integer(rawOrderBook, 'checksum')
542
542
  if calculatedChecksum != responseChecksum:
543
543
  error = InvalidNonce(self.id + ' invalid checksum')
544
+ del client.subscriptions[messageHash]
545
+ del self.orderbooks[symbol]
544
546
  client.reject(error, messageHash)
547
+ return
545
548
  else:
546
549
  orderbook = self.order_book({})
547
550
  parsedOrderbook = self.parse_order_book(rawOrderBook, symbol, timestamp)
ccxt/pro/bybit.py CHANGED
@@ -22,11 +22,11 @@ class bybit(ccxt.async_support.bybit):
22
22
  return self.deep_extend(super(bybit, self).describe(), {
23
23
  'has': {
24
24
  'ws': True,
25
- 'createOrderWs': False, # available only in sandbox
26
- 'editOrderWs': False,
25
+ 'createOrderWs': True,
26
+ 'editOrderWs': True,
27
27
  'fetchOpenOrdersWs': False,
28
28
  'fetchOrderWs': False,
29
- 'cancelOrderWs': False,
29
+ 'cancelOrderWs': True,
30
30
  'cancelOrdersWs': False,
31
31
  'cancelAllOrdersWs': False,
32
32
  'fetchTradesWs': False,
ccxt/pro/htx.py CHANGED
@@ -418,6 +418,8 @@ class htx(ccxt.async_support.htx):
418
418
  self.orderbooks[symbol] = orderbook
419
419
  client.resolve(orderbook, messageHash)
420
420
  except Exception as e:
421
+ del client.subscriptions[messageHash]
422
+ del self.orderbooks[symbol]
421
423
  client.reject(e, messageHash)
422
424
 
423
425
  async def watch_order_book_snapshot(self, client, message, subscription):
@@ -213,6 +213,8 @@ class independentreserve(ccxt.async_support.independentreserve):
213
213
  responseChecksum = self.safe_integer(orderBook, 'Crc32')
214
214
  if calculatedChecksum != responseChecksum:
215
215
  error = InvalidNonce(self.id + ' invalid checksum')
216
+ del client.subscriptions[messageHash]
217
+ del self.orderbooks[symbol]
216
218
  client.reject(error, messageHash)
217
219
  if receivedSnapshot:
218
220
  client.resolve(orderbook, messageHash)
ccxt/pro/kraken.py CHANGED
@@ -734,6 +734,8 @@ class kraken(ccxt.async_support.kraken):
734
734
  localChecksum = self.crc32(payload, False)
735
735
  if localChecksum != c:
736
736
  error = InvalidNonce(self.id + ' invalid checksum')
737
+ del client.subscriptions[messageHash]
738
+ del self.orderbooks[symbol]
737
739
  client.reject(error, messageHash)
738
740
  return
739
741
  orderbook['symbol'] = symbol
ccxt/pro/okx.py CHANGED
@@ -9,6 +9,7 @@ import hashlib
9
9
  from ccxt.base.types import Balances, Int, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade
10
10
  from ccxt.async_support.base.ws.client import Client
11
11
  from typing import List
12
+ from ccxt.base.errors import ExchangeError
12
13
  from ccxt.base.errors import AuthenticationError
13
14
  from ccxt.base.errors import ArgumentsRequired
14
15
  from ccxt.base.errors import BadRequest
@@ -424,10 +425,12 @@ class okx(ccxt.async_support.okx):
424
425
 
425
426
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
426
427
  """
428
+ :see: https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-order-book-channel
427
429
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
428
430
  :param str symbol: unified symbol of the market to fetch the order book for
429
431
  :param int [limit]: the maximum amount of order book entries to return
430
432
  :param dict [params]: extra parameters specific to the exchange API endpoint
433
+ :param str [params.depth]: okx order book depth, can be books, books5, books-l2-tbt, books50-l2-tbt, bbo-tbt
431
434
  :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
432
435
  """
433
436
  #
@@ -457,28 +460,30 @@ class okx(ccxt.async_support.okx):
457
460
 
458
461
  async def watch_order_book_for_symbols(self, symbols: List[str], limit: Int = None, params={}) -> OrderBook:
459
462
  """
463
+ :see: https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-order-book-channel
460
464
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
461
465
  :param str[] symbols: unified array of symbols
462
466
  :param int [limit]: 1,5, 400, 50(l2-tbt, vip4+) or 40000(vip5+) the maximum amount of order book entries to return
463
467
  :param dict [params]: extra parameters specific to the exchange API endpoint
468
+ :param str [params.depth]: okx order book depth, can be books, books5, books-l2-tbt, books50-l2-tbt, bbo-tbt
464
469
  :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
465
470
  """
466
471
  await self.load_markets()
467
472
  symbols = self.market_symbols(symbols)
468
- options = self.safe_value(self.options, 'watchOrderBook', {})
469
- depth = self.safe_string(options, 'depth', 'books')
473
+ depth = None
474
+ depth, params = self.handle_option_and_params(params, 'watchOrderBook', 'depth', 'books')
470
475
  if limit is not None:
471
476
  if limit == 1:
472
477
  depth = 'bbo-tbt'
473
478
  elif limit > 1 and limit <= 5:
474
479
  depth = 'books5'
475
- elif limit == 400:
476
- depth = 'books'
477
480
  elif limit == 50:
478
481
  depth = 'books50-l2-tbt' # Make sure you have VIP4 and above
479
- elif limit == 4000:
480
- depth = 'books-l2-tbt' # Make sure you have VIP5 and above
482
+ elif limit == 400:
483
+ depth = 'books'
481
484
  if (depth == 'books-l2-tbt') or (depth == 'books50-l2-tbt'):
485
+ if not self.check_required_credentials(False):
486
+ raise AuthenticationError(self.id + ' watchOrderBook/watchOrderBookForSymbols requires authentication for self depth. Add credentials or change the depth option to books or books5')
482
487
  await self.authenticate({'access': 'public'})
483
488
  topics = []
484
489
  messageHashes = []
@@ -539,6 +544,8 @@ class okx(ccxt.async_support.okx):
539
544
  storedBids = orderbook['bids']
540
545
  self.handle_deltas(storedAsks, asks)
541
546
  self.handle_deltas(storedBids, bids)
547
+ marketId = self.safe_string(message, 'instId')
548
+ symbol = self.safe_symbol(marketId)
542
549
  checksum = self.safe_bool(self.options, 'checksum', True)
543
550
  if checksum:
544
551
  asksLength = len(storedAsks)
@@ -556,6 +563,8 @@ class okx(ccxt.async_support.okx):
556
563
  localChecksum = self.crc32(payload, True)
557
564
  if responseChecksum != localChecksum:
558
565
  error = InvalidNonce(self.id + ' invalid checksum')
566
+ del client.subscriptions[messageHash]
567
+ del self.orderbooks[symbol]
559
568
  client.reject(error, messageHash)
560
569
  timestamp = self.safe_integer(message, 'ts')
561
570
  orderbook['timestamp'] = timestamp
@@ -648,10 +657,10 @@ class okx(ccxt.async_support.okx):
648
657
  # ]
649
658
  # }
650
659
  #
651
- arg = self.safe_value(message, 'arg', {})
660
+ arg = self.safe_dict(message, 'arg', {})
652
661
  channel = self.safe_string(arg, 'channel')
653
662
  action = self.safe_string(message, 'action')
654
- data = self.safe_value(message, 'data', [])
663
+ data = self.safe_list(message, 'data', [])
655
664
  marketId = self.safe_string(arg, 'instId')
656
665
  market = self.safe_market(marketId)
657
666
  symbol = market['symbol']
@@ -1416,23 +1425,18 @@ class okx(ccxt.async_support.okx):
1416
1425
  # {event: 'error', msg: "Illegal request: {"op":"subscribe","args":["spot/ticker:BTC-USDT"]}", code: "60012"}
1417
1426
  # {event: 'error", msg: "channel:ticker,instId:BTC-USDT doesn"t exist", code: "60018"}
1418
1427
  #
1419
- errorCode = self.safe_integer(message, 'code')
1428
+ errorCode = self.safe_string(message, 'code')
1420
1429
  try:
1421
- if errorCode:
1430
+ if errorCode and errorCode != '0':
1422
1431
  feedback = self.id + ' ' + self.json(message)
1423
1432
  self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
1424
1433
  messageString = self.safe_value(message, 'msg')
1425
1434
  if messageString is not None:
1426
1435
  self.throw_broadly_matched_exception(self.exceptions['broad'], messageString, feedback)
1436
+ raise ExchangeError(feedback)
1427
1437
  except Exception as e:
1428
- if isinstance(e, AuthenticationError):
1429
- messageHash = 'authenticated'
1430
- client.reject(e, messageHash)
1431
- if messageHash in client.subscriptions:
1432
- del client.subscriptions[messageHash]
1433
- return False
1434
- else:
1435
- client.reject(e)
1438
+ client.reject(e)
1439
+ return False
1436
1440
  return message
1437
1441
 
1438
1442
  def handle_message(self, client: Client, message):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ccxt
3
- Version: 4.3.16
3
+ Version: 4.3.17
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.16/dist/ccxt.browser.js
266
- * unpkg: https://unpkg.com/ccxt@4.3.16/dist/ccxt.browser.js
265
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.17/dist/ccxt.browser.js
266
+ * unpkg: https://unpkg.com/ccxt@4.3.17/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.16/dist/ccxt.browser.js"></script>
271
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.17/dist/ccxt.browser.js"></script>
272
272
  ```
273
273
 
274
274
  Creates a global `ccxt` object:
@@ -1,10 +1,10 @@
1
- ccxt/__init__.py,sha256=xy1CCCLeDY_rUn0t8MFI3SjgzObRlass9cmISH732ws,15739
1
+ ccxt/__init__.py,sha256=PKQAL6JNGsit5jrG5-x55O0-anLpPCPxDm8zCl6CQKs,15739
2
2
  ccxt/ace.py,sha256=j7Aq0hnsMTcUCIrWCm-ZZMkptWzAY23D8zi3jZWjq3c,41650
3
3
  ccxt/alpaca.py,sha256=NadHil-XkNFteqE7GwzIhKCCRjQ7m0xBQBCUlKxS6Sc,47215
4
4
  ccxt/ascendex.py,sha256=0W7umzuDzp6_DRcESoL7IAiBapPNMaAJ13R04SgqbbQ,151431
5
5
  ccxt/bequant.py,sha256=RBiAmaTbL35DgiV3Hl6uchLUd78V0z1T9riTlNsrpdc,1174
6
6
  ccxt/bigone.py,sha256=e9bOBUENqxUI1IjcCRBpc_eb7CilAxgk0tHGguESOEU,92168
7
- ccxt/binance.py,sha256=O_hDjDKKNaa6_ctIeGtzUwJm1b0pN5vo6wVUkafgTh4,615715
7
+ ccxt/binance.py,sha256=cZMky2HgTBh6svMy-xe7PWfWgY_JYvjfVPCGgK4R7F4,615718
8
8
  ccxt/binancecoinm.py,sha256=pncdw6Xw2X1Po-vEvAB4nL37scoS_axGAVxetPy1YQs,1645
9
9
  ccxt/binanceus.py,sha256=hdcT4OnadcdFFFjF3GtM0nWv90jqojqwdVS3xWGuW40,9163
10
10
  ccxt/binanceusdm.py,sha256=KPQGlCalQ0eGlPCs2tSanOxaP8O0zFRQjGntA16Yprw,2480
@@ -35,7 +35,7 @@ ccxt/btcalpha.py,sha256=9cjW8u3j3L5Jok3G0_WbILreo5MG40yo7OxNTkArewY,36695
35
35
  ccxt/btcbox.py,sha256=fI62e8f0CBMbSrVD1Cukk2SHcd4o4PcNfiEEbrIUETQ,23486
36
36
  ccxt/btcmarkets.py,sha256=R_LqHslDyQeJ6rQdN3sH02ICf4M91Dt_MegrpEi19lY,51478
37
37
  ccxt/btcturk.py,sha256=yz2w0eRyWju4znaIovBkVrQN-mjm3XlR_5F7AmQaogU,36651
38
- ccxt/bybit.py,sha256=8RbeV8se-l3nvhJkwiiQRcfpJsCUN6nTzddTayqGqsM,410667
38
+ ccxt/bybit.py,sha256=sKnsMLGA2Il8ZCqDJm81z7jWE31J0WUQ148Vur3C4I0,410943
39
39
  ccxt/cex.py,sha256=nIBZhdCtCeKLapnwHDZ9QSkjoIlgLmTggh-7BTEL3ug,69924
40
40
  ccxt/coinbase.py,sha256=zrPkfEPaiX8LVfqpQ7VoLtefxZmOPMoBASlLa4v9wtk,211987
41
41
  ccxt/coinbaseinternational.py,sha256=wieWUwsLsBYAgNpvnnrKseqAE7aOw__apSP6MQK9u9E,87240
@@ -83,7 +83,7 @@ ccxt/ndax.py,sha256=fRer4mSYS3N3xXuxu2xWxmjJBgHnzoUswxdQY7bsBp8,108595
83
83
  ccxt/novadax.py,sha256=h9U_ckSCN4ZDgvXrrb7MmcOTioqG_3DsmR-2Gjpx6yw,64299
84
84
  ccxt/oceanex.py,sha256=YH3tUzegvfG0fUCjtmtb3USOQtlL1tlqQ40B_i-xx7w,37860
85
85
  ccxt/okcoin.py,sha256=oJDR1yRlV_3HlgI6Uii6zr5cKDg9IaUSrhdlJZAXIMc,151110
86
- ccxt/okx.py,sha256=LP-uNcZcJFPHxSGyvANLtYglDpb6AH6VsRxKUCHnd5M,373734
86
+ ccxt/okx.py,sha256=F8sNPwwRGtvS-08nhn2bwlCFiIrdLLG8tsSVjzUHy0o,376031
87
87
  ccxt/onetrading.py,sha256=T68x4qfncbcnXU-YdMTVEGwnr3zKvcbbfdQZa8Zourc,88107
88
88
  ccxt/p2b.py,sha256=FYxL36KwtaLIIQ793frJEtqtHyzm39hNK0mJEzAAH0U,54213
89
89
  ccxt/paymium.py,sha256=2mBwmyT93k-dXBEKEix48G8PsA2IEN_5yScEM985Z10,24203
@@ -206,13 +206,13 @@ ccxt/abstract/woo.py,sha256=yH0aXeyohXdyS3jZrztapwRmzNWk7JGpbrrf7pX_LKU,10368
206
206
  ccxt/abstract/yobit.py,sha256=8ycfCO8ORFly9hc0Aa47sZyX4_ZKPXS9h9yJzI-uQ7Q,1339
207
207
  ccxt/abstract/zaif.py,sha256=m15WHdl3gYy0GOXNZ8NEH8eE7sVh8c0T_ITNuU8vXeU,3935
208
208
  ccxt/abstract/zonda.py,sha256=aSfewvRojzmuymX6QbOnDR8v9VFqWTULMHX9Y7kKD1M,5820
209
- ccxt/async_support/__init__.py,sha256=4q-OrADm90JR3prA3kpYzsqUSn_HB_I8csdwd_pxQjw,15492
209
+ ccxt/async_support/__init__.py,sha256=Y04DLbQkLgyTS0mRwYr_NqgwFkc1i8LkMmxTc9vDhqQ,15492
210
210
  ccxt/async_support/ace.py,sha256=FNZKajNtvFhDEmBYzgv46pGMwvHbPQcqhsWRpAk9iwU,41874
211
211
  ccxt/async_support/alpaca.py,sha256=rjD8PdQr1B5e9hvaoTQBKVtWwHLs04e6_-gooXl4eEE,47427
212
212
  ccxt/async_support/ascendex.py,sha256=pprQOgeyclQtFMPtXmTMyXj_WU5PIn9rOfBZi8fxmLs,152219
213
213
  ccxt/async_support/bequant.py,sha256=1hTwHovo1bW1XTIc8ZKjvJ-Xg6LfmpGdzT7TepykaVM,1188
214
214
  ccxt/async_support/bigone.py,sha256=VRcmcf65P0Uw-EpEf78u_KQdE9J6MVOKdd311z-thRA,92622
215
- ccxt/async_support/binance.py,sha256=lFhG_094X4l6JlMPbP5xtGDggTPUTZOOzsJLSXHjj-w,618413
215
+ ccxt/async_support/binance.py,sha256=7yqKN2HLM4FB6QkyVK8zMEGdbZ_U2GLSKB7ua_ykkyw,618416
216
216
  ccxt/async_support/binancecoinm.py,sha256=IY3RLZptQA2nmZaUYRGfTa5ZY4VMWBpFYfwHc8zTHw0,1683
217
217
  ccxt/async_support/binanceus.py,sha256=c-K3Tk7LaRJjmYdCx8vBOqsx01uXrtvt0PC2ekBiD0g,9177
218
218
  ccxt/async_support/binanceusdm.py,sha256=-1r4A4tmV2pCiLGO80hzq7MIIj4MTzOD7buZGv6JauA,2518
@@ -243,7 +243,7 @@ ccxt/async_support/btcalpha.py,sha256=tfGT1xE4_tgWhyBx5UMiwhll-xf5FWx7NZZ6v7dOt1
243
243
  ccxt/async_support/btcbox.py,sha256=DUVQQhJSlH9QCg3RToVL4cSUtFsRomArZIav1YdLxzo,23680
244
244
  ccxt/async_support/btcmarkets.py,sha256=aHWHZNsllU8dBEUPGLe78K3B0X_Q1f0PGYS7TUSSwUM,51828
245
245
  ccxt/async_support/btcturk.py,sha256=tkhs24jrrjhiwPvzmAXSGZVnmrlvQxqfIi3PCP-iwN0,36869
246
- ccxt/async_support/bybit.py,sha256=slXYI_zo1G_mxFgmr0-Fhi8IPJjTVjQii0VL_z0JjoE,412447
246
+ ccxt/async_support/bybit.py,sha256=y1_dRiMEqhvrV0X4oq10WcbD3vZzvQv6ZbRjgXgYb5Q,412723
247
247
  ccxt/async_support/cex.py,sha256=28Bixn0KAtlz-I171izhzgxR59sOx0tMV6d32XUkOnY,70274
248
248
  ccxt/async_support/coinbase.py,sha256=TQiVDuE9ga8gwmmmFG1bpollPCoUcE3UWiNtmlbW-tM,213093
249
249
  ccxt/async_support/coinbaseinternational.py,sha256=fuU-h5UpO_nVs1j8KA7oGsQlP0kQefuPycZrc8ph6OQ,87794
@@ -291,7 +291,7 @@ ccxt/async_support/ndax.py,sha256=k6qSVA0603yWrVi9GzqSjqjg544ZDdonmMQ_Qfs5yBE,10
291
291
  ccxt/async_support/novadax.py,sha256=ttRfw2h1Nc-9RUgBHefTuAPLUNjp9hxfxZTxoJDViwQ,64667
292
292
  ccxt/async_support/oceanex.py,sha256=aYdYRl42FDFpaPaoLaiGYxvDM_7aq0dEjAhUa0NsJQQ,38180
293
293
  ccxt/async_support/okcoin.py,sha256=HQSAZdG_yFP9oHyJYJaZrWsRZ9IHB6qrIgDp4b0zetA,151634
294
- ccxt/async_support/okx.py,sha256=iota_nLiZQUN668q_hy6T3qEFSwnNOlqNA9kSHAASUw,375321
294
+ ccxt/async_support/okx.py,sha256=awEvYKTM2_ogU-66MXgIQ6lUJ2BGWVvBJLG7lzjP-04,377618
295
295
  ccxt/async_support/onetrading.py,sha256=2O3d2_E-oUZABQEyR9igcke0AJ-to-_J9579iDyGKfo,88559
296
296
  ccxt/async_support/p2b.py,sha256=KrNc3sLbHQCxbgShyqWytuQVaQfKa42Q6_HcUYNUaKI,54455
297
297
  ccxt/async_support/paymium.py,sha256=3P1J9OcDOqQKG5fUs6Xte9Xu8NB5lWu-OD-AHHGZbkM,24391
@@ -311,7 +311,7 @@ ccxt/async_support/yobit.py,sha256=6eqYOcSBmXhJgcKDRMj8oRH_7aoz2E21hxgzvA1TzrA,5
311
311
  ccxt/async_support/zaif.py,sha256=laP7nbqRvoVT8u829fgoI5Svm3AUSlII_5WjRvhVNvM,28155
312
312
  ccxt/async_support/zonda.py,sha256=nHlJJSlr_zBSiw4WrKOp2FbO33_UFMK5YyLuf2Pvjr0,80871
313
313
  ccxt/async_support/base/__init__.py,sha256=aVYSsFi--b4InRs9zDN_wtCpj8odosAB726JdUHavrk,67
314
- ccxt/async_support/base/exchange.py,sha256=VT4JVwrI3bBTDFVkBhaDLCC_MUdl9zYK3lgwthnnuCY,107442
314
+ ccxt/async_support/base/exchange.py,sha256=eIyMM5IaCh3jzSC6Z2deT1uxKn1GJw2ulZDGP363WKg,107442
315
315
  ccxt/async_support/base/throttler.py,sha256=tvDVcdRUVYi8fZRlEcnqtgzcgB_KMUMRs5Pu8tuU-tU,1847
316
316
  ccxt/async_support/base/ws/__init__.py,sha256=uockzpLuwntKGZbs5EOWFe-Zg-k6Cj7GhNJLc_RX0so,1791
317
317
  ccxt/async_support/base/ws/aiohttp_client.py,sha256=Ed1765emEde2Hj8Ys6f5EjS54ZI1wQ0qIhd04eB7yhU,5751
@@ -325,10 +325,10 @@ ccxt/async_support/base/ws/order_book_side.py,sha256=Pxrq22nCODckJ6G1OXkYEmUunIu
325
325
  ccxt/base/__init__.py,sha256=eTx1OE3HJjspFUQjGm6LBhaQiMKJnXjkdP-JUXknyQ0,1320
326
326
  ccxt/base/decimal_to_precision.py,sha256=fgWRBzRTtsf3r2INyS4f7WHlzgjB5YM1ekiwqD21aac,6634
327
327
  ccxt/base/errors.py,sha256=FGdyULeNCNcl52gA_CNhe2dZmat9GJGkTdlIyDXAF_A,4213
328
- ccxt/base/exchange.py,sha256=R_jwU6bcDjJl0WlxmEencYBxq8kgqxSn_dwpycBFp3c,275941
328
+ ccxt/base/exchange.py,sha256=5kQbE3fgKdj5aFz6SVd6d1z-xUf1je6PgRWwnT6QKs8,275941
329
329
  ccxt/base/precise.py,sha256=_xfu54sV0vWNnOfGTKRFykeuWP8mn4K1m9lk1tcllX4,8565
330
330
  ccxt/base/types.py,sha256=m9kkJ1elksA8JwVeoSZyL6BBH4qu3l8h5zhi3W22-1o,8495
331
- ccxt/pro/__init__.py,sha256=1h-K2wsvAiyjB0quVK85cQgyG0WFoYBtA53fNZUPF5Y,6999
331
+ ccxt/pro/__init__.py,sha256=dWwwODlWmY4G_Af9c7IGkWY6cJpt59GEJK1WjcHsZlc,6999
332
332
  ccxt/pro/alpaca.py,sha256=7ePyWli0949ti5UheIn553xmnFpedrNc2W5CKauSZio,27167
333
333
  ccxt/pro/ascendex.py,sha256=fCM3EujSfJvtvffqI56UAstTtwjXFIocwukm15cF8rE,35432
334
334
  ccxt/pro/bequant.py,sha256=5zbsP8BHQTUZ8ZNL6uaACxDbUClgkOV4SYfXT_LfQVg,1351
@@ -339,8 +339,8 @@ ccxt/pro/binanceusdm.py,sha256=S0eT662O2ReplsihWk42nhJWqw1XsODpeDQa9eFVVt8,1357
339
339
  ccxt/pro/bingx.py,sha256=DX-_TEWhTSi__zP865UUM0DqnEO9VO6KHysLiVr2JpE,42110
340
340
  ccxt/pro/bitcoincom.py,sha256=zAX6hiz4hS6Un8dSGp88rpnvItxQHfNmsfF0IZ2xIVA,1181
341
341
  ccxt/pro/bitfinex.py,sha256=VdvMikgWO7htYSAEKmGkDBYISWCJon1bnkv3JkV4nv0,24826
342
- ccxt/pro/bitfinex2.py,sha256=jxWqkZu_gVf-_S2HB3UnGdllHvgb6WerkaQY78fOdgY,42744
343
- ccxt/pro/bitget.py,sha256=TCKf4m_dFL6F8KwB7NsD_068LGi3hCZb1CimMY-xkYE,73862
342
+ ccxt/pro/bitfinex2.py,sha256=9_N-a4eyiOndD1_1qRDEH7_02U75K1dH7qOYu8M5xUg,42834
343
+ ccxt/pro/bitget.py,sha256=RwkWzvkJGVhnSFQZG9_CT9KuZQkiQOsNLyFxCvhRcF0,73995
344
344
  ccxt/pro/bithumb.py,sha256=xMFS5eOYLAdqePz2Tcwu76qG_k7XbgnUjW9hKDehBjA,16799
345
345
  ccxt/pro/bitmart.py,sha256=Jyp-MyCUlvLDcMgz4Y8Dbjm8FJkjc79iLCBLgjYJHwc,62382
346
346
  ccxt/pro/bitmex.py,sha256=EJ_M666RDhhKal8umRKTbYZHCqHrrkRbWnOCzSEe3kI,68956
@@ -350,7 +350,7 @@ ccxt/pro/bitrue.py,sha256=gPN1lVaDZ4IBYGhaS-1WCkcNQ5__RMbtn2dC2sKZUI4,16448
350
350
  ccxt/pro/bitstamp.py,sha256=nlqEaAMHpFI-FbQBXnvBee6DW0LcZRprJ8Sp8bIzsSs,20886
351
351
  ccxt/pro/bitvavo.py,sha256=5xzpVRMcI2z0r41eoN-NORr5-qQYBao_bMsH8all9Q0,56143
352
352
  ccxt/pro/blockchaincom.py,sha256=Uv1ijvxvFGrqFPH6iifCk5AgQYTDsXUa5n0ktpusVjM,29560
353
- ccxt/pro/bybit.py,sha256=fgsR5e-X4rY7gVBKx01p0DqiDtpa3HJgIt6eZFxQal8,85090
353
+ ccxt/pro/bybit.py,sha256=4NoyThWt5wiIwGU8NGx311Y_TzWb3umusv4bfX-dPNI,85058
354
354
  ccxt/pro/cex.py,sha256=psU0k-icE931Z_wpkr16IdSZ2iDUwLnqJz3KUmQ5Xls,58380
355
355
  ccxt/pro/coinbase.py,sha256=j1iI52eNa-qya7Q7BZCpd1SAJQZc4LEGu25DIu0LMwo,29324
356
356
  ccxt/pro/coinbaseinternational.py,sha256=9Pbe6je_6nqA7SviyzmcR_4CscKdQzBYNLECOYJ4BoU,25428
@@ -367,13 +367,13 @@ ccxt/pro/gateio.py,sha256=_uBWXYQbmsHRivKnZOJDmxJ9tWLO_0HAxmOjAEUy9nE,391
367
367
  ccxt/pro/gemini.py,sha256=a8yZNyLnv1VI6FPhSK-d8MzG7wEX60wL8uUJrqeWmOI,36641
368
368
  ccxt/pro/hitbtc.py,sha256=JLlqcR0h6yz02FPZ2zT_hC1QEyvMwtkej4jnaDp7XE8,56284
369
369
  ccxt/pro/hollaex.py,sha256=q233J-P83OZj1DN_WRRgoq2gfur5AjlW2krlkKUoQTs,21957
370
- ccxt/pro/htx.py,sha256=tP7x0sgQqj4S2CP05nUmoq0k-DWe3okQpStSwx7SuqU,95779
370
+ ccxt/pro/htx.py,sha256=mC9zvrtdCjG8dHBx_zOTlJATqsYw8wDLKm-gCe2gQck,95869
371
371
  ccxt/pro/huobi.py,sha256=rKZVgYqEr-MmZzTqAk4FoJt8qWFjCi_FY0ci_mWZrL0,385
372
372
  ccxt/pro/huobijp.py,sha256=fcC66ECLwrR9LN_AYZZltoE_w9EltT5DcXimPOHKJk0,23174
373
373
  ccxt/pro/hyperliquid.py,sha256=V6ev_19ttD0jmlaejvJwTl429_K1eyt0O3mUusQcrgk,20791
374
374
  ccxt/pro/idex.py,sha256=MJWG56eMN8rAE4Tmz-WxXDDO2KacfY7eFSoCwL15DnQ,28282
375
- ccxt/pro/independentreserve.py,sha256=QuEULuFQN-769Tga3JjucFYlo8Ifui4LSl5RMDnTJ1Q,11081
376
- ccxt/pro/kraken.py,sha256=YCC_Qtq-C3Ds-reEkkF2qpEh_XY1zUV3SLVzEGKkko8,60658
375
+ ccxt/pro/independentreserve.py,sha256=39qWY0BpNoOfTpunMA9gwBePU8Ney6SO_zVuDy4uWLM,11179
376
+ ccxt/pro/kraken.py,sha256=e4VgjQXUAJaWaCQf2r2PG8qBYjriDYhil-Enx8VTs5E,60764
377
377
  ccxt/pro/krakenfutures.py,sha256=QTeLsAXmM3CxLbDI6ktESj8LYQYhJISsB95Za1nFzh8,63917
378
378
  ccxt/pro/kucoin.py,sha256=wxUoyXjTV0iU5X4C2EdWRFFTzljICccpRJq4b9MWmmg,50705
379
379
  ccxt/pro/kucoinfutures.py,sha256=sjhdtLP8WMisETvXnl6TP1xVx7TK5iP0x0R4LE7M7gI,46006
@@ -382,7 +382,7 @@ ccxt/pro/luno.py,sha256=2Y-8IQrrmwX8Y1lLWVDtrFjZD3t3qtMZJQ_JjNwj65s,12348
382
382
  ccxt/pro/mexc.py,sha256=caL4b1Q1YEJsKKQG5mmscqacYfkbyUuN0xin00eYPoc,43183
383
383
  ccxt/pro/ndax.py,sha256=Yrdy4UxjrDwO7gNMmSy09Wj6kHnRx1n0DTWmfirMEj8,22643
384
384
  ccxt/pro/okcoin.py,sha256=F38UBVjH2O7v6-XZMr5eJytnyBLp-0Uzx8q4qle_gXs,30385
385
- ccxt/pro/okx.py,sha256=3mwiUgBWsGLUhNQ3eXqdmlCbcL9Ni-7PuPjBEpHtA90,68821
385
+ ccxt/pro/okx.py,sha256=IuNV74OptcXq8XDcyg8yWLXODBSyQL_KS5d2nXD1O-0,69412
386
386
  ccxt/pro/onetrading.py,sha256=9-WTi6ZNjsG7TJ6CA6pGpnm_6Jg2gg21ny4GZypjr6s,54634
387
387
  ccxt/pro/p2b.py,sha256=lO8mTtBCOU1yHQnmOQAI3USn67tsZd4nTGHDqFd4qEE,17877
388
388
  ccxt/pro/phemex.py,sha256=lD4r2KQdpkgeXGors3jtEMxoaxpEF0tl6MYXZ99GSYg,61032
@@ -527,7 +527,7 @@ ccxt/test/base/test_ticker.py,sha256=cMTIMb1oySNORUCmqI5ZzMswlEyCF6gJMah3vfvo8wQ
527
527
  ccxt/test/base/test_trade.py,sha256=PMtmB8V38dpaP-eb8h488xYMlR6D69yCOhsA1RuWrUA,2336
528
528
  ccxt/test/base/test_trading_fee.py,sha256=2aDCNJtqBkTC_AieO0l1HYGq5hz5qkWlkWb9Nv_fcwk,1066
529
529
  ccxt/test/base/test_transaction.py,sha256=BTbB4UHHXkrvYgwbrhh867nVRlevmIkIrz1W_odlQJI,1434
530
- ccxt-4.3.16.dist-info/METADATA,sha256=jTXsNwLaoh5av5hqLC7k9AwMX1rB1YKAIo5WLqRsisQ,111193
531
- ccxt-4.3.16.dist-info/WHEEL,sha256=P2T-6epvtXQ2cBOE_U1K4_noqlJFN3tj15djMgEu4NM,110
532
- ccxt-4.3.16.dist-info/top_level.txt,sha256=CkQDuCTDKNcImPV60t36G6MdYfxsAPNiSaEwifVoVMo,5
533
- ccxt-4.3.16.dist-info/RECORD,,
530
+ ccxt-4.3.17.dist-info/METADATA,sha256=HRHCQ3Fhs6cUkhBCII7DgbkQBCMlupOWdLXaER_lBXA,111193
531
+ ccxt-4.3.17.dist-info/WHEEL,sha256=P2T-6epvtXQ2cBOE_U1K4_noqlJFN3tj15djMgEu4NM,110
532
+ ccxt-4.3.17.dist-info/top_level.txt,sha256=CkQDuCTDKNcImPV60t36G6MdYfxsAPNiSaEwifVoVMo,5
533
+ ccxt-4.3.17.dist-info/RECORD,,
File without changes