ccxt 4.2.63__py2.py3-none-any.whl → 4.2.65__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 (59) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/blofin.py +1 -0
  3. ccxt/abstract/krakenfutures.py +1 -0
  4. ccxt/abstract/kucoin.py +10 -0
  5. ccxt/abstract/kucoinfutures.py +10 -0
  6. ccxt/async_support/__init__.py +1 -1
  7. ccxt/async_support/base/exchange.py +2 -2
  8. ccxt/async_support/binance.py +32 -13
  9. ccxt/async_support/bingx.py +56 -49
  10. ccxt/async_support/bitget.py +66 -2
  11. ccxt/async_support/bitmex.py +2 -1
  12. ccxt/async_support/blofin.py +45 -12
  13. ccxt/async_support/btcmarkets.py +9 -0
  14. ccxt/async_support/bybit.py +90 -6
  15. ccxt/async_support/coinbase.py +9 -2
  16. ccxt/async_support/delta.py +92 -2
  17. ccxt/async_support/gate.py +1 -1
  18. ccxt/async_support/gemini.py +9 -5
  19. ccxt/async_support/hitbtc.py +1 -1
  20. ccxt/async_support/krakenfutures.py +1 -0
  21. ccxt/async_support/kucoin.py +85 -61
  22. ccxt/async_support/okx.py +1 -1
  23. ccxt/async_support/woo.py +1 -1
  24. ccxt/async_support/yobit.py +15 -15
  25. ccxt/base/exchange.py +14 -3
  26. ccxt/binance.py +32 -13
  27. ccxt/bingx.py +56 -49
  28. ccxt/bitget.py +66 -2
  29. ccxt/bitmex.py +2 -1
  30. ccxt/blofin.py +45 -12
  31. ccxt/btcmarkets.py +9 -0
  32. ccxt/bybit.py +90 -6
  33. ccxt/coinbase.py +9 -2
  34. ccxt/delta.py +92 -2
  35. ccxt/gate.py +1 -1
  36. ccxt/gemini.py +9 -5
  37. ccxt/hitbtc.py +1 -1
  38. ccxt/krakenfutures.py +1 -0
  39. ccxt/kucoin.py +85 -61
  40. ccxt/okx.py +1 -1
  41. ccxt/pro/__init__.py +1 -1
  42. ccxt/pro/bitget.py +4 -3
  43. ccxt/pro/coinex.py +4 -4
  44. ccxt/pro/currencycom.py +1 -1
  45. ccxt/pro/lbank.py +1 -1
  46. ccxt/static_dependencies/ethereum/utils/__init__.py +0 -6
  47. ccxt/static_dependencies/ethereum/utils/curried/__init__.py +0 -4
  48. ccxt/test/base/test_shared_methods.py +1 -1
  49. ccxt/test/test_async.py +13 -1
  50. ccxt/test/test_sync.py +13 -1
  51. ccxt/woo.py +1 -1
  52. ccxt/yobit.py +15 -15
  53. {ccxt-4.2.63.dist-info → ccxt-4.2.65.dist-info}/METADATA +4 -4
  54. {ccxt-4.2.63.dist-info → ccxt-4.2.65.dist-info}/RECORD +56 -59
  55. ccxt/static_dependencies/ethereum/utils/__json/eth_networks.json +0 -1
  56. ccxt/static_dependencies/ethereum/utils/network.py +0 -88
  57. ccxt-4.2.63.data/data/ccxt/eth_networks.json +0 -1
  58. {ccxt-4.2.63.dist-info → ccxt-4.2.65.dist-info}/WHEEL +0 -0
  59. {ccxt-4.2.63.dist-info → ccxt-4.2.65.dist-info}/top_level.txt +0 -0
@@ -3564,8 +3564,8 @@ class bybit(Exchange, ImplicitAPI):
3564
3564
  market = self.market(symbols[0])
3565
3565
  category = None
3566
3566
  category, params = self.get_bybit_type('createOrders', market, params)
