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.
- ccxt/__init__.py +1 -1
- ccxt/abstract/blofin.py +1 -0
- ccxt/abstract/krakenfutures.py +1 -0
- ccxt/abstract/kucoin.py +10 -0
- ccxt/abstract/kucoinfutures.py +10 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +2 -2
- ccxt/async_support/binance.py +32 -13
- ccxt/async_support/bingx.py +56 -49
- ccxt/async_support/bitget.py +66 -2
- ccxt/async_support/bitmex.py +2 -1
- ccxt/async_support/blofin.py +45 -12
- ccxt/async_support/btcmarkets.py +9 -0
- ccxt/async_support/bybit.py +90 -6
- ccxt/async_support/coinbase.py +9 -2
- ccxt/async_support/delta.py +92 -2
- ccxt/async_support/gate.py +1 -1
- ccxt/async_support/gemini.py +9 -5
- ccxt/async_support/hitbtc.py +1 -1
- ccxt/async_support/krakenfutures.py +1 -0
- ccxt/async_support/kucoin.py +85 -61
- ccxt/async_support/okx.py +1 -1
- ccxt/async_support/woo.py +1 -1
- ccxt/async_support/yobit.py +15 -15
- ccxt/base/exchange.py +14 -3
- ccxt/binance.py +32 -13
- ccxt/bingx.py +56 -49
- ccxt/bitget.py +66 -2
- ccxt/bitmex.py +2 -1
- ccxt/blofin.py +45 -12
- ccxt/btcmarkets.py +9 -0
- ccxt/bybit.py +90 -6
- ccxt/coinbase.py +9 -2
- ccxt/delta.py +92 -2
- ccxt/gate.py +1 -1
- ccxt/gemini.py +9 -5
- ccxt/hitbtc.py +1 -1
- ccxt/krakenfutures.py +1 -0
- ccxt/kucoin.py +85 -61
- ccxt/okx.py +1 -1
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitget.py +4 -3
- ccxt/pro/coinex.py +4 -4
- ccxt/pro/currencycom.py +1 -1
- ccxt/pro/lbank.py +1 -1
- ccxt/static_dependencies/ethereum/utils/__init__.py +0 -6
- ccxt/static_dependencies/ethereum/utils/curried/__init__.py +0 -4
- ccxt/test/base/test_shared_methods.py +1 -1
- ccxt/test/test_async.py +13 -1
- ccxt/test/test_sync.py +13 -1
- ccxt/woo.py +1 -1
- ccxt/yobit.py +15 -15
- {ccxt-4.2.63.dist-info → ccxt-4.2.65.dist-info}/METADATA +4 -4
- {ccxt-4.2.63.dist-info → ccxt-4.2.65.dist-info}/RECORD +56 -59
- ccxt/static_dependencies/ethereum/utils/__json/eth_networks.json +0 -1
- ccxt/static_dependencies/ethereum/utils/network.py +0 -88
- ccxt-4.2.63.data/data/ccxt/eth_networks.json +0 -1
- {ccxt-4.2.63.dist-info → ccxt-4.2.65.dist-info}/WHEEL +0 -0
- {ccxt-4.2.63.dist-info → ccxt-4.2.65.dist-info}/top_level.txt +0 -0
ccxt/async_support/bybit.py
CHANGED
@@ -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
|
3568
|
-
raise NotSupported(self.id + ' createOrders does not allow
|
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
|
-
|
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
|
"""
|
ccxt/async_support/coinbase.py
CHANGED
@@ -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
|
-
|
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
|
-
|
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 = {
|
ccxt/async_support/delta.py
CHANGED
@@ -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':
|
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
|
ccxt/async_support/gate.py
CHANGED
ccxt/async_support/gemini.py
CHANGED
@@ -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
|
-
|
415
|
-
|
416
|
-
|
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={}):
|
ccxt/async_support/hitbtc.py
CHANGED
@@ -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:
|
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
|