ccxt 4.2.85__py2.py3-none-any.whl → 4.2.87__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 +1 -1
- ccxt/abstract/coinex.py +232 -123
- ccxt/ascendex.py +16 -6
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ascendex.py +16 -6
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +18 -5
- ccxt/async_support/bingx.py +72 -22
- ccxt/async_support/bitbank.py +19 -21
- ccxt/async_support/bitfinex.py +2 -0
- ccxt/async_support/bitfinex2.py +18 -4
- ccxt/async_support/bitflyer.py +18 -0
- ccxt/async_support/bitget.py +20 -6
- ccxt/async_support/bitopro.py +2 -0
- ccxt/async_support/bitrue.py +16 -8
- ccxt/async_support/bitvavo.py +2 -0
- ccxt/async_support/btcmarkets.py +1 -1
- ccxt/async_support/btcturk.py +2 -1
- ccxt/async_support/coinex.py +572 -306
- ccxt/async_support/currencycom.py +1 -1
- ccxt/async_support/delta.py +8 -6
- ccxt/async_support/digifinex.py +9 -7
- ccxt/async_support/exmo.py +15 -15
- ccxt/async_support/gate.py +9 -6
- ccxt/async_support/hitbtc.py +31 -7
- ccxt/async_support/htx.py +2 -2
- ccxt/async_support/huobijp.py +1 -1
- ccxt/async_support/hyperliquid.py +242 -16
- ccxt/async_support/idex.py +11 -11
- ccxt/async_support/krakenfutures.py +2 -4
- ccxt/async_support/kucoinfutures.py +2 -2
- ccxt/async_support/lbank.py +2 -0
- ccxt/async_support/mexc.py +3 -3
- ccxt/async_support/oceanex.py +1 -1
- ccxt/async_support/okcoin.py +2 -1
- ccxt/async_support/okx.py +29 -15
- ccxt/async_support/phemex.py +6 -4
- ccxt/async_support/wazirx.py +1 -1
- ccxt/async_support/zonda.py +2 -0
- ccxt/base/exchange.py +1 -1
- ccxt/base/types.py +12 -0
- ccxt/binance.py +18 -5
- ccxt/bingx.py +72 -22
- ccxt/bitbank.py +19 -21
- ccxt/bitfinex.py +2 -0
- ccxt/bitfinex2.py +18 -4
- ccxt/bitflyer.py +18 -0
- ccxt/bitget.py +20 -6
- ccxt/bitopro.py +2 -0
- ccxt/bitrue.py +16 -8
- ccxt/bitvavo.py +2 -0
- ccxt/btcmarkets.py +1 -1
- ccxt/btcturk.py +2 -1
- ccxt/coinex.py +572 -306
- ccxt/currencycom.py +1 -1
- ccxt/delta.py +8 -6
- ccxt/digifinex.py +9 -7
- ccxt/exmo.py +15 -15
- ccxt/gate.py +9 -6
- ccxt/hitbtc.py +31 -7
- ccxt/htx.py +2 -2
- ccxt/huobijp.py +1 -1
- ccxt/hyperliquid.py +241 -16
- ccxt/idex.py +11 -11
- ccxt/krakenfutures.py +2 -4
- ccxt/kucoinfutures.py +2 -2
- ccxt/lbank.py +2 -0
- ccxt/mexc.py +3 -3
- ccxt/oceanex.py +1 -1
- ccxt/okcoin.py +2 -1
- ccxt/okx.py +29 -15
- ccxt/phemex.py +6 -4
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitget.py +1 -0
- ccxt/pro/kucoin.py +10 -6
- ccxt/test/base/test_last_price.py +0 -1
- ccxt/test/base/test_shared_methods.py +1 -2
- ccxt/test/base/test_status.py +1 -1
- ccxt/wazirx.py +1 -1
- ccxt/zonda.py +2 -0
- {ccxt-4.2.85.dist-info → ccxt-4.2.87.dist-info}/METADATA +6 -6
- {ccxt-4.2.85.dist-info → ccxt-4.2.87.dist-info}/RECORD +84 -84
- {ccxt-4.2.85.dist-info → ccxt-4.2.87.dist-info}/WHEEL +0 -0
- {ccxt-4.2.85.dist-info → ccxt-4.2.87.dist-info}/top_level.txt +0 -0
@@ -5,7 +5,8 @@
|
|
5
5
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.hyperliquid import ImplicitAPI
|
8
|
-
|
8
|
+
import asyncio
|
9
|
+
from ccxt.base.types import Balances, Int, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Trade, TransferEntry
|
9
10
|
from typing import List
|
10
11
|
from ccxt.base.errors import ExchangeError
|
11
12
|
from ccxt.base.errors import ArgumentsRequired
|
@@ -32,7 +33,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
32
33
|
'pro': True,
|
33
34
|
'has': {
|
34
35
|
'CORS': None,
|
35
|
-
'spot':
|
36
|
+
'spot': True,
|
36
37
|
'margin': False,
|
37
38
|
'swap': True,
|
38
39
|
'future': True,
|
@@ -165,6 +166,10 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
165
166
|
'taker': self.parse_number('0.00035'),
|
166
167
|
'maker': self.parse_number('0.0001'),
|
167
168
|
},
|
169
|
+
'spot': {
|
170
|
+
'taker': self.parse_number('0.00035'),
|
171
|
+
'maker': self.parse_number('0.0001'),
|
172
|
+
},
|
168
173
|
},
|
169
174
|
'requiredCredentials': {
|
170
175
|
'apiKey': False,
|
@@ -192,6 +197,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
192
197
|
'commonCurrencies': {
|
193
198
|
},
|
194
199
|
'options': {
|
200
|
+
'defaultType': 'swap',
|
195
201
|
'sandboxMode': False,
|
196
202
|
'defaultSlippage': 0.05,
|
197
203
|
'zeroAddress': '0x0000000000000000000000000000000000000000',
|
@@ -257,6 +263,22 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
257
263
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
258
264
|
:returns dict[]: an array of objects representing market data
|
259
265
|
"""
|
266
|
+
rawPromises = [
|
267
|
+
self.fetch_swap_markets(params),
|
268
|
+
self.fetch_spot_markets(params),
|
269
|
+
]
|
270
|
+
promises = await asyncio.gather(*rawPromises)
|
271
|
+
swapMarkets = promises[0]
|
272
|
+
spotMarkets = promises[1]
|
273
|
+
return self.array_concat(swapMarkets, spotMarkets)
|
274
|
+
|
275
|
+
async def fetch_swap_markets(self, params={}) -> List[Market]:
|
276
|
+
"""
|
277
|
+
retrieves data on all swap markets for hyperliquid
|
278
|
+
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-asset-contexts-includes-mark-price-current-funding-open-interest-etc
|
279
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
280
|
+
:returns dict[]: an array of objects representing market data
|
281
|
+
"""
|
260
282
|
request = {
|
261
283
|
'type': 'metaAndAssetCtxs',
|
262
284
|
}
|
@@ -304,6 +326,129 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
304
326
|
result.append(data)
|
305
327
|
return self.parse_markets(result)
|
306
328
|
|
329
|
+
async def fetch_spot_markets(self, params={}) -> List[Market]:
|
330
|
+
"""
|
331
|
+
retrieves data on all spot markets for hyperliquid
|
332
|
+
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-asset-contexts-includes-mark-price-current-funding-open-interest-etc
|
333
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
334
|
+
:returns dict[]: an array of objects representing market data
|
335
|
+
"""
|
336
|
+
request = {
|
337
|
+
'type': 'spotMetaAndAssetCtxs',
|
338
|
+
}
|
339
|
+
response = await self.publicPostInfo(self.extend(request, params))
|
340
|
+
#
|
341
|
+
# [
|
342
|
+
# {
|
343
|
+
# 'tokens': [
|
344
|
+
# {
|
345
|
+
# 'name': 'USDC',
|
346
|
+
# 'szDecimals': '8',
|
347
|
+
# 'weiDecimals': '8',
|
348
|
+
# },
|
349
|
+
# {
|
350
|
+
# 'name': 'PURR',
|
351
|
+
# 'szDecimals': '0',
|
352
|
+
# 'weiDecimals': '5',
|
353
|
+
# },
|
354
|
+
# ],
|
355
|
+
# 'universe': [
|
356
|
+
# {
|
357
|
+
# 'name': 'PURR/USDC',
|
358
|
+
# 'tokens': [
|
359
|
+
# 1,
|
360
|
+
# 0,
|
361
|
+
# ],
|
362
|
+
# },
|
363
|
+
# ],
|
364
|
+
# },
|
365
|
+
# [
|
366
|
+
# {
|
367
|
+
# 'dayNtlVlm': '264250385.14640012',
|
368
|
+
# 'markPx': '0.018314',
|
369
|
+
# 'midPx': '0.0182235',
|
370
|
+
# 'prevDayPx': '0.017427',
|
371
|
+
# },
|
372
|
+
# ],
|
373
|
+
# ]
|
374
|
+
#
|
375
|
+
first = self.safe_dict(response, 0, {})
|
376
|
+
meta = self.safe_list(first, 'universe', [])
|
377
|
+
tokens = self.safe_list(first, 'tokens', [])
|
378
|
+
markets = []
|
379
|
+
for i in range(0, len(meta)):
|
380
|
+
market = self.safe_dict(meta, i, {})
|
381
|
+
marketName = self.safe_string(market, 'name')
|
382
|
+
marketParts = marketName.split('/')
|
383
|
+
baseName = self.safe_string(marketParts, 0)
|
384
|
+
quoteId = self.safe_string(marketParts, 1)
|
385
|
+
base = self.safe_currency_code(baseName)
|
386
|
+
quote = self.safe_currency_code(quoteId)
|
387
|
+
symbol = base + '/' + quote
|
388
|
+
fees = self.safe_dict(self.fees, 'spot', {})
|
389
|
+
taker = self.safe_number(fees, 'taker')
|
390
|
+
maker = self.safe_number(fees, 'maker')
|
391
|
+
tokensPos = self.safe_list(market, 'tokens', [])
|
392
|
+
baseTokenPos = self.safe_integer(tokensPos, 0)
|
393
|
+
quoteTokenPos = self.safe_integer(tokensPos, 1)
|
394
|
+
baseTokenInfo = self.safe_dict(tokens, baseTokenPos, {})
|
395
|
+
quoteTokenInfo = self.safe_dict(tokens, quoteTokenPos, {})
|
396
|
+
baseDecimals = self.safe_string(baseTokenInfo, 'szDecimals')
|
397
|
+
quoteDecimals = self.safe_integer(quoteTokenInfo, 'szDecimals')
|
398
|
+
baseId = self.number_to_string(i + 10000)
|
399
|
+
markets.append(self.safe_market_structure({
|
400
|
+
'id': baseId,
|
401
|
+
'symbol': symbol,
|
402
|
+
'base': base,
|
403
|
+
'quote': quote,
|
404
|
+
'settle': None,
|
405
|
+
'baseId': baseId,
|
406
|
+
'quoteId': quoteId,
|
407
|
+
'settleId': None,
|
408
|
+
'type': 'spot',
|
409
|
+
'spot': True,
|
410
|
+
'margin': None,
|
411
|
+
'swap': False,
|
412
|
+
'future': False,
|
413
|
+
'option': False,
|
414
|
+
'active': True,
|
415
|
+
'contract': False,
|
416
|
+
'linear': True,
|
417
|
+
'inverse': False,
|
418
|
+
'taker': taker,
|
419
|
+
'maker': maker,
|
420
|
+
'contractSize': None,
|
421
|
+
'expiry': None,
|
422
|
+
'expiryDatetime': None,
|
423
|
+
'strike': None,
|
424
|
+
'optionType': None,
|
425
|
+
'precision': {
|
426
|
+
'amount': self.parse_number(self.parse_precision(baseDecimals)), # decimal places
|
427
|
+
'price': quoteDecimals, # significant digits
|
428
|
+
},
|
429
|
+
'limits': {
|
430
|
+
'leverage': {
|
431
|
+
'min': None,
|
432
|
+
'max': None,
|
433
|
+
},
|
434
|
+
'amount': {
|
435
|
+
'min': None,
|
436
|
+
'max': None,
|
437
|
+
},
|
438
|
+
'price': {
|
439
|
+
'min': None,
|
440
|
+
'max': None,
|
441
|
+
},
|
442
|
+
'cost': {
|
443
|
+
'min': None,
|
444
|
+
'max': None,
|
445
|
+
},
|
446
|
+
},
|
447
|
+
'created': None,
|
448
|
+
'info': market,
|
449
|
+
}))
|
450
|
+
return markets
|
451
|
+
|
307
452
|
def parse_market(self, market) -> Market:
|
308
453
|
#
|
309
454
|
# {
|
@@ -398,12 +543,17 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
398
543
|
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-a-users-state
|
399
544
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
400
545
|
:param str [params.user]: user address, will default to self.walletAddress if not provided
|
546
|
+
:param str [params.type]: wallet type, ['spot', 'swap'], defaults to swap
|
401
547
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
402
548
|
"""
|
403
549
|
userAddress = None
|
404
550
|
userAddress, params = self.handle_public_address('fetchBalance', params)
|
551
|
+
type = None
|
552
|
+
type, params = self.handle_market_type_and_params('fetchBalance', None, params)
|
553
|
+
isSpot = (type == 'spot')
|
554
|
+
reqType = 'spotClearinghouseState' if (isSpot) else 'clearinghouseState'
|
405
555
|
request = {
|
406
|
-
'type':
|
556
|
+
'type': reqType,
|
407
557
|
'user': userAddress,
|
408
558
|
}
|
409
559
|
response = await self.publicPostInfo(self.extend(request, params))
|
@@ -426,7 +576,35 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
426
576
|
# "time": "1704261007014",
|
427
577
|
# "withdrawable": "100.0"
|
428
578
|
# }
|
579
|
+
# spot
|
580
|
+
#
|
581
|
+
# {
|
582
|
+
# "balances":[
|
583
|
+
# {
|
584
|
+
# "coin":"USDC",
|
585
|
+
# "hold":"0.0",
|
586
|
+
# "total":"1481.844"
|
587
|
+
# },
|
588
|
+
# {
|
589
|
+
# "coin":"PURR",
|
590
|
+
# "hold":"0.0",
|
591
|
+
# "total":"999.65004"
|
592
|
+
# }
|
593
|
+
# }
|
429
594
|
#
|
595
|
+
balances = self.safe_list(response, 'balances')
|
596
|
+
if balances is not None:
|
597
|
+
spotBalances = {'info': response}
|
598
|
+
for i in range(0, len(balances)):
|
599
|
+
balance = balances[i]
|
600
|
+
code = self.safe_currency_code(self.safe_string(balance, 'coin'))
|
601
|
+
account = self.account()
|
602
|
+
total = self.safe_string(balance, 'total')
|
603
|
+
free = self.safe_string(balance, 'hold')
|
604
|
+
account['total'] = total
|
605
|
+
account['free'] = free
|
606
|
+
spotBalances[code] = account
|
607
|
+
return self.safe_balance(spotBalances)
|
430
608
|
data = self.safe_dict(response, 'marginSummary', {})
|
431
609
|
result = {
|
432
610
|
'info': response,
|
@@ -915,6 +1093,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
915
1093
|
:param str symbol: unified symbol of the market the order was made in
|
916
1094
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
917
1095
|
:param str [params.clientOrderId]: client order id,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
|
1096
|
+
:param str [params.vaultAddress]: the vault address for order
|
918
1097
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
919
1098
|
"""
|
920
1099
|
return await self.cancel_orders([id], symbol, params)
|
@@ -928,6 +1107,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
928
1107
|
:param str [symbol]: unified market symbol
|
929
1108
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
930
1109
|
:param string|str[] [params.clientOrderId]: client order ids,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
|
1110
|
+
:param str [params.vaultAddress]: the vault address
|
931
1111
|
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
932
1112
|
"""
|
933
1113
|
self.check_required_credentials()
|
@@ -1377,7 +1557,10 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1377
1557
|
coin = self.safe_string(entry, 'coin')
|
1378
1558
|
marketId = None
|
1379
1559
|
if coin is not None:
|
1380
|
-
|
1560
|
+
if coin.find('/') > -1:
|
1561
|
+
marketId = coin
|
1562
|
+
else:
|
1563
|
+
marketId = coin + '/USDC:USDC'
|
1381
1564
|
if self.safe_string(entry, 'id') is None:
|
1382
1565
|
market = self.safe_market(marketId, None)
|
1383
1566
|
else:
|
@@ -1772,7 +1955,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1772
1955
|
#
|
1773
1956
|
return response
|
1774
1957
|
|
1775
|
-
async def add_margin(self, symbol: str, amount, params={}):
|
1958
|
+
async def add_margin(self, symbol: str, amount, params={}) -> MarginModification:
|
1776
1959
|
"""
|
1777
1960
|
add margin
|
1778
1961
|
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-isolated-margin
|
@@ -1783,7 +1966,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1783
1966
|
"""
|
1784
1967
|
return await self.modify_margin_helper(symbol, amount, 'add', params)
|
1785
1968
|
|
1786
|
-
async def reduce_margin(self, symbol: str, amount, params={}):
|
1969
|
+
async def reduce_margin(self, symbol: str, amount, params={}) -> MarginModification:
|
1787
1970
|
"""
|
1788
1971
|
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-isolated-margin
|
1789
1972
|
remove margin from a position
|
@@ -1794,7 +1977,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1794
1977
|
"""
|
1795
1978
|
return await self.modify_margin_helper(symbol, amount, 'reduce', params)
|
1796
1979
|
|
1797
|
-
async def modify_margin_helper(self, symbol: str, amount, type, params={}):
|
1980
|
+
async def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
|
1798
1981
|
await self.load_markets()
|
1799
1982
|
market = self.market(symbol)
|
1800
1983
|
asset = self.parse_to_int(market['baseId'])
|
@@ -1828,10 +2011,27 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1828
2011
|
# 'status': 'ok'
|
1829
2012
|
# }
|
1830
2013
|
#
|
1831
|
-
return response
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
2014
|
+
return self.extend(self.parse_margin_modification(response, market), {
|
2015
|
+
'code': self.safe_string(response, 'status'),
|
2016
|
+
})
|
2017
|
+
|
2018
|
+
def parse_margin_modification(self, data, market: Market = None) -> MarginModification:
|
2019
|
+
#
|
2020
|
+
# {
|
2021
|
+
# 'type': 'default'
|
2022
|
+
# }
|
2023
|
+
#
|
2024
|
+
return {
|
2025
|
+
'info': data,
|
2026
|
+
'symbol': self.safe_symbol(None, market),
|
2027
|
+
'type': None,
|
2028
|
+
'amount': None,
|
2029
|
+
'total': None,
|
2030
|
+
'code': self.safe_string(market, 'settle'),
|
2031
|
+
'status': None,
|
2032
|
+
'timestamp': None,
|
2033
|
+
'datetime': None,
|
2034
|
+
}
|
1835
2035
|
|
1836
2036
|
async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
1837
2037
|
"""
|
@@ -1839,23 +2039,49 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1839
2039
|
:see: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#l1-usdc-transfer
|
1840
2040
|
:param str code: unified currency code
|
1841
2041
|
:param float amount: amount to transfer
|
1842
|
-
:param str fromAccount: account to transfer from
|
1843
|
-
:param str toAccount: account to transfer to
|
2042
|
+
:param str fromAccount: account to transfer from *spot, swap*
|
2043
|
+
:param str toAccount: account to transfer to *swap, spot or address*
|
1844
2044
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2045
|
+
:param str [params.vaultAddress]: the vault address for order
|
1845
2046
|
:returns dict: a `transfer structure <https://docs.ccxt.com/#/?id=transfer-structure>`
|
1846
2047
|
"""
|
1847
2048
|
self.check_required_credentials()
|
1848
2049
|
await self.load_markets()
|
2050
|
+
isSandboxMode = self.safe_bool(self.options, 'sandboxMode')
|
2051
|
+
nonce = self.milliseconds()
|
2052
|
+
if self.in_array(fromAccount, ['spot', 'swap', 'perp']):
|
2053
|
+
# handle swap <> spot account transfer
|
2054
|
+
if not self.in_array(toAccount, ['spot', 'swap', 'perp']):
|
2055
|
+
raise NotSupported(self.id + 'transfer() only support spot <> swap transfer')
|
2056
|
+
vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
|
2057
|
+
params = self.omit(params, 'vaultAddress')
|
2058
|
+
toPerp = (toAccount == 'perp') or (toAccount == 'swap')
|
2059
|
+
action = {
|
2060
|
+
'type': 'spotUser',
|
2061
|
+
'classTransfer': {
|
2062
|
+
'usdc': amount,
|
2063
|
+
'toPerp': toPerp,
|
2064
|
+
},
|
2065
|
+
}
|
2066
|
+
signature = self.sign_l1_action(action, nonce, vaultAddress)
|
2067
|
+
innerRequest = {
|
2068
|
+
'action': self.extend(action, params),
|
2069
|
+
'nonce': nonce,
|
2070
|
+
'signature': signature,
|
2071
|
+
}
|
2072
|
+
if vaultAddress is not None:
|
2073
|
+
innerRequest['vaultAddress'] = vaultAddress
|
2074
|
+
transferResponse = await self.privatePostExchange(innerRequest)
|
2075
|
+
return transferResponse
|
2076
|
+
# handle sub-account/different account transfer
|
1849
2077
|
self.check_address(toAccount)
|
1850
2078
|
if code is not None:
|
1851
2079
|
code = code.upper()
|
1852
2080
|
if code != 'USDC':
|
1853
2081
|
raise NotSupported(self.id + 'withdraw() only support USDC')
|
1854
|
-
isSandboxMode = self.safe_bool(self.options, 'sandboxMode')
|
1855
|
-
nonce = self.milliseconds()
|
1856
2082
|
payload = {
|
1857
2083
|
'destination': toAccount,
|
1858
|
-
'amount':
|
2084
|
+
'amount': self.number_to_string(amount),
|
1859
2085
|
'time': nonce,
|
1860
2086
|
}
|
1861
2087
|
sig = self.build_transfer_sig(payload)
|
ccxt/async_support/idex.py
CHANGED
@@ -173,13 +173,15 @@ class idex(Exchange, ImplicitAPI):
|
|
173
173
|
'network': 'MATIC',
|
174
174
|
},
|
175
175
|
'exceptions': {
|
176
|
-
'
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
176
|
+
'exact': {
|
177
|
+
'INVALID_ORDER_QUANTITY': InvalidOrder,
|
178
|
+
'INSUFFICIENT_FUNDS': InsufficientFunds,
|
179
|
+
'SERVICE_UNAVAILABLE': ExchangeNotAvailable,
|
180
|
+
'EXCEEDED_RATE_LIMIT': DDoSProtection,
|
181
|
+
'INVALID_PARAMETER': BadRequest,
|
182
|
+
'WALLET_NOT_ASSOCIATED': InvalidAddress,
|
183
|
+
'INVALID_WALLET_SIGNATURE': AuthenticationError,
|
184
|
+
},
|
183
185
|
},
|
184
186
|
'requiredCredentials': {
|
185
187
|
'walletAddress': True,
|
@@ -461,7 +463,7 @@ class idex(Exchange, ImplicitAPI):
|
|
461
463
|
if since is not None:
|
462
464
|
request['start'] = since
|
463
465
|
if limit is not None:
|
464
|
-
request['limit'] = limit
|
466
|
+
request['limit'] = min(limit, 1000)
|
465
467
|
response = await self.publicGetCandles(self.extend(request, params))
|
466
468
|
if isinstance(response, list):
|
467
469
|
# [
|
@@ -1413,10 +1415,8 @@ class idex(Exchange, ImplicitAPI):
|
|
1413
1415
|
def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
|
1414
1416
|
errorCode = self.safe_string(response, 'code')
|
1415
1417
|
message = self.safe_string(response, 'message')
|
1416
|
-
if errorCode in self.exceptions:
|
1417
|
-
Exception = self.exceptions[errorCode]
|
1418
|
-
raise Exception(self.id + ' ' + message)
|
1419
1418
|
if errorCode is not None:
|
1419
|
+
self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, message)
|
1420
1420
|
raise ExchangeError(self.id + ' ' + message)
|
1421
1421
|
return None
|
1422
1422
|
|
@@ -635,14 +635,12 @@ class krakenfutures(Exchange, ImplicitAPI):
|
|
635
635
|
request['from'] = self.parse_to_int(since / 1000)
|
636
636
|
if limit is None:
|
637
637
|
limit = 5000
|
638
|
-
|
639
|
-
raise BadRequest(self.id + ' fetchOHLCV() limit cannot exceed 5000')
|
638
|
+
limit = min(limit, 5000)
|
640
639
|
toTimestamp = self.sum(request['from'], limit * duration - 1)
|
641
640
|
currentTimestamp = self.seconds()
|
642
641
|
request['to'] = min(toTimestamp, currentTimestamp)
|
643
642
|
elif limit is not None:
|
644
|
-
|
645
|
-
raise BadRequest(self.id + ' fetchOHLCV() limit cannot exceed 5000')
|
643
|
+
limit = min(limit, 5000)
|
646
644
|
duration = self.parse_timeframe(timeframe)
|
647
645
|
request['to'] = self.seconds()
|
648
646
|
request['from'] = self.parse_to_int(request['to'] - (duration * limit))
|
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
from ccxt.async_support.kucoin import kucoin
|
7
7
|
from ccxt.abstract.kucoinfutures import ImplicitAPI
|
8
|
-
from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
8
|
+
from ccxt.base.types import Balances, Currency, Int, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
9
9
|
from typing import List
|
10
10
|
from ccxt.base.errors import PermissionDenied
|
11
11
|
from ccxt.base.errors import AccountSuspended
|
@@ -1424,7 +1424,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
|
|
1424
1424
|
#
|
1425
1425
|
return self.safe_value(response, 'data')
|
1426
1426
|
|
1427
|
-
async def add_margin(self, symbol: str, amount, params={}):
|
1427
|
+
async def add_margin(self, symbol: str, amount, params={}) -> MarginModification:
|
1428
1428
|
"""
|
1429
1429
|
add margin
|
1430
1430
|
:see: https://www.kucoin.com/docs/rest/futures-trading/positions/add-margin-manually
|
ccxt/async_support/lbank.py
CHANGED
@@ -970,6 +970,8 @@ class lbank(Exchange, ImplicitAPI):
|
|
970
970
|
market = self.market(symbol)
|
971
971
|
if limit is None:
|
972
972
|
limit = 100
|
973
|
+
else:
|
974
|
+
limit = min(limit, 2000)
|
973
975
|
if since is None:
|
974
976
|
duration = self.parse_timeframe(timeframe)
|
975
977
|
since = self.milliseconds() - duration * 1000 * limit
|
ccxt/async_support/mexc.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.mexc import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Account, Balances, Currency, IndexType, Int, Leverage, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
9
|
+
from ccxt.base.types import Account, Balances, Currency, IndexType, Int, Leverage, MarginModification, 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
|
@@ -3778,7 +3778,7 @@ class mexc(Exchange, ImplicitAPI):
|
|
3778
3778
|
# }
|
3779
3779
|
return response
|
3780
3780
|
|
3781
|
-
async def reduce_margin(self, symbol: str, amount, params={}):
|
3781
|
+
async def reduce_margin(self, symbol: str, amount, params={}) -> MarginModification:
|
3782
3782
|
"""
|
3783
3783
|
remove margin from a position
|
3784
3784
|
:param str symbol: unified market symbol
|
@@ -3788,7 +3788,7 @@ class mexc(Exchange, ImplicitAPI):
|
|
3788
3788
|
"""
|
3789
3789
|
return await self.modify_margin_helper(symbol, amount, 'SUB', params)
|
3790
3790
|
|
3791
|
-
async def add_margin(self, symbol: str, amount, params={}):
|
3791
|
+
async def add_margin(self, symbol: str, amount, params={}) -> MarginModification:
|
3792
3792
|
"""
|
3793
3793
|
add margin
|
3794
3794
|
:param str symbol: unified market symbol
|
ccxt/async_support/oceanex.py
CHANGED
@@ -750,7 +750,7 @@ class oceanex(Exchange, ImplicitAPI):
|
|
750
750
|
if since is not None:
|
751
751
|
request['timestamp'] = since
|
752
752
|
if limit is not None:
|
753
|
-
request['limit'] = limit
|
753
|
+
request['limit'] = min(limit, 10000)
|
754
754
|
response = await self.publicPostK(self.extend(request, params))
|
755
755
|
ohlcvs = self.safe_list(response, 'data', [])
|
756
756
|
return self.parse_ohlcvs(ohlcvs, market, timeframe, since, limit)
|
ccxt/async_support/okcoin.py
CHANGED
@@ -1121,8 +1121,9 @@ class okcoin(Exchange, ImplicitAPI):
|
|
1121
1121
|
request = {
|
1122
1122
|
'instId': market['id'],
|
1123
1123
|
'bar': bar,
|
1124
|
-
'limit': limit,
|
1125
1124
|
}
|
1125
|
+
if limit is not None:
|
1126
|
+
request['limit'] = limit # default 100, max 100
|
1126
1127
|
method = None
|
1127
1128
|
method, params = self.handle_option_and_params(params, 'fetchOHLCV', 'method', 'publicGetMarketCandles')
|
1128
1129
|
response = None
|
ccxt/async_support/okx.py
CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.okx import ImplicitAPI
|
8
8
|
import asyncio
|
9
9
|
import hashlib
|
10
|
-
from ccxt.base.types import Account, Balances, Currency, Greeks, Int, Leverage, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
10
|
+
from ccxt.base.types import Account, Balances, Currency, Greeks, Int, Leverage, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, 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
|
@@ -6007,7 +6007,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6007
6007
|
data = self.safe_value(response, 'data')
|
6008
6008
|
return self.parse_borrow_rate_history(data, code, since, limit)
|
6009
6009
|
|
6010
|
-
async def modify_margin_helper(self, symbol: str, amount, type, params={}):
|
6010
|
+
async def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
|
6011
6011
|
await self.load_markets()
|
6012
6012
|
market = self.market(symbol)
|
6013
6013
|
posSide = self.safe_string(params, 'posSide', 'net')
|
@@ -6033,29 +6033,43 @@ class okx(Exchange, ImplicitAPI):
|
|
6033
6033
|
# "msg": ""
|
6034
6034
|
# }
|
6035
6035
|
#
|
6036
|
-
|
6036
|
+
data = self.safe_list(response, 'data', [])
|
6037
|
+
errorCode = self.safe_string(response, 'code')
|
6038
|
+
item = self.safe_dict(data, 0, {})
|
6039
|
+
return self.extend(self.parse_margin_modification(item, market), {
|
6040
|
+
'status': 'ok' if (errorCode == '0') else 'failed',
|
6041
|
+
})
|
6037
6042
|
|
6038
|
-
def parse_margin_modification(self, data, market: Market = None):
|
6039
|
-
|
6040
|
-
|
6041
|
-
|
6042
|
-
|
6043
|
-
|
6044
|
-
|
6043
|
+
def parse_margin_modification(self, data, market: Market = None) -> MarginModification:
|
6044
|
+
#
|
6045
|
+
# addMargin/reduceMargin
|
6046
|
+
#
|
6047
|
+
# {
|
6048
|
+
# "amt": "0.01",
|
6049
|
+
# "instId": "ETH-USD-SWAP",
|
6050
|
+
# "posSide": "net",
|
6051
|
+
# "type": "reduce"
|
6052
|
+
# }
|
6053
|
+
#
|
6054
|
+
amountRaw = self.safe_number(data, 'amt')
|
6055
|
+
typeRaw = self.safe_string(data, 'type')
|
6045
6056
|
type = 'reduce' if (typeRaw == 'reduce') else 'add'
|
6046
|
-
marketId = self.safe_string(
|
6057
|
+
marketId = self.safe_string(data, 'instId')
|
6047
6058
|
responseMarket = self.safe_market(marketId, market)
|
6048
6059
|
code = responseMarket['base'] if responseMarket['inverse'] else responseMarket['quote']
|
6049
6060
|
return {
|
6050
6061
|
'info': data,
|
6062
|
+
'symbol': responseMarket['symbol'],
|
6051
6063
|
'type': type,
|
6052
6064
|
'amount': amountRaw,
|
6065
|
+
'total': None,
|
6053
6066
|
'code': code,
|
6054
|
-
'
|
6055
|
-
'
|
6067
|
+
'status': None,
|
6068
|
+
'timestamp': None,
|
6069
|
+
'datetime': None,
|
6056
6070
|
}
|
6057
6071
|
|
6058
|
-
async def reduce_margin(self, symbol: str, amount, params={}):
|
6072
|
+
async def reduce_margin(self, symbol: str, amount, params={}) -> MarginModification:
|
6059
6073
|
"""
|
6060
6074
|
remove margin from a position
|
6061
6075
|
:see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-increase-decrease-margin
|
@@ -6066,7 +6080,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6066
6080
|
"""
|
6067
6081
|
return await self.modify_margin_helper(symbol, amount, 'reduce', params)
|
6068
6082
|
|
6069
|
-
async def add_margin(self, symbol: str, amount, params={}):
|
6083
|
+
async def add_margin(self, symbol: str, amount, params={}) -> MarginModification:
|
6070
6084
|
"""
|
6071
6085
|
add margin
|
6072
6086
|
:see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-increase-decrease-margin
|
ccxt/async_support/phemex.py
CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.phemex import ImplicitAPI
|
8
8
|
import hashlib
|
9
9
|
import numbers
|
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 Balances, Currency, Int, MarginModification, 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
|
@@ -3744,7 +3744,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3744
3744
|
'previousFundingDatetime': None,
|
3745
3745
|
}
|
3746
3746
|
|
3747
|
-
async def set_margin(self, symbol: str, amount: float, params={}):
|
3747
|
+
async def set_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
|
3748
3748
|
"""
|
3749
3749
|
Either adds or reduces margin in an isolated position in order to set the margin to a specific value
|
3750
3750
|
:see: https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#assign-position-balance-in-isolated-marign-mode
|
@@ -3777,7 +3777,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3777
3777
|
}
|
3778
3778
|
return self.safe_string(statuses, status, status)
|
3779
3779
|
|
3780
|
-
def parse_margin_modification(self, data, market: Market = None):
|
3780
|
+
def parse_margin_modification(self, data, market: Market = None) -> MarginModification:
|
3781
3781
|
#
|
3782
3782
|
# {
|
3783
3783
|
# "code": 0,
|
@@ -3790,12 +3790,14 @@ class phemex(Exchange, ImplicitAPI):
|
|
3790
3790
|
codeCurrency = 'base' if inverse else 'quote'
|
3791
3791
|
return {
|
3792
3792
|
'info': data,
|
3793
|
+
'symbol': self.safe_symbol(None, market),
|
3793
3794
|
'type': 'set',
|
3794
3795
|
'amount': None,
|
3795
3796
|
'total': None,
|
3796
3797
|
'code': market[codeCurrency],
|
3797
|
-
'symbol': self.safe_symbol(None, market),
|
3798
3798
|
'status': self.parse_margin_status(self.safe_string(data, 'code')),
|
3799
|
+
'timestamp': None,
|
3800
|
+
'datetime': None,
|
3799
3801
|
}
|
3800
3802
|
|
3801
3803
|
async def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
|
ccxt/async_support/wazirx.py
CHANGED
@@ -324,7 +324,7 @@ class wazirx(Exchange, ImplicitAPI):
|
|
324
324
|
'interval': self.safe_string(self.timeframes, timeframe, timeframe),
|
325
325
|
}
|
326
326
|
if limit is not None:
|
327
|
-
request['limit'] = limit
|
327
|
+
request['limit'] = min(limit, 2000)
|
328
328
|
until = self.safe_integer(params, 'until')
|
329
329
|
params = self.omit(params, ['until'])
|
330
330
|
if since is not None:
|