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/async_support/hollaex.py
CHANGED
@@ -829,7 +829,7 @@ class hollaex(Exchange, ImplicitAPI):
|
|
829
829
|
|
830
830
|
async 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
|
await 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 = await 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/async_support/htx.py
CHANGED
@@ -6992,10 +6992,12 @@ class htx(Exchange, ImplicitAPI):
|
|
6992
6992
|
'AccessKeyId': self.apiKey,
|
6993
6993
|
'Timestamp': timestamp,
|
6994
6994
|
}
|
6995
|
-
|
6996
|
-
request = self.extend(request, query)
|
6995
|
+
# sorting needs such flow exactly, before urlencoding(more at: https://github.com/ccxt/ccxt/issues/24930 )
|
6997
6996
|
request = self.keysort(request)
|
6998
|
-
|
6997
|
+
if method != 'POST':
|
6998
|
+
sortedQuery = self.keysort(query)
|
6999
|
+
request = self.extend(request, sortedQuery)
|
7000
|
+
auth = self.urlencode(request).replace('%2c', '%2C') # in c# it manually needs to be uppercased
|
6999
7001
|
# unfortunately, PHP demands double quotes for the escaped newline symbol
|
7000
7002
|
payload = "\n".join([method, hostname, url, auth]) # eslint-disable-line quotes
|
7001
7003
|
signature = self.hmac(self.encode(payload), self.encode(self.secret), hashlib.sha256, 'base64')
|
ccxt/async_support/kucoin.py
CHANGED
@@ -1352,8 +1352,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1352
1352
|
:param dict params: extra parameters specific to the exchange API endpoint
|
1353
1353
|
:returns dict: an associative dictionary of currencies
|
1354
1354
|
"""
|
1355
|
-
|
1356
|
-
promises.append(self.publicGetCurrencies(params))
|
1355
|
+
response = await self.publicGetCurrencies(params)
|
1357
1356
|
#
|
1358
1357
|
# {
|
1359
1358
|
# "code":"200000",
|
@@ -1379,87 +1378,39 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1379
1378
|
# "isDepositEnabled":false,
|
1380
1379
|
# "confirms":12,
|
1381
1380
|
# "preConfirms":12,
|
1381
|
+
# "withdrawPrecision": 8,
|
1382
|
+
# "maxWithdraw": null,
|
1383
|
+
# "maxDeposit": null,
|
1384
|
+
# "needTag": False,
|
1382
1385
|
# "contractAddress":"0xa6446d655a0c34bc4f05042ee88170d056cbaf45",
|
1383
1386
|
# "depositFeeRate": "0.001", # present for some currencies/networks
|
1384
1387
|
# }
|
1385
1388
|
# ]
|
1386
1389
|
# },
|
1387
|
-
# }
|
1388
|
-
#
|
1389
|
-
promises.append(self.fetch_web_endpoint('fetchCurrencies', 'webExchangeGetCurrencyCurrencyChainInfo', True))
|
1390
|
-
#
|
1391
|
-
# {
|
1392
|
-
# "success": True,
|
1393
|
-
# "code": "200",
|
1394
|
-
# "msg": "success",
|
1395
|
-
# "retry": False,
|
1396
|
-
# "data": [
|
1397
|
-
# {
|
1398
|
-
# "status": "enabled",
|
1399
|
-
# "currency": "BTC",
|
1400
|
-
# "isChainEnabled": "true",
|
1401
|
-
# "chain": "btc",
|
1402
|
-
# "chainName": "BTC",
|
1403
|
-
# "chainFullName": "Bitcoin",
|
1404
|
-
# "walletPrecision": "8",
|
1405
|
-
# "isDepositEnabled": "true",
|
1406
|
-
# "depositMinSize": "0.00005",
|
1407
|
-
# "confirmationCount": "2",
|
1408
|
-
# "isWithdrawEnabled": "true",
|
1409
|
-
# "withdrawMinSize": "0.001",
|
1410
|
-
# "withdrawMinFee": "0.0005",
|
1411
|
-
# "withdrawFeeRate": "0",
|
1412
|
-
# "depositDisabledTip": "Wallet Maintenance",
|
1413
|
-
# "preDepositTipEnabled": "true",
|
1414
|
-
# "preDepositTip": "Do not transfer from ETH network directly",
|
1415
|
-
# "withdrawDisabledTip": "",
|
1416
|
-
# "preWithdrawTipEnabled": "false",
|
1417
|
-
# "preWithdrawTip": "",
|
1418
|
-
# "orgAddress": "",
|
1419
|
-
# "userAddressName": "Memo",
|
1420
|
-
# },
|
1421
1390
|
# ]
|
1422
1391
|
# }
|
1423
1392
|
#
|
1424
|
-
|
1425
|
-
currenciesResponse = self.safe_dict(responses, 0, {})
|
1426
|
-
currenciesData = self.safe_list(currenciesResponse, 'data', [])
|
1427
|
-
additionalResponse = self.safe_dict(responses, 1, {})
|
1428
|
-
additionalData = self.safe_list(additionalResponse, 'data', [])
|
1429
|
-
additionalDataGrouped = self.group_by(additionalData, 'currency')
|
1393
|
+
currenciesData = self.safe_list(response, 'data', [])
|
1430
1394
|
result: dict = {}
|
1431
1395
|
for i in range(0, len(currenciesData)):
|
1432
1396
|
entry = currenciesData[i]
|
1433
1397
|
id = self.safe_string(entry, 'currency')
|
1434
1398
|
name = self.safe_string(entry, 'fullName')
|
1435
1399
|
code = self.safe_currency_code(id)
|
1436
|
-
isWithdrawEnabled = None
|
1437
|
-
isDepositEnabled = None
|
1438
1400
|
networks: dict = {}
|
1439
1401
|
chains = self.safe_list(entry, 'chains', [])
|
1440
|
-
extraChainsData = self.index_by(self.safe_list(additionalDataGrouped, id, []), 'chain')
|
1441
1402
|
rawPrecision = self.safe_string(entry, 'precision')
|
1442
1403
|
precision = self.parse_number(self.parse_precision(rawPrecision))
|
1443
1404
|
chainsLength = len(chains)
|
1444
1405
|
if not chainsLength:
|
1445
|
-
# https://t.me/KuCoin_API/173118
|
1446
|
-
|
1447
|
-
isDepositEnabled = False
|
1406
|
+
# one buggy coin, which doesn't contain info https://t.me/KuCoin_API/173118
|
1407
|
+
continue
|
1448
1408
|
for j in range(0, chainsLength):
|
1449
1409
|
chain = chains[j]
|
1450
1410
|
chainId = self.safe_string(chain, 'chainId')
|
1451
1411
|
networkCode = self.network_id_to_code(chainId, code)
|
1452
1412
|
chainWithdrawEnabled = self.safe_bool(chain, 'isWithdrawEnabled', False)
|
1453
|
-
if isWithdrawEnabled is None:
|
1454
|
-
isWithdrawEnabled = chainWithdrawEnabled
|
1455
|
-
else:
|
1456
|
-
isWithdrawEnabled = isWithdrawEnabled or chainWithdrawEnabled
|
1457
1413
|
chainDepositEnabled = self.safe_bool(chain, 'isDepositEnabled', False)
|
1458
|
-
if isDepositEnabled is None:
|
1459
|
-
isDepositEnabled = chainDepositEnabled
|
1460
|
-
else:
|
1461
|
-
isDepositEnabled = isDepositEnabled or chainDepositEnabled
|
1462
|
-
chainExtraData = self.safe_dict(extraChainsData, chainId, {})
|
1463
1414
|
networks[networkCode] = {
|
1464
1415
|
'info': chain,
|
1465
1416
|
'id': chainId,
|
@@ -1469,34 +1420,34 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1469
1420
|
'fee': self.safe_number(chain, 'withdrawalMinFee'),
|
1470
1421
|
'deposit': chainDepositEnabled,
|
1471
1422
|
'withdraw': chainWithdrawEnabled,
|
1472
|
-
'precision': self.parse_number(self.parse_precision(self.safe_string(
|
1423
|
+
'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'withdrawPrecision'))),
|
1473
1424
|
'limits': {
|
1474
1425
|
'withdraw': {
|
1475
1426
|
'min': self.safe_number(chain, 'withdrawalMinSize'),
|
1476
|
-
'max':
|
1427
|
+
'max': self.safe_number(chain, 'maxWithdraw'),
|
1477
1428
|
},
|
1478
1429
|
'deposit': {
|
1479
1430
|
'min': self.safe_number(chain, 'depositMinSize'),
|
1480
|
-
'max':
|
1431
|
+
'max': self.safe_number(chain, 'maxDeposit'),
|
1481
1432
|
},
|
1482
1433
|
},
|
1483
1434
|
}
|
1484
1435
|
# kucoin has determined 'fiat' currencies with below logic
|
1485
1436
|
isFiat = (rawPrecision == '2') and (chainsLength == 0)
|
1486
|
-
result[code] = {
|
1437
|
+
result[code] = self.safe_currency_structure({
|
1487
1438
|
'id': id,
|
1488
1439
|
'name': name,
|
1489
1440
|
'code': code,
|
1490
1441
|
'type': 'fiat' if isFiat else 'crypto',
|
1491
1442
|
'precision': precision,
|
1492
1443
|
'info': entry,
|
1493
|
-
'active': (isDepositEnabled or isWithdrawEnabled),
|
1494
|
-
'deposit': isDepositEnabled,
|
1495
|
-
'withdraw': isWithdrawEnabled,
|
1496
|
-
'fee': None,
|
1497
|
-
'limits': self.limits,
|
1498
1444
|
'networks': networks,
|
1499
|
-
|
1445
|
+
'deposit': None,
|
1446
|
+
'withdraw': None,
|
1447
|
+
'active': None,
|
1448
|
+
'fee': None,
|
1449
|
+
'limits': None,
|
1450
|
+
})
|
1500
1451
|
return result
|
1501
1452
|
|
1502
1453
|
async def fetch_accounts(self, params={}) -> List[Account]:
|
@@ -1636,6 +1587,35 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1636
1587
|
# "chain": "ERC20"
|
1637
1588
|
# }
|
1638
1589
|
#
|
1590
|
+
if 'chains' in fee:
|
1591
|
+
# if data obtained through `currencies` endpoint
|
1592
|
+
resultNew: dict = {
|
1593
|
+
'info': fee,
|
1594
|
+
'withdraw': {
|
1595
|
+
'fee': None,
|
1596
|
+
'percentage': False,
|
1597
|
+
},
|
1598
|
+
'deposit': {
|
1599
|
+
'fee': None,
|
1600
|
+
'percentage': None,
|
1601
|
+
},
|
1602
|
+
'networks': {},
|
1603
|
+
}
|
1604
|
+
chains = self.safe_list(fee, 'chains', [])
|
1605
|
+
for i in range(0, len(chains)):
|
1606
|
+
chain = chains[i]
|
1607
|
+
networkCodeNew = self.network_id_to_code(self.safe_string(chain, 'chainId'), self.safe_string(currency, 'code'))
|
1608
|
+
resultNew['networks'][networkCodeNew] = {
|
1609
|
+
'withdraw': {
|
1610
|
+
'fee': self.safe_number(chain, 'withdrawMinFee'),
|
1611
|
+
'percentage': False,
|
1612
|
+
},
|
1613
|
+
'deposit': {
|
1614
|
+
'fee': None,
|
1615
|
+
'percentage': None,
|
1616
|
+
},
|
1617
|
+
}
|
1618
|
+
return resultNew
|
1639
1619
|
minWithdrawFee = self.safe_number(fee, 'withdrawMinFee')
|
1640
1620
|
result: dict = {
|
1641
1621
|
'info': fee,
|
@@ -3121,14 +3101,14 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3121
3101
|
if symbol is not None:
|
3122
3102
|
market = self.market(symbol)
|
3123
3103
|
request['symbol'] = market['id']
|
3124
|
-
if limit is not None:
|
3125
|
-
request['pageSize'] = limit
|
3126
3104
|
method = self.options['fetchMyTradesMethod']
|
3127
3105
|
parseResponseData = False
|
3128
3106
|
response = None
|
3129
3107
|
request, params = self.handle_until_option('endAt', request, params)
|
3130
3108
|
if hf:
|
3131
3109
|
# does not return trades earlier than 2019-02-18T00:00:00Z
|
3110
|
+
if limit is not None:
|
3111
|
+
request['limit'] = limit
|
3132
3112
|
if since is not None:
|
3133
3113
|
# only returns trades up to one week after the since param
|
3134
3114
|
request['startAt'] = since
|
ccxt/async_support/mexc.py
CHANGED
@@ -1380,6 +1380,7 @@ class mexc(Exchange, ImplicitAPI):
|
|
1380
1380
|
quote = self.safe_currency_code(quoteId)
|
1381
1381
|
settle = self.safe_currency_code(settleId)
|
1382
1382
|
state = self.safe_string(market, 'state')
|
1383
|
+
isLinear = quote == settle
|
1383
1384
|
result.append({
|
1384
1385
|
'id': id,
|
1385
1386
|
'symbol': base + '/' + quote + ':' + settle,
|
@@ -1397,8 +1398,8 @@ class mexc(Exchange, ImplicitAPI):
|
|
1397
1398
|
'option': False,
|
1398
1399
|
'active': (state == '0'),
|
1399
1400
|
'contract': True,
|
1400
|
-
'linear':
|
1401
|
-
'inverse':
|
1401
|
+
'linear': isLinear,
|
1402
|
+
'inverse': not isLinear,
|
1402
1403
|
'taker': self.safe_number(market, 'takerFeeRate'),
|
1403
1404
|
'maker': self.safe_number(market, 'makerFeeRate'),
|
1404
1405
|
'contractSize': self.safe_number(market, 'contractSize'),
|
@@ -2234,7 +2235,7 @@ class mexc(Exchange, ImplicitAPI):
|
|
2234
2235
|
:param bool [params.postOnly]: if True, the order will only be posted if it will be a maker order
|
2235
2236
|
:param bool [params.reduceOnly]: *contract only* indicates if self order is to reduce the size of a position
|
2236
2237
|
:param bool [params.hedged]: *swap only* True for hedged mode, False for one way mode, default is False
|
2237
|
-
|
2238
|
+
:param str [params.timeInForce]: 'IOC' or 'FOK', default is 'GTC'
|
2238
2239
|
EXCHANGE SPECIFIC PARAMETERS
|
2239
2240
|
:param int [params.leverage]: *contract only* leverage is necessary on isolated margin
|
2240
2241
|
:param long [params.positionId]: *contract only* it is recommended to hasattr(self, fill) parameter when closing a position
|
@@ -2289,6 +2290,13 @@ class mexc(Exchange, ImplicitAPI):
|
|
2289
2290
|
postOnly, params = self.handle_post_only(type == 'market', type == 'LIMIT_MAKER', params)
|
2290
2291
|
if postOnly:
|
2291
2292
|
request['type'] = 'LIMIT_MAKER'
|
2293
|
+
tif = self.safe_string(params, 'timeInForce')
|
2294
|
+
if tif is not None:
|
2295
|
+
params = self.omit(params, 'timeInForce')
|
2296
|
+
if tif == 'IOC':
|
2297
|
+
request['type'] = 'IMMEDIATE_OR_CANCEL'
|
2298
|
+
elif tif == 'FOK':
|
2299
|
+
request['type'] = 'FILL_OR_KILL'
|
2292
2300
|
return self.extend(request, params)
|
2293
2301
|
|
2294
2302
|
async def create_spot_order(self, market, type, side, amount, price=None, marginMode=None, params={}):
|
@@ -5708,12 +5716,20 @@ class mexc(Exchange, ImplicitAPI):
|
|
5708
5716
|
url = self.urls['api'][section][access] + '/' + path
|
5709
5717
|
else:
|
5710
5718
|
url = self.urls['api'][section][access] + '/api/' + self.version + '/' + path
|
5711
|
-
|
5719
|
+
urlParams = params
|
5712
5720
|
if access == 'private':
|
5713
|
-
|
5714
|
-
|
5715
|
-
|
5716
|
-
|
5721
|
+
if section == 'broker' and ((method == 'POST') or (method == 'PUT') or (method == 'DELETE')):
|
5722
|
+
urlParams = {
|
5723
|
+
'timestamp': self.nonce(),
|
5724
|
+
'recvWindow': self.safe_integer(self.options, 'recvWindow', 5000),
|
5725
|
+
}
|
5726
|
+
body = self.json(params)
|
5727
|
+
else:
|
5728
|
+
urlParams['timestamp'] = self.nonce()
|
5729
|
+
urlParams['recvWindow'] = self.safe_integer(self.options, 'recvWindow', 5000)
|
5730
|
+
paramsEncoded = ''
|
5731
|
+
if urlParams:
|
5732
|
+
paramsEncoded = self.urlencode(urlParams)
|
5717
5733
|
url += '?' + paramsEncoded
|
5718
5734
|
if access == 'private':
|
5719
5735
|
self.check_required_credentials()
|
ccxt/async_support/okcoin.py
CHANGED
@@ -707,12 +707,20 @@ class okcoin(Exchange, ImplicitAPI):
|
|
707
707
|
"""
|
708
708
|
response = await 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
|
async def fetch_markets(self, params={}) -> List[Market]:
|
718
726
|
"""
|
ccxt/async_support/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/async_support/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/async_support/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/async_support/probit.py
CHANGED
@@ -103,7 +103,7 @@ class probit(Exchange, ImplicitAPI):
|
|
103
103
|
'fetchWithdrawal': False,
|
104
104
|
'fetchWithdrawals': True,
|
105
105
|
'reduceMargin': False,
|
106
|
-
'sandbox':
|
106
|
+
'sandbox': False,
|
107
107
|
'setLeverage': False,
|
108
108
|
'setMarginMode': False,
|
109
109
|
'setPositionMode': False,
|
@@ -185,6 +185,73 @@ class probit(Exchange, ImplicitAPI):
|
|
185
185
|
'taker': self.parse_number('0.002'),
|
186
186
|
},
|
187
187
|
},
|
188
|
+
'features': {
|
189
|
+
'spot': {
|
190
|
+
'sandbox': False,
|
191
|
+
'createOrder': {
|
192
|
+
'marginMode': False,
|
193
|
+
'triggerPrice': False,
|
194
|
+
'triggerDirection': False,
|
195
|
+
'triggerPriceType': None,
|
196
|
+
'stopLossPrice': False,
|
197
|
+
'takeProfitPrice': False,
|
198
|
+
'attachedStopLossTakeProfit': None,
|
199
|
+
# todo
|
200
|
+
'timeInForce': {
|
201
|
+
'IOC': True,
|
202
|
+
'FOK': True,
|
203
|
+
'PO': False,
|
204
|
+
'GTD': False,
|
205
|
+
},
|
206
|
+
'hedged': False,
|
207
|
+
'trailing': False,
|
208
|
+
'leverage': False,
|
209
|
+
'marketBuyByCost': True,
|
210
|
+
'marketBuyRequiresPrice': False,
|
211
|
+
'selfTradePrevention': False,
|
212
|
+
'iceberg': False,
|
213
|
+
},
|
214
|
+
'createOrders': None,
|
215
|
+
'fetchMyTrades': {
|
216
|
+
'marginMode': False,
|
217
|
+
'limit': 1000,
|
218
|
+
'daysBack': 100000, # todo
|
219
|
+
'untilDays': 100000, # todo
|
220
|
+
},
|
221
|
+
'fetchOrder': {
|
222
|
+
'marginMode': False,
|
223
|
+
'trigger': False,
|
224
|
+
'trailing': False,
|
225
|
+
},
|
226
|
+
'fetchOpenOrders': {
|
227
|
+
'marginMode': False,
|
228
|
+
'limit': None,
|
229
|
+
'trigger': False,
|
230
|
+
'trailing': False,
|
231
|
+
},
|
232
|
+
'fetchOrders': None,
|
233
|
+
'fetchClosedOrders': {
|
234
|
+
'marginMode': False,
|
235
|
+
'limit': 1000,
|
236
|
+
'daysBack': 100000, # todo
|
237
|
+
'daysBackCanceled': 1, # todo
|
238
|
+
'untilDays': 90,
|
239
|
+
'trigger': False,
|
240
|
+
'trailing': False,
|
241
|
+
},
|
242
|
+
'fetchOHLCV': {
|
243
|
+
'limit': 4000,
|
244
|
+
},
|
245
|
+
},
|
246
|
+
'swap': {
|
247
|
+
'linear': None,
|
248
|
+
'inverse': None,
|
249
|
+
},
|
250
|
+
'future': {
|
251
|
+
'linear': None,
|
252
|
+
'inverse': None,
|
253
|
+
},
|
254
|
+
},
|
188
255
|
'exceptions': {
|
189
256
|
'exact': {
|
190
257
|
'UNAUTHORIZED': AuthenticationError,
|
@@ -923,6 +990,7 @@ class probit(Exchange, ImplicitAPI):
|
|
923
990
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
924
991
|
:param int [limit]: the maximum amount of candles to fetch
|
925
992
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
993
|
+
:param str [params.until]: timestamp in ms of the earliest candle to fetch
|
926
994
|
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
927
995
|
"""
|
928
996
|
await self.load_markets()
|
@@ -938,18 +1006,19 @@ class probit(Exchange, ImplicitAPI):
|
|
938
1006
|
'limit': requestLimit, # max 1000
|
939
1007
|
}
|
940
1008
|
now = self.milliseconds()
|
941
|
-
|
1009
|
+
until = self.safe_integer(params, 'until')
|
1010
|
+
durationMilliseconds = self.parse_timeframe(timeframe) * 1000
|
942
1011
|
startTime = since
|
943
|
-
endTime = now
|
1012
|
+
endTime = until - durationMilliseconds if (until is not None) else now
|
944
1013
|
if since is None:
|
945
1014
|
if limit is None:
|
946
1015
|
limit = requestLimit
|
947
|
-
|
1016
|
+
startLimit = limit - 1
|
1017
|
+
startTime = endTime - startLimit * durationMilliseconds
|
948
1018
|
else:
|
949
|
-
if limit is None:
|
950
|
-
|
951
|
-
|
952
|
-
endTime = self.sum(since, self.sum(limit, 1) * duration * 1000)
|
1019
|
+
if limit is not None:
|
1020
|
+
endByLimit = self.sum(since, limit * durationMilliseconds)
|
1021
|
+
endTime = min(endTime, endByLimit)
|
953
1022
|
startTimeNormalized = self.normalize_ohlcv_timestamp(startTime, timeframe)
|
954
1023
|
endTimeNormalized = self.normalize_ohlcv_timestamp(endTime, timeframe, True)
|
955
1024
|
request['start_time'] = startTimeNormalized
|
ccxt/async_support/timex.py
CHANGED
@@ -281,6 +281,73 @@ class timex(Exchange, ImplicitAPI):
|
|
281
281
|
'defaultSort': 'timestamp,asc',
|
282
282
|
'defaultSortOrders': 'createdAt,asc',
|
283
283
|
},
|
284
|
+
'features': {
|
285
|
+
'spot': {
|
286
|
+
'sandbox': False,
|
287
|
+
'createOrder': {
|
288
|
+
'marginMode': False,
|
289
|
+
'triggerPrice': False,
|
290
|
+
'triggerDirection': False,
|
291
|
+
'triggerPriceType': None,
|
292
|
+
'stopLossPrice': False,
|
293
|
+
'takeProfitPrice': False,
|
294
|
+
'attachedStopLossTakeProfit': None,
|
295
|
+
# todo
|
296
|
+
'timeInForce': {
|
297
|
+
'IOC': True,
|
298
|
+
'FOK': True,
|
299
|
+
'PO': False,
|
300
|
+
'GTD': True,
|
301
|
+
},
|
302
|
+
'hedged': False,
|
303
|
+
'trailing': False,
|
304
|
+
'leverage': False,
|
305
|
+
'marketBuyByCost': False,
|
306
|
+
'marketBuyRequiresPrice': False,
|
307
|
+
'selfTradePrevention': False,
|
308
|
+
'iceberg': False,
|
309
|
+
},
|
310
|
+
'createOrders': None,
|
311
|
+
'fetchMyTrades': {
|
312
|
+
'marginMode': False,
|
313
|
+
'limit': 100, # todo
|
314
|
+
'daysBack': 100000, # todo
|
315
|
+
'untilDays': 100000, # todo
|
316
|
+
},
|
317
|
+
'fetchOrder': {
|
318
|
+
'marginMode': False,
|
319
|
+
'trigger': False,
|
320
|
+
'trailing': False,
|
321
|
+
},
|
322
|
+
'fetchOpenOrders': {
|
323
|
+
'marginMode': False,
|
324
|
+
'limit': 100, # todo
|
325
|
+
'trigger': False,
|
326
|
+
'trailing': False,
|
327
|
+
},
|
328
|
+
'fetchOrders': None, # todo
|
329
|
+
'fetchClosedOrders': {
|
330
|
+
'marginMode': False,
|
331
|
+
'limit': 100, # todo
|
332
|
+
'daysBack': 100000, # todo
|
333
|
+
'daysBackCanceled': 1, # todo
|
334
|
+
'untilDays': 100000, # todo
|
335
|
+
'trigger': False,
|
336
|
+
'trailing': False,
|
337
|
+
},
|
338
|
+
'fetchOHLCV': {
|
339
|
+
'limit': None,
|
340
|
+
},
|
341
|
+
},
|
342
|
+
'swap': {
|
343
|
+
'linear': None,
|
344
|
+
'inverse': None,
|
345
|
+
},
|
346
|
+
'future': {
|
347
|
+
'linear': None,
|
348
|
+
'inverse': None,
|
349
|
+
},
|
350
|
+
},
|
284
351
|
})
|
285
352
|
|
286
353
|
async def fetch_time(self, params={}):
|