ccxt 4.4.20__py2.py3-none-any.whl → 4.4.22__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/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +3 -0
- ccxt/abstract/bybit.py +1 -0
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/gate.py +5 -0
- ccxt/abstract/gateio.py +5 -0
- ccxt/abstract/kucoin.py +2 -0
- ccxt/abstract/kucoinfutures.py +2 -0
- ccxt/abstract/okx.py +4 -0
- ccxt/alpaca.py +1 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/alpaca.py +1 -0
- ccxt/async_support/base/exchange.py +7 -1
- ccxt/async_support/bigone.py +3 -0
- ccxt/async_support/binance.py +96 -10
- ccxt/async_support/bingx.py +5 -1
- ccxt/async_support/bitflyer.py +56 -1
- ccxt/async_support/bitget.py +73 -1
- ccxt/async_support/bybit.py +135 -4
- ccxt/async_support/cex.py +1247 -1326
- ccxt/async_support/cryptocom.py +1 -1
- ccxt/async_support/gate.py +97 -2
- ccxt/async_support/htx.py +27 -7
- ccxt/async_support/hyperliquid.py +15 -12
- ccxt/async_support/kucoin.py +42 -88
- ccxt/async_support/kucoinfutures.py +2 -2
- ccxt/async_support/okx.py +76 -10
- ccxt/base/exchange.py +33 -1
- ccxt/base/types.py +9 -0
- ccxt/bigone.py +3 -0
- ccxt/binance.py +96 -10
- ccxt/bingx.py +5 -1
- ccxt/bitflyer.py +56 -1
- ccxt/bitget.py +73 -1
- ccxt/bybit.py +135 -4
- ccxt/cex.py +1246 -1326
- ccxt/cryptocom.py +1 -1
- ccxt/gate.py +97 -2
- ccxt/htx.py +27 -7
- ccxt/hyperliquid.py +15 -12
- ccxt/kucoin.py +42 -88
- ccxt/kucoinfutures.py +2 -2
- ccxt/okx.py +76 -10
- ccxt/pro/__init__.py +1 -1
- ccxt/test/tests_async.py +4 -4
- ccxt/test/tests_sync.py +4 -4
- {ccxt-4.4.20.dist-info → ccxt-4.4.22.dist-info}/METADATA +5 -5
- {ccxt-4.4.20.dist-info → ccxt-4.4.22.dist-info}/RECORD +52 -52
- {ccxt-4.4.20.dist-info → ccxt-4.4.22.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.20.dist-info → ccxt-4.4.22.dist-info}/WHEEL +0 -0
- {ccxt-4.4.20.dist-info → ccxt-4.4.22.dist-info}/top_level.txt +0 -0
ccxt/cryptocom.py
CHANGED
@@ -1496,7 +1496,7 @@ class cryptocom(Exchange, ImplicitAPI):
|
|
1496
1496
|
paginate = False
|
1497
1497
|
paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
|
1498
1498
|
if paginate:
|
1499
|
-
return self.fetch_paginated_call_dynamic('fetchMyTrades', symbol, since, limit, params)
|
1499
|
+
return self.fetch_paginated_call_dynamic('fetchMyTrades', symbol, since, limit, params, 100)
|
1500
1500
|
request: dict = {}
|
1501
1501
|
market = None
|
1502
1502
|
if symbol is not None:
|
ccxt/gate.py
CHANGED
@@ -339,10 +339,17 @@ class gate(Exchange, ImplicitAPI):
|
|
339
339
|
'interest_records': 20 / 15,
|
340
340
|
'estimate_rate': 20 / 15,
|
341
341
|
'currency_discount_tiers': 20 / 15,
|
342
|
+
'risk_units': 20 / 15,
|
343
|
+
'unified_mode': 20 / 15,
|
344
|
+
'loan_margin_tiers': 20 / 15,
|
342
345
|
},
|
343
346
|
'post': {
|
344
347
|
'account_mode': 20 / 15,
|
345
348
|
'loans': 200 / 15, # 15r/10s cost = 20 / 1.5 = 13.33
|
349
|
+
'portfolio_calculator': 20 / 15,
|
350
|
+
},
|
351
|
+
'put': {
|
352
|
+
'unified_mode': 20 / 15,
|
346
353
|
},
|
347
354
|
},
|
348
355
|
'spot': {
|
@@ -644,6 +651,7 @@ class gate(Exchange, ImplicitAPI):
|
|
644
651
|
},
|
645
652
|
'options': {
|
646
653
|
'sandboxMode': False,
|
654
|
+
'unifiedAccount': None,
|
647
655
|
'createOrder': {
|
648
656
|
'expiration': 86400, # for conditional orders
|
649
657
|
},
|
@@ -905,6 +913,34 @@ class gate(Exchange, ImplicitAPI):
|
|
905
913
|
super(gate, self).set_sandbox_mode(enable)
|
906
914
|
self.options['sandboxMode'] = enable
|
907
915
|
|
916
|
+
def load_unified_status(self, params={}):
|
917
|
+
"""
|
918
|
+
returns unifiedAccount so the user can check if the unified account is enabled
|
919
|
+
:see: https://www.gate.io/docs/developers/apiv4/#get-account-detail
|
920
|
+
:returns boolean: True or False if the enabled unified account is enabled or not and sets the unifiedAccount option if it is None
|
921
|
+
"""
|
922
|
+
unifiedAccount = self.safe_bool(self.options, 'unifiedAccount')
|
923
|
+
if unifiedAccount is None:
|
924
|
+
response = self.privateAccountGetDetail(params)
|
925
|
+
#
|
926
|
+
# {
|
927
|
+
# "user_id": 10406147,
|
928
|
+
# "ip_whitelist": [],
|
929
|
+
# "currency_pairs": [],
|
930
|
+
# "key": {
|
931
|
+
# "mode": 1
|
932
|
+
# },
|
933
|
+
# "tier": 0,
|
934
|
+
# "tier_expire_time": "0001-01-01T00:00:00Z",
|
935
|
+
# "copy_trading_role": 0
|
936
|
+
# }
|
937
|
+
#
|
938
|
+
result = self.safe_dict(response, 'key', {})
|
939
|
+
self.options['unifiedAccount'] = self.safe_integer(result, 'mode') == 2
|
940
|
+
|
941
|
+
def upgrade_unified_trade_account(self, params={}):
|
942
|
+
return self.privateUnifiedPutUnifiedMode(params)
|
943
|
+
|
908
944
|
def create_expired_option_market(self, symbol: str):
|
909
945
|
# support expired option contracts
|
910
946
|
quote = 'USDT'
|
@@ -1549,6 +1585,8 @@ class gate(Exchange, ImplicitAPI):
|
|
1549
1585
|
apiBackup = self.safe_value(self.urls, 'apiBackup')
|
1550
1586
|
if apiBackup is not None:
|
1551
1587
|
return None
|
1588
|
+
if self.check_required_credentials(False):
|
1589
|
+
self.load_unified_status()
|
1552
1590
|
response = self.publicSpotGetCurrencies(params)
|
1553
1591
|
#
|
1554
1592
|
# {
|
@@ -2573,10 +2611,14 @@ class gate(Exchange, ImplicitAPI):
|
|
2573
2611
|
:param str [params.settle]: 'btc' or 'usdt' - settle currency for perpetual swap and future - default="usdt" for swap and "btc" for future
|
2574
2612
|
:param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
|
2575
2613
|
:param str [params.symbol]: margin only - unified ccxt symbol
|
2614
|
+
:param boolean [params.unifiedAccount]: default False, set to True for fetching the unified account balance
|
2576
2615
|
"""
|
2577
2616
|
self.load_markets()
|
2617
|
+
self.load_unified_status()
|
2578
2618
|
symbol = self.safe_string(params, 'symbol')
|
2579
2619
|
params = self.omit(params, 'symbol')
|
2620
|
+
isUnifiedAccount = False
|
2621
|
+
isUnifiedAccount, params = self.handle_option_and_params(params, 'fetchBalance', 'unifiedAccount')
|
2580
2622
|
type, query = self.handle_market_type_and_params('fetchBalance', None, params)
|
2581
2623
|
request, requestParams = self.prepare_request(None, type, query)
|
2582
2624
|
marginMode, requestQuery = self.get_margin_mode(False, requestParams)
|
@@ -2584,7 +2626,9 @@ class gate(Exchange, ImplicitAPI):
|
|
2584
2626
|
market = self.market(symbol)
|
2585
2627
|
request['currency_pair'] = market['id']
|
2586
2628
|
response = None
|
2587
|
-
if
|
2629
|
+
if isUnifiedAccount:
|
2630
|
+
response = self.privateUnifiedGetAccounts(self.extend(request, params))
|
2631
|
+
elif type == 'spot':
|
2588
2632
|
if marginMode == 'spot':
|
2589
2633
|
response = self.privateSpotGetAccounts(self.extend(request, requestQuery))
|
2590
2634
|
elif marginMode == 'margin':
|
@@ -2747,12 +2791,63 @@ class gate(Exchange, ImplicitAPI):
|
|
2747
2791
|
# "orders_limit": 10
|
2748
2792
|
# }
|
2749
2793
|
#
|
2794
|
+
# unified
|
2795
|
+
#
|
2796
|
+
# {
|
2797
|
+
# "user_id": 10001,
|
2798
|
+
# "locked": False,
|
2799
|
+
# "balances": {
|
2800
|
+
# "ETH": {
|
2801
|
+
# "available": "0",
|
2802
|
+
# "freeze": "0",
|
2803
|
+
# "borrowed": "0.075393666654",
|
2804
|
+
# "negative_liab": "0",
|
2805
|
+
# "futures_pos_liab": "0",
|
2806
|
+
# "equity": "1016.1",
|
2807
|
+
# "total_freeze": "0",
|
2808
|
+
# "total_liab": "0"
|
2809
|
+
# },
|
2810
|
+
# "POINT": {
|
2811
|
+
# "available": "9999999999.017023138734",
|
2812
|
+
# "freeze": "0",
|
2813
|
+
# "borrowed": "0",
|
2814
|
+
# "negative_liab": "0",
|
2815
|
+
# "futures_pos_liab": "0",
|
2816
|
+
# "equity": "12016.1",
|
2817
|
+
# "total_freeze": "0",
|
2818
|
+
# "total_liab": "0"
|
2819
|
+
# },
|
2820
|
+
# "USDT": {
|
2821
|
+
# "available": "0.00000062023",
|
2822
|
+
# "freeze": "0",
|
2823
|
+
# "borrowed": "0",
|
2824
|
+
# "negative_liab": "0",
|
2825
|
+
# "futures_pos_liab": "0",
|
2826
|
+
# "equity": "16.1",
|
2827
|
+
# "total_freeze": "0",
|
2828
|
+
# "total_liab": "0"
|
2829
|
+
# }
|
2830
|
+
# },
|
2831
|
+
# "total": "230.94621713",
|
2832
|
+
# "borrowed": "161.66395521",
|
2833
|
+
# "total_initial_margin": "1025.0524665088",
|
2834
|
+
# "total_margin_balance": "3382495.944473949183",
|
2835
|
+
# "total_maintenance_margin": "205.01049330176",
|
2836
|
+
# "total_initial_margin_rate": "3299.827135672679",
|
2837
|
+
# "total_maintenance_margin_rate": "16499.135678363399",
|
2838
|
+
# "total_available_margin": "3381470.892007440383",
|
2839
|
+
# "unified_account_total": "3381470.892007440383",
|
2840
|
+
# "unified_account_total_liab": "0",
|
2841
|
+
# "unified_account_total_equity": "100016.1",
|
2842
|
+
# "leverage": "2"
|
2843
|
+
# }
|
2844
|
+
#
|
2750
2845
|
result: dict = {
|
2751
2846
|
'info': response,
|
2752
2847
|
}
|
2753
2848
|
isolated = marginMode == 'margin'
|
2754
2849
|
data = response
|
2755
|
-
if 'balances' in data: # True for cross_margin
|
2850
|
+
if 'balances' in data: # True for cross_margin and unified
|
2756
2851
|
flatBalances = []
|
2757
2852
|
balances = self.safe_value(data, 'balances', [])
|
2758
2853
|
# inject currency and create an artificial balance object
|
ccxt/htx.py
CHANGED
@@ -1627,6 +1627,10 @@ class htx(Exchange, ImplicitAPI):
|
|
1627
1627
|
def fetch_markets(self, params={}) -> List[Market]:
|
1628
1628
|
"""
|
1629
1629
|
retrieves data on all markets for huobi
|
1630
|
+
:see: https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-trading-symbol-v1-deprecated
|
1631
|
+
:see: https://huobiapi.github.io/docs/dm/v1/en/#get-contract-info
|
1632
|
+
:see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-swap-info
|
1633
|
+
:see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-swap-info
|
1630
1634
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1631
1635
|
:returns dict[]: an array of objects representing market data
|
1632
1636
|
"""
|
@@ -1650,7 +1654,19 @@ class htx(Exchange, ImplicitAPI):
|
|
1650
1654
|
allMarkets = self.array_concat(allMarkets, promises[i])
|
1651
1655
|
return allMarkets
|
1652
1656
|
|
1653
|
-
def fetch_markets_by_type_and_sub_type(self, type, subType, params={}):
|
1657
|
+
def fetch_markets_by_type_and_sub_type(self, type: Str, subType: Str, params={}):
|
1658
|
+
"""
|
1659
|
+
* @ignore
|
1660
|
+
retrieves data on all markets of a certain type and/or subtype
|
1661
|
+
:see: https://huobiapi.github.io/docs/spot/v1/en/#get-all-supported-trading-symbol-v1-deprecated
|
1662
|
+
:see: https://huobiapi.github.io/docs/dm/v1/en/#get-contract-info
|
1663
|
+
:see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#query-swap-info
|
1664
|
+
:see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-query-swap-info
|
1665
|
+
:param str [type]: 'spot', 'swap' or 'future'
|
1666
|
+
:param str [subType]: 'linear' or 'inverse'
|
1667
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1668
|
+
:returns dict[]: an array of objects representing market data
|
1669
|
+
"""
|
1654
1670
|
isSpot = (type == 'spot')
|
1655
1671
|
request: dict = {}
|
1656
1672
|
response = None
|
@@ -3014,7 +3030,15 @@ class htx(Exchange, ImplicitAPI):
|
|
3014
3030
|
'code': None,
|
3015
3031
|
}
|
3016
3032
|
|
3017
|
-
def fetch_account_id_by_type(self, type, marginMode=None, symbol=None, params={}):
|
3033
|
+
def fetch_account_id_by_type(self, type: str, marginMode: Str = None, symbol: Str = None, params={}):
|
3034
|
+
"""
|
3035
|
+
fetch all the accounts by a type and marginModeassociated with a profile
|
3036
|
+
:see: https://huobiapi.github.io/docs/spot/v1/en/#get-all-accounts-of-the-current-user
|
3037
|
+
:param str type: 'spot', 'swap' or 'future
|
3038
|
+
:param str [marginMode]: 'cross' or 'isolated'
|
3039
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3040
|
+
:returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
|
3041
|
+
"""
|
3018
3042
|
accounts = self.load_accounts()
|
3019
3043
|
accountId = self.safe_value_2(params, 'accountId', 'account-id')
|
3020
3044
|
if accountId is not None:
|
@@ -4755,11 +4779,7 @@ class htx(Exchange, ImplicitAPI):
|
|
4755
4779
|
cost = None
|
4756
4780
|
amount = None
|
4757
4781
|
if (type is not None) and (type.find('market') >= 0):
|
4758
|
-
|
4759
|
-
if side == 'sell':
|
4760
|
-
cost = self.safe_string(order, 'field-cash-amount')
|
4761
|
-
else:
|
4762
|
-
cost = self.safe_string(order, 'amount')
|
4782
|
+
cost = self.safe_string(order, 'field-cash-amount')
|
4763
4783
|
else:
|
4764
4784
|
amount = self.safe_string_2(order, 'volume', 'amount')
|
4765
4785
|
cost = self.safe_string_n(order, ['filled-cash-amount', 'field-cash-amount', 'trade_turnover']) # same typo here
|
ccxt/hyperliquid.py
CHANGED
@@ -638,17 +638,17 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
638
638
|
code = self.safe_currency_code(self.safe_string(balance, 'coin'))
|
639
639
|
account = self.account()
|
640
640
|
total = self.safe_string(balance, 'total')
|
641
|
-
|
641
|
+
used = self.safe_string(balance, 'hold')
|
642
642
|
account['total'] = total
|
643
|
-
account['used'] =
|
643
|
+
account['used'] = used
|
644
644
|
spotBalances[code] = account
|
645
645
|
return self.safe_balance(spotBalances)
|
646
646
|
data = self.safe_dict(response, 'marginSummary', {})
|
647
647
|
result: dict = {
|
648
648
|
'info': response,
|
649
649
|
'USDC': {
|
650
|
-
'total': self.
|
651
|
-
'
|
650
|
+
'total': self.safe_number(data, 'accountValue'),
|
651
|
+
'free': self.safe_number(response, 'withdrawable'),
|
652
652
|
},
|
653
653
|
}
|
654
654
|
timestamp = self.safe_integer(response, 'time')
|
@@ -2112,13 +2112,16 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2112
2112
|
leverage = self.safe_dict(entry, 'leverage', {})
|
2113
2113
|
marginMode = self.safe_string(leverage, 'type')
|
2114
2114
|
isIsolated = (marginMode == 'isolated')
|
2115
|
-
|
2115
|
+
rawSize = self.safe_string(entry, 'szi')
|
2116
|
+
size = rawSize
|
2116
2117
|
side = None
|
2117
2118
|
if size is not None:
|
2118
|
-
side = 'long' if (
|
2119
|
-
|
2120
|
-
|
2121
|
-
|
2119
|
+
side = 'long' if Precise.string_gt(rawSize, '0') else 'short'
|
2120
|
+
size = Precise.string_abs(size)
|
2121
|
+
rawUnrealizedPnl = self.safe_string(entry, 'unrealizedPnl')
|
2122
|
+
absRawUnrealizedPnl = Precise.string_abs(rawUnrealizedPnl)
|
2123
|
+
initialMargin = self.safe_string(entry, 'marginUsed')
|
2124
|
+
percentage = Precise.string_mul(Precise.string_div(absRawUnrealizedPnl, initialMargin), '100')
|
2122
2125
|
return self.safe_position({
|
2123
2126
|
'info': position,
|
2124
2127
|
'id': None,
|
@@ -2128,7 +2131,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2128
2131
|
'isolated': isIsolated,
|
2129
2132
|
'hedged': None,
|
2130
2133
|
'side': side,
|
2131
|
-
'contracts': size,
|
2134
|
+
'contracts': self.parse_number(size),
|
2132
2135
|
'contractSize': None,
|
2133
2136
|
'entryPrice': self.safe_number(entry, 'entryPx'),
|
2134
2137
|
'markPrice': None,
|
@@ -2139,10 +2142,10 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2139
2142
|
'maintenanceMargin': None,
|
2140
2143
|
'initialMarginPercentage': None,
|
2141
2144
|
'maintenanceMarginPercentage': None,
|
2142
|
-
'unrealizedPnl':
|
2145
|
+
'unrealizedPnl': self.parse_number(rawUnrealizedPnl),
|
2143
2146
|
'liquidationPrice': self.safe_number(entry, 'liquidationPx'),
|
2144
2147
|
'marginMode': marginMode,
|
2145
|
-
'percentage': percentage,
|
2148
|
+
'percentage': self.parse_number(percentage),
|
2146
2149
|
})
|
2147
2150
|
|
2148
2151
|
def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
|
ccxt/kucoin.py
CHANGED
@@ -183,6 +183,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
183
183
|
'mark-price/{symbol}/current': 3, # 2PW
|
184
184
|
'mark-price/all-symbols': 3,
|
185
185
|
'margin/config': 25, # 25SW
|
186
|
+
'announcements': 20, # 20W
|
186
187
|
},
|
187
188
|
'post': {
|
188
189
|
# ws
|
@@ -306,6 +307,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
306
307
|
# ws
|
307
308
|
'bullet-private': 10, # 10SW
|
308
309
|
'position/update-user-leverage': 5,
|
310
|
+
'deposit-address/create': 20,
|
309
311
|
},
|
310
312
|
'delete': {
|
311
313
|
# account
|
@@ -472,6 +474,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
472
474
|
'precisionMode': TICK_SIZE,
|
473
475
|
'exceptions': {
|
474
476
|
'exact': {
|
477
|
+
'The order does not exist.': OrderNotFound,
|
475
478
|
'order not exist': OrderNotFound,
|
476
479
|
'order not exist.': OrderNotFound, # duplicated error temporarily
|
477
480
|
'order_not_exist': OrderNotFound, # {"code":"order_not_exist","msg":"order_not_exist"} ¯\_(ツ)_/¯
|
@@ -672,6 +675,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
672
675
|
'currencies/{currency}': 'v3',
|
673
676
|
'symbols': 'v2',
|
674
677
|
'mark-price/all-symbols': 'v3',
|
678
|
+
'announcements': 'v3',
|
675
679
|
},
|
676
680
|
},
|
677
681
|
'private': {
|
@@ -723,6 +727,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
723
727
|
'accounts/sub-transfer': 'v2',
|
724
728
|
'accounts/inner-transfer': 'v2',
|
725
729
|
'transfer-out': 'v3',
|
730
|
+
'deposit-address/create': 'v3',
|
726
731
|
# spot trading
|
727
732
|
'oco/order': 'v3',
|
728
733
|
# margin trading
|
@@ -734,6 +739,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
734
739
|
'redeem': 'v3',
|
735
740
|
'lend/purchase/update': 'v3',
|
736
741
|
'position/update-user-leverage': 'v3',
|
742
|
+
'withdrawals': 'v3',
|
737
743
|
},
|
738
744
|
'DELETE': {
|
739
745
|
# account
|
@@ -799,7 +805,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
799
805
|
'TLOS': 'tlos', # tlosevm is different
|
800
806
|
'CFX': 'cfx',
|
801
807
|
'ACA': 'aca',
|
802
|
-
'
|
808
|
+
'OP': 'optimism',
|
803
809
|
'ONT': 'ont',
|
804
810
|
'GLMR': 'glmr',
|
805
811
|
'CSPR': 'cspr',
|
@@ -1529,38 +1535,28 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1529
1535
|
# "chain": "ERC20"
|
1530
1536
|
# }
|
1531
1537
|
#
|
1538
|
+
minWithdrawFee = self.safe_number(fee, 'withdrawMinFee')
|
1532
1539
|
result: dict = {
|
1533
1540
|
'info': fee,
|
1534
1541
|
'withdraw': {
|
1542
|
+
'fee': minWithdrawFee,
|
1543
|
+
'percentage': False,
|
1544
|
+
},
|
1545
|
+
'deposit': {
|
1535
1546
|
'fee': None,
|
1536
1547
|
'percentage': None,
|
1537
1548
|
},
|
1549
|
+
'networks': {},
|
1550
|
+
}
|
1551
|
+
networkId = self.safe_string(fee, 'chain')
|
1552
|
+
networkCode = self.network_id_to_code(networkId, self.safe_string(currency, 'code'))
|
1553
|
+
result['networks'][networkCode] = {
|
1554
|
+
'withdraw': minWithdrawFee,
|
1538
1555
|
'deposit': {
|
1539
1556
|
'fee': None,
|
1540
1557
|
'percentage': None,
|
1541
1558
|
},
|
1542
|
-
'networks': {},
|
1543
1559
|
}
|
1544
|
-
isWithdrawEnabled = self.safe_bool(fee, 'isWithdrawEnabled', True)
|
1545
|
-
minFee = None
|
1546
|
-
if isWithdrawEnabled:
|
1547
|
-
result['withdraw']['percentage'] = False
|
1548
|
-
chains = self.safe_list(fee, 'chains', [])
|
1549
|
-
for i in range(0, len(chains)):
|
1550
|
-
chain = chains[i]
|
1551
|
-
networkId = self.safe_string(chain, 'chainId')
|
1552
|
-
networkCode = self.network_id_to_code(networkId, self.safe_string(currency, 'code'))
|
1553
|
-
withdrawFee = self.safe_string(chain, 'withdrawalMinFee')
|
1554
|
-
if minFee is None or (Precise.string_lt(withdrawFee, minFee)):
|
1555
|
-
minFee = withdrawFee
|
1556
|
-
result['networks'][networkCode] = {
|
1557
|
-
'withdraw': self.parse_number(withdrawFee),
|
1558
|
-
'deposit': {
|
1559
|
-
'fee': None,
|
1560
|
-
'percentage': None,
|
1561
|
-
},
|
1562
|
-
}
|
1563
|
-
result['withdraw']['fee'] = self.parse_number(minFee)
|
1564
1560
|
return result
|
1565
1561
|
|
1566
1562
|
def is_futures_method(self, methodName, params):
|
@@ -1869,7 +1865,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1869
1865
|
|
1870
1866
|
def create_deposit_address(self, code: str, params={}):
|
1871
1867
|
"""
|
1872
|
-
:see: https://
|
1868
|
+
:see: https://www.kucoin.com/docs/rest/funding/deposit/create-deposit-address-v3-
|
1873
1869
|
create a currency deposit address
|
1874
1870
|
:param str code: unified currency code of the currency for the deposit address
|
1875
1871
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1884,11 +1880,23 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1884
1880
|
networkCode = None
|
1885
1881
|
networkCode, params = self.handle_network_code_and_params(params)
|
1886
1882
|
if networkCode is not None:
|
1887
|
-
request['chain'] = self.network_code_to_id(networkCode)
|
1888
|
-
response = self.
|
1883
|
+
request['chain'] = self.network_code_to_id(networkCode) # docs mention "chain-name", but seems "chain-id" is used, like in "fetchDepositAddress"
|
1884
|
+
response = self.privatePostDepositAddressCreate(self.extend(request, params))
|
1889
1885
|
# {"code":"260000","msg":"Deposit address already exists."}
|
1890
|
-
#
|
1891
|
-
#
|
1886
|
+
#
|
1887
|
+
# {
|
1888
|
+
# "code": "200000",
|
1889
|
+
# "data": {
|
1890
|
+
# "address": "0x2336d1834faab10b2dac44e468f2627138417431",
|
1891
|
+
# "memo": null,
|
1892
|
+
# "chainId": "bsc",
|
1893
|
+
# "to": "MAIN",
|
1894
|
+
# "expirationDate": 0,
|
1895
|
+
# "currency": "BNB",
|
1896
|
+
# "chainName": "BEP20"
|
1897
|
+
# }
|
1898
|
+
# }
|
1899
|
+
#
|
1892
1900
|
data = self.safe_dict(response, 'data', {})
|
1893
1901
|
return self.parse_deposit_address(data, currency)
|
1894
1902
|
|
@@ -1938,7 +1946,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1938
1946
|
return {
|
1939
1947
|
'info': depositAddress,
|
1940
1948
|
'currency': code,
|
1941
|
-
'network': self.network_id_to_code(self.safe_string(depositAddress, '
|
1949
|
+
'network': self.network_id_to_code(self.safe_string(depositAddress, 'chainId')),
|
1942
1950
|
'address': address,
|
1943
1951
|
'tag': self.safe_string(depositAddress, 'memo'),
|
1944
1952
|
}
|
@@ -2920,7 +2928,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2920
2928
|
},
|
2921
2929
|
'status': status,
|
2922
2930
|
'lastTradeTimestamp': None,
|
2923
|
-
'average':
|
2931
|
+
'average': self.safe_string(order, 'avgDealPrice'),
|
2924
2932
|
'trades': None,
|
2925
2933
|
}, market)
|
2926
2934
|
|
@@ -3245,7 +3253,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3245
3253
|
def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
|
3246
3254
|
"""
|
3247
3255
|
make a withdrawal
|
3248
|
-
:see: https://www.kucoin.com/docs/rest/funding/withdrawals/apply-withdraw
|
3256
|
+
:see: https://www.kucoin.com/docs/rest/funding/withdrawals/apply-withdraw-v3-
|
3249
3257
|
:param str code: unified currency code
|
3250
3258
|
:param float amount: the amount to withdraw
|
3251
3259
|
:param str address: the address to withdraw to
|
@@ -3259,7 +3267,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3259
3267
|
currency = self.currency(code)
|
3260
3268
|
request: dict = {
|
3261
3269
|
'currency': currency['id'],
|
3262
|
-
'
|
3270
|
+
'toAddress': address,
|
3271
|
+
'withdrawType': 'ADDRESS',
|
3263
3272
|
# 'memo': tag,
|
3264
3273
|
# 'isInner': False, # internal transfer or external withdrawal
|
3265
3274
|
# 'remark': 'optional',
|
@@ -3271,15 +3280,14 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3271
3280
|
networkCode, params = self.handle_network_code_and_params(params)
|
3272
3281
|
if networkCode is not None:
|
3273
3282
|
request['chain'] = self.network_code_to_id(networkCode).lower()
|
3274
|
-
self.
|
3275
|
-
request['amount'] = self.currency_to_precision(code, amount, networkCode)
|
3283
|
+
request['amount'] = float(self.currency_to_precision(code, amount, networkCode))
|
3276
3284
|
includeFee = None
|
3277
3285
|
includeFee, params = self.handle_option_and_params(params, 'withdraw', 'includeFee', False)
|
3278
3286
|
if includeFee:
|
3279
3287
|
request['feeDeductType'] = 'INTERNAL'
|
3280
3288
|
response = self.privatePostWithdrawals(self.extend(request, params))
|
3281
3289
|
#
|
3282
|
-
#
|
3290
|
+
# the id is inside "data"
|
3283
3291
|
#
|
3284
3292
|
# {
|
3285
3293
|
# "code": 200000,
|
@@ -3291,51 +3299,6 @@ class kucoin(Exchange, ImplicitAPI):
|
|
3291
3299
|
data = self.safe_dict(response, 'data', {})
|
3292
3300
|
return self.parse_transaction(data, currency)
|
3293
3301
|
|
3294
|
-
def load_currency_precision(self, currency, networkCode: Str = None):
|
3295
|
-
# might not have network specific precisions defined in fetchCurrencies(because of webapi failure)
|
3296
|
-
# we should check and refetch precision once-per-instance for that specific currency & network
|
3297
|
-
# so avoids thorwing exceptions and burden to users
|
3298
|
-
# Note: self needs to be executed only if networkCode was provided
|
3299
|
-
if networkCode is not None:
|
3300
|
-
networks = currency['networks']
|
3301
|
-
network = self.safe_dict(networks, networkCode)
|
3302
|
-
if self.safe_number(network, 'precision') is not None:
|
3303
|
-
# if precision exists, no need to refetch
|
3304
|
-
return
|
3305
|
-
# otherwise try to fetch and store in instance
|
3306
|
-
request: dict = {
|
3307
|
-
'currency': currency['id'],
|
3308
|
-
'chain': self.network_code_to_id(networkCode).lower(),
|
3309
|
-
}
|
3310
|
-
response = self.privateGetWithdrawalsQuotas(request)
|
3311
|
-
#
|
3312
|
-
# {
|
3313
|
-
# "code": "200000",
|
3314
|
-
# "data": {
|
3315
|
-
# "currency": "USDT",
|
3316
|
-
# "limitBTCAmount": "14.24094850",
|
3317
|
-
# "usedBTCAmount": "0.00000000",
|
3318
|
-
# "quotaCurrency": "USDT",
|
3319
|
-
# "limitQuotaCurrencyAmount": "999999.00000000",
|
3320
|
-
# "usedQuotaCurrencyAmount": "0",
|
3321
|
-
# "remainAmount": "999999.0000",
|
3322
|
-
# "availableAmount": "10.77545071",
|
3323
|
-
# "withdrawMinFee": "1",
|
3324
|
-
# "innerWithdrawMinFee": "0",
|
3325
|
-
# "withdrawMinSize": "10",
|
3326
|
-
# "isWithdrawEnabled": True,
|
3327
|
-
# "precision": 4,
|
3328
|
-
# "chain": "EOS",
|
3329
|
-
# "reason": null,
|
3330
|
-
# "lockedAmount": "0"
|
3331
|
-
# }
|
3332
|
-
# }
|
3333
|
-
#
|
3334
|
-
data = self.safe_dict(response, 'data', {})
|
3335
|
-
precision = self.parse_number(self.parse_precision(self.safe_string(data, 'precision')))
|
3336
|
-
code = currency['code']
|
3337
|
-
self.currencies[code]['networks'][networkCode]['precision'] = precision
|
3338
|
-
|
3339
3302
|
def parse_transaction_status(self, status: Str):
|
3340
3303
|
statuses: dict = {
|
3341
3304
|
'SUCCESS': 'ok',
|
@@ -4153,15 +4116,6 @@ class kucoin(Exchange, ImplicitAPI):
|
|
4153
4116
|
return config['v1']
|
4154
4117
|
return self.safe_value(config, 'cost', 1)
|
4155
4118
|
|
4156
|
-
def parse_borrow_rate_history(self, response, code, since, limit):
|
4157
|
-
result = []
|
4158
|
-
for i in range(0, len(response)):
|
4159
|
-
item = response[i]
|
4160
|
-
borrowRate = self.parse_borrow_rate(item)
|
4161
|
-
result.append(borrowRate)
|
4162
|
-
sorted = self.sort_by(result, 'timestamp')
|
4163
|
-
return self.filter_by_currency_since_limit(sorted, code, since, limit)
|
4164
|
-
|
4165
4119
|
def parse_borrow_rate(self, info, currency: Currency = None):
|
4166
4120
|
#
|
4167
4121
|
# {
|
ccxt/kucoinfutures.py
CHANGED
@@ -2103,8 +2103,8 @@ class kucoinfutures(kucoin, ImplicitAPI):
|
|
2103
2103
|
amount = self.safe_string(order, 'size')
|
2104
2104
|
filled = self.safe_string(order, 'filledSize')
|
2105
2105
|
cost = self.safe_string(order, 'filledValue')
|
2106
|
-
average =
|
2107
|
-
if Precise.string_gt(filled, '0'):
|
2106
|
+
average = self.safe_string(order, 'avgDealPrice')
|
2107
|
+
if (average is None) and Precise.string_gt(filled, '0'):
|
2108
2108
|
contractSize = self.safe_string(market, 'contractSize')
|
2109
2109
|
if market['linear']:
|
2110
2110
|
average = Precise.string_div(cost, Precise.string_mul(contractSize, filled))
|