ccxt 4.2.58__py2.py3-none-any.whl → 4.2.60__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (68) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/blofin.py +1 -0
  3. ccxt/abstract/kraken.py +37 -37
  4. ccxt/abstract/wazirx.py +6 -1
  5. ccxt/ascendex.py +10 -12
  6. ccxt/async_support/__init__.py +1 -1
  7. ccxt/async_support/ascendex.py +10 -12
  8. ccxt/async_support/base/exchange.py +1 -1
  9. ccxt/async_support/binance.py +2 -2
  10. ccxt/async_support/bingx.py +40 -4
  11. ccxt/async_support/bitfinex2.py +20 -3
  12. ccxt/async_support/bitget.py +8 -3
  13. ccxt/async_support/bitmart.py +40 -23
  14. ccxt/async_support/bitmex.py +1 -1
  15. ccxt/async_support/blofin.py +53 -3
  16. ccxt/async_support/coinbase.py +21 -12
  17. ccxt/async_support/hitbtc.py +1 -1
  18. ccxt/async_support/htx.py +3 -1
  19. ccxt/async_support/kraken.py +42 -39
  20. ccxt/async_support/kucoinfutures.py +1 -0
  21. ccxt/async_support/lbank.py +1 -1
  22. ccxt/async_support/mexc.py +1 -1
  23. ccxt/async_support/okx.py +1 -1
  24. ccxt/async_support/phemex.py +1 -1
  25. ccxt/async_support/wazirx.py +6 -1
  26. ccxt/async_support/woo.py +148 -76
  27. ccxt/base/exchange.py +3 -1
  28. ccxt/binance.py +2 -2
  29. ccxt/bingx.py +40 -4
  30. ccxt/bitfinex2.py +20 -3
  31. ccxt/bitget.py +8 -3
  32. ccxt/bitmart.py +40 -23
  33. ccxt/bitmex.py +1 -1
  34. ccxt/blofin.py +53 -3
  35. ccxt/coinbase.py +21 -12
  36. ccxt/hitbtc.py +1 -1
  37. ccxt/htx.py +3 -1
  38. ccxt/kraken.py +42 -39
  39. ccxt/kucoinfutures.py +1 -0
  40. ccxt/lbank.py +1 -1
  41. ccxt/mexc.py +1 -1
  42. ccxt/okx.py +1 -1
  43. ccxt/phemex.py +1 -1
  44. ccxt/pro/__init__.py +1 -1
  45. ccxt/pro/binance.py +12 -3
  46. ccxt/pro/bitfinex2.py +1 -1
  47. ccxt/pro/bitget.py +1 -1
  48. ccxt/pro/bitmart.py +44 -78
  49. ccxt/pro/bitvavo.py +1 -1
  50. ccxt/pro/bybit.py +1 -1
  51. ccxt/pro/coinex.py +1 -1
  52. ccxt/pro/cryptocom.py +1 -1
  53. ccxt/pro/deribit.py +188 -84
  54. ccxt/pro/gate.py +1 -1
  55. ccxt/pro/independentreserve.py +1 -1
  56. ccxt/pro/kraken.py +1 -1
  57. ccxt/pro/kucoinfutures.py +1 -1
  58. ccxt/pro/mexc.py +5 -4
  59. ccxt/pro/okx.py +1 -1
  60. ccxt/pro/woo.py +1 -1
  61. ccxt/test/test_async.py +4 -4
  62. ccxt/test/test_sync.py +4 -4
  63. ccxt/wazirx.py +6 -1
  64. ccxt/woo.py +148 -76
  65. {ccxt-4.2.58.dist-info → ccxt-4.2.60.dist-info}/METADATA +4 -4
  66. {ccxt-4.2.58.dist-info → ccxt-4.2.60.dist-info}/RECORD +68 -68
  67. {ccxt-4.2.58.dist-info → ccxt-4.2.60.dist-info}/WHEEL +0 -0
  68. {ccxt-4.2.58.dist-info → ccxt-4.2.60.dist-info}/top_level.txt +0 -0
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.blofin import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, Leverage, Market, Order, TransferEntry, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, Transaction
9
+ from ccxt.base.types import Balances, Currency, Int, Leverage, Leverages, Market, Order, TransferEntry, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import ArgumentsRequired
@@ -89,6 +89,7 @@ class blofin(Exchange, ImplicitAPI):
89
89
  'fetchLedger': True,
