ccxt 4.4.91__py2.py3-none-any.whl → 4.4.93__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/lbank.py +2 -1
- ccxt/ascendex.py +9 -8
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ascendex.py +9 -8
- ccxt/async_support/base/exchange.py +4 -1
- ccxt/async_support/base/ws/client.py +4 -1
- ccxt/async_support/binance.py +42 -1
- ccxt/async_support/bitmart.py +7 -0
- ccxt/async_support/bitmex.py +3 -3
- ccxt/async_support/bitvavo.py +7 -1
- ccxt/async_support/bybit.py +81 -8
- ccxt/async_support/coinbaseexchange.py +53 -0
- ccxt/async_support/coincheck.py +45 -4
- ccxt/async_support/coinex.py +16 -12
- ccxt/async_support/cryptomus.py +30 -52
- ccxt/async_support/deribit.py +6 -6
- ccxt/async_support/exmo.py +70 -50
- ccxt/async_support/htx.py +1 -1
- ccxt/async_support/hyperliquid.py +2 -1
- ccxt/async_support/krakenfutures.py +1 -1
- ccxt/async_support/kucoin.py +12 -14
- ccxt/async_support/latoken.py +19 -71
- ccxt/async_support/lbank.py +115 -35
- ccxt/async_support/okx.py +151 -2
- ccxt/async_support/paradex.py +54 -0
- ccxt/async_support/phemex.py +3 -3
- ccxt/base/exchange.py +69 -30
- ccxt/base/types.py +1 -0
- ccxt/binance.py +42 -1
- ccxt/bitmart.py +7 -0
- ccxt/bitmex.py +3 -3
- ccxt/bitvavo.py +7 -1
- ccxt/bybit.py +81 -8
- ccxt/coinbaseexchange.py +53 -0
- ccxt/coincheck.py +45 -4
- ccxt/coinex.py +16 -12
- ccxt/cryptomus.py +30 -52
- ccxt/deribit.py +6 -6
- ccxt/exmo.py +70 -50
- ccxt/htx.py +1 -1
- ccxt/hyperliquid.py +2 -1
- ccxt/krakenfutures.py +1 -1
- ccxt/kucoin.py +12 -14
- ccxt/latoken.py +19 -71
- ccxt/lbank.py +115 -35
- ccxt/okx.py +151 -2
- ccxt/paradex.py +54 -0
- ccxt/phemex.py +3 -3
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitstamp.py +48 -16
- ccxt/pro/bybit.py +5 -5
- {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/METADATA +4 -4
- {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/RECORD +57 -57
- {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/WHEEL +0 -0
- {ccxt-4.4.91.dist-info → ccxt-4.4.93.dist-info}/top_level.txt +0 -0
ccxt/kucoin.py
CHANGED
@@ -1396,35 +1396,31 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1396
1396
|
# }
|
1397
1397
|
#
|
1398
1398
|
currenciesData = self.safe_list(response, 'data', [])
|
1399
|
+
brokenCurrencies = self.safe_list(self.options, 'brokenCurrencies', ['00', 'OPEN_ERROR', 'HUF', 'BDT'])
|
1400
|
+
otherFiats = self.safe_list(self.options, 'fiats', ['KWD', 'IRR', 'PKR'])
|
1399
1401
|
result: dict = {}
|
1400
1402
|
for i in range(0, len(currenciesData)):
|
1401
1403
|
entry = currenciesData[i]
|
1402
1404
|
id = self.safe_string(entry, 'currency')
|
1403
|
-
|
1405
|
+
if self.in_array(id, brokenCurrencies):
|
1406
|
+
continue # skip buggy entries: https://t.me/KuCoin_API/217798
|
1404
1407
|
code = self.safe_currency_code(id)
|
1405
1408
|
networks: dict = {}
|
1406
1409
|
chains = self.safe_list(entry, 'chains', [])
|
1407
|
-
rawPrecision = self.safe_string(entry, 'precision')
|
1408
|
-
precision = self.parse_number(self.parse_precision(rawPrecision))
|
1409
1410
|
chainsLength = len(chains)
|
1410
|
-
if not chainsLength:
|
1411
|
-
# one buggy coin, which doesn't contain info https://t.me/KuCoin_API/173118
|
1412
|
-
continue
|
1413
1411
|
for j in range(0, chainsLength):
|
1414
1412
|
chain = chains[j]
|
1415
1413
|
chainId = self.safe_string(chain, 'chainId')
|
1416
1414
|
networkCode = self.network_id_to_code(chainId, code)
|
1417
|
-
chainWithdrawEnabled = self.safe_bool(chain, 'isWithdrawEnabled', False)
|
1418
|
-
chainDepositEnabled = self.safe_bool(chain, 'isDepositEnabled', False)
|
1419
1415
|
networks[networkCode] = {
|
1420
1416
|
'info': chain,
|
1421
1417
|
'id': chainId,
|
1422
1418
|
'name': self.safe_string(chain, 'chainName'),
|
1423
1419
|
'code': networkCode,
|
1424
|
-
'active':
|
1420
|
+
'active': None,
|
1425
1421
|
'fee': self.safe_number(chain, 'withdrawalMinFee'),
|
1426
|
-
'deposit':
|
1427
|
-
'withdraw':
|
1422
|
+
'deposit': self.safe_bool(chain, 'isDepositEnabled'),
|
1423
|
+
'withdraw': self.safe_bool(chain, 'isWithdrawEnabled'),
|
1428
1424
|
'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'withdrawPrecision'))),
|
1429
1425
|
'limits': {
|
1430
1426
|
'withdraw': {
|
@@ -1438,10 +1434,12 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1438
1434
|
},
|
1439
1435
|
}
|
1440
1436
|
# kucoin has determined 'fiat' currencies with below logic
|
1441
|
-
|
1437
|
+
rawPrecision = self.safe_string(entry, 'precision')
|
1438
|
+
precision = self.parse_number(self.parse_precision(rawPrecision))
|
1439
|
+
isFiat = self.in_array(id, otherFiats) or ((rawPrecision == '2') and (chainsLength == 0))
|
1442
1440
|
result[code] = self.safe_currency_structure({
|
1443
1441
|
'id': id,
|
1444
|
-
'name':
|
1442
|
+
'name': self.safe_string(entry, 'fullName'),
|
1445
1443
|
'code': code,
|
1446
1444
|
'type': 'fiat' if isFiat else 'crypto',
|
1447
1445
|
'precision': precision,
|
@@ -2627,7 +2625,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2627
2625
|
"""
|
2628
2626
|
self.load_markets()
|
2629
2627
|
request: dict = {}
|
2630
|
-
trigger = self.
|
2628
|
+
trigger = self.safe_bool_2(params, 'trigger', 'stop', False)
|
2631
2629
|
hf = None
|
2632
2630
|
hf, params = self.handle_hf_and_params(params)
|
2633
2631
|
params = self.omit(params, 'stop')
|
ccxt/latoken.py
CHANGED
@@ -247,6 +247,8 @@ class latoken(Exchange, ImplicitAPI):
|
|
247
247
|
'fetchTradingFee': {
|
248
248
|
'method': 'fetchPrivateTradingFee', # or 'fetchPublicTradingFee'
|
249
249
|
},
|
250
|
+
'timeDifference': 0, # the difference between system clock and exchange clock
|
251
|
+
'adjustForTimeDifference': True, # controls the adjustment logic upon instantiation
|
250
252
|
},
|
251
253
|
'features': {
|
252
254
|
'spot': {
|
@@ -347,39 +349,6 @@ class latoken(Exchange, ImplicitAPI):
|
|
347
349
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
348
350
|
:returns dict[]: an array of objects representing market data
|
349
351
|
"""
|
350
|
-
currencies = self.fetch_currencies_from_cache(params)
|
351
|
-
#
|
352
|
-
# [
|
353
|
-
# {
|
354
|
-
# "id":"1a075819-9e0b-48fc-8784-4dab1d186d6d",
|
355
|
-
# "status":"CURRENCY_STATUS_ACTIVE",
|
356
|
-
# "type":"CURRENCY_TYPE_ALTERNATIVE", # CURRENCY_TYPE_CRYPTO, CURRENCY_TYPE_IEO
|
357
|
-
# "name":"MyCryptoBank",
|
358
|
-
# "tag":"MCB",
|
359
|
-
# "description":"",
|
360
|
-
# "logo":"",
|
361
|
-
# "decimals":18,
|
362
|
-
# "created":1572912000000,
|
363
|
-
# "tier":1,
|
364
|
-
# "assetClass":"ASSET_CLASS_UNKNOWN",
|
365
|
-
# "minTransferAmount":0
|
366
|
-
# },
|
367
|
-
# {
|
368
|
-
# "id":"db02758e-2507-46a5-a805-7bc60355b3eb",
|
369
|
-
# "status":"CURRENCY_STATUS_ACTIVE",
|
370
|
-
# "type":"CURRENCY_TYPE_FUTURES_CONTRACT",
|
371
|
-
# "name":"BTC USDT Futures Contract",
|
372
|
-
# "tag":"BTCUSDT",
|
373
|
-
# "description":"",
|
374
|
-
# "logo":"",
|
375
|
-
# "decimals":8,
|
376
|
-
# "created":1589459984395,
|
377
|
-
# "tier":1,
|
378
|
-
# "assetClass":"ASSET_CLASS_UNKNOWN",
|
379
|
-
# "minTransferAmount":0
|
380
|
-
# },
|
381
|
-
# ]
|
382
|
-
#
|
383
352
|
response = self.publicGetPair(params)
|
384
353
|
#
|
385
354
|
# [
|
@@ -401,8 +370,9 @@ class latoken(Exchange, ImplicitAPI):
|
|
401
370
|
# }
|
402
371
|
# ]
|
403
372
|
#
|
404
|
-
if self.
|
373
|
+
if self.safe_bool(self.options, 'adjustForTimeDifference', False):
|
405
374
|
self.load_time_difference()
|
375
|
+
currencies = self.safe_dict(self.options, 'cachedCurrencies', {})
|
406
376
|
currenciesById = self.index_by(currencies, 'id')
|
407
377
|
result = []
|
408
378
|
for i in range(0, len(response)):
|
@@ -411,11 +381,13 @@ class latoken(Exchange, ImplicitAPI):
|
|
411
381
|
# the exchange shows them inverted
|
412
382
|
baseId = self.safe_string(market, 'baseCurrency')
|
413
383
|
quoteId = self.safe_string(market, 'quoteCurrency')
|
414
|
-
baseCurrency = self.
|
415
|
-
quoteCurrency = self.
|
416
|
-
|
417
|
-
|
418
|
-
|
384
|
+
baseCurrency = self.safe_dict(currenciesById, baseId)
|
385
|
+
quoteCurrency = self.safe_dict(currenciesById, quoteId)
|
386
|
+
baseCurrencyInfo = self.safe_dict(baseCurrency, 'info')
|
387
|
+
quoteCurrencyInfo = self.safe_dict(quoteCurrency, 'info')
|
388
|
+
if baseCurrencyInfo is not None and quoteCurrencyInfo is not None:
|
389
|
+
base = self.safe_currency_code(self.safe_string(baseCurrencyInfo, 'tag'))
|
390
|
+
quote = self.safe_currency_code(self.safe_string(quoteCurrencyInfo, 'tag'))
|
419
391
|
lowercaseQuote = quote.lower()
|
420
392
|
capitalizedQuote = self.capitalize(lowercaseQuote)
|
421
393
|
status = self.safe_string(market, 'status')
|
@@ -470,28 +442,13 @@ class latoken(Exchange, ImplicitAPI):
|
|
470
442
|
})
|
471
443
|
return result
|
472
444
|
|
473
|
-
def fetch_currencies_from_cache(self, params={}):
|
474
|
-
# self method is now redundant
|
475
|
-
# currencies are now fetched before markets
|
476
|
-
options = self.safe_value(self.options, 'fetchCurrencies', {})
|
477
|
-
timestamp = self.safe_integer(options, 'timestamp')
|
478
|
-
expires = self.safe_integer(options, 'expires', 1000)
|
479
|
-
now = self.milliseconds()
|
480
|
-
if (timestamp is None) or ((now - timestamp) > expires):
|
481
|
-
response = self.publicGetCurrency(params)
|
482
|
-
self.options['fetchCurrencies'] = self.extend(options, {
|
483
|
-
'response': response,
|
484
|
-
'timestamp': now,
|
485
|
-
})
|
486
|
-
return self.safe_value(self.options['fetchCurrencies'], 'response')
|
487
|
-
|
488
445
|
def fetch_currencies(self, params={}) -> Currencies:
|
489
446
|
"""
|
490
447
|
fetches all available currencies on an exchange
|
491
448
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
492
449
|
:returns dict: an associative dictionary of currencies
|
493
450
|
"""
|
494
|
-
response = self.
|
451
|
+
response = self.publicGetCurrency(params)
|
495
452
|
#
|
496
453
|
# [
|
497
454
|
# {
|
@@ -530,27 +487,18 @@ class latoken(Exchange, ImplicitAPI):
|
|
530
487
|
id = self.safe_string(currency, 'id')
|
531
488
|
tag = self.safe_string(currency, 'tag')
|
532
489
|
code = self.safe_currency_code(tag)
|
533
|
-
fee = self.safe_number(currency, 'fee')
|
534
490
|
currencyType = self.safe_string(currency, 'type')
|
535
|
-
|
536
|
-
|
537
|
-
type = 'other'
|
538
|
-
else:
|
539
|
-
# CURRENCY_TYPE_CRYPTO and CURRENCY_TYPE_IEO are all cryptos
|
540
|
-
type = 'crypto'
|
541
|
-
status = self.safe_string(currency, 'status')
|
542
|
-
active = (status == 'CURRENCY_STATUS_ACTIVE')
|
543
|
-
name = self.safe_string(currency, 'name')
|
544
|
-
result[code] = {
|
491
|
+
isCrypto = (currencyType == 'CURRENCY_TYPE_CRYPTO' or currencyType == 'CURRENCY_TYPE_IEO')
|
492
|
+
result[code] = self.safe_currency_structure({
|
545
493
|
'id': id,
|
546
494
|
'code': code,
|
547
495
|
'info': currency,
|
548
|
-
'name': name,
|
549
|
-
'type':
|
550
|
-
'active':
|
496
|
+
'name': self.safe_string(currency, 'name'),
|
497
|
+
'type': 'crypto' if isCrypto else 'other',
|
498
|
+
'active': self.safe_string(currency, 'status') == 'CURRENCY_STATUS_ACTIVE',
|
551
499
|
'deposit': None,
|
552
500
|
'withdraw': None,
|
553
|
-
'fee': fee,
|
501
|
+
'fee': self.safe_number(currency, 'fee'),
|
554
502
|
'precision': self.parse_number(self.parse_precision(self.safe_string(currency, 'decimals'))),
|
555
503
|
'limits': {
|
556
504
|
'amount': {
|
@@ -563,7 +511,7 @@ class latoken(Exchange, ImplicitAPI):
|
|
563
511
|
},
|
564
512
|
},
|
565
513
|
'networks': {},
|
566
|
-
}
|
514
|
+
})
|
567
515
|
return result
|
568
516
|
|
569
517
|
def fetch_balance(self, params={}) -> Balances:
|
ccxt/lbank.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.lbank import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Any, Balances, Currency, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction
|
9
|
+
from ccxt.base.types import Any, Balances, Currencies, Currency, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import AuthenticationError
|
@@ -61,6 +61,7 @@ class lbank(Exchange, ImplicitAPI):
|
|
61
61
|
'fetchClosedOrders': False,
|
62
62
|
'fetchCrossBorrowRate': False,
|
63
63
|
'fetchCrossBorrowRates': False,
|
64
|
+
'fetchCurrencies': True,
|
64
65
|
'fetchDepositAddress': True,
|
65
66
|
'fetchDepositAddresses': False,
|
66
67
|
'fetchDepositAddressesByNetwork': False,
|
@@ -135,7 +136,8 @@ class lbank(Exchange, ImplicitAPI):
|
|
135
136
|
'currencyPairs': 2.5,
|
136
137
|
'accuracy': 2.5,
|
137
138
|
'usdToCny': 2.5,
|
138
|
-
'
|
139
|
+
'assetConfigs': 2.5,
|
140
|
+
'withdrawConfigs': 2.5 * 1.5, # frequently rate-limits, so increase self endpoint RL
|
139
141
|
'timestamp': 2.5,
|
140
142
|
'ticker/24hr': 2.5,
|
141
143
|
'ticker': 2.5,
|
@@ -221,6 +223,7 @@ class lbank(Exchange, ImplicitAPI):
|
|
221
223
|
},
|
222
224
|
},
|
223
225
|
'commonCurrencies': {
|
226
|
+
'XBT': 'XBT', # not BTC!
|
224
227
|
'HIT': 'Hiver',
|
225
228
|
'VET_ERC20': 'VEN',
|
226
229
|
'PNT': 'Penta',
|
@@ -288,21 +291,12 @@ class lbank(Exchange, ImplicitAPI):
|
|
288
291
|
# ptx: 1
|
289
292
|
# }
|
290
293
|
},
|
291
|
-
'
|
294
|
+
'networksById': {
|
292
295
|
'erc20': 'ERC20',
|
293
296
|
'trc20': 'TRC20',
|
294
|
-
'
|
295
|
-
'
|
296
|
-
'bep20
|
297
|
-
'bep20': 'BSC',
|
298
|
-
'heco': 'HT',
|
299
|
-
'bep2': 'BNB',
|
300
|
-
'btc': 'BTC',
|
301
|
-
'dogecoin': 'DOGE',
|
302
|
-
'matic': 'MATIC',
|
303
|
-
'oec': 'OEC',
|
304
|
-
'btctron': 'BTCTRON',
|
305
|
-
'xrp': 'XRP',
|
297
|
+
'TRX': 'TRC20',
|
298
|
+
'bep20(bsc)': 'BEP20',
|
299
|
+
'bep20': 'BEP20',
|
306
300
|
},
|
307
301
|
'defaultNetworks': {
|
308
302
|
'USDT': 'TRC20',
|
@@ -423,6 +417,104 @@ class lbank(Exchange, ImplicitAPI):
|
|
423
417
|
#
|
424
418
|
return self.safe_integer(response, 'data')
|
425
419
|
|
420
|
+
def fetch_currencies(self, params={}) -> Currencies:
|
421
|
+
"""
|
422
|
+
fetches all available currencies on an exchange
|
423
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
424
|
+
:returns dict: an associative dictionary of currencies
|
425
|
+
"""
|
426
|
+
response = self.spotPublicGetWithdrawConfigs(params)
|
427
|
+
#
|
428
|
+
# {
|
429
|
+
# "msg": "Success",
|
430
|
+
# "result": "true",
|
431
|
+
# "data": [
|
432
|
+
# {
|
433
|
+
# "amountScale": "4",
|
434
|
+
# "chain": "bep20(bsc)",
|
435
|
+
# "assetCode": "usdt",
|
436
|
+
# "min": "10",
|
437
|
+
# "transferAmtScale": "4",
|
438
|
+
# "canWithDraw": True,
|
439
|
+
# "fee": "0.0000",
|
440
|
+
# "minTransfer": "0.0001",
|
441
|
+
# "type": "1"
|
442
|
+
# },
|
443
|
+
# {
|
444
|
+
# "amountScale": "4",
|
445
|
+
# "chain": "trc20",
|
446
|
+
# "assetCode": "usdt",
|
447
|
+
# "min": "1",
|
448
|
+
# "transferAmtScale": "4",
|
449
|
+
# "canWithDraw": True,
|
450
|
+
# "fee": "1.0000",
|
451
|
+
# "minTransfer": "0.0001",
|
452
|
+
# "type": "1"
|
453
|
+
# },
|
454
|
+
# ...
|
455
|
+
# ],
|
456
|
+
# "error_code": "0",
|
457
|
+
# "ts": "1747973911431"
|
458
|
+
# }
|
459
|
+
#
|
460
|
+
currenciesData = self.safe_list(response, 'data', [])
|
461
|
+
grouped = self.group_by(currenciesData, 'assetCode')
|
462
|
+
groupedKeys = list(grouped.keys())
|
463
|
+
result: dict = {}
|
464
|
+
for i in range(0, len(groupedKeys)):
|
465
|
+
id = str((groupedKeys[i])) # some currencies are numeric
|
466
|
+
code = self.safe_currency_code(id)
|
467
|
+
networksRaw = grouped[id]
|
468
|
+
networks = {}
|
469
|
+
for j in range(0, len(networksRaw)):
|
470
|
+
networkEntry = networksRaw[j]
|
471
|
+
networkId = self.safe_string(networkEntry, 'chain')
|
472
|
+
networkCode = self.network_id_to_code(networkId)
|
473
|
+
networks[networkCode] = {
|
474
|
+
'id': networkId,
|
475
|
+
'network': networkCode,
|
476
|
+
'limits': {
|
477
|
+
'withdraw': {
|
478
|
+
'min': self.safe_number(networkEntry, 'min'),
|
479
|
+
'max': None,
|
480
|
+
},
|
481
|
+
'deposit': {
|
482
|
+
'min': self.safe_number(networkEntry, 'minTransfer'),
|
483
|
+
'max': None,
|
484
|
+
},
|
485
|
+
},
|
486
|
+
'active': None,
|
487
|
+
'deposit': None,
|
488
|
+
'withdraw': self.safe_bool(networkEntry, 'canWithDraw'),
|
489
|
+
'fee': self.safe_number(networkEntry, 'fee'),
|
490
|
+
'precision': self.parse_number(self.parse_precision(self.safe_string(networkEntry, 'transferAmtScale'))),
|
491
|
+
'info': networkEntry,
|
492
|
+
}
|
493
|
+
result[code] = self.safe_currency_structure({
|
494
|
+
'id': id,
|
495
|
+
'code': code,
|
496
|
+
'precision': None,
|
497
|
+
'type': None,
|
498
|
+
'name': None,
|
499
|
+
'active': None,
|
500
|
+
'deposit': None,
|
501
|
+
'withdraw': None,
|
502
|
+
'fee': None,
|
503
|
+
'limits': {
|
504
|
+
'withdraw': {
|
505
|
+
'min': None,
|
506
|
+
'max': None,
|
507
|
+
},
|
508
|
+
'deposit': {
|
509
|
+
'min': None,
|
510
|
+
'max': None,
|
511
|
+
},
|
512
|
+
},
|
513
|
+
'networks': networks,
|
514
|
+
'info': networksRaw,
|
515
|
+
})
|
516
|
+
return result
|
517
|
+
|
426
518
|
def fetch_markets(self, params={}) -> List[Market]:
|
427
519
|
"""
|
428
520
|
retrieves data on all markets for lbank
|
@@ -582,7 +674,7 @@ class lbank(Exchange, ImplicitAPI):
|
|
582
674
|
'active': True,
|
583
675
|
'contract': True,
|
584
676
|
'linear': True,
|
585
|
-
'inverse':
|
677
|
+
'inverse': False,
|
586
678
|
'contractSize': self.safe_number(market, 'volumeMultiple'),
|
587
679
|
'expiry': None,
|
588
680
|
'expiryDatetime': None,
|
@@ -2097,13 +2189,10 @@ class lbank(Exchange, ImplicitAPI):
|
|
2097
2189
|
result = self.safe_value(response, 'data')
|
2098
2190
|
address = self.safe_string(result, 'address')
|
2099
2191
|
tag = self.safe_string(result, 'memo')
|
2100
|
-
networkId = self.safe_string(result, 'netWork')
|
2101
|
-
inverseNetworks = self.safe_value(self.options, 'inverse-networks', {})
|
2102
|
-
networkCode = self.safe_string_upper(inverseNetworks, networkId, networkId)
|
2103
2192
|
return {
|
2104
2193
|
'info': response,
|
2105
2194
|
'currency': code,
|
2106
|
-
'network':
|
2195
|
+
'network': self.network_id_to_code(self.safe_string(result, 'netWork')),
|
2107
2196
|
'address': address,
|
2108
2197
|
'tag': tag,
|
2109
2198
|
}
|
@@ -2137,12 +2226,10 @@ class lbank(Exchange, ImplicitAPI):
|
|
2137
2226
|
result = self.safe_value(response, 'data')
|
2138
2227
|
address = self.safe_string(result, 'address')
|
2139
2228
|
tag = self.safe_string(result, 'memo')
|
2140
|
-
inverseNetworks = self.safe_value(self.options, 'inverse-networks', {})
|
2141
|
-
networkCode = self.safe_string_upper(inverseNetworks, network, network)
|
2142
2229
|
return {
|
2143
2230
|
'info': response,
|
2144
2231
|
'currency': code,
|
2145
|
-
'network':
|
2232
|
+
'network': None,
|
2146
2233
|
'address': address,
|
2147
2234
|
'tag': tag,
|
2148
2235
|
}
|
@@ -2262,9 +2349,6 @@ class lbank(Exchange, ImplicitAPI):
|
|
2262
2349
|
type = 'withdrawal'
|
2263
2350
|
txid = self.safe_string(transaction, 'txId')
|
2264
2351
|
timestamp = self.safe_integer_2(transaction, 'insertTime', 'applyTime')
|
2265
|
-
networks = self.safe_value(self.options, 'inverse-networks', {})
|
2266
|
-
networkId = self.safe_string(transaction, 'networkName')
|
2267
|
-
network = self.safe_string(networks, networkId, networkId)
|
2268
2352
|
address = self.safe_string(transaction, 'address')
|
2269
2353
|
addressFrom = None
|
2270
2354
|
addressTo = None
|
@@ -2289,7 +2373,7 @@ class lbank(Exchange, ImplicitAPI):
|
|
2289
2373
|
'txid': txid,
|
2290
2374
|
'timestamp': timestamp,
|
2291
2375
|
'datetime': self.iso8601(timestamp),
|
2292
|
-
'network':
|
2376
|
+
'network': self.network_id_to_code(self.safe_string(transaction, 'networkName')),
|
2293
2377
|
'address': address,
|
2294
2378
|
'addressTo': addressTo,
|
2295
2379
|
'addressFrom': addressFrom,
|
@@ -2482,10 +2566,9 @@ class lbank(Exchange, ImplicitAPI):
|
|
2482
2566
|
withdrawFees[code] = {}
|
2483
2567
|
for j in range(0, len(networkList)):
|
2484
2568
|
networkEntry = networkList[j]
|
2485
|
-
networkId = self.safe_string(networkEntry, 'name')
|
2486
|
-
networkCode = self.safe_string(self.options['inverse-networks'], networkId, networkId)
|
2487
2569
|
fee = self.safe_number(networkEntry, 'withdrawFee')
|
2488
2570
|
if fee is not None:
|
2571
|
+
networkCode = self.network_id_to_code(self.safe_string(networkEntry, 'name'))
|
2489
2572
|
withdrawFees[code][networkCode] = fee
|
2490
2573
|
return {
|
2491
2574
|
'withdraw': withdrawFees,
|
@@ -2533,8 +2616,7 @@ class lbank(Exchange, ImplicitAPI):
|
|
2533
2616
|
if canWithdraw == 'true':
|
2534
2617
|
currencyId = self.safe_string(item, 'assetCode')
|
2535
2618
|
codeInner = self.safe_currency_code(currencyId)
|
2536
|
-
|
2537
|
-
network = self.safe_string(self.options['inverse-networks'], chain, chain)
|
2619
|
+
network = self.network_id_to_code(self.safe_string(item, 'chain'))
|
2538
2620
|
if network is None:
|
2539
2621
|
network = codeInner
|
2540
2622
|
fee = self.safe_string(item, 'fee')
|
@@ -2675,8 +2757,7 @@ class lbank(Exchange, ImplicitAPI):
|
|
2675
2757
|
else:
|
2676
2758
|
resultCodeInfo = result[code]['info']
|
2677
2759
|
resultCodeInfo.append(fee)
|
2678
|
-
|
2679
|
-
networkCode = self.safe_string(self.options['inverse-networks'], chain, chain)
|
2760
|
+
networkCode = self.network_id_to_code(self.safe_string(fee, 'chain'))
|
2680
2761
|
if networkCode is not None:
|
2681
2762
|
result[code]['networks'][networkCode] = {
|
2682
2763
|
'withdraw': {
|
@@ -2726,8 +2807,7 @@ class lbank(Exchange, ImplicitAPI):
|
|
2726
2807
|
networkList = self.safe_value(fee, 'networkList', [])
|
2727
2808
|
for j in range(0, len(networkList)):
|
2728
2809
|
networkEntry = networkList[j]
|
2729
|
-
|
2730
|
-
networkCode = self.safe_string_upper(self.options['inverse-networks'], networkId, networkId)
|
2810
|
+
networkCode = self.network_id_to_code(self.safe_string(networkEntry, 'name'))
|
2731
2811
|
withdrawFee = self.safe_number(networkEntry, 'withdrawFee')
|
2732
2812
|
isDefault = self.safe_value(networkEntry, 'isDefault')
|
2733
2813
|
if withdrawFee is not None:
|
ccxt/okx.py
CHANGED
@@ -80,6 +80,7 @@ class okx(Exchange, ImplicitAPI):
|
|
80
80
|
'createTriggerOrder': True,
|
81
81
|
'editOrder': True,
|
82
82
|
'fetchAccounts': True,
|
83
|
+
'fetchAllGreeks': True,
|
83
84
|
'fetchBalance': True,
|
84
85
|
'fetchBidsAsks': None,
|
85
86
|
'fetchBorrowInterest': True,
|
@@ -3613,6 +3614,84 @@ class okx(Exchange, ImplicitAPI):
|
|
3613
3614
|
# "uTime": "1621910749815"
|
3614
3615
|
# }
|
3615
3616
|
#
|
3617
|
+
# watchOrders & fetchClosedOrders
|
3618
|
+
#
|
3619
|
+
# {
|
3620
|
+
# "algoClOrdId": "",
|
3621
|
+
# "algoId": "",
|
3622
|
+
# "attachAlgoClOrdId": "",
|
3623
|
+
# "attachAlgoOrds": [],
|
3624
|
+
# "cancelSource": "",
|
3625
|
+
# "cancelSourceReason": "", # not present in WS, but present in fetchClosedOrders
|
3626
|
+
# "category": "normal",
|
3627
|
+
# "ccy": "", # empty in WS, but eg. `USDT` in fetchClosedOrders
|
3628
|
+
# "clOrdId": "",
|
3629
|
+
# "cTime": "1751705801423",
|
3630
|
+
# "feeCcy": "USDT",
|
3631
|
+
# "instId": "LINK-USDT-SWAP",
|
3632
|
+
# "instType": "SWAP",
|
3633
|
+
# "isTpLimit": "false",
|
3634
|
+
# "lever": "3",
|
3635
|
+
# "linkedAlgoOrd": {"algoId": ""},
|
3636
|
+
# "ordId": "2657625147249614848",
|
3637
|
+
# "ordType": "limit",
|
3638
|
+
# "posSide": "net",
|
3639
|
+
# "px": "13.142",
|
3640
|
+
# "pxType": "",
|
3641
|
+
# "pxUsd": "",
|
3642
|
+
# "pxVol": "",
|
3643
|
+
# "quickMgnType": "",
|
3644
|
+
# "rebate": "0",
|
3645
|
+
# "rebateCcy": "USDT",
|
3646
|
+
# "reduceOnly": "true",
|
3647
|
+
# "side": "sell",
|
3648
|
+
# "slOrdPx": "",
|
3649
|
+
# "slTriggerPx": "",
|
3650
|
+
# "slTriggerPxType": "",
|
3651
|
+
# "source": "",
|
3652
|
+
# "stpId": "",
|
3653
|
+
# "stpMode": "cancel_maker",
|
3654
|
+
# "sz": "0.1",
|
3655
|
+
# "tag": "",
|
3656
|
+
# "tdMode": "isolated",
|
3657
|
+
# "tgtCcy": "",
|
3658
|
+
# "tpOrdPx": "",
|
3659
|
+
# "tpTriggerPx": "",
|
3660
|
+
# "tpTriggerPxType": "",
|
3661
|
+
# "uTime": "1751705807467",
|
3662
|
+
# "reqId": "", # field present only in WS
|
3663
|
+
# "msg": "", # field present only in WS
|
3664
|
+
# "amendResult": "", # field present only in WS
|
3665
|
+
# "amendSource": "", # field present only in WS
|
3666
|
+
# "code": "0", # field present only in WS
|
3667
|
+
# "fillFwdPx": "", # field present only in WS
|
3668
|
+
# "fillMarkVol": "", # field present only in WS
|
3669
|
+
# "fillPxUsd": "", # field present only in WS
|
3670
|
+
# "fillPxVol": "", # field present only in WS
|
3671
|
+
# "lastPx": "13.142", # field present only in WS
|
3672
|
+
# "notionalUsd": "1.314515408", # field present only in WS
|
3673
|
+
#
|
3674
|
+
# #### these below fields are empty on first omit from websocket, because of "creation" event. however, if order is executed, it also immediately sends another update with these fields filled ###
|
3675
|
+
#
|
3676
|
+
# "pnl": "-0.0001",
|
3677
|
+
# "accFillSz": "0.1",
|
3678
|
+
# "avgPx": "13.142",
|
3679
|
+
# "state": "filled",
|
3680
|
+
# "fee": "-0.00026284",
|
3681
|
+
# "fillPx": "13.142",
|
3682
|
+
# "tradeId": "293429690",
|
3683
|
+
# "fillSz": "0.1",
|
3684
|
+
# "fillTime": "1751705807467",
|
3685
|
+
# "fillNotionalUsd": "1.314515408", # field present only in WS
|
3686
|
+
# "fillPnl": "-0.0001", # field present only in WS
|
3687
|
+
# "fillFee": "-0.00026284", # field present only in WS
|
3688
|
+
# "fillFeeCcy": "USDT", # field present only in WS
|
3689
|
+
# "execType": "M", # field present only in WS
|
3690
|
+
# "fillMarkPx": "13.141", # field present only in WS
|
3691
|
+
# "fillIdxPx": "13.147" # field present only in WS
|
3692
|
+
# }
|
3693
|
+
#
|
3694
|
+
#
|
3616
3695
|
# Algo Order fetchOpenOrders, fetchCanceledOrders, fetchClosedOrders
|
3617
3696
|
#
|
3618
3697
|
# {
|
@@ -4893,7 +4972,7 @@ class okx(Exchange, ImplicitAPI):
|
|
4893
4972
|
fee = self.safe_string(params, 'fee')
|
4894
4973
|
if fee is None:
|
4895
4974
|
currencies = self.fetch_currencies()
|
4896
|
-
self.currencies = self.deep_extend(self.currencies, currencies)
|
4975
|
+
self.currencies = self.map_to_safe_map(self.deep_extend(self.currencies, currencies))
|
4897
4976
|
targetNetwork = self.safe_dict(currency['networks'], self.network_id_to_code(network), {})
|
4898
4977
|
fee = self.safe_string(targetNetwork, 'fee')
|
4899
4978
|
if fee is None:
|
@@ -6843,7 +6922,7 @@ class okx(Exchange, ImplicitAPI):
|
|
6843
6922
|
|
6844
6923
|
def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
|
6845
6924
|
"""
|
6846
|
-
fetch the interest owed
|
6925
|
+
fetch the interest owed b the user for borrowing currency for margin trading
|
6847
6926
|
|
6848
6927
|
https://www.okx.com/docs-v5/en/#rest-api-account-get-interest-accrued-data
|
6849
6928
|
|
@@ -7547,6 +7626,76 @@ class okx(Exchange, ImplicitAPI):
|
|
7547
7626
|
return self.parse_greeks(entry, market)
|
7548
7627
|
return None
|
7549
7628
|
|
7629
|
+
def fetch_all_greeks(self, symbols: Strings = None, params={}) -> List[Greeks]:
|
7630
|
+
"""
|
7631
|
+
fetches all option contracts greeks, financial metrics used to measure the factors that affect the price of an options contract
|
7632
|
+
|
7633
|
+
https://www.okx.com/docs-v5/en/#public-data-rest-api-get-option-market-data
|
7634
|
+
|
7635
|
+
:param str[] [symbols]: unified symbols of the markets to fetch greeks for, all markets are returned if not assigned
|
7636
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
7637
|
+
:param str params['uly']: Underlying, either uly or instFamily is required
|
7638
|
+
:param str params['instFamily']: Instrument family, either uly or instFamily is required
|
7639
|
+
:returns dict: a `greeks structure <https://docs.ccxt.com/#/?id=greeks-structure>`
|
7640
|
+
"""
|
7641
|
+
self.load_markets()
|
7642
|
+
request: dict = {}
|
7643
|
+
symbols = self.market_symbols(symbols, None, True, True, True)
|
7644
|
+
symbolsLength = None
|
7645
|
+
if symbols is not None:
|
7646
|
+
symbolsLength = len(symbols)
|
7647
|
+
if (symbols is None) or (symbolsLength != 1):
|
7648
|
+
uly = self.safe_string(params, 'uly')
|
7649
|
+
if uly is not None:
|
7650
|
+
request['uly'] = uly
|
7651
|
+
instFamily = self.safe_string(params, 'instFamily')
|
7652
|
+
if instFamily is not None:
|
7653
|
+
request['instFamily'] = instFamily
|
7654
|
+
if (uly is None) and (instFamily is None):
|
7655
|
+
raise BadRequest(self.id + ' fetchAllGreeks() requires either a uly or instFamily parameter')
|
7656
|
+
market = None
|
7657
|
+
if symbols is not None:
|
7658
|
+
if symbolsLength == 1:
|
7659
|
+
market = self.market(symbols[0])
|
7660
|
+
marketId = market['id']
|
7661
|
+
optionParts = marketId.split('-')
|
7662
|
+
request['uly'] = market['info']['uly']
|
7663
|
+
request['instFamily'] = market['info']['instFamily']
|
7664
|
+
request['expTime'] = self.safe_string(optionParts, 2)
|
7665
|
+
params = self.omit(params, ['uly', 'instFamily'])
|
7666
|
+
response = self.publicGetPublicOptSummary(self.extend(request, params))
|
7667
|
+
#
|
7668
|
+
# {
|
7669
|
+
# "code": "0",
|
7670
|
+
# "data": [
|
7671
|
+
# {
|
7672
|
+
# "askVol": "0",
|
7673
|
+
# "bidVol": "0",
|
7674
|
+
# "delta": "0.5105464486882039",
|
7675
|
+
# "deltaBS": "0.7325502184143025",
|
7676
|
+
# "fwdPx": "37675.80158694987186",
|
7677
|
+
# "gamma": "-0.13183515090501083",
|
7678
|
+
# "gammaBS": "0.000024139685826358558",
|
7679
|
+
# "instId": "BTC-USD-240329-32000-C",
|
7680
|
+
# "instType": "OPTION",
|
7681
|
+
# "lever": "4.504428015946619",
|
7682
|
+
# "markVol": "0.5916253554539876",
|
7683
|
+
# "realVol": "0",
|
7684
|
+
# "theta": "-0.0004202992014012855",
|
7685
|
+
# "thetaBS": "-18.52354631567909",
|
7686
|
+
# "ts": "1699586421976",
|
7687
|
+
# "uly": "BTC-USD",
|
7688
|
+
# "vega": "0.0020207455080045846",
|
7689
|
+
# "vegaBS": "74.44022302387287",
|
7690
|
+
# "volLv": "0.5948549730405797"
|
7691
|
+
# },
|
7692
|
+
# ],
|
7693
|
+
# "msg": ""
|
7694
|
+
# }
|
7695
|
+
#
|
7696
|
+
data = self.safe_list(response, 'data', [])
|
7697
|
+
return self.parse_all_greeks(data, symbols)
|
7698
|
+
|
7550
7699
|
def parse_greeks(self, greeks: dict, market: Market = None) -> Greeks:
|
7551
7700
|
#
|
7552
7701
|
# {
|