ccxt 4.2.73__py2.py3-none-any.whl → 4.2.75__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.
- ccxt/__init__.py +3 -1
- ccxt/abstract/tradeogre.py +16 -0
- ccxt/ascendex.py +5 -4
- ccxt/async_support/__init__.py +3 -1
- ccxt/async_support/ascendex.py +5 -4
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/bitget.py +53 -43
- ccxt/async_support/bitmart.py +2 -0
- ccxt/async_support/bybit.py +84 -29
- ccxt/async_support/coinbase.py +4 -4
- ccxt/async_support/coinbaseinternational.py +1 -1
- ccxt/async_support/coinbasepro.py +2 -2
- ccxt/async_support/coinex.py +4 -3
- ccxt/async_support/coinlist.py +2 -2
- ccxt/async_support/cryptocom.py +2 -2
- ccxt/async_support/currencycom.py +2 -2
- ccxt/async_support/deribit.py +2 -2
- ccxt/async_support/gate.py +1 -0
- ccxt/async_support/htx.py +16 -9
- ccxt/async_support/huobijp.py +2 -2
- ccxt/async_support/hyperliquid.py +2 -1
- ccxt/async_support/kraken.py +3 -3
- ccxt/async_support/kucoin.py +3 -3
- ccxt/async_support/luno.py +2 -2
- ccxt/async_support/mexc.py +2 -2
- ccxt/async_support/ndax.py +2 -2
- ccxt/async_support/novadax.py +2 -2
- ccxt/async_support/okx.py +2 -2
- ccxt/async_support/tradeogre.py +598 -0
- ccxt/async_support/woo.py +2 -2
- ccxt/base/exchange.py +3 -3
- ccxt/base/types.py +8 -1
- ccxt/bitget.py +53 -43
- ccxt/bitmart.py +2 -0
- ccxt/bybit.py +84 -29
- ccxt/coinbase.py +4 -4
- ccxt/coinbaseinternational.py +1 -1
- ccxt/coinbasepro.py +2 -2
- ccxt/coinex.py +4 -3
- ccxt/coinlist.py +2 -2
- ccxt/cryptocom.py +2 -2
- ccxt/currencycom.py +2 -2
- ccxt/deribit.py +2 -2
- ccxt/gate.py +1 -0
- ccxt/htx.py +16 -9
- ccxt/huobijp.py +2 -2
- ccxt/hyperliquid.py +2 -1
- ccxt/kraken.py +3 -3
- ccxt/kucoin.py +3 -3
- ccxt/luno.py +2 -2
- ccxt/mexc.py +2 -2
- ccxt/ndax.py +2 -2
- ccxt/novadax.py +2 -2
- ccxt/okx.py +2 -2
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/krakenfutures.py +8 -7
- ccxt/test/base/test_market.py +1 -1
- ccxt/test/test_async.py +16 -12
- ccxt/test/test_sync.py +16 -12
- ccxt/tradeogre.py +598 -0
- ccxt/woo.py +2 -2
- {ccxt-4.2.73.dist-info → ccxt-4.2.75.dist-info}/METADATA +11 -10
- {ccxt-4.2.73.dist-info → ccxt-4.2.75.dist-info}/RECORD +65 -62
- {ccxt-4.2.73.dist-info → ccxt-4.2.75.dist-info}/WHEEL +0 -0
- {ccxt-4.2.73.dist-info → ccxt-4.2.75.dist-info}/top_level.txt +0 -0
ccxt/bitget.py
CHANGED
@@ -1361,10 +1361,10 @@ class bitget(Exchange, ImplicitAPI):
|
|
1361
1361
|
},
|
1362
1362
|
'fetchOHLCV': {
|
1363
1363
|
'spot': {
|
1364
|
-
'method': 'publicSpotGetV2SpotMarketCandles', # or publicSpotGetV2SpotMarketHistoryCandles
|
1364
|
+
'method': 'publicSpotGetV2SpotMarketCandles', # publicSpotGetV2SpotMarketCandles or publicSpotGetV2SpotMarketHistoryCandles
|
1365
1365
|
},
|
1366
1366
|
'swap': {
|
1367
|
-
'method': 'publicMixGetV2MixMarketCandles', # or publicMixGetV2MixMarketHistoryCandles or publicMixGetV2MixMarketHistoryIndexCandles or publicMixGetV2MixMarketHistoryMarkCandles
|
1367
|
+
'method': 'publicMixGetV2MixMarketCandles', # publicMixGetV2MixMarketCandles or publicMixGetV2MixMarketHistoryCandles or publicMixGetV2MixMarketHistoryIndexCandles or publicMixGetV2MixMarketHistoryMarkCandles
|
1368
1368
|
},
|
1369
1369
|
'maxDaysPerTimeframe': {
|
1370
1370
|
'1m': 30,
|
@@ -3196,11 +3196,13 @@ class bitget(Exchange, ImplicitAPI):
|
|
3196
3196
|
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
3197
3197
|
"""
|
3198
3198
|
self.load_markets()
|
3199
|
-
|
3199
|
+
defaultLimit = 100 # default 100, max 1000
|
3200
|
+
maxLimitForRecentEndpoint = 1000
|
3201
|
+
maxLimitForHistoryEndpoint = 200 # note, max 1000 bars are supported for "recent-candles" endpoint, but "historical-candles" support only max 200
|
3200
3202
|
paginate = False
|
3201
3203
|
paginate, params = self.handle_option_and_params(params, 'fetchOHLCV', 'paginate')
|
3202
3204
|
if paginate:
|
3203
|
-
return self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params,
|
3205
|
+
return self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimitForHistoryEndpoint)
|
3204
3206
|
sandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
|
3205
3207
|
market = None
|
3206
3208
|
if sandboxMode:
|
@@ -3210,28 +3212,17 @@ class bitget(Exchange, ImplicitAPI):
|
|
3210
3212
|
market = self.market(symbol)
|
3211
3213
|
marketType = 'spot' if market['spot'] else 'swap'
|
3212
3214
|
timeframes = self.options['timeframes'][marketType]
|
3213
|
-
|
3215
|
+
msInDay = 86400000
|
3214
3216
|
duration = self.parse_timeframe(timeframe) * 1000
|
3215
3217
|
request = {
|
3216
3218
|
'symbol': market['id'],
|
3217
|
-
'granularity':
|
3219
|
+
'granularity': self.safe_string(timeframes, timeframe, timeframe),
|
3218
3220
|
}
|
3219
|
-
defaultLimit = 100 # by default, exchange returns 100 items
|
3220
|
-
msInDay = 1000 * 60 * 60 * 24
|
3221
|
-
if limit is not None:
|
3222
|
-
limit = min(limit, maxLimit)
|
3223
|
-
request['limit'] = limit
|
3224
3221
|
until = self.safe_integer_2(params, 'until', 'till')
|
3222
|
+
limitDefined = limit is not None
|
3223
|
+
sinceDefined = since is not None
|
3224
|
+
untilDefined = until is not None
|
3225
3225
|
params = self.omit(params, ['until', 'till'])
|
3226
|
-
if until is not None:
|
3227
|
-
request['endTime'] = until
|
3228
|
-
if since is not None:
|
3229
|
-
request['startTime'] = since
|
3230
|
-
if market['spot'] and (until is None):
|
3231
|
-
# for spot we need to send "entTime" too
|
3232
|
-
limitForEnd = limit if (limit is not None) else defaultLimit
|
3233
|
-
calculatedEnd = self.sum(since, duration * limitForEnd)
|
3234
|
-
request['endTime'] = calculatedEnd
|
3235
3226
|
response = None
|
3236
3227
|
now = self.milliseconds()
|
3237
3228
|
# retrievable periods listed here:
|
@@ -3239,33 +3230,52 @@ class bitget(Exchange, ImplicitAPI):
|
|
3239
3230
|
# - https://www.bitget.com/api-doc/contract/market/Get-Candle-Data#description
|
3240
3231
|
ohlcOptions = self.safe_dict(self.options, 'fetchOHLCV', {})
|
3241
3232
|
retrievableDaysMap = self.safe_dict(ohlcOptions, 'maxDaysPerTimeframe', {})
|
3242
|
-
|
3243
|
-
endpointTsBoundary = now -
|
3244
|
-
|
3245
|
-
|
3246
|
-
|
3247
|
-
|
3248
|
-
|
3249
|
-
|
3250
|
-
|
3251
|
-
|
3252
|
-
|
3233
|
+
maxRetrievableDaysForRecent = self.safe_integer(retrievableDaysMap, timeframe, 30) # default to safe minimum
|
3234
|
+
endpointTsBoundary = now - maxRetrievableDaysForRecent * msInDay
|
3235
|
+
if limitDefined:
|
3236
|
+
limit = min(limit, maxLimitForRecentEndpoint)
|
3237
|
+
request['limit'] = limit
|
3238
|
+
else:
|
3239
|
+
limit = defaultLimit
|
3240
|
+
limitMultipliedDuration = limit * duration
|
3241
|
+
# exchange aligns from endTime, so it's important, not startTime
|
3242
|
+
# startTime is supported only on "recent" endpoint, not on "historical" endpoint
|
3243
|
+
calculatedStartTime = None
|
3244
|
+
calculatedEndTime = None
|
3245
|
+
if sinceDefined:
|
3246
|
+
calculatedStartTime = since
|
3247
|
+
request['startTime'] = since
|
3248
|
+
if not untilDefined:
|
3249
|
+
calculatedEndTime = self.sum(calculatedStartTime, limitMultipliedDuration)
|
3250
|
+
request['endTime'] = calculatedEndTime
|
3251
|
+
if untilDefined:
|
3252
|
+
calculatedEndTime = until
|
3253
|
+
request['endTime'] = calculatedEndTime
|
3254
|
+
if not sinceDefined:
|
3255
|
+
calculatedStartTime = calculatedEndTime - limitMultipliedDuration
|
3256
|
+
# we do not need to set "startTime" here
|
3257
|
+
historicalEndpointNeeded = (calculatedStartTime is not None) and (calculatedStartTime <= endpointTsBoundary)
|
3258
|
+
if historicalEndpointNeeded:
|
3259
|
+
# only for "historical-candles" - ensure we use correct max limit
|
3260
|
+
if limitDefined:
|
3261
|
+
request['limit'] = min(limit, maxLimitForHistoryEndpoint)
|
3262
|
+
# make request
|
3253
3263
|
if market['spot']:
|
3254
|
-
if
|
3264
|
+
# checks if we need history endpoint
|
3265
|
+
if historicalEndpointNeeded:
|
3255
3266
|
response = self.publicSpotGetV2SpotMarketHistoryCandles(self.extend(request, params))
|
3256
3267
|
else:
|
3257
3268
|
response = self.publicSpotGetV2SpotMarketCandles(self.extend(request, params))
|
3258
3269
|
else:
|
3259
|
-
maxDistanceDaysForContracts = 90 # maximum 90 days allowed between start-end times
|
3260
|
-
|
3261
|
-
if
|
3262
|
-
|
3263
|
-
|
3264
|
-
|
3265
|
-
|
3266
|
-
|
3267
|
-
priceType = self.
|
3268
|
-
params = self.omit(params, ['price'])
|
3270
|
+
maxDistanceDaysForContracts = 90 # for contract, maximum 90 days allowed between start-end times
|
3271
|
+
# only correct the request to fix 90 days if until was auto-calculated
|
3272
|
+
if sinceDefined:
|
3273
|
+
if not untilDefined:
|
3274
|
+
request['endTime'] = min(calculatedEndTime, self.sum(since, maxDistanceDaysForContracts * msInDay))
|
3275
|
+
elif calculatedEndTime - calculatedStartTime > maxDistanceDaysForContracts * msInDay:
|
3276
|
+
raise BadRequest(self.id + ' fetchOHLCV() between start and end must be less than ' + str(maxDistanceDaysForContracts) + ' days')
|
3277
|
+
priceType = None
|
3278
|
+
priceType, params = self.handle_param_string(params, 'price')
|
3269
3279
|
productType = None
|
3270
3280
|
productType, params = self.handle_product_type_and_params(market, params)
|
3271
3281
|
request['productType'] = productType
|
@@ -3276,7 +3286,7 @@ class bitget(Exchange, ImplicitAPI):
|
|
3276
3286
|
elif priceType == 'index':
|
3277
3287
|
response = self.publicMixGetV2MixMarketHistoryIndexCandles(extended)
|
3278
3288
|
else:
|
3279
|
-
if
|
3289
|
+
if historicalEndpointNeeded:
|
3280
3290
|
response = self.publicMixGetV2MixMarketHistoryCandles(extended)
|
3281
3291
|
else:
|
3282
3292
|
response = self.publicMixGetV2MixMarketCandles(extended)
|
ccxt/bitmart.py
CHANGED
@@ -19,6 +19,7 @@ from ccxt.base.errors import InvalidAddress
|
|
19
19
|
from ccxt.base.errors import InvalidOrder
|
20
20
|
from ccxt.base.errors import OrderNotFound
|
21
21
|
from ccxt.base.errors import NotSupported
|
22
|
+
from ccxt.base.errors import NetworkError
|
22
23
|
from ccxt.base.errors import RateLimitExceeded
|
23
24
|
from ccxt.base.errors import ExchangeNotAvailable
|
24
25
|
from ccxt.base.errors import OnMaintenance
|
@@ -365,6 +366,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
365
366
|
'70000': ExchangeError, # 200, no data
|
366
367
|
'70001': BadRequest, # 200, request param can not be null
|
367
368
|
'70002': BadSymbol, # 200, symbol is invalid
|
369
|
+
'70003': NetworkError, # {"code":70003,"trace":"81a9d57b63be4819b65d3065e6a4682b.105.17105295323593915","message":"net error, please try later","data":null}
|
368
370
|
'71001': BadRequest, # 200, after is invalid
|
369
371
|
'71002': BadRequest, # 200, before is invalid
|
370
372
|
'71003': BadRequest, # 200, request after or before is invalid
|
ccxt/bybit.py
CHANGED
@@ -93,6 +93,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
93
93
|
'fetchIsolatedBorrowRates': False,
|
94
94
|
'fetchLedger': True,
|
95
95
|
'fetchLeverage': True,
|
96
|
+
'fetchLeverageTiers': True,
|
96
97
|
'fetchMarketLeverageTiers': True,
|
97
98
|
'fetchMarkets': True,
|
98
99
|
'fetchMarkOHLCV': True,
|
@@ -6751,35 +6752,6 @@ class bybit(Exchange, ImplicitAPI):
|
|
6751
6752
|
request['symbol'] = market['id']
|
6752
6753
|
return self.fetch_derivatives_market_leverage_tiers(symbol, params)
|
6753
6754
|
|
6754
|
-
def parse_market_leverage_tiers(self, info, market: Market = None):
|
6755
|
-
#
|
6756
|
-
# {
|
6757
|
-
# "id": 1,
|
6758
|
-
# "symbol": "BTCUSD",
|
6759
|
-
# "riskLimitValue": "150",
|
6760
|
-
# "maintenanceMargin": "0.5",
|
6761
|
-
# "initialMargin": "1",
|
6762
|
-
# "isLowestRisk": 1,
|
6763
|
-
# "maxLeverage": "100.00"
|
6764
|
-
# }
|
6765
|
-
#
|
6766
|
-
minNotional = 0
|
6767
|
-
tiers = []
|
6768
|
-
for i in range(0, len(info)):
|
6769
|
-
item = info[i]
|
6770
|
-
maxNotional = self.safe_number(item, 'riskLimitValue')
|
6771
|
-
tiers.append({
|
6772
|
-
'tier': self.sum(i, 1),
|
6773
|
-
'currency': market['base'],
|
6774
|
-
'minNotional': minNotional,
|
6775
|
-
'maxNotional': maxNotional,
|
6776
|
-
'maintenanceMarginRate': self.safe_number(item, 'maintenanceMargin'),
|
6777
|
-
'maxLeverage': self.safe_number(item, 'maxLeverage'),
|
6778
|
-
'info': item,
|
6779
|
-
})
|
6780
|
-
minNotional = maxNotional
|
6781
|
-
return tiers
|
6782
|
-
|
6783
6755
|
def parse_trading_fee(self, fee, market: Market = None):
|
6784
6756
|
#
|
6785
6757
|
# {
|
@@ -7447,6 +7419,89 @@ class bybit(Exchange, ImplicitAPI):
|
|
7447
7419
|
'datetime': self.iso8601(timestamp),
|
7448
7420
|
})
|
7449
7421
|
|
7422
|
+
def fetch_leverage_tiers(self, symbols: Strings = None, params={}):
|
7423
|
+
"""
|
7424
|
+
:see: https://bybit-exchange.github.io/docs/v5/market/risk-limit
|
7425
|
+
retrieve information on the maximum leverage, for different trade sizes
|
7426
|
+
:param str[] [symbols]: a list of unified market symbols
|
7427
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7428
|
+
:param str [params.subType]: market subType, ['linear', 'inverse'], default is 'linear'
|
7429
|
+
:returns dict: a dictionary of `leverage tiers structures <https://docs.ccxt.com/#/?id=leverage-tiers-structure>`, indexed by market symbols
|
7430
|
+
"""
|
7431
|
+
self.load_markets()
|
7432
|
+
market = None
|
7433
|
+
if symbols is not None:
|
7434
|
+
market = self.market(symbols[0])
|
7435
|
+
if market['spot']:
|
7436
|
+
raise NotSupported(self.id + ' fetchLeverageTiers() is not supported for spot market')
|
7437
|
+
subType = None
|
7438
|
+
subType, params = self.handle_sub_type_and_params('fetchTickers', market, params, 'linear')
|
7439
|
+
request = {
|
7440
|
+
'category': subType,
|
7441
|
+
}
|
7442
|
+
response = self.publicGetV5MarketRiskLimit(self.extend(request, params))
|
7443
|
+
result = self.safe_dict(response, 'result', {})
|
7444
|
+
data = self.safe_list(result, 'list', [])
|
7445
|
+
symbols = self.market_symbols(symbols)
|
7446
|
+
return self.parse_leverage_tiers(data, symbols, 'symbol')
|
7447
|
+
|
7448
|
+
def parse_leverage_tiers(self, response, symbols: Strings = None, marketIdKey=None):
|
7449
|
+
#
|
7450
|
+
# [
|
7451
|
+
# {
|
7452
|
+
# "id": 1,
|
7453
|
+
# "symbol": "BTCUSD",
|
7454
|
+
# "riskLimitValue": "150",
|
7455
|
+
# "maintenanceMargin": "0.5",
|
7456
|
+
# "initialMargin": "1",
|
7457
|
+
# "isLowestRisk": 1,
|
7458
|
+
# "maxLeverage": "100.00"
|
7459
|
+
# }
|
7460
|
+
# ]
|
7461
|
+
#
|
7462
|
+
tiers = {}
|
7463
|
+
marketIds = self.market_ids(symbols)
|
7464
|
+
filteredResults = self.filter_by_array(response, marketIdKey, marketIds, False)
|
7465
|
+
grouped = self.group_by(filteredResults, marketIdKey)
|
7466
|
+
keys = list(grouped.keys())
|
7467
|
+
for i in range(0, len(keys)):
|
7468
|
+
marketId = keys[i]
|
7469
|
+
entry = grouped[marketId]
|
7470
|
+
market = self.safe_market(marketId, None, None, 'contract')
|
7471
|
+
symbol = market['symbol']
|
7472
|
+
tiers[symbol] = self.parse_market_leverage_tiers(entry, market)
|
7473
|
+
return tiers
|
7474
|
+
|
7475
|
+
def parse_market_leverage_tiers(self, info, market: Market = None):
|
7476
|
+
#
|
7477
|
+
# [
|
7478
|
+
# {
|
7479
|
+
# "id": 1,
|
7480
|
+
# "symbol": "BTCUSD",
|
7481
|
+
# "riskLimitValue": "150",
|
7482
|
+
# "maintenanceMargin": "0.5",
|
7483
|
+
# "initialMargin": "1",
|
7484
|
+
# "isLowestRisk": 1,
|
7485
|
+
# "maxLeverage": "100.00"
|
7486
|
+
# }
|
7487
|
+
# ]
|
7488
|
+
#
|
7489
|
+
tiers = []
|
7490
|
+
for i in range(0, len(info)):
|
7491
|
+
tier = info[i]
|
7492
|
+
marketId = self.safe_string(info, 'symbol')
|
7493
|
+
market = self.safe_market(marketId)
|
7494
|
+
tiers.append({
|
7495
|
+
'tier': self.safe_integer(tier, 'id'),
|
7496
|
+
'currency': market['settle'],
|
7497
|
+
'minNotional': None,
|
7498
|
+
'maxNotional': None,
|
7499
|
+
'maintenanceMarginRate': self.safe_number(tier, 'maintenanceMargin'),
|
7500
|
+
'maxLeverage': self.safe_number(tier, 'maxLeverage'),
|
7501
|
+
'info': tier,
|
7502
|
+
})
|
7503
|
+
return tiers
|
7504
|
+
|
7450
7505
|
def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
|
7451
7506
|
url = self.implode_hostname(self.urls['api'][api]) + '/' + path
|
7452
7507
|
if api == 'public':
|
ccxt/coinbase.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.coinbase import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
|
9
|
+
from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, 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
|
@@ -400,7 +400,7 @@ class coinbase(Exchange, ImplicitAPI):
|
|
400
400
|
#
|
401
401
|
return self.safe_timestamp_2(response, 'epoch', 'epochSeconds')
|
402
402
|
|
403
|
-
def fetch_accounts(self, params={}):
|
403
|
+
def fetch_accounts(self, params={}) -> List[Account]:
|
404
404
|
"""
|
405
405
|
fetch all the accounts associated with a profile
|
406
406
|
:see: https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getaccounts
|
@@ -414,7 +414,7 @@ class coinbase(Exchange, ImplicitAPI):
|
|
414
414
|
return self.fetch_accounts_v3(params)
|
415
415
|
return self.fetch_accounts_v2(params)
|
416
416
|
|
417
|
-
def fetch_accounts_v2(self, params={}):
|
417
|
+
def fetch_accounts_v2(self, params={}) -> List[Account]:
|
418
418
|
self.load_markets()
|
419
419
|
paginate = False
|
420
420
|
paginate, params = self.handle_option_and_params(params, 'fetchAccounts', 'paginate')
|
@@ -480,7 +480,7 @@ class coinbase(Exchange, ImplicitAPI):
|
|
480
480
|
accounts[lastIndex] = last
|
481
481
|
return self.parse_accounts(data, params)
|
482
482
|
|
483
|
-
def fetch_accounts_v3(self, params={}):
|
483
|
+
def fetch_accounts_v3(self, params={}) -> List[Account]:
|
484
484
|
self.load_markets()
|
485
485
|
paginate = False
|
486
486
|
paginate, params = self.handle_option_and_params(params, 'fetchAccounts', 'paginate')
|
ccxt/coinbaseinternational.py
CHANGED
@@ -124,7 +124,7 @@ class coinbaseinternational(Exchange, ImplicitAPI):
|
|
124
124
|
'test': {
|
125
125
|
'rest': 'https://api-n5e1.coinbase.com/api',
|
126
126
|
},
|
127
|
-
'www': 'https://
|
127
|
+
'www': 'https://international.coinbase.com',
|
128
128
|
'doc': [
|
129
129
|
'https://docs.cloud.coinbaseinternational.com/intx/docs',
|
130
130
|
],
|
ccxt/coinbasepro.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.coinbasepro import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
|
9
|
+
from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, 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 PermissionDenied
|
@@ -425,7 +425,7 @@ class coinbasepro(Exchange, ImplicitAPI):
|
|
425
425
|
}))
|
426
426
|
return result
|
427
427
|
|
428
|
-
def fetch_accounts(self, params={}):
|
428
|
+
def fetch_accounts(self, params={}) -> List[Account]:
|
429
429
|
"""
|
430
430
|
fetch all the accounts associated with a profile
|
431
431
|
:see: https://docs.cloud.coinbase.com/exchange/reference/exchangerestapi_getaccounts
|
ccxt/coinex.py
CHANGED
@@ -146,7 +146,7 @@ class coinex(Exchange, ImplicitAPI):
|
|
146
146
|
'perpetualPrivate': 'https://api.coinex.com/perpetual',
|
147
147
|
},
|
148
148
|
'www': 'https://www.coinex.com',
|
149
|
-
'doc': 'https://github.
|
149
|
+
'doc': 'https://viabtc.github.io/coinex_api_en_doc',
|
150
150
|
'fees': 'https://www.coinex.com/fees',
|
151
151
|
'referral': 'https://www.coinex.com/register?refer_code=yw5fz',
|
152
152
|
},
|
@@ -360,6 +360,7 @@ class coinex(Exchange, ImplicitAPI):
|
|
360
360
|
},
|
361
361
|
'broad': {
|
362
362
|
'ip not allow visit': PermissionDenied,
|
363
|
+
'service too busy': ExchangeNotAvailable,
|
363
364
|
},
|
364
365
|
},
|
365
366
|
})
|
@@ -4813,7 +4814,7 @@ class coinex(Exchange, ImplicitAPI):
|
|
4813
4814
|
def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
|
4814
4815
|
"""
|
4815
4816
|
create a loan to borrow margin
|
4816
|
-
:see: https://github.
|
4817
|
+
:see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot002_account017_margin_loan
|
4817
4818
|
:param str symbol: unified market symbol, required for coinex
|
4818
4819
|
:param str code: unified currency code of the currency to borrow
|
4819
4820
|
:param float amount: the amount to borrow
|
@@ -4848,7 +4849,7 @@ class coinex(Exchange, ImplicitAPI):
|
|
4848
4849
|
def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
|
4849
4850
|
"""
|
4850
4851
|
repay borrowed margin and interest
|
4851
|
-
:see: https://github.
|
4852
|
+
:see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot002_account018_margin_flat
|
4852
4853
|
:param str symbol: unified market symbol, required for coinex
|
4853
4854
|
:param str code: unified currency code of the currency to repay
|
4854
4855
|
:param float amount: the amount to repay
|
ccxt/coinlist.py
CHANGED
@@ -7,7 +7,7 @@ from ccxt.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.coinlist import ImplicitAPI
|
8
8
|
import hashlib
|
9
9
|
import math
|
10
|
-
from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
10
|
+
from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
13
|
from ccxt.base.errors import PermissionDenied
|
@@ -1031,7 +1031,7 @@ class coinlist(Exchange, ImplicitAPI):
|
|
1031
1031
|
'taker': takerFees,
|
1032
1032
|
}
|
1033
1033
|
|
1034
|
-
def fetch_accounts(self, params={}):
|
1034
|
+
def fetch_accounts(self, params={}) -> List[Account]:
|
1035
1035
|
"""
|
1036
1036
|
fetch all the accounts associated with a profile
|
1037
1037
|
:see: https://trade-docs.coinlist.co/?javascript--nodejs#list-accounts
|
ccxt/cryptocom.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.cryptocom import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
|
9
|
+
from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, 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 PermissionDenied
|
@@ -2298,7 +2298,7 @@ class cryptocom(Exchange, ImplicitAPI):
|
|
2298
2298
|
}
|
2299
2299
|
return self.safe_string(ledgerType, type, type)
|
2300
2300
|
|
2301
|
-
def fetch_accounts(self, params={}):
|
2301
|
+
def fetch_accounts(self, params={}) -> List[Account]:
|
2302
2302
|
"""
|
2303
2303
|
fetch all the accounts associated with a profile
|
2304
2304
|
:see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-get-accounts
|
ccxt/currencycom.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.currencycom import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Currency, Int, Leverage, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
|
9
|
+
from ccxt.base.types import Account, Balances, Currency, Int, Leverage, Market, Num, Order, OrderBook, OrderSide, OrderType, 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
|
@@ -574,7 +574,7 @@ class currencycom(Exchange, ImplicitAPI):
|
|
574
574
|
})
|
575
575
|
return result
|
576
576
|
|
577
|
-
def fetch_accounts(self, params={}):
|
577
|
+
def fetch_accounts(self, params={}) -> List[Account]:
|
578
578
|
"""
|
579
579
|
fetch all the accounts associated with a profile
|
580
580
|
:see: https://apitradedoc.currency.com/swagger-ui.html#/rest-api/accountUsingGET
|
ccxt/deribit.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.deribit import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Currency, Greeks, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
9
|
+
from ccxt.base.types import Account, Balances, Currency, Greeks, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import PermissionDenied
|
@@ -682,7 +682,7 @@ class deribit(Exchange, ImplicitAPI):
|
|
682
682
|
'info': response,
|
683
683
|
}
|
684
684
|
|
685
|
-
def fetch_accounts(self, params={}):
|
685
|
+
def fetch_accounts(self, params={}) -> List[Account]:
|
686
686
|
"""
|
687
687
|
fetch all the accounts associated with a profile
|
688
688
|
:see: https://docs.deribit.com/#private-get_subaccounts
|
ccxt/gate.py
CHANGED
ccxt/htx.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.htx import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
9
|
+
from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import PermissionDenied
|
@@ -967,6 +967,9 @@ class htx(Exchange, ImplicitAPI):
|
|
967
967
|
},
|
968
968
|
},
|
969
969
|
},
|
970
|
+
'fetchOHLCV': {
|
971
|
+
'useHistoricalEndpointForSpot': True,
|
972
|
+
},
|
970
973
|
'withdraw': {
|
971
974
|
'includeFee': False,
|
972
975
|
},
|
@@ -2828,6 +2831,7 @@ class htx(Exchange, ImplicitAPI):
|
|
2828
2831
|
:param int [limit]: the maximum amount of candles to fetch
|
2829
2832
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2830
2833
|
:param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
2834
|
+
:param str [params.useHistoricalEndpointForSpot]: True/false - whether use the historical candles endpoint for spot markets or default klines endpoint
|
2831
2835
|
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
2832
2836
|
"""
|
2833
2837
|
self.load_markets()
|
@@ -2905,16 +2909,19 @@ class htx(Exchange, ImplicitAPI):
|
|
2905
2909
|
else:
|
2906
2910
|
response = self.contractPublicGetLinearSwapExMarketHistoryKline(self.extend(request, params))
|
2907
2911
|
else:
|
2908
|
-
if since is not None:
|
2909
|
-
request['from'] = self.parse_to_int(since / 1000)
|
2910
|
-
if limit is not None:
|
2911
|
-
request['size'] = limit # max 2000
|
2912
2912
|
request['symbol'] = market['id']
|
2913
|
-
|
2914
|
-
|
2915
|
-
|
2913
|
+
useHistorical = None
|
2914
|
+
useHistorical, params = self.handle_option_and_params(params, 'fetchOHLCV', 'useHistoricalEndpointForSpot', True)
|
2915
|
+
if not useHistorical:
|
2916
|
+
# `limit` only available for the self endpoint
|
2917
|
+
if limit is not None:
|
2918
|
+
request['size'] = limit # max 2000
|
2916
2919
|
response = self.spotPublicGetMarketHistoryKline(self.extend(request, params))
|
2917
2920
|
else:
|
2921
|
+
# `since` only available for the self endpoint
|
2922
|
+
if since is not None:
|
2923
|
+
# default 150 bars
|
2924
|
+
request['from'] = self.parse_to_int(since / 1000)
|
2918
2925
|
response = self.spotPublicGetMarketHistoryCandles(self.extend(request, params))
|
2919
2926
|
#
|
2920
2927
|
# {
|
@@ -2931,7 +2938,7 @@ class htx(Exchange, ImplicitAPI):
|
|
2931
2938
|
data = self.safe_value(response, 'data', [])
|
2932
2939
|
return self.parse_ohlcvs(data, market, timeframe, since, limit)
|
2933
2940
|
|
2934
|
-
def fetch_accounts(self, params={}):
|
2941
|
+
def fetch_accounts(self, params={}) -> List[Account]:
|
2935
2942
|
"""
|
2936
2943
|
fetch all the accounts associated with a profile
|
2937
2944
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
ccxt/huobijp.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.huobijp import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
|
9
|
+
from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, 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 PermissionDenied
|
@@ -944,7 +944,7 @@ class huobijp(Exchange, ImplicitAPI):
|
|
944
944
|
data = self.safe_value(response, 'data', [])
|
945
945
|
return self.parse_ohlcvs(data, market, timeframe, since, limit)
|
946
946
|
|
947
|
-
def fetch_accounts(self, params={}):
|
947
|
+
def fetch_accounts(self, params={}) -> List[Account]:
|
948
948
|
"""
|
949
949
|
fetch all the accounts associated with a profile
|
950
950
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
ccxt/hyperliquid.py
CHANGED
@@ -368,7 +368,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
368
368
|
'optionType': None,
|
369
369
|
'precision': {
|
370
370
|
'amount': self.parse_number(self.parse_precision(self.safe_string(market, 'szDecimals'))), # decimal places
|
371
|
-
'price':
|
371
|
+
'price': 5, # significant digits
|
372
372
|
},
|
373
373
|
'limits': {
|
374
374
|
'leverage': {
|
@@ -824,6 +824,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
824
824
|
if price is None:
|
825
825
|
raise ArgumentsRequired(self.id + ' market orders require price to calculate the max slippage price. Default slippage can be set in options(default is 5%).')
|
826
826
|
px = Precise.string_mul(price, Precise.string_add('1', slippage)) if (isBuy) else Precise.string_mul(price, Precise.string_sub('1', slippage))
|
827
|
+
px = self.price_to_precision(symbol, px) # round after adding slippage
|
827
828
|
else:
|
828
829
|
px = self.price_to_precision(symbol, price)
|
829
830
|
sz = self.amount_to_precision(symbol, amount)
|
ccxt/kraken.py
CHANGED
@@ -2586,7 +2586,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
2586
2586
|
# todo unify parsePosition/parsePositions
|
2587
2587
|
return result
|
2588
2588
|
|
2589
|
-
def
|
2589
|
+
def parse_account_type(self, account):
|
2590
2590
|
accountByType = {
|
2591
2591
|
'spot': 'Spot Wallet',
|
2592
2592
|
'swap': 'Futures Wallet',
|
@@ -2618,8 +2618,8 @@ class kraken(Exchange, ImplicitAPI):
|
|
2618
2618
|
"""
|
2619
2619
|
self.load_markets()
|
2620
2620
|
currency = self.currency(code)
|
2621
|
-
fromAccount = self.
|
2622
|
-
toAccount = self.
|
2621
|
+
fromAccount = self.parse_account_type(fromAccount)
|
2622
|
+
toAccount = self.parse_account_type(toAccount)
|
2623
2623
|
request = {
|
2624
2624
|
'amount': self.currency_to_precision(code, amount),
|
2625
2625
|
'from': fromAccount,
|
ccxt/kucoin.py
CHANGED
@@ -8,7 +8,7 @@ from ccxt.abstract.kucoin import ImplicitAPI
|
|
8
8
|
import hashlib
|
9
9
|
import math
|
10
10
|
import json
|
11
|
-
from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
11
|
+
from ccxt.base.types import Account, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
12
12
|
from typing import List
|
13
13
|
from ccxt.base.errors import ExchangeError
|
14
14
|
from ccxt.base.errors import PermissionDenied
|
@@ -479,7 +479,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
479
479
|
'400006': AuthenticationError,
|
480
480
|
'400007': AuthenticationError,
|
481
481
|
'400008': NotSupported,
|
482
|
-
'400100':
|
482
|
+
'400100': InsufficientFunds, # {"msg":"account.available.amount","code":"400100"}
|
483
483
|
'400200': InvalidOrder, # {"code":"400200","msg":"Forbidden to place an order"}
|
484
484
|
'400350': InvalidOrder, # {"code":"400350","msg":"Upper limit for holding: 10,000USDT, you can still buy 10,000USDT worth of coin."}
|
485
485
|
'400370': InvalidOrder, # {"code":"400370","msg":"Max. price: 0.02500000000000000000"}
|
@@ -1226,7 +1226,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1226
1226
|
}
|
1227
1227
|
return result
|
1228
1228
|
|
1229
|
-
def fetch_accounts(self, params={}):
|
1229
|
+
def fetch_accounts(self, params={}) -> List[Account]:
|
1230
1230
|
"""
|
1231
1231
|
fetch all the accounts associated with a profile
|
1232
1232
|
:see: https://docs.kucoin.com/#list-accounts
|