90
90
  'fetchLedgerEntry': None,
91
91
  'fetchLeverage': True,
92
+ 'fetchLeverages': True,
92
93
  'fetchLeverageTiers': False,
93
94
  'fetchMarketLeverageTiers': False,
94
95
  'fetchMarkets': True,
@@ -193,6 +194,7 @@ class blofin(Exchange, ImplicitAPI):
193
194
  'account/balance': 1,
194
195
  'account/positions': 1,
195
196
  'account/leverage-info': 1,
197
+ 'account/batch-leverage-info': 1,
196
198
  'trade/orders-tpsl-pending': 1,
197
199
  'trade/orders-history': 1,
198
200
  'trade/orders-tpsl-history': 1,
@@ -491,7 +493,7 @@ class blofin(Exchange, ImplicitAPI):
491
493
  symbol = market['symbol']
492
494
  last = self.safe_string(ticker, 'last')
493
495
  open = self.safe_string(ticker, 'open24h')
494
- spot = self.safe_value(market, 'spot', False)
496
+ spot = self.safe_bool(market, 'spot', False)
495
497
  quoteVolume = self.safe_string(ticker, 'volCurrency24h') if spot else None
496
498
  baseVolume = self.safe_string(ticker, 'vol24h')
497
499
  high = self.safe_string(ticker, 'high24h')
@@ -1757,10 +1759,58 @@ class blofin(Exchange, ImplicitAPI):
1757
1759
  'takeProfitPrice': None,
1758
1760
  })
1759
1761
 
1762
+ async def fetch_leverages(self, symbols: List[str] = None, params={}) -> Leverages:
1763
+ """
1764
+ fetch the set leverage for all contract markets
1765
+ :see: https://docs.blofin.com/index.html#get-multiple-leverage
1766
+ :param str[] symbols: a list of unified market symbols, required on blofin
1767
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1768
+ :param str [params.marginMode]: 'cross' or 'isolated'
1769
+ :returns dict: a list of `leverage structures <https://docs.ccxt.com/#/?id=leverage-structure>`
1770
+ """
1771
+ await self.load_markets()
1772
+ if symbols is None:
1773
+ raise ArgumentsRequired(self.id + ' fetchLeverages() requires a symbols argument')
1774
+ marginMode = None
1775
+ marginMode, params = self.handle_margin_mode_and_params('fetchLeverages', params)
1776
+ if marginMode is None:
1777
+ marginMode = self.safe_string(params, 'marginMode', 'cross') # cross marginMode
1778
+ if (marginMode != 'cross') and (marginMode != 'isolated'):
1779
+ raise BadRequest(self.id + ' fetchLeverages() requires a marginMode parameter that must be either cross or isolated')
1780
+ symbols = self.market_symbols(symbols)
1781
+ instIds = ''
1782
+ for i in range(0, len(symbols)):
1783
+ entry = symbols[i]
1784
+ entryMarket = self.market(entry)
1785
+ if i > 0:
1786
+ instIds = instIds + ',' + entryMarket['id']
1787
+ else:
1788
+ instIds = instIds + entryMarket['id']
1789
+ request = {
1790
+ 'instId': instIds,
1791
+ 'marginMode': marginMode,
1792
+ }
1793
+ response = await self.privateGetAccountBatchLeverageInfo(self.extend(request, params))
1794
+ #
1795
+ # {
1796
+ # "code": "0",
1797
+ # "msg": "success",
1798
+ # "data": [
1799
+ # {
1800
+ # "leverage": "3",
1801
+ # "marginMode": "cross",
1802
+ # "instId": "BTC-USDT"
1803
+ # },
1804
+ # ]
1805
+ # }
1806
+ #
1807
+ leverages = self.safe_list(response, 'data', [])
1808
+ return self.parse_leverages(leverages, symbols, 'instId')
1809
+
1760
1810
  async def fetch_leverage(self, symbol: str, params={}) -> Leverage:
