ccxt 4.4.49__py2.py3-none-any.whl → 4.4.51__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/binance.py +1 -0
- ccxt/abstract/binancecoinm.py +1 -0
- ccxt/abstract/binanceus.py +1 -0
- ccxt/abstract/binanceusdm.py +1 -0
- ccxt/alpaca.py +63 -2
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/alpaca.py +63 -2
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +39 -20
- ccxt/async_support/blofin.py +5 -1
- ccxt/async_support/coinex.py +4 -4
- ccxt/async_support/coinmetro.py +16 -3
- ccxt/async_support/deribit.py +11 -3
- ccxt/async_support/gate.py +1 -1
- ccxt/async_support/hollaex.py +14 -17
- ccxt/async_support/htx.py +5 -3
- ccxt/async_support/kucoin.py +49 -69
- ccxt/async_support/mexc.py +24 -8
- ccxt/async_support/okcoin.py +13 -5
- ccxt/async_support/onetrading.py +1 -1
- ccxt/async_support/paradex.py +1 -1
- ccxt/async_support/paymium.py +42 -0
- ccxt/async_support/probit.py +77 -8
- ccxt/async_support/timex.py +67 -0
- ccxt/async_support/tokocrypto.py +81 -4
- ccxt/async_support/tradeogre.py +58 -1
- ccxt/async_support/vertex.py +65 -2
- ccxt/async_support/wavesexchange.py +73 -0
- ccxt/async_support/wazirx.py +59 -3
- ccxt/async_support/whitebit.py +79 -4
- ccxt/async_support/xt.py +112 -0
- ccxt/async_support/yobit.py +56 -0
- ccxt/async_support/zaif.py +55 -0
- ccxt/async_support/zonda.py +58 -0
- ccxt/base/exchange.py +72 -4
- ccxt/binance.py +39 -20
- ccxt/blofin.py +5 -1
- ccxt/coinex.py +4 -4
- ccxt/coinmetro.py +16 -3
- ccxt/deribit.py +11 -3
- ccxt/gate.py +1 -1
- ccxt/hollaex.py +14 -17
- ccxt/htx.py +5 -3
- ccxt/kucoin.py +49 -69
- ccxt/mexc.py +24 -8
- ccxt/okcoin.py +13 -5
- ccxt/onetrading.py +1 -1
- ccxt/paradex.py +1 -1
- ccxt/paymium.py +42 -0
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +2 -0
- ccxt/pro/blofin.py +8 -0
- ccxt/pro/coinex.py +4 -1
- ccxt/probit.py +77 -8
- ccxt/timex.py +67 -0
- ccxt/tokocrypto.py +81 -4
- ccxt/tradeogre.py +58 -1
- ccxt/vertex.py +65 -2
- ccxt/wavesexchange.py +73 -0
- ccxt/wazirx.py +59 -3
- ccxt/whitebit.py +79 -4
- ccxt/xt.py +112 -0
- ccxt/yobit.py +56 -0
- ccxt/zaif.py +55 -0
- ccxt/zonda.py +58 -0
- {ccxt-4.4.49.dist-info → ccxt-4.4.51.dist-info}/METADATA +18 -18
- {ccxt-4.4.49.dist-info → ccxt-4.4.51.dist-info}/RECORD +71 -71
- {ccxt-4.4.49.dist-info → ccxt-4.4.51.dist-info}/WHEEL +1 -1
- {ccxt-4.4.49.dist-info → ccxt-4.4.51.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.49.dist-info → ccxt-4.4.51.dist-info}/top_level.txt +0 -0
ccxt/coinmetro.py
CHANGED
@@ -219,7 +219,7 @@ class coinmetro(Exchange, ImplicitAPI):
|
|
219
219
|
# exchange-specific options
|
220
220
|
'options': {
|
221
221
|
'currenciesByIdForParseMarket': None,
|
222
|
-
'currencyIdsListForParseMarket':
|
222
|
+
'currencyIdsListForParseMarket': ['QRDO'],
|
223
223
|
},
|
224
224
|
'features': {
|
225
225
|
'spot': {
|
@@ -407,7 +407,11 @@ class coinmetro(Exchange, ImplicitAPI):
|
|
407
407
|
if self.safe_value(self.options, 'currenciesByIdForParseMarket') is None:
|
408
408
|
currenciesById = self.index_by(result, 'id')
|
409
409
|
self.options['currenciesByIdForParseMarket'] = currenciesById
|
410
|
-
self.options
|
410
|
+
currentCurrencyIdsList = self.safe_list(self.options, 'currencyIdsListForParseMarket', [])
|
411
|
+
currencyIdsList = list(currenciesById.keys())
|
412
|
+
for i in range(0, len(currencyIdsList)):
|
413
|
+
currentCurrencyIdsList.append(currencyIdsList[i])
|
414
|
+
self.options['currencyIdsListForParseMarket'] = currentCurrencyIdsList
|
411
415
|
return result
|
412
416
|
|
413
417
|
def fetch_markets(self, params={}) -> List[Market]:
|
@@ -506,10 +510,19 @@ class coinmetro(Exchange, ImplicitAPI):
|
|
506
510
|
baseId = None
|
507
511
|
quoteId = None
|
508
512
|
currencyIds = self.safe_value(self.options, 'currencyIdsListForParseMarket', [])
|
513
|
+
# Bubble sort by length(longest first)
|
514
|
+
currencyIdsLength = len(currencyIds)
|
515
|
+
for i in range(0, currencyIdsLength):
|
516
|
+
for j in range(0, currencyIdsLength - i - 1):
|
517
|
+
a = currencyIds[j]
|
518
|
+
b = currencyIds[j + 1]
|
519
|
+
if len(a) < len(b):
|
520
|
+
currencyIds[j] = b
|
521
|
+
currencyIds[j + 1] = a
|
509
522
|
for i in range(0, len(currencyIds)):
|
510
523
|
currencyId = currencyIds[i]
|
511
524
|
entryIndex = marketId.find(currencyId)
|
512
|
-
if entryIndex
|
525
|
+
if entryIndex == 0:
|
513
526
|
restId = marketId.replace(currencyId, '')
|
514
527
|
if self.in_array(restId, currencyIds):
|
515
528
|
if entryIndex == 0:
|
ccxt/deribit.py
CHANGED
@@ -3063,7 +3063,7 @@ class deribit(Exchange, ImplicitAPI):
|
|
3063
3063
|
:param int [since]: the earliest time in ms to fetch funding rate history for
|
3064
3064
|
:param int [limit]: the maximum number of entries to retrieve
|
3065
3065
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3066
|
-
:param int [params.
|
3066
|
+
:param int [params.until]: fetch funding rate ending at self timestamp
|
3067
3067
|
: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)
|
3068
3068
|
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
3069
3069
|
"""
|
@@ -3072,16 +3072,24 @@ class deribit(Exchange, ImplicitAPI):
|
|
3072
3072
|
paginate = False
|
3073
3073
|
paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
|
3074
3074
|
if paginate:
|
3075
|
-
|
3075
|
+
# 1h needed to fix : https://github.com/ccxt/ccxt/issues/25040
|
3076
|
+
return self.fetch_paginated_call_deterministic('fetchFundingRateHistory', symbol, since, limit, '1h', params, 720)
|
3076
3077
|
time = self.milliseconds()
|
3077
3078
|
month = 30 * 24 * 60 * 60 * 1000
|
3078
3079
|
if since is None:
|
3079
3080
|
since = time - month
|
3081
|
+
else:
|
3082
|
+
time = since + month
|
3080
3083
|
request: dict = {
|
3081
3084
|
'instrument_name': market['id'],
|
3082
3085
|
'start_timestamp': since - 1,
|
3083
|
-
'end_timestamp': time,
|
3084
3086
|
}
|
3087
|
+
until = self.safe_integer_2(params, 'until', 'end_timestamp')
|
3088
|
+
if until is not None:
|
3089
|
+
params = self.omit(params, ['until'])
|
3090
|
+
request['end_timestamp'] = until
|
3091
|
+
else:
|
3092
|
+
request['end_timestamp'] = time
|
3085
3093
|
response = self.publicGetGetFundingRateHistory(self.extend(request, params))
|
3086
3094
|
#
|
3087
3095
|
# {
|
ccxt/gate.py
CHANGED
@@ -1791,7 +1791,7 @@ class gate(Exchange, ImplicitAPI):
|
|
1791
1791
|
active = listed and tradeEnabled and withdrawEnabled and depositEnabled
|
1792
1792
|
if self.safe_value(result, code) is None:
|
1793
1793
|
result[code] = {
|
1794
|
-
'id':
|
1794
|
+
'id': currency,
|
1795
1795
|
'code': code,
|
1796
1796
|
'info': None,
|
1797
1797
|
'name': None,
|
ccxt/hollaex.py
CHANGED
@@ -829,7 +829,7 @@ class hollaex(Exchange, ImplicitAPI):
|
|
829
829
|
|
830
830
|
def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
831
831
|
"""
|
832
|
-
|
832
|
+
hollaex has large gaps between candles, so it's recommended to specify since
|
833
833
|
|
834
834
|
https://apidocs.hollaex.com/#chart
|
835
835
|
|
@@ -838,6 +838,7 @@ class hollaex(Exchange, ImplicitAPI):
|
|
838
838
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
839
839
|
:param int [limit]: the maximum amount of candles to fetch
|
840
840
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
841
|
+
:param int [params.until]: timestamp in ms of the latest candle to fetch
|
841
842
|
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
842
843
|
"""
|
843
844
|
self.load_markets()
|
@@ -846,22 +847,17 @@ class hollaex(Exchange, ImplicitAPI):
|
|
846
847
|
'symbol': market['id'],
|
847
848
|
'resolution': self.safe_string(self.timeframes, timeframe, timeframe),
|
848
849
|
}
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
request['
|
856
|
-
request['from'] = start
|
850
|
+
until = self.safe_integer(params, 'until')
|
851
|
+
end = self.seconds()
|
852
|
+
if until is not None:
|
853
|
+
end = self.parse_to_int(until / 1000)
|
854
|
+
defaultSpan = 2592000 # 30 days
|
855
|
+
if since is not None:
|
856
|
+
request['from'] = self.parse_to_int(since / 1000)
|
857
857
|
else:
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
else:
|
862
|
-
start = self.parse_to_int(since / 1000)
|
863
|
-
request['from'] = start
|
864
|
-
request['to'] = self.sum(start, duration * limit)
|
858
|
+
request['from'] = end - defaultSpan
|
859
|
+
request['to'] = end
|
860
|
+
params = self.omit(params, 'until')
|
865
861
|
response = self.publicGetChart(self.extend(request, params))
|
866
862
|
#
|
867
863
|
# [
|
@@ -1916,13 +1912,14 @@ class hollaex(Exchange, ImplicitAPI):
|
|
1916
1912
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
1917
1913
|
|
1918
1914
|
def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
|
1915
|
+
# {"message": "Invalid token"}
|
1919
1916
|
if response is None:
|
1920
1917
|
return None
|
1921
1918
|
if (code >= 400) and (code <= 503):
|
1922
1919
|
#
|
1923
1920
|
# {"message": "Invalid token"}
|
1924
1921
|
#
|
1925
|
-
# different errors return the same code eg
|
1922
|
+
# different errors return the same code eg
|
1926
1923
|
#
|
1927
1924
|
# {"message":"Error 1001 - Order rejected. Order could not be submitted order was set to a post only order."}
|
1928
1925
|
#
|
ccxt/htx.py
CHANGED
@@ -6991,10 +6991,12 @@ class htx(Exchange, ImplicitAPI):
|
|
6991
6991
|
'AccessKeyId': self.apiKey,
|
6992
6992
|
'Timestamp': timestamp,
|
6993
6993
|
}
|
6994
|
-
|
6995
|
-
request = self.extend(request, query)
|
6994
|
+
# sorting needs such flow exactly, before urlencoding(more at: https://github.com/ccxt/ccxt/issues/24930 )
|
6996
6995
|
request = self.keysort(request)
|
6997
|
-
|
6996
|
+
if method != 'POST':
|
6997
|
+
sortedQuery = self.keysort(query)
|
6998
|
+
request = self.extend(request, sortedQuery)
|
6999
|
+
auth = self.urlencode(request).replace('%2c', '%2C') # in c# it manually needs to be uppercased
|
6998
7000
|
# unfortunately, PHP demands double quotes for the escaped newline symbol
|
6999
7001
|
payload = "\n".join([method, hostname, url, auth]) # eslint-disable-line quotes
|
7000
7002
|
signature = self.hmac(self.encode(payload), self.encode(self.secret), hashlib.sha256, 'base64')
|
ccxt/kucoin.py
CHANGED
@@ -1351,8 +1351,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1351
1351
|
:param dict params: extra parameters specific to the exchange API endpoint
|
1352
1352
|
:returns dict: an associative dictionary of currencies
|
1353
1353
|
"""
|
1354
|
-
|
1355
|
-
promises.append(self.publicGetCurrencies(params))
|
1354
|
+
response = self.publicGetCurrencies(params)
|
1356
1355
|
#
|
1357
1356
|
# {
|
1358
1357
|
# "code":"200000",
|
@@ -1378,87 +1377,39 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1378
1377
|
# "isDepositEnabled":false,
|
1379
1378
|
# "confirms":12,
|
1380
1379
|
# "preConfirms":12,
|
1380
|
+
# "withdrawPrecision": 8,
|
1381
|
+
# "maxWithdraw": null,
|
1382
|
+
# "maxDeposit": null,
|
1383
|
+
# "needTag": False,
|
1381
1384
|
# "contractAddress":"0xa6446d655a0c34bc4f05042ee88170d056cbaf45",
|
1382
1385
|
# "depositFeeRate": "0.001", # present for some currencies/networks
|
1383
1386
|
# }
|
1384
1387
|
# ]
|
1385
1388
|
# },
|
1386
|
-
# }
|
1387
|
-
#
|
1388
|
-
promises.append(self.fetch_web_endpoint('fetchCurrencies', 'webExchangeGetCurrencyCurrencyChainInfo', True))
|
1389
|
-
#
|
1390
|
-
# {
|
1391
|
-
# "success": True,
|
1392
|
-
# "code": "200",
|
1393
|
-
# "msg": "success",
|
1394
|
-
# "retry": False,
|
1395
|
-
# "data": [
|
1396
|
-
# {
|
1397
|
-
# "status": "enabled",
|
1398
|
-
# "currency": "BTC",
|
1399
|
-
# "isChainEnabled": "true",
|
1400
|
-
# "chain": "btc",
|
1401
|
-
# "chainName": "BTC",
|
1402
|
-
# "chainFullName": "Bitcoin",
|
1403
|
-
# "walletPrecision": "8",
|
1404
|
-
# "isDepositEnabled": "true",
|
1405
|
-
# "depositMinSize": "0.00005",
|
1406
|
-
# "confirmationCount": "2",
|
1407
|
-
# "isWithdrawEnabled": "true",
|
1408
|
-
# "withdrawMinSize": "0.001",
|
1409
|
-
# "withdrawMinFee": "0.0005",
|
1410
|
-
# "withdrawFeeRate": "0",
|
1411
|
-
# "depositDisabledTip": "Wallet Maintenance",
|
1412
|
-
# "preDepositTipEnabled": "true",
|
1413
|
-
# "preDepositTip": "Do not transfer from ETH network directly",
|
1414
|
-
# "withdrawDisabledTip": "",
|
1415
|
-
# "preWithdrawTipEnabled": "false",
|
1416
|
-
# "preWithdrawTip": "",
|
1417
|
-
# "orgAddress": "",
|
1418
|
-
# "userAddressName": "Memo",
|
1419
|
-
# },
|
1420
1389
|
# ]
|
1421
1390
|
# }
|
1422
1391
|
#
|
1423
|
-
|
1424
|
-
currenciesResponse = self.safe_dict(responses, 0, {})
|
1425
|
-
currenciesData = self.safe_list(currenciesResponse, 'data', [])
|
1426
|
-
additionalResponse = self.safe_dict(responses, 1, {})
|
1427
|
-
additionalData = self.safe_list(additionalResponse, 'data', [])
|
1428
|
-
additionalDataGrouped = self.group_by(additionalData, 'currency')
|
1392
|
+
currenciesData = self.safe_list(response, 'data', [])
|
1429
1393
|
result: dict = {}
|
1430
1394
|
for i in range(0, len(currenciesData)):
|
1431
1395
|
entry = currenciesData[i]
|
1432
1396
|
id = self.safe_string(entry, 'currency')
|
1433
1397
|
name = self.safe_string(entry, 'fullName')
|
1434
1398
|
code = self.safe_currency_code(id)
|
1435
|
-
isWithdrawEnabled = None
|
1436
|
-
isDepositEnabled = None
|
1437
1399
|
networks: dict = {}
|
1438
1400
|
chains = self.safe_list(entry, 'chains', [])
|
1439
|
-
extraChainsData = self.index_by(self.safe_list(additionalDataGrouped, id, []), 'chain')
|
1440
1401
|
rawPrecision = self.safe_string(entry, 'precision')
|
1441
1402
|
precision = self.parse_number(self.parse_precision(rawPrecision))
|
1442
1403
|
chainsLength = len(chains)
|
1443
1404
|
if not chainsLength:
|
1444
|
-
# https://t.me/KuCoin_API/173118
|
1445
|
-
|
1446
|
-
isDepositEnabled = False
|
1405
|
+
# one buggy coin, which doesn't contain info https://t.me/KuCoin_API/173118
|
1406
|
+
continue
|
1447
1407
|
for j in range(0, chainsLength):
|
1448
1408
|
chain = chains[j]
|
1449
1409
|
chainId = self.safe_string(chain, 'chainId')
|
1450
1410
|
networkCode = self.network_id_to_code(chainId, code)
|
1451
1411
|
chainWithdrawEnabled = self.safe_bool(chain, 'isWithdrawEnabled', False)
|
1452
|
-
if isWithdrawEnabled is None:
|
1453
|
-
isWithdrawEnabled = chainWithdrawEnabled
|
1454
|
-
else:
|
1455
|
-
isWithdrawEnabled = isWithdrawEnabled or chainWithdrawEnabled
|
1456
1412
|
chainDepositEnabled = self.safe_bool(chain, 'isDepositEnabled', False)
|
1457
|
-
if isDepositEnabled is None:
|
1458
|
-
isDepositEnabled = chainDepositEnabled
|
1459
|
-
else:
|
1460
|
-
isDepositEnabled = isDepositEnabled or chainDepositEnabled
|
1461
|
-
chainExtraData = self.safe_dict(extraChainsData, chainId, {})
|
1462
1413
|
networks[networkCode] = {
|
1463
1414
|
'info': chain,
|
1464
1415
|
'id': chainId,
|
@@ -1468,34 +1419,34 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1468
1419
|
'fee': self.safe_number(chain, 'withdrawalMinFee'),
|
1469
1420
|
'deposit': chainDepositEnabled,
|
1470
1421
|
'withdraw': chainWithdrawEnabled,
|
1471
|
-
'precision': self.parse_number(self.parse_precision(self.safe_string(
|
1422
|
+
'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'withdrawPrecision'))),
|
1472
1423
|
'limits': {
|
1473
1424
|
'withdraw': {
|
1474
1425
|
'min': self.safe_number(chain, 'withdrawalMinSize'),
|
1475
|
-
'max':
|
1426
|
+
'max': self.safe_number(chain, 'maxWithdraw'),
|
1476
1427
|
},
|
1477
1428
|
'deposit': {
|
1478
1429
|
'min': self.safe_number(chain, 'depositMinSize'),
|
1479
|
-
'max':
|
1430
|
+
'max': self.safe_number(chain, 'maxDeposit'),
|
1480
1431
|
},
|
1481
1432
|
},
|
1482
1433
|
}
|
1483
1434
|
# kucoin has determined 'fiat' currencies with below logic
|
1484
1435
|
isFiat = (rawPrecision == '2') and (chainsLength == 0)
|
1485
|
-
result[code] = {
|
1436
|
+
result[code] = self.safe_currency_structure({
|
1486
1437
|
'id': id,
|
1487
1438
|
'name': name,
|
1488
1439
|
'code': code,
|
1489
1440
|
'type': 'fiat' if isFiat else 'crypto',
|
1490
1441
|
'precision': precision,
|
1491
1442
|
'info': entry,
|
1492
|
-
'active': (isDepositEnabled or isWithdrawEnabled),
|
1493
|
-
'deposit': isDepositEnabled,
|
1494
|
-
'withdraw': isWithdrawEnabled,
|
1495
|
-
'fee': None,
|
1496
|
-
'limits': self.limits,
|
1497
1443
|
'networks': networks,
|
1498
|
-
|
1444
|
+
'deposit': None,
|
1445
|
+
'withdraw': None,
|
1446
|
+
'active': None,
|
1447
|
+
'fee': None,
|
1448
|
+
'limits': None,
|
1449
|
+
})
|
1499
1450
|
return result
|
1500
1451
|
|
1501
1452
|
def fetch_accounts(self, params={}) -> List[Account]:
|
@@ -1635,6 +1586,35 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1635
1586
|
# "chain": "ERC20"
|
1636
1587
|
# }
|
1637
1588
|
#
|
1589
|
+
if 'chains' in fee:
|
1590
|
+
# if data obtained through `currencies` endpoint
|
1591
|
+
resultNew: dict = {
|
1592
|
+
'info': fee,
|
1593
|
+
'withdraw': {
|
1594
|
+
'fee': None,
|
1595
|
+
'percentage': False,
|
1596
|
+
},
|
1597
|
+
'deposit': {
|
1598
|
+
'fee': None,
|
1599
|
+
'percentage': None,
|
1600
|
+
},
|
1601
|
+
'networks': {},
|
1602
|
+
}
|
1603
|
+
chains = self.safe_list(fee, 'chains', [])
|
1604
|
+
for i in range(0, len(chains)):
|
1605
|
+
chain = chains[i]
|
1606
|
+
networkCodeNew = self.network_id_to_code(self.safe_string(chain, 'chainId'), self.safe_string(currency, 'code'))
|
1607
|
+
resultNew['networks'][networkCodeNew] = {
|
1608
|
+
'withdraw': {
|
1609
|
+
'fee': self.safe_number(chain, 'withdrawMinFee'),
|
1610
|
+
'percentage': False,
|
1611
|
+
},
|
1612
|
+
'deposit': {
|
1613
|
+
'fee': None,
|
1614
|
+
'percentage': None,
|
1615
|
+
},
|
1616
|
+
}
|
1617
|
+
return resultNew
|
1638
1618
|
minWithdrawFee = self.safe_number(fee, 'withdrawMinFee')
|
1639
1619
|
result: dict = {
|
1640
1620
|
'info': fee,
|
@@ -3120,14 +3100,14 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3120
3100
|
if symbol is not None:
|
3121
3101
|
market = self.market(symbol)
|
3122
3102
|
request['symbol'] = market['id']
|
3123
|
-
if limit is not None:
|
3124
|
-
request['pageSize'] = limit
|
3125
3103
|
method = self.options['fetchMyTradesMethod']
|
3126
3104
|
parseResponseData = False
|
3127
3105
|
response = None
|
3128
3106
|
request, params = self.handle_until_option('endAt', request, params)
|
3129
3107
|
if hf:
|
3130
3108
|
# does not return trades earlier than 2019-02-18T00:00:00Z
|
3109
|
+
if limit is not None:
|
3110
|
+
request['limit'] = limit
|
3131
3111
|
if since is not None:
|
3132
3112
|
# only returns trades up to one week after the since param
|
3133
3113
|
request['startAt'] = since
|
ccxt/mexc.py
CHANGED
@@ -1379,6 +1379,7 @@ class mexc(Exchange, ImplicitAPI):
|
|
1379
1379
|
quote = self.safe_currency_code(quoteId)
|
1380
1380
|
settle = self.safe_currency_code(settleId)
|
1381
1381
|
state = self.safe_string(market, 'state')
|
1382
|
+
isLinear = quote == settle
|
1382
1383
|
result.append({
|
1383
1384
|
'id': id,
|
1384
1385
|
'symbol': base + '/' + quote + ':' + settle,
|
@@ -1396,8 +1397,8 @@ class mexc(Exchange, ImplicitAPI):
|
|
1396
1397
|
'option': False,
|
1397
1398
|
'active': (state == '0'),
|
1398
1399
|
'contract': True,
|
1399
|
-
'linear':
|
1400
|
-
'inverse':
|
1400
|
+
'linear': isLinear,
|
1401
|
+
'inverse': not isLinear,
|
1401
1402
|
'taker': self.safe_number(market, 'takerFeeRate'),
|
1402
1403
|
'maker': self.safe_number(market, 'makerFeeRate'),
|
1403
1404
|
'contractSize': self.safe_number(market, 'contractSize'),
|
@@ -2233,7 +2234,7 @@ class mexc(Exchange, ImplicitAPI):
|
|
2233
2234
|
:param bool [params.postOnly]: if True, the order will only be posted if it will be a maker order
|
2234
2235
|
:param bool [params.reduceOnly]: *contract only* indicates if self order is to reduce the size of a position
|
2235
2236
|
:param bool [params.hedged]: *swap only* True for hedged mode, False for one way mode, default is False
|
2236
|
-
|
2237
|
+
:param str [params.timeInForce]: 'IOC' or 'FOK', default is 'GTC'
|
2237
2238
|
EXCHANGE SPECIFIC PARAMETERS
|
2238
2239
|
:param int [params.leverage]: *contract only* leverage is necessary on isolated margin
|
2239
2240
|
:param long [params.positionId]: *contract only* it is recommended to hasattr(self, fill) parameter when closing a position
|
@@ -2288,6 +2289,13 @@ class mexc(Exchange, ImplicitAPI):
|
|
2288
2289
|
postOnly, params = self.handle_post_only(type == 'market', type == 'LIMIT_MAKER', params)
|
2289
2290
|
if postOnly:
|
2290
2291
|
request['type'] = 'LIMIT_MAKER'
|
2292
|
+
tif = self.safe_string(params, 'timeInForce')
|
2293
|
+
if tif is not None:
|
2294
|
+
params = self.omit(params, 'timeInForce')
|
2295
|
+
if tif == 'IOC':
|
2296
|
+
request['type'] = 'IMMEDIATE_OR_CANCEL'
|
2297
|
+
elif tif == 'FOK':
|
2298
|
+
request['type'] = 'FILL_OR_KILL'
|
2291
2299
|
return self.extend(request, params)
|
2292
2300
|
|
2293
2301
|
def create_spot_order(self, market, type, side, amount, price=None, marginMode=None, params={}):
|
@@ -5707,12 +5715,20 @@ class mexc(Exchange, ImplicitAPI):
|
|
5707
5715
|
url = self.urls['api'][section][access] + '/' + path
|
5708
5716
|
else:
|
5709
5717
|
url = self.urls['api'][section][access] + '/api/' + self.version + '/' + path
|
5710
|
-
|
5718
|
+
urlParams = params
|
5711
5719
|
if access == 'private':
|
5712
|
-
|
5713
|
-
|
5714
|
-
|
5715
|
-
|
5720
|
+
if section == 'broker' and ((method == 'POST') or (method == 'PUT') or (method == 'DELETE')):
|
5721
|
+
urlParams = {
|
5722
|
+
'timestamp': self.nonce(),
|
5723
|
+
'recvWindow': self.safe_integer(self.options, 'recvWindow', 5000),
|
5724
|
+
}
|
5725
|
+
body = self.json(params)
|
5726
|
+
else:
|
5727
|
+
urlParams['timestamp'] = self.nonce()
|
5728
|
+
urlParams['recvWindow'] = self.safe_integer(self.options, 'recvWindow', 5000)
|
5729
|
+
paramsEncoded = ''
|
5730
|
+
if urlParams:
|
5731
|
+
paramsEncoded = self.urlencode(urlParams)
|
5716
5732
|
url += '?' + paramsEncoded
|
5717
5733
|
if access == 'private':
|
5718
5734
|
self.check_required_credentials()
|
ccxt/okcoin.py
CHANGED
@@ -707,12 +707,20 @@ class okcoin(Exchange, ImplicitAPI):
|
|
707
707
|
"""
|
708
708
|
response = self.publicGetPublicTime(params)
|
709
709
|
#
|
710
|
-
#
|
711
|
-
#
|
712
|
-
#
|
713
|
-
#
|
710
|
+
# {
|
711
|
+
# "code": "0",
|
712
|
+
# "data":
|
713
|
+
# [
|
714
|
+
# {
|
715
|
+
# "ts": "1737379360033"
|
716
|
+
# }
|
717
|
+
# ],
|
718
|
+
# "msg": ""
|
719
|
+
# }
|
714
720
|
#
|
715
|
-
|
721
|
+
data = self.safe_list(response, 'data')
|
722
|
+
timestamp = self.safe_dict(data, 0)
|
723
|
+
return self.safe_integer(timestamp, 'ts')
|
716
724
|
|
717
725
|
def fetch_markets(self, params={}) -> List[Market]:
|
718
726
|
"""
|
ccxt/onetrading.py
CHANGED
@@ -1200,7 +1200,7 @@ class onetrading(Exchange, ImplicitAPI):
|
|
1200
1200
|
https://docs.onetrading.com/#create-order
|
1201
1201
|
|
1202
1202
|
:param str symbol: unified symbol of the market to create an order in
|
1203
|
-
:param str type: '
|
1203
|
+
:param str type: 'limit'
|
1204
1204
|
:param str side: 'buy' or 'sell'
|
1205
1205
|
:param float amount: how much of currency you want to trade in units of base currency
|
1206
1206
|
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
ccxt/paradex.py
CHANGED
@@ -943,7 +943,7 @@ class paradex(Exchange, ImplicitAPI):
|
|
943
943
|
#
|
944
944
|
# {
|
945
945
|
# "symbol": "BTC-USD-PERP",
|
946
|
-
# "oracle_price": "68465.
|
946
|
+
# "oracle_price": "68465.17449904",
|
947
947
|
# "mark_price": "68465.17449906",
|
948
948
|
# "last_traded_price": "68495.1",
|
949
949
|
# "bid": "68477.6",
|
ccxt/paymium.py
CHANGED
@@ -113,6 +113,48 @@ class paymium(Exchange, ImplicitAPI):
|
|
113
113
|
},
|
114
114
|
},
|
115
115
|
'precisionMode': TICK_SIZE,
|
116
|
+
'features': {
|
117
|
+
'spot': {
|
118
|
+
'sandbox': False,
|
119
|
+
'createOrder': {
|
120
|
+
'marginMode': False,
|
121
|
+
'triggerPrice': False,
|
122
|
+
'triggerDirection': False,
|
123
|
+
'triggerPriceType': None,
|
124
|
+
'stopLossPrice': False,
|
125
|
+
'takeProfitPrice': False,
|
126
|
+
'attachedStopLossTakeProfit': None,
|
127
|
+
'timeInForce': {
|
128
|
+
'IOC': False,
|
129
|
+
'FOK': False,
|
130
|
+
'PO': False,
|
131
|
+
'GTD': False,
|
132
|
+
},
|
133
|
+
'hedged': False,
|
134
|
+
'trailing': False,
|
135
|
+
'leverage': False,
|
136
|
+
'marketBuyByCost': True, # todo
|
137
|
+
'marketBuyRequiresPrice': False,
|
138
|
+
'selfTradePrevention': False,
|
139
|
+
'iceberg': False,
|
140
|
+
},
|
141
|
+
'createOrders': None,
|
142
|
+
'fetchMyTrades': None,
|
143
|
+
'fetchOrder': None, # todo
|
144
|
+
'fetchOpenOrders': None, # todo
|
145
|
+
'fetchOrders': None, # todo
|
146
|
+
'fetchClosedOrders': None, # todo
|
147
|
+
'fetchOHLCV': None, # todo
|
148
|
+
},
|
149
|
+
'swap': {
|
150
|
+
'linear': None,
|
151
|
+
'inverse': None,
|
152
|
+
},
|
153
|
+
'future': {
|
154
|
+
'linear': None,
|
155
|
+
'inverse': None,
|
156
|
+
},
|
157
|
+
},
|
116
158
|
})
|
117
159
|
|
118
160
|
def parse_balance(self, response) -> Balances:
|
ccxt/pro/__init__.py
CHANGED
ccxt/pro/binance.py
CHANGED
@@ -2215,6 +2215,7 @@ class binance(ccxt.async_support.binance):
|
|
2215
2215
|
response = None
|
2216
2216
|
if isPortfolioMargin:
|
2217
2217
|
response = await self.papiPostListenKey(params)
|
2218
|
+
params = self.extend(params, {'portfolioMargin': True})
|
2218
2219
|
elif type == 'future':
|
2219
2220
|
response = await self.fapiPrivatePostListenKey(params)
|
2220
2221
|
elif type == 'delivery':
|
@@ -2259,6 +2260,7 @@ class binance(ccxt.async_support.binance):
|
|
2259
2260
|
try:
|
2260
2261
|
if isPortfolioMargin:
|
2261
2262
|
await self.papiPutListenKey(self.extend(request, params))
|
2263
|
+
params = self.extend(params, {'portfolioMargin': True})
|
2262
2264
|
elif type == 'future':
|
2263
2265
|
await self.fapiPrivatePutListenKey(self.extend(request, params))
|
2264
2266
|
elif type == 'delivery':
|
ccxt/pro/blofin.py
CHANGED
@@ -42,6 +42,14 @@ class blofin(ccxt.async_support.blofin):
|
|
42
42
|
},
|
43
43
|
},
|
44
44
|
},
|
45
|
+
'test': {
|
46
|
+
'ws': {
|
47
|
+
'swap': {
|
48
|
+
'public': 'wss://demo-trading-openapi.blofin.com/ws/public',
|
49
|
+
'private': 'wss://demo-trading-openapi.blofin.com/ws/private',
|
50
|
+
},
|
51
|
+
},
|
52
|
+
},
|
45
53
|
},
|
46
54
|
'options': {
|
47
55
|
'defaultType': 'swap',
|
ccxt/pro/coinex.py
CHANGED
@@ -263,7 +263,10 @@ class coinex(ccxt.async_support.coinex):
|
|
263
263
|
type, params = self.handle_market_type_and_params('watchBalance', None, params, 'spot')
|
264
264
|
await self.authenticate(type)
|
265
265
|
url = self.urls['api']['ws'][type]
|
266
|
-
currencies
|
266
|
+
# coinex throws a closes the websocket when subscribing over 1422 currencies, therefore we filter out inactive currencies
|
267
|
+
activeCurrencies = self.filter_by(self.currencies_by_id, 'active', True)
|
268
|
+
activeCurrenciesById = self.index_by(activeCurrencies, 'id')
|
269
|
+
currencies = list(activeCurrenciesById.keys())
|
267
270
|
if currencies is None:
|
268
271
|
currencies = []
|
269
272
|
messageHash = 'balances'
|