3567
- if (category == 'spot') or (category == 'inverse'):
3568
- raise NotSupported(self.id + ' createOrders does not allow spot or inverse orders')
3567
+ if category == 'inverse':
3568
+ raise NotSupported(self.id + ' createOrders does not allow inverse orders')
3569
3569
  request = {
3570
3570
  'category': category,
3571
3571
  'request': ordersRequests,
@@ -3986,6 +3986,81 @@ class bybit(Exchange, ImplicitAPI):
3986
3986
  result = self.safe_value(response, 'result', {})
3987
3987
  return self.parse_order(result, market)
3988
3988
 
3989
+ async def cancel_orders(self, ids, symbol: Str = None, params={}):
3990
+ """
3991
+ cancel multiple orders
3992
+ :see: https://bybit-exchange.github.io/docs/v5/order/batch-cancel
3993
+ :param str[] ids: order ids
3994
+ :param str symbol: unified symbol of the market the order was made in
3995
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3996
+ :param str[] [params.clientOrderIds]: client order ids
3997
+ :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
3998
+ """
3999
+ if symbol is None:
4000
+ raise ArgumentsRequired(self.id + ' cancelOrders() requires a symbol argument')
4001
+ await self.load_markets()
4002
+ market = self.market(symbol)
4003
+ category = None
4004
+ category, params = self.get_bybit_type('cancelOrders', market, params)
4005
+ if category == 'inverse':
4006
+ raise NotSupported(self.id + ' cancelOrders does not allow inverse orders')
4007
+ ordersRequests = []
4008
+ clientOrderIds = self.safe_list_2(params, 'clientOrderIds', 'clientOids', [])
4009
+ params = self.omit(params, ['clientOrderIds', 'clientOids'])
4010
+ for i in range(0, len(clientOrderIds)):
4011
+ ordersRequests.append({
4012
+ 'symbol': market['id'],
4013
+ 'orderLinkId': self.safe_string(clientOrderIds, i),
4014
+ })
4015
+ for i in range(0, len(ids)):
4016
+ ordersRequests.append({
4017
+ 'symbol': market['id'],
4018
+ 'orderId': self.safe_string(ids, i),
4019
+ })
4020
+ request = {
4021
+ 'category': category,
4022
+ 'request': ordersRequests,
4023
+ }
4024
+ response = await self.privatePostV5OrderCancelBatch(self.extend(request, params))
4025
+ #
4026
+ # {
4027
+ # "retCode": "0",
4028
+ # "retMsg": "OK",
4029
+ # "result": {
4030
+ # "list": [
4031
+ # {
4032
+ # "category": "spot",
4033
+ # "symbol": "BTCUSDT",
4034
+ # "orderId": "1636282505818800896",
4035
+ # "orderLinkId": "1636282505818800897"
4036
+ # },
4037
+ # {
4038
+ # "category": "spot",
4039
+ # "symbol": "BTCUSDT",
4040
+ # "orderId": "1636282505818800898",
4041
+ # "orderLinkId": "1636282505818800899"
4042
+ # }
4043
+ # ]
4044
+ # },
4045
+ # "retExtInfo": {
4046
+ # "list": [
4047
+ # {
4048
+ # "code": "0",
4049
+ # "msg": "OK"
4050
+ # },
4051
+ # {
4052
+ # "code": "0",
4053
+ # "msg": "OK"
4054
+ # }
4055
+ # ]
4056
+ # },
4057
+ # "time": "1709796158501"
4058
+ # }
4059
+ #
4060
+ result = self.safe_dict(response, 'result', {})
4061
+ row = self.safe_list(result, 'list', [])
4062
+ return self.parse_orders(row, market)
4063
+
3989
4064
  async def cancel_all_usdc_orders(self, symbol: Str = None, params={}):
3990
4065
  if symbol is None:
3991
4066
  raise ArgumentsRequired(self.id + ' cancelAllUsdcOrders() requires a symbol argument')
@@ -6715,7 +6790,8 @@ class bybit(Exchange, ImplicitAPI):
6715
6790
  # }
6716
6791
  #
6717
6792
  marketId = self.safe_string(fee, 'symbol')
6718
- symbol = self.safe_symbol(marketId, None, None, 'contract')
6793
+ defaultType = market['type'] if (market is not None) else 'contract'
6794
+ symbol = self.safe_symbol(marketId, market, None, defaultType)
6719
6795
  return {
6720
6796
  'info': fee,
6721
6797
  'symbol': symbol,
@@ -6733,11 +6809,19 @@ class bybit(Exchange, ImplicitAPI):
6733
6809
  """
6734
6810
  await self.load_markets()
6735
6811
  market = self.market(symbol)
6736
- if market['spot']:
6737
- raise NotSupported(self.id + ' fetchTradingFee() is not supported for spot market')
6738
6812
  request = {
6739
6813
  'symbol': market['id'],
6740
6814
  }
6815
+ category = None
6816
+ if market['linear']:
6817
+ category = 'linear'
6818
+ elif market['inverse']:
6819
+ category = 'inverse'
6820
+ elif market['spot']:
6821
+ category = 'spot'
6822
+ else:
6823
+ category = 'option'
6824
+ request['category'] = category
6741
6825
  response = await self.privateGetV5AccountFeeRate(self.extend(request, params))
6742
6826
  #
6743
6827
  # {
@@ -6759,7 +6843,7 @@ class bybit(Exchange, ImplicitAPI):
6759
6843
  result = self.safe_value(response, 'result', {})
6760
6844
  fees = self.safe_value(result, 'list', [])
6761
6845
  first = self.safe_value(fees, 0, {})
6762
- return self.parse_trading_fee(first)
6846
+ return self.parse_trading_fee(first, market)
6763
6847
 
6764
6848
  async def fetch_trading_fees(self, params={}):
6765
6849
  """
@@ -3522,7 +3522,8 @@ class coinbase(Exchange, ImplicitAPI):
3522
3522
  def sign(self, path, api=[], method='GET', params={}, headers=None, body=None):
3523
3523
  version = api[0]
3524
3524
  signed = api[1] == 'private'
3525
- pathPart = 'api/v3' if (version == 'v3') else 'v2'
3525
+ isV3 = version == 'v3'
3526
+ pathPart = 'api/v3' if (isV3) else 'v2'
3526
3527
  fullPath = '/' + pathPart + '/' + self.implode_params(path, params)
3527
3528
  query = self.omit(params, self.extract_params(path))
3528
3529
  savedPath = fullPath
@@ -3556,8 +3557,14 @@ class coinbase(Exchange, ImplicitAPI):
3556
3557
  if query:
3557
3558
  body = self.json(query)
3558
3559
  payload = body
3559
- # 'GET' doesn't need payload in the signature. inside url is enough
3560
+ else:
3561
+ if not isV3:
3562
+ if query:
3563
+ payload += '?' + self.urlencode(query)
3564
+ # v3: 'GET' doesn't need payload in the signature. inside url is enough
3560
3565
  # https://docs.cloud.coinbase.com/advanced-trade-api/docs/auth#example-request
3566
+ # v2: 'GET' require payload in the signature
3567
+ # https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-key-authentication
3561
3568
  auth = timestampString + method + savedPath + payload
3562
3569
  signature = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256)
3563
3570
  headers = {
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.delta import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Greeks, Int, Leverage, Market, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade
9
+ from ccxt.base.types import Balances, Currency, Greeks, Int, Leverage, MarginMode, Market, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import ArgumentsRequired
@@ -61,7 +61,8 @@ class delta(Exchange, ImplicitAPI):
61
61
  'fetchLedger': True,
62
62
  'fetchLeverage': True,
63
63
  'fetchLeverageTiers': False, # An infinite number of tiers, see examples/js/delta-maintenance-margin-rate-max-leverage.js
64
- 'fetchMarginMode': False,
64
+ 'fetchMarginMode': True,
65
+ 'fetchMarginModes': False,
65
66
  'fetchMarketLeverageTiers': False,
66
67
  'fetchMarkets': True,
67
68
  'fetchMarkOHLCV': True,
@@ -3088,6 +3089,95 @@ class delta(Exchange, ImplicitAPI):
3088
3089
  position = self.parse_position(self.safe_value(response, 'result', {}))
3089
3090
  return [position]
3090
3091
 
3092
+ async def fetch_margin_mode(self, symbol: str, params={}) -> MarginMode:
3093
+ """
3094
+ fetches the margin mode of a trading pair
3095
+ :see: https://docs.delta.exchange/#get-user
3096
+ :param str symbol: unified symbol of the market to fetch the margin mode for
3097
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3098
+ :returns dict: a `margin mode structure <https://docs.ccxt.com/#/?id=margin-mode-structure>`
3099
+ """
3100
+ await self.load_markets()
3101
+ market = None
3102
+ if symbol is not None:
3103
+ market = self.market(symbol)
3104
+ response = await self.privateGetProfile(params)
3105
+ #
3106
+ # {
3107
+ # "result": {
3108
+ # "is_password_set": True,
3109
+ # "kyc_expiry_date": null,
3110
+ # "phishing_code": "12345",
3111
+ # "preferences": {
3112
+ # "favorites": []
3113
+ # },
3114
+ # "is_kyc_provisioned": False,
3115
+ # "country": "Canada",
3116
+ # "margin_mode": "isolated",
3117
+ # "mfa_updated_at": "2023-07-19T01:04:43Z",
3118
+ # "last_name": "",
3119
+ # "oauth_apple_active": False,
3120
+ # "pf_index_symbol": null,
3121
+ # "proof_of_identity_status": "approved",
3122
+ # "dob": null,
3123
+ # "email": "abc_123@gmail.com",
3124
+ # "force_change_password": False,
3125
+ # "nick_name": "still-breeze-123",
3126
+ # "oauth_google_active": False,
3127
+ # "phone_verification_status": "verified",
3128
+ # "id": 12345678,
3129
+ # "last_seen": null,
3130
+ # "is_withdrawal_enabled": True,
3131
+ # "force_change_mfa": False,
3132
+ # "enable_bots": False,
3133
+ # "kyc_verified_on": null,
3134
+ # "created_at": "2023-07-19T01:02:32Z",
3135
+ # "withdrawal_blocked_till": null,
3136
+ # "proof_of_address_status": "approved",
3137
+ # "is_password_change_blocked": False,
3138
+ # "is_mfa_enabled": True,
3139
+ # "is_kyc_done": True,
3140
+ # "oauth": null,
3141
+ # "account_name": "Main",
3142
+ # "sub_account_permissions": null,
3143
+ # "phone_number": null,
3144
+ # "tracking_info": {
3145
+ # "ga_cid": "1234.4321",
3146
+ # "is_kyc_gtm_tracked": True,
3147
+ # "sub_account_config": {
3148
+ # "cross": 2,
3149
+ # "isolated": 2,
3150
+ # "portfolio": 2
3151
+ # }
3152
+ # },
3153
+ # "first_name": "",
3154
+ # "phone_verified_on": null,
3155
+ # "seen_intro": False,
3156
+ # "password_updated_at": null,
3157
+ # "is_login_enabled": True,
3158
+ # "registration_date": "2023-07-19T01:02:32Z",
3159
+ # "permissions": {},
3160
+ # "max_sub_accounts_limit": 2,
3161
+ # "country_calling_code": null,
3162
+ # "is_sub_account": False,
3163
+ # "is_kyc_refresh_required": False
3164
+ # },
3165
+ # "success": True
3166
+ # }
3167
+ #
3168
+ result = self.safe_dict(response, 'result', {})
3169
+ return self.parse_margin_mode(result, market)
3170
+
3171
+ def parse_margin_mode(self, marginMode, market=None) -> MarginMode:
3172
+ symbol = None
3173
+ if market is not None:
3174
+ symbol = market['symbol']
3175
+ return {
3176
+ 'info': marginMode,
3177
+ 'symbol': symbol,
3178
+ 'marginMode': self.safe_string(marginMode, 'margin_mode'),
3179
+ }
3180
+
3091
3181
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
3092
3182
  requestPath = '/' + self.version + '/' + self.implode_params(path, params)
3093
3183
  url = self.urls['api'][api] + requestPath
@@ -880,7 +880,7 @@ class gate(Exchange, ImplicitAPI):
880
880
  },
881
881
  })