1761
1811
  """
1762
1812
  fetch the set leverage for a market
1763
- :see: https://blofin.com/docs#set-leverage
1813
+ :see: https://docs.blofin.com/index.html#get-leverage
1764
1814
  :param str symbol: unified market symbol
1765
1815
  :param dict [params]: extra parameters specific to the exchange API endpoint
1766
1816
  :param str [params.marginMode]: 'cross' or 'isolated'
@@ -2909,10 +2909,12 @@ class coinbase(Exchange, ImplicitAPI):
2909
2909
  :returns int[][]: A list of candles ordered, open, high, low, close, volume
2910
2910
  """
2911
2911
  await self.load_markets()
2912
+ maxLimit = 300
2913
+ limit = maxLimit if (limit is None) else min(limit, maxLimit)
2912
2914
  paginate = False
2913
2915
  paginate, params = self.handle_option_and_params(params, 'fetchOHLCV', 'paginate', False)
2914
2916
  if paginate:
2915
- return await self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 299)
2917
+ return await self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimit - 1)
2916
2918
  market = self.market(symbol)
2917
2919
  request = {
2918
2920
  'product_id': market['id'],
@@ -2921,18 +2923,18 @@ class coinbase(Exchange, ImplicitAPI):
2921
2923
  until = self.safe_value_n(params, ['until', 'till', 'end'])
2922
2924
  params = self.omit(params, ['until', 'till'])
2923
2925
  duration = self.parse_timeframe(timeframe)
2924
- candles300 = 300 * duration
2926
+ requestedDuration = limit * duration
2925
2927
  sinceString = None
2926
2928
  if since is not None:
2927
2929
  sinceString = self.number_to_string(self.parse_to_int(since / 1000))
2928
2930
  else:
2929
2931
  now = str(self.seconds())
2930
- sinceString = Precise.string_sub(now, str(candles300))
2932
+ sinceString = Precise.string_sub(now, str(requestedDuration))
2931
2933
  request['start'] = sinceString
2932
2934
  endString = self.number_to_string(until)
2933
2935
  if until is None:
2934
2936
  # 300 candles max
2935
- endString = Precise.string_add(sinceString, str(candles300))
2937
+ endString = Precise.string_add(sinceString, str(requestedDuration))
2936
2938
  request['end'] = endString
2937
2939
  response = await self.v3PrivateGetBrokerageProductsProductIdCandles(self.extend(request, params))
2938
2940
  #
@@ -2989,8 +2991,16 @@ class coinbase(Exchange, ImplicitAPI):
2989
2991
  request = {
2990
2992
  'product_id': market['id'],
2991
2993
  }
2994
+ if since is not None:
2995
+ request['start'] = self.number_to_string(self.parse_to_int(since / 1000))
2992
2996
  if limit is not None:
2993
- request['limit'] = limit
2997
+ request['limit'] = min(limit, 1000)
2998
+ until = None
2999
+ until, params = self.handle_option_and_params(params, 'fetchTrades', 'until')
3000
+ if until is not None:
3001
+ request['end'] = self.number_to_string(self.parse_to_int(until / 1000))
3002
+ elif since is not None:
3003
+ raise ArgumentsRequired(self.id + ' fetchTrades() requires a `until` parameter when you use `since` argument')
2994
3004
  response = await self.v3PrivateGetBrokerageProductsProductIdTicker(self.extend(request, params))
2995
3005
  #
2996
3006
  # {
@@ -3111,7 +3121,7 @@ class coinbase(Exchange, ImplicitAPI):
3111
3121
  # }
3112
3122
  # }
3113
3123
  #
3114
- data = self.safe_value(response, 'pricebook', {})
3124
+ data = self.safe_dict(response, 'pricebook', {})
3115
3125
  time = self.safe_string(data, 'time')
3116
3126
  timestamp = self.parse8601(time)
3117
3127
  return self.parse_order_book(data, symbol, timestamp, 'bids', 'asks', 'price', 'size')
@@ -3535,21 +3545,20 @@ class coinbase(Exchange, ImplicitAPI):
3535
3545
  body = self.json(query)
3536
3546
  else:
3537
3547
  self.check_required_credentials()
3538
- nonce = str(self.nonce())
3548
+ timestampString = str(self.seconds())
3539
3549
  payload = ''
3540
3550
  if method != 'GET':
3541
3551
  if query:
3542
3552
  body = self.json(query)
3543
3553
  payload = body
3544
- else:
3545
- if query:
3546
- payload += '?' + self.urlencode(query)
3547
- auth = nonce + method + savedPath + payload
3554
+ # 'GET' doesn't need payload in the signature. inside url is enough
3555
+ # https://docs.cloud.coinbase.com/advanced-trade-api/docs/auth#example-request
3556
+ auth = timestampString + method + savedPath + payload
3548
3557
  signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256)
3549
3558
  headers = {
3550
3559
  'CB-ACCESS-KEY': self.apiKey,
3551
3560
  'CB-ACCESS-SIGN': signature,
3552
- 'CB-ACCESS-TIMESTAMP': nonce,
3561
+ 'CB-ACCESS-TIMESTAMP': timestampString,
3553
3562
  'Content-Type': 'application/json',
3554
3563
  }
3555
3564
  return {'url': url, 'method': method, 'body': body, 'headers': headers}
@@ -2508,7 +2508,7 @@ class hitbtc(Exchange, ImplicitAPI):
2508
2508
  if (network is not None) and (code == 'USDT'):
2509
2509
  parsedNetwork = self.safe_string(networks, network)
2510
2510
  if parsedNetwork is not None:
2511
- request['currency'] = parsedNetwork
2511
+ request['network_code'] = parsedNetwork
2512
2512
  params = self.omit(params, 'network')
2513
2513
  withdrawOptions = self.safe_value(self.options, 'withdraw', {})
2514
2514
  includeFee = self.safe_bool(withdrawOptions, 'includeFee', False)
ccxt/async_support/htx.py CHANGED
@@ -2507,7 +2507,9 @@ class htx(Exchange, ImplicitAPI):
2507
2507
  amountString = self.safe_string(trade, 'trade_volume', amountString)
2508
2508
  costString = self.safe_string(trade, 'trade_turnover')
2509
2509
  fee = None
2510
- feeCost = self.safe_string_2(trade, 'filled-fees', 'trade_fee')
2510
+ feeCost = self.safe_string(trade, 'filled-fees')
2511
+ if feeCost is None:
2512
+ feeCost = Precise.string_neg(self.safe_string(trade, 'trade_fee'))
2511
2513
  feeCurrencyId = self.safe_string_2(trade, 'fee-currency', 'fee_asset')
2512
2514
  feeCurrency = self.safe_currency_code(feeCurrencyId)
2513
2515
  filledPoints = self.safe_string(trade, 'filled-points')
@@ -39,7 +39,10 @@ class kraken(Exchange, ImplicitAPI):
39
39
  'name': 'Kraken',
40
40
  'countries': ['US'],
41
41
  'version': '0',
42
- 'rateLimit': 3000, # bucket fills max 15, but drains 1 every 3s
42
+ # rate-limits: https://support.kraken.com/hc/en-us/articles/206548367-What-are-the-API-rate-limits-#1
43
+ # for public: 1 req/s
44
+ # for private: every second 0.33 weight added to your allowed capacity(some private endpoints need 1 weight, some need 2)
45
+ 'rateLimit': 1000,
43
46
  'certified': False,
44
47
  'pro': True,
45
48
  'has': {
@@ -169,7 +172,7 @@ class kraken(Exchange, ImplicitAPI):
169
172
  },
170
173
  'public': {
171
174
  'get': {
172
- # public endpoint rate-limits are described in article: https://support.kraken.com/hc/en-us/articles/206548367-What-are-the-API-rate-limits-#1
175
+ # rate-limits explained in comment in the top of self file
173
176
  'Assets': 1,
174
177
  'AssetPairs': 1,
175
178
  'Depth': 1,
@@ -185,48 +188,48 @@ class kraken(Exchange, ImplicitAPI):
185
188
  'post': {
186
189
  'AddOrder': 0,
187
190
  'AddOrderBatch': 0,
188
- 'AddExport': 1,
189
- 'Balance': 1,
190
- 'CancelAll': 1,
191
- 'CancelAllOrdersAfter': 1,
191
+ 'AddExport': 3,
192
+ 'Balance': 3,
193
+ 'CancelAll': 3,
194
+ 'CancelAllOrdersAfter': 3,
192
195
  'CancelOrder': 0,
193
196
  'CancelOrderBatch': 0,
194
- 'ClosedOrders': 1,
195
- 'DepositAddresses': 1,
196
- 'DepositMethods': 1,
197
- 'DepositStatus': 1,
197
+ 'ClosedOrders': 3,
198
+ 'DepositAddresses': 3,
199
+ 'DepositMethods': 3,
200
+ 'DepositStatus': 3,
198
201
  'EditOrder': 0,
199
- 'ExportStatus': 1,
200
- 'GetWebSocketsToken': 1,
201
- 'Ledgers': 2,
202
- 'OpenOrders': 1,
203
- 'OpenPositions': 1,
204
- 'QueryLedgers': 1,
205
- 'QueryOrders': 1,
206
- 'QueryTrades': 1,
207
- 'RetrieveExport': 1,
208
- 'RemoveExport': 1,
209
- 'BalanceEx': 1,
210
- 'TradeBalance': 1,
211
- 'TradesHistory': 2,
212
- 'TradeVolume': 1,
213
- 'Withdraw': 1,
214
- 'WithdrawCancel': 1,
215
- 'WithdrawInfo': 1,
216
- 'WithdrawMethods': 1,
217
- 'WithdrawAddresses': 1,
218
- 'WithdrawStatus': 1,
219
- 'WalletTransfer': 1,
202
+ 'ExportStatus': 3,
203
+ 'GetWebSocketsToken': 3,
204
+ 'Ledgers': 6,
205
+ 'OpenOrders': 3,
206
+ 'OpenPositions': 3,
207
+ 'QueryLedgers': 3,
208
+ 'QueryOrders': 3,
209
+ 'QueryTrades': 3,
210
+ 'RetrieveExport': 3,
211
+ 'RemoveExport': 3,
212
+ 'BalanceEx': 3,
213
+ 'TradeBalance': 3,
214
+ 'TradesHistory': 6,
215
+ 'TradeVolume': 3,
216
+ 'Withdraw': 3,
217
+ 'WithdrawCancel': 3,
218
+ 'WithdrawInfo': 3,
219
+ 'WithdrawMethods': 3,
220
+ 'WithdrawAddresses': 3,
221
+ 'WithdrawStatus': 3,
222
+ 'WalletTransfer': 3,
220
223
  # sub accounts
221
- 'CreateSubaccount': 1,
222
- 'AccountTransfer': 1,
224
+ 'CreateSubaccount': 3,
225
+ 'AccountTransfer': 3,
223
226
  # earn
224
- 'Earn/Allocate': 1,
225
- 'Earn/Deallocate': 1,
226
- 'Earn/AllocateStatus': 1,
227
- 'Earn/DeallocateStatus': 1,
228
- 'Earn/Strategies': 1,
229
- 'Earn/Allocations': 1,
227
+ 'Earn/Allocate': 3,
228
+ 'Earn/Deallocate': 3,
229
+ 'Earn/AllocateStatus': 3,
230
+ 'Earn/DeallocateStatus': 3,
231
+ 'Earn/Strategies': 3,
232
+ 'Earn/Allocations': 3,
230
233
  },
231
234
  },
232
235
  },