882
882
 
883
- def set_sandbox_mode(self, enable):
883
+ def set_sandbox_mode(self, enable: bool):
884
884
  super(gate, self).set_sandbox_mode(enable)
885
885
  self.options['sandboxMode'] = enable
886
886
 
@@ -267,7 +267,7 @@ class gemini(Exchange, ImplicitAPI):
267
267
  },
268
268
  },
269
269
  'options': {
270
- 'fetchMarketsMethod': 'fetch_markets_from_web',
270
+ 'fetchMarketsMethod': 'fetch_markets_from_web', # fetch_markets_from_api, fetch_markets_from_web
271
271
  'fetchMarketFromWebRetries': 10,
272
272
  'fetchMarketsFromAPI': {
273
273
  'fetchDetailsForAllSymbols': False,
@@ -277,12 +277,12 @@ class gemini(Exchange, ImplicitAPI):
277
277
  'webApiEnable': True, # fetches from WEB
278
278
  'webApiRetries': 10,
279
279
  },
280
+ 'fetchUsdtMarkets': ['btcusdt', 'ethusdt'], # self is only used if markets-fetch is set from "web"; keep self list updated(not available trough web api)
280
281
  'fetchCurrencies': {
281
282
  'webApiEnable': True, # fetches from WEB
282
283
  'webApiRetries': 5,
283
284
  'webApiMuteFailure': True,
284
285
  },
285
- 'fetchUsdtMarkets': ['btcusdt', 'ethusdt'], # keep self list updated(not available trough web api)
286
286
  'fetchTickerMethod': 'fetchTickerV1', # fetchTickerV1, fetchTickerV2, fetchTickerV1AndV2
287
287
  'networks': {
288
288
  'BTC': 'bitcoin',
@@ -411,9 +411,11 @@ class gemini(Exchange, ImplicitAPI):
411
411
  """
412
412
  method = self.safe_value(self.options, 'fetchMarketsMethod', 'fetch_markets_from_api')
413
413
  if method == 'fetch_markets_from_web':
414
- usdMarkets = await self.fetch_markets_from_web(params) # get usd markets
415
- usdtMarkets = await self.fetch_usdt_markets(params) # get usdt markets
416
- return self.array_concat(usdMarkets, usdtMarkets)
414
+ promises = []
415
+ promises.append(self.fetch_markets_from_web(params)) # get usd markets
416
+ promises.append(self.fetch_usdt_markets(params)) # get usdt markets
417
+ promisesResult = await asyncio.gather(*promises)
418
+ return self.array_concat(promisesResult[0], promisesResult[1])
417
419
  return await self.fetch_markets_from_api(params)
418
420
 
419
421
  async def fetch_markets_from_web(self, params={}):
@@ -516,6 +518,8 @@ class gemini(Exchange, ImplicitAPI):
516
518
  'post_only': True,
517
519
  'limit_only': True,
518
520
  }
521
+ if status is None:
522
+ return True # below
519
523
  return self.safe_bool(statuses, status, True)
520
524
 
521
525
  async def fetch_usdt_markets(self, params={}):
@@ -2339,7 +2339,7 @@ class hitbtc(Exchange, ImplicitAPI):
2339
2339
  :see: https://api.hitbtc.com/#get-futures-position-parameters
2340
2340
  :param str symbol: unified symbol of the market the order was made in
2341
2341
  :param dict [params]: extra parameters specific to the exchange API endpoint
2342
- :returns dict: Struct of MarginMode
2342
+ :returns dict: a list of `margin mode structures <https://docs.ccxt.com/#/?id=margin-mode-structure>`
2343
2343
  """
2344
2344
  await self.load_markets()
2345
2345
  market = None
@@ -161,6 +161,7 @@ class krakenfutures(Exchange, ImplicitAPI):
161
161
  'executions',
162
162
  'triggers',
163
163
  'accountlogcsv',
164
+ 'account-log',
164
165
  'market/{symbol}/orders',
165
166
  'market/{symbol}/executions',
166
167
  ],