@@ -46,6 +46,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
46
46
  'addMargin': True,
47
47
  'cancelAllOrders': True,
48
48
  'cancelOrder': True,
49
+ 'closeAllPositions': False,
49
50
  'closePosition': True,
50
51
  'closePositions': False,
51
52
  'createDepositAddress': True,
@@ -2530,7 +2530,7 @@ class lbank(Exchange, ImplicitAPI):
2530
2530
  uppercaseHash = hash.upper()
2531
2531
  sign = None
2532
2532
  if signatureMethod == 'RSA':
2533
- cacheSecretAsPem = self.safe_value(self.options, 'cacheSecretAsPem', True)
2533
+ cacheSecretAsPem = self.safe_bool(self.options, 'cacheSecretAsPem', True)
2534
2534
  pem = None
2535
2535
  if cacheSecretAsPem:
2536
2536
  pem = self.safe_value(self.options, 'pem')
@@ -5148,7 +5148,7 @@ class mexc(Exchange, ImplicitAPI):
5148
5148
  'X-MEXC-APIKEY': self.apiKey,
5149
5149
  'source': self.safe_string(self.options, 'broker', 'CCXT'),
5150
5150
  }
5151
- if (method == 'POST') or (method == 'PUT'):
5151
+ if (method == 'POST') or (method == 'PUT') or (method == 'DELETE'):
5152
5152
  headers['Content-Type'] = 'application/json'
5153
5153
  elif section == 'contract' or section == 'spot2':
5154
5154
  url = self.urls['api'][section][access] + '/' + self.implode_params(path, params)
ccxt/async_support/okx.py CHANGED
@@ -1550,7 +1550,7 @@ class okx(Exchange, ImplicitAPI):
1550
1550
  # while fetchCurrencies is a public API method by design
1551
1551
  # therefore we check the keys here
1552
1552
  # and fallback to generating the currencies from the markets
1553
- isSandboxMode = self.safe_value(self.options, 'sandboxMode', False)
1553
+ isSandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
1554
1554
  if not self.check_required_credentials(False) or isSandboxMode:
1555
1555
  return None
1556
1556
  #
@@ -2337,7 +2337,7 @@ class phemex(Exchange, ImplicitAPI):
2337
2337
 
2338
2338
  def parse_order(self, order, market: Market = None) -> Order:
2339
2339
  isSwap = self.safe_bool(market, 'swap', False)
2340
- hasPnl = ('closedPnl' in order)
2340
+ hasPnl = ('closedPnl' in order) or ('closedPnlRv' in order) or ('totalPnlRv' in order)
2341
2341
  if isSwap or hasPnl:
2342
2342
  return self.parse_swap_order(order, market)
2343
2343
  return self.parse_spot_order(order, market)
@@ -121,7 +121,7 @@ class wazirx(Exchange, ImplicitAPI):
121
121
  'public': {
122
122
  'get': {
123
123
  'exchangeInfo': 1,
124
- 'depth': 1,
124
+ 'depth': 0.5,
125
125
  'ping': 1,
126
126
  'systemStatus': 1,
127
127
  'tickers/24hr': 1,
@@ -140,6 +140,11 @@ class wazirx(Exchange, ImplicitAPI):
140
140
  'openOrders': 1,
141
141
  'order': 0.5,
142
142
  'myTrades': 0.5,
143
+ 'coins': 12,
144
+ 'crypto/withdraws': 12,
145
+ 'crypto/deposits/address': 60,
146
+ 'sub_account/fund_transfer/history': 1,
147
+ 'sub_account/accounts': 1,
143
148
  },
144
149
  'post': {
145
150
  'order': 0.1,