ccxt 4.3.65__py2.py3-none-any.whl → 4.3.67__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/bingx.py +7 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/base/ws/fast_client.py +2 -1
- ccxt/async_support/base/ws/future.py +13 -2
- ccxt/async_support/bingx.py +147 -19
- ccxt/async_support/bithumb.py +60 -17
- ccxt/async_support/hyperliquid.py +60 -7
- ccxt/async_support/kraken.py +25 -0
- ccxt/async_support/whitebit.py +1 -1
- ccxt/async_support/zonda.py +1 -1
- ccxt/base/exchange.py +10 -10
- ccxt/bingx.py +147 -19
- ccxt/bithumb.py +59 -17
- ccxt/hyperliquid.py +60 -7
- ccxt/kraken.py +25 -0
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitget.py +1 -1
- ccxt/pro/bybit.py +1 -1
- ccxt/pro/coinone.py +1 -1
- ccxt/pro/currencycom.py +1 -1
- ccxt/pro/hollaex.py +1 -1
- ccxt/pro/hyperliquid.py +103 -3
- ccxt/pro/kucoin.py +1 -1
- ccxt/pro/kucoinfutures.py +1 -1
- ccxt/pro/mexc.py +1 -1
- ccxt/pro/okcoin.py +1 -1
- ccxt/pro/okx.py +21 -9
- ccxt/pro/oxfun.py +1 -1
- ccxt/pro/p2b.py +1 -1
- ccxt/pro/poloniex.py +1 -1
- ccxt/pro/whitebit.py +1 -1
- ccxt/test/tests_async.py +58 -28
- ccxt/test/tests_helpers.py +8 -1
- ccxt/test/tests_sync.py +58 -28
- ccxt/whitebit.py +1 -1
- ccxt/zonda.py +1 -1
- {ccxt-4.3.65.dist-info → ccxt-4.3.67.dist-info}/METADATA +5 -4
- {ccxt-4.3.65.dist-info → ccxt-4.3.67.dist-info}/RECORD +43 -43
- {ccxt-4.3.65.dist-info → ccxt-4.3.67.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.3.65.dist-info → ccxt-4.3.67.dist-info}/WHEEL +0 -0
- {ccxt-4.3.65.dist-info → ccxt-4.3.67.dist-info}/top_level.txt +0 -0
ccxt/__init__.py
CHANGED
ccxt/abstract/bingx.py
CHANGED
@@ -85,13 +85,20 @@ class ImplicitAPI:
|
|
85
85
|
cswap_v1_private_get_trade_leverage = cswapV1PrivateGetTradeLeverage = Entry('trade/leverage', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
86
86
|
cswap_v1_private_get_trade_forceorders = cswapV1PrivateGetTradeForceOrders = Entry('trade/forceOrders', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
87
87
|
cswap_v1_private_get_trade_allfillorders = cswapV1PrivateGetTradeAllFillOrders = Entry('trade/allFillOrders', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
88
|
+
cswap_v1_private_get_trade_openorders = cswapV1PrivateGetTradeOpenOrders = Entry('trade/openOrders', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
89
|
+
cswap_v1_private_get_trade_orderdetail = cswapV1PrivateGetTradeOrderDetail = Entry('trade/orderDetail', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
90
|
+
cswap_v1_private_get_trade_orderhistory = cswapV1PrivateGetTradeOrderHistory = Entry('trade/orderHistory', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
91
|
+
cswap_v1_private_get_trade_margintype = cswapV1PrivateGetTradeMarginType = Entry('trade/marginType', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
88
92
|
cswap_v1_private_get_user_commissionrate = cswapV1PrivateGetUserCommissionRate = Entry('user/commissionRate', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
89
93
|
cswap_v1_private_get_user_positions = cswapV1PrivateGetUserPositions = Entry('user/positions', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
90
94
|
cswap_v1_private_get_user_balance = cswapV1PrivateGetUserBalance = Entry('user/balance', ['cswap', 'v1', 'private'], 'GET', {'cost': 2})
|
91
95
|
cswap_v1_private_post_trade_order = cswapV1PrivatePostTradeOrder = Entry('trade/order', ['cswap', 'v1', 'private'], 'POST', {'cost': 2})
|
92
96
|
cswap_v1_private_post_trade_leverage = cswapV1PrivatePostTradeLeverage = Entry('trade/leverage', ['cswap', 'v1', 'private'], 'POST', {'cost': 2})
|
93
97
|
cswap_v1_private_post_trade_closeallpositions = cswapV1PrivatePostTradeCloseAllPositions = Entry('trade/closeAllPositions', ['cswap', 'v1', 'private'], 'POST', {'cost': 2})
|
98
|
+
cswap_v1_private_post_trade_margintype = cswapV1PrivatePostTradeMarginType = Entry('trade/marginType', ['cswap', 'v1', 'private'], 'POST', {'cost': 2})
|
99
|
+
cswap_v1_private_post_trade_positionmargin = cswapV1PrivatePostTradePositionMargin = Entry('trade/positionMargin', ['cswap', 'v1', 'private'], 'POST', {'cost': 2})
|
94
100
|
cswap_v1_private_delete_trade_allopenorders = cswapV1PrivateDeleteTradeAllOpenOrders = Entry('trade/allOpenOrders', ['cswap', 'v1', 'private'], 'DELETE', {'cost': 2})
|
101
|
+
cswap_v1_private_delete_trade_cancelorder = cswapV1PrivateDeleteTradeCancelOrder = Entry('trade/cancelOrder', ['cswap', 'v1', 'private'], 'DELETE', {'cost': 2})
|
95
102
|
contract_v1_private_get_allposition = contractV1PrivateGetAllPosition = Entry('allPosition', ['contract', 'v1', 'private'], 'GET', {'cost': 2})
|
96
103
|
contract_v1_private_get_allorders = contractV1PrivateGetAllOrders = Entry('allOrders', ['contract', 'v1', 'private'], 'GET', {'cost': 2})
|
97
104
|
contract_v1_private_get_balance = contractV1PrivateGetBalance = Entry('balance', ['contract', 'v1', 'private'], 'GET', {'cost': 2})
|
ccxt/async_support/__init__.py
CHANGED
@@ -4,6 +4,7 @@ import asyncio
|
|
4
4
|
import socket
|
5
5
|
import collections
|
6
6
|
from ccxt.async_support.base.ws.aiohttp_client import AiohttpClient
|
7
|
+
from ccxt.base.errors import NetworkError
|
7
8
|
|
8
9
|
|
9
10
|
class FastClient(AiohttpClient):
|
@@ -38,7 +39,7 @@ class FastClient(AiohttpClient):
|
|
38
39
|
if self.connection._close_code == 1000: # OK close
|
39
40
|
self.on_close(1000)
|
40
41
|
else:
|
41
|
-
self.on_error(
|
42
|
+
self.on_error(NetworkError("Abnormal closure of client")) # ABNORMAL_CLOSURE
|
42
43
|
|
43
44
|
def wrapper(func):
|
44
45
|
def parse_frame(buf):
|
@@ -7,11 +7,22 @@ class Future(asyncio.Future):
|
|
7
7
|
|
8
8
|
def resolve(self, result=None):
|
9
9
|
if not self.done():
|
10
|
-
|
10
|
+
try:
|
11
|
+
self.set_result(result)
|
12
|
+
except BaseException as e:
|
13
|
+
print("Error in Future.resolve")
|
14
|
+
raise e
|
11
15
|
|
12
16
|
def reject(self, error=None):
|
13
17
|
if not self.done():
|
14
|
-
|
18
|
+
# If not an exception, wrap it in a generic Exception
|
19
|
+
if not isinstance(error, BaseException):
|
20
|
+
error = Exception(error)
|
21
|
+
try:
|
22
|
+
self.set_exception(error)
|
23
|
+
except BaseException as e:
|
24
|
+
print("Error in Future.reject")
|
25
|
+
raise e
|
15
26
|
|
16
27
|
@classmethod
|
17
28
|
def race(cls, futures):
|
ccxt/async_support/bingx.py
CHANGED
@@ -298,6 +298,10 @@ class bingx(Exchange, ImplicitAPI):
|
|
298
298
|
'trade/leverage': 2,
|
299
299
|
'trade/forceOrders': 2,
|
300
300
|
'trade/allFillOrders': 2,
|
301
|
+
'trade/openOrders': 2,
|
302
|
+
'trade/orderDetail': 2,
|
303
|
+
'trade/orderHistory': 2,
|
304
|
+
'trade/marginType': 2,
|
301
305
|
'user/commissionRate': 2,
|
302
306
|
'user/positions': 2,
|
303
307
|
'user/balance': 2,
|
@@ -306,9 +310,12 @@ class bingx(Exchange, ImplicitAPI):
|
|
306
310
|
'trade/order': 2,
|
307
311
|
'trade/leverage': 2,
|
308
312
|
'trade/closeAllPositions': 2,
|
313
|
+
'trade/marginType': 2,
|
314
|
+
'trade/positionMargin': 2,
|
309
315
|
},
|
310
316
|
'delete': {
|
311
317
|
'trade/allOpenOrders': 2,
|
318
|
+
'trade/cancelOrder': 2,
|
312
319
|
},
|
313
320
|
},
|
314
321
|
},
|
@@ -2835,7 +2842,8 @@ class bingx(Exchange, ImplicitAPI):
|
|
2835
2842
|
# "clientOrderID": ""
|
2836
2843
|
# }
|
2837
2844
|
#
|
2838
|
-
# inverse swap cancelAllOrders
|
2845
|
+
# inverse swap cancelAllOrders, cancelOrder
|
2846
|
+
# inverse swap cancelAllOrders, cancelOrder, fetchOpenOrders
|
2839
2847
|
#
|
2840
2848
|
# {
|
2841
2849
|
# "symbol": "SOL-USD",
|
@@ -2979,13 +2987,14 @@ class bingx(Exchange, ImplicitAPI):
|
|
2979
2987
|
async def cancel_order(self, id: str, symbol: Str = None, params={}):
|
2980
2988
|
"""
|
2981
2989
|
cancels an open order
|
2982
|
-
:see: https://bingx-api.github.io/docs/#/spot/trade-api.html#Cancel%
|
2983
|
-
:see: https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Cancel%
|
2990
|
+
:see: https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Cancel%20Order
|
2991
|
+
:see: https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Cancel%20Order
|
2992
|
+
:see: https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Cancel%20an%20Order
|
2984
2993
|
:param str id: order id
|
2985
2994
|
:param str symbol: unified symbol of the market the order was made in
|
2986
2995
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2987
2996
|
:param str [params.clientOrderId]: a unique id for the order
|
2988
|
-
:returns dict:
|
2997
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2989
2998
|
"""
|
2990
2999
|
if symbol is None:
|
2991
3000
|
raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
|
@@ -3001,11 +3010,17 @@ class bingx(Exchange, ImplicitAPI):
|
|
3001
3010
|
else:
|
3002
3011
|
request['orderId'] = id
|
3003
3012
|
response = None
|
3004
|
-
|
3005
|
-
|
3006
|
-
|
3013
|
+
type = None
|
3014
|
+
subType = None
|
3015
|
+
type, params = self.handle_market_type_and_params('cancelOrder', market, params)
|
3016
|
+
subType, params = self.handle_sub_type_and_params('cancelOrder', market, params)
|
3017
|
+
if type == 'spot':
|
3018
|
+
response = await self.spotV1PrivatePostTradeCancel(self.extend(request, params))
|
3007
3019
|
else:
|
3008
|
-
|
3020
|
+
if subType == 'inverse':
|
3021
|
+
response = await self.cswapV1PrivateDeleteTradeCancelOrder(self.extend(request, params))
|
3022
|
+
else:
|
3023
|
+
response = await self.swapV2PrivateDeleteTradeOrder(self.extend(request, params))
|
3009
3024
|
#
|
3010
3025
|
# spot
|
3011
3026
|
#
|
@@ -3025,7 +3040,59 @@ class bingx(Exchange, ImplicitAPI):
|
|
3025
3040
|
# }
|
3026
3041
|
# }
|
3027
3042
|
#
|
3028
|
-
# swap
|
3043
|
+
# inverse swap
|
3044
|
+
#
|
3045
|
+
# {
|
3046
|
+
# "code": 0,
|
3047
|
+
# "msg": "",
|
3048
|
+
# "data": {
|
3049
|
+
# "order": {
|
3050
|
+
# "symbol": "SOL-USD",
|
3051
|
+
# "orderId": "1816002957423951872",
|
3052
|
+
# "side": "BUY",
|
3053
|
+
# "positionSide": "Long",
|
3054
|
+
# "type": "Pending",
|
3055
|
+
# "quantity": 0,
|
3056
|
+
# "origQty": "0",
|
3057
|
+
# "price": "150",
|
3058
|
+
# "executedQty": "0",
|
3059
|
+
# "avgPrice": "0",
|
3060
|
+
# "cumQuote": "0",
|
3061
|
+
# "stopPrice": "",
|
3062
|
+
# "profit": "0.0000",
|
3063
|
+
# "commission": "0.000000",
|
3064
|
+
# "status": "CANCELLED",
|
3065
|
+
# "time": 1721803819410,
|
3066
|
+
# "updateTime": 1721803819427,
|
3067
|
+
# "clientOrderId": "",
|
3068
|
+
# "leverage": "",
|
3069
|
+
# "takeProfit": {
|
3070
|
+
# "type": "",
|
3071
|
+
# "quantity": 0,
|
3072
|
+
# "stopPrice": 0,
|
3073
|
+
# "price": 0,
|
3074
|
+
# "workingType": "",
|
3075
|
+
# "stopGuaranteed": ""
|
3076
|
+
# },
|
3077
|
+
# "stopLoss": {
|
3078
|
+
# "type": "",
|
3079
|
+
# "quantity": 0,
|
3080
|
+
# "stopPrice": 0,
|
3081
|
+
# "price": 0,
|
3082
|
+
# "workingType": "",
|
3083
|
+
# "stopGuaranteed": ""
|
3084
|
+
# },
|
3085
|
+
# "advanceAttr": 0,
|
3086
|
+
# "positionID": 0,
|
3087
|
+
# "takeProfitEntrustPrice": 0,
|
3088
|
+
# "stopLossEntrustPrice": 0,
|
3089
|
+
# "orderType": "",
|
3090
|
+
# "workingType": ""
|
3091
|
+
# }
|
3092
|
+
# }
|
3093
|
+
# }
|
3094
|
+
#
|
3095
|
+
# linear swap
|
3029
3096
|
#
|
3030
3097
|
# {
|
3031
3098
|
# "code": 0,
|
@@ -3052,9 +3119,9 @@ class bingx(Exchange, ImplicitAPI):
|
|
3052
3119
|
# }
|
3053
3120
|
# }
|
3054
3121
|
#
|
3055
|
-
data = self.
|
3056
|
-
|
3057
|
-
return self.parse_order(
|
3122
|
+
data = self.safe_dict(response, 'data', {})
|
3123
|
+
order = self.safe_dict(data, 'order', data)
|
3124
|
+
return self.parse_order(order, market)
|
3058
3125
|
|
3059
3126
|
async def cancel_all_orders(self, symbol: Str = None, params={}):
|
3060
3127
|
"""
|
@@ -3498,9 +3565,10 @@ class bingx(Exchange, ImplicitAPI):
|
|
3498
3565
|
|
3499
3566
|
async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
3500
3567
|
"""
|
3501
|
-
:see: https://bingx-api.github.io/docs/#/spot/trade-api.html#Query%20Open%20Orders
|
3502
|
-
:see: https://bingx-api.github.io/docs/#/swapV2/trade-api.html#Query%20all%20current%20pending%20orders
|
3503
3568
|
fetch all unfilled currently open orders
|
3569
|
+
:see: https://bingx-api.github.io/docs/#/en-us/spot/trade-api.html#Current%20Open%20Orders
|
3570
|
+
:see: https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Current%20All%20Open%20Orders
|
3571
|
+
:see: https://bingx-api.github.io/docs/#/en-us/cswap/trade-api.html#Query%20all%20current%20pending%20orders
|
3504
3572
|
:param str symbol: unified market symbol
|
3505
3573
|
:param int [since]: the earliest time in ms to fetch open orders for
|
3506
3574
|
:param int [limit]: the maximum number of open order structures to retrieve
|
@@ -3513,12 +3581,18 @@ class bingx(Exchange, ImplicitAPI):
|
|
3513
3581
|
if symbol is not None:
|
3514
3582
|
market = self.market(symbol)
|
3515
3583
|
request['symbol'] = market['id']
|
3584
|
+
type = None
|
3585
|
+
subType = None
|
3516
3586
|
response = None
|
3517
|
-
|
3518
|
-
|
3519
|
-
|
3587
|
+
type, params = self.handle_market_type_and_params('fetchOpenOrders', market, params)
|
3588
|
+
subType, params = self.handle_sub_type_and_params('fetchOpenOrders', market, params)
|
3589
|
+
if type == 'spot':
|
3590
|
+
response = await self.spotV1PrivateGetTradeOpenOrders(self.extend(request, params))
|
3520
3591
|
else:
|
3521
|
-
|
3592
|
+
if subType == 'inverse':
|
3593
|
+
response = await self.cswapV1PrivateGetTradeOpenOrders(self.extend(request, params))
|
3594
|
+
else:
|
3595
|
+
response = await self.swapV2PrivateGetTradeOpenOrders(self.extend(request, params))
|
3522
3596
|
#
|
3523
3597
|
# spot
|
3524
3598
|
#
|
@@ -3545,7 +3619,61 @@ class bingx(Exchange, ImplicitAPI):
|
|
3545
3619
|
# }
|
3546
3620
|
# }
|
3547
3621
|
#
|
3548
|
-
# swap
|
3622
|
+
# inverse swap
|
3623
|
+
#
|
3624
|
+
# {
|
3625
|
+
# "code": 0,
|
3626
|
+
# "msg": "",
|
3627
|
+
# "data": {
|
3628
|
+
# "orders": [
|
3629
|
+
# {
|
3630
|
+
# "symbol": "SOL-USD",
|
3631
|
+
# "orderId": "1816013900044320768",
|
3632
|
+
# "side": "BUY",
|
3633
|
+
# "positionSide": "Long",
|
3634
|
+
# "type": "LIMIT",
|
3635
|
+
# "quantity": 1,
|
3636
|
+
# "origQty": "",
|
3637
|
+
# "price": "150",
|
3638
|
+
# "executedQty": "0",
|
3639
|
+
# "avgPrice": "0.000",
|
3640
|
+
# "cumQuote": "",
|
3641
|
+
# "stopPrice": "",
|
3642
|
+
# "profit": "0.0000",
|
3643
|
+
# "commission": "0.0000",
|
3644
|
+
# "status": "Pending",
|
3645
|
+
# "time": 1721806428334,
|
3646
|
+
# "updateTime": 1721806428352,
|
3647
|
+
# "clientOrderId": "",
|
3648
|
+
# "leverage": "",
|
3649
|
+
# "takeProfit": {
|
3650
|
+
# "type": "TAKE_PROFIT",
|
3651
|
+
# "quantity": 0,
|
3652
|
+
# "stopPrice": 0,
|
3653
|
+
# "price": 0,
|
3654
|
+
# "workingType": "MARK_PRICE",
|
3655
|
+
# "stopGuaranteed": ""
|
3656
|
+
# },
|
3657
|
+
# "stopLoss": {
|
3658
|
+
# "type": "STOP",
|
3659
|
+
# "quantity": 0,
|
3660
|
+
# "stopPrice": 0,
|
3661
|
+
# "price": 0,
|
3662
|
+
# "workingType": "MARK_PRICE",
|
3663
|
+
# "stopGuaranteed": ""
|
3664
|
+
# },
|
3665
|
+
# "advanceAttr": 0,
|
3666
|
+
# "positionID": 0,
|
3667
|
+
# "takeProfitEntrustPrice": 0,
|
3668
|
+
# "stopLossEntrustPrice": 0,
|
3669
|
+
# "orderType": "",
|
3670
|
+
# "workingType": "MARK_PRICE"
|
3671
|
+
# }
|
3672
|
+
# ]
|
3673
|
+
# }
|
3674
|
+
# }
|
3675
|
+
#
|
3676
|
+
# linear swap
|
3549
3677
|
#
|
3550
3678
|
# {
|
3551
3679
|
# "code": 0,
|
ccxt/async_support/bithumb.py
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.bithumb import ImplicitAPI
|
8
|
+
import asyncio
|
8
9
|
import hashlib
|
9
10
|
from ccxt.base.types import Balances, Currency, Int, Market, MarketInterface, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
|
10
11
|
from typing import List
|
@@ -212,17 +213,56 @@ class bithumb(Exchange, ImplicitAPI):
|
|
212
213
|
:returns dict[]: an array of objects representing market data
|
213
214
|
"""
|
214
215
|
result = []
|
215
|
-
quoteCurrencies = self.
|
216
|
+
quoteCurrencies = self.safe_dict(self.options, 'quoteCurrencies', {})
|
216
217
|
quotes = list(quoteCurrencies.keys())
|
218
|
+
promises = []
|
219
|
+
for i in range(0, len(quotes)):
|
220
|
+
request = {
|
221
|
+
'quoteId': quotes[i],
|
222
|
+
}
|
223
|
+
promises.append(self.publicGetTickerALLQuoteId(self.extend(request, params)))
|
224
|
+
#
|
225
|
+
# {
|
226
|
+
# "status": "0000",
|
227
|
+
# "data": {
|
228
|
+
# "ETH": {
|
229
|
+
# "opening_price": "0.05153399",
|
230
|
+
# "closing_price": "0.05145144",
|
231
|
+
# "min_price": "0.05145144",
|
232
|
+
# "max_price": "0.05160781",
|
233
|
+
# "units_traded": "6.541124172077830855",
|
234
|
+
# "acc_trade_value": "0.33705472498492329997697755",
|
235
|
+
# "prev_closing_price": "0.0515943",
|
236
|
+
# "units_traded_24H": "43.368879902677400513",
|
237
|
+
# "acc_trade_value_24H": "2.24165339555398079994373342",
|
238
|
+
# "fluctate_24H": "-0.00018203",
|
239
|
+
# "fluctate_rate_24H": "-0.35"
|
240
|
+
# },
|
241
|
+
# "XRP": {
|
242
|
+
# "opening_price": "0.00000918",
|
243
|
+
# "closing_price": "0.0000092",
|
244
|
+
# "min_price": "0.00000918",
|
245
|
+
# "max_price": "0.0000092",
|
246
|
+
# "units_traded": "6516.949363",
|
247
|
+
# "acc_trade_value": "0.0598792533602796",
|
248
|
+
# "prev_closing_price": "0.00000916",
|
249
|
+
# "units_traded_24H": "229161.50354738",
|
250
|
+
# "acc_trade_value_24H": "2.0446589371637117",
|
251
|
+
# "fluctate_24H": "0.00000049",
|
252
|
+
# "fluctate_rate_24H": "5.63"
|
253
|
+
# },
|
254
|
+
# ...
|
255
|
+
# "date": "1721675913145"
|
256
|
+
# }
|
257
|
+
# }
|
258
|
+
#
|
259
|
+
results = await asyncio.gather(*promises)
|
217
260
|
for i in range(0, len(quotes)):
|
218
261
|
quote = quotes[i]
|
219
262
|
quoteId = quote
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
}
|
224
|
-
response = await self.publicGetTickerALLQuoteId(self.extend(request, params))
|
225
|
-
data = self.safe_value(response, 'data')
|
263
|
+
response = results[i]
|
264
|
+
data = self.safe_dict(response, 'data')
|
265
|
+
extension = self.safe_dict(quoteCurrencies, quote, {})
|
226
266
|
currencyIds = list(data.keys())
|
227
267
|
for j in range(0, len(currencyIds)):
|
228
268
|
currencyId = currencyIds[j]
|
@@ -286,7 +326,7 @@ class bithumb(Exchange, ImplicitAPI):
|
|
286
326
|
|
287
327
|
def parse_balance(self, response) -> Balances:
|
288
328
|
result: dict = {'info': response}
|
289
|
-
balances = self.
|
329
|
+
balances = self.safe_dict(response, 'data')
|
290
330
|
codes = list(self.currencies.keys())
|
291
331
|
for i in range(0, len(codes)):
|
292
332
|
code = codes[i]
|
@@ -351,7 +391,7 @@ class bithumb(Exchange, ImplicitAPI):
|
|
351
391
|
# }
|
352
392
|
# }
|
353
393
|
#
|
354
|
-
data = self.
|
394
|
+
data = self.safe_dict(response, 'data', {})
|
355
395
|
timestamp = self.safe_integer(data, 'timestamp')
|
356
396
|
return self.parse_order_book(data, symbol, timestamp, 'bids', 'asks', 'price', 'quantity')
|
357
397
|
|
@@ -413,15 +453,18 @@ class bithumb(Exchange, ImplicitAPI):
|
|
413
453
|
"""
|
414
454
|
await self.load_markets()
|
415
455
|
result: dict = {}
|
416
|
-
quoteCurrencies = self.
|
456
|
+
quoteCurrencies = self.safe_dict(self.options, 'quoteCurrencies', {})
|
417
457
|
quotes = list(quoteCurrencies.keys())
|
458
|
+
promises = []
|
418
459
|
for i in range(0, len(quotes)):
|
419
|
-
quote = quotes[i]
|
420
|
-
quoteId = quote
|
421
460
|
request: dict = {
|
422
|
-
'quoteId':
|
461
|
+
'quoteId': quotes[i],
|
423
462
|
}
|
424
|
-
|
463
|
+
promises.append(self.publicGetTickerALLQuoteId(self.extend(request, params)))
|
464
|
+
responses = await asyncio.gather(*promises)
|
465
|
+
for i in range(0, len(quotes)):
|
466
|
+
quote = quotes[i]
|
467
|
+
response = responses[i]
|
425
468
|
#
|
426
469
|
# {
|
427
470
|
# "status":"0000",
|
@@ -443,7 +486,7 @@ class bithumb(Exchange, ImplicitAPI):
|
|
443
486
|
# }
|
444
487
|
# }
|
445
488
|
#
|
446
|
-
data = self.
|
489
|
+
data = self.safe_dict(response, 'data', {})
|
447
490
|
timestamp = self.safe_integer(data, 'date')
|
448
491
|
tickers = self.omit(data, 'date')
|
449
492
|
currencyIds = list(tickers.keys())
|
@@ -805,7 +848,7 @@ class bithumb(Exchange, ImplicitAPI):
|
|
805
848
|
# }
|
806
849
|
#
|
807
850
|
timestamp = self.safe_integer_product(order, 'order_date', 0.001)
|
808
|
-
sideProperty = self.
|
851
|
+
sideProperty = self.safe_string_2(order, 'type', 'side')
|
809
852
|
side = 'buy' if (sideProperty == 'bid') else 'sell'
|
810
853
|
status = self.parse_order_status(self.safe_string(order, 'order_status'))
|
811
854
|
price = self.safe_string_2(order, 'order_price', 'price')
|
@@ -830,7 +873,7 @@ class bithumb(Exchange, ImplicitAPI):
|
|
830
873
|
market = self.safe_market(None, market)
|
831
874
|
symbol = market['symbol']
|
832
875
|
id = self.safe_string(order, 'order_id')
|
833
|
-
rawTrades = self.
|
876
|
+
rawTrades = self.safe_list(order, 'contract', [])
|
834
877
|
return self.safe_order({
|
835
878
|
'info': order,
|
836
879
|
'id': id,
|
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.hyperliquid import ImplicitAPI
|
8
8
|
import asyncio
|
9
|
-
from ccxt.base.types import Balances, Currencies, Currency, Int, MarginModification, Market, Num, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Str, Strings, Trade, TradingFeeInterface, Transaction, TransferEntry
|
9
|
+
from ccxt.base.types import Balances, Currencies, Currency, Int, MarginModification, Market, Num, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import ArgumentsRequired
|
@@ -102,8 +102,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
102
102
|
'fetchPositions': True,
|
103
103
|
'fetchPositionsRisk': False,
|
104
104
|
'fetchPremiumIndexOHLCV': False,
|
105
|
-
'fetchTicker':
|
106
|
-
'fetchTickers':
|
105
|
+
'fetchTicker': 'emulated',
|
106
|
+
'fetchTickers': True,
|
107
107
|
'fetchTime': False,
|
108
108
|
'fetchTrades': True,
|
109
109
|
'fetchTradingFee': True,
|
@@ -328,12 +328,12 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
328
328
|
#
|
329
329
|
#
|
330
330
|
meta = self.safe_dict(response, 0, {})
|
331
|
-
|
331
|
+
universe = self.safe_list(meta, 'universe', [])
|
332
332
|
assetCtxs = self.safe_dict(response, 1, {})
|
333
333
|
result = []
|
334
|
-
for i in range(0, len(
|
334
|
+
for i in range(0, len(universe)):
|
335
335
|
data = self.extend(
|
336
|
-
self.safe_dict(
|
336
|
+
self.safe_dict(universe, i, {}),
|
337
337
|
self.safe_dict(assetCtxs, i, {})
|
338
338
|
)
|
339
339
|
data['baseId'] = i
|
@@ -447,11 +447,13 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
447
447
|
#
|
448
448
|
# response differs depending on the environment(mainnet vs sandbox)
|
449
449
|
first = self.safe_dict(response, 0, {})
|
450
|
+
second = self.safe_list(response, 1, [])
|
450
451
|
meta = self.safe_list_2(first, 'universe', 'spot_infos', [])
|
451
452
|
tokens = self.safe_list_2(first, 'tokens', 'token_infos', [])
|
452
453
|
markets = []
|
453
454
|
for i in range(0, len(meta)):
|
454
455
|
market = self.safe_dict(meta, i, {})
|
456
|
+
extraData = self.safe_dict(second, i, {})
|
455
457
|
marketName = self.safe_string(market, 'name')
|
456
458
|
# if marketName.find('/') < 0:
|
457
459
|
# # there are some weird spot markets in testnet, eg @2
|
@@ -528,7 +530,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
528
530
|
},
|
529
531
|
},
|
530
532
|
'created': None,
|
531
|
-
'info': market,
|
533
|
+
'info': self.extend(extraData, market),
|
532
534
|
}))
|
533
535
|
return markets
|
534
536
|
|
@@ -747,6 +749,57 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
747
749
|
timestamp = self.safe_integer(response, 'time')
|
748
750
|
return self.parse_order_book(result, market['symbol'], timestamp, 'bids', 'asks', 'px', 'sz')
|
749
751
|
|
752
|
+
async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
753
|
+
"""
|
754
|
+
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
755
|
+
:see: https://www.bitmex.com/api/explorer/#not /Instrument/Instrument_getActiveAndIndices
|
756
|
+
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
757
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
758
|
+
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
759
|
+
"""
|
760
|
+
await self.load_markets()
|
761
|
+
symbols = self.market_symbols(symbols)
|
762
|
+
# at self stage, to get tickers data, we use fetchMarkets endpoints
|
763
|
+
response = await self.fetch_markets(params)
|
764
|
+
# same response "fetchMarkets"
|
765
|
+
result: dict = {}
|
766
|
+
for i in range(0, len(response)):
|
767
|
+
market = response[i]
|
768
|
+
info = market['info']
|
769
|
+
ticker = self.parse_ticker(info, market)
|
770
|
+
symbol = self.safe_string(ticker, 'symbol')
|
771
|
+
result[symbol] = ticker
|
772
|
+
return self.filter_by_array_tickers(result, 'symbol', symbols)
|
773
|
+
|
774
|
+
def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
|
775
|
+
#
|
776
|
+
# {
|
777
|
+
# "prevDayPx": "3400.5",
|
778
|
+
# "dayNtlVlm": "511297257.47936022",
|
779
|
+
# "markPx": "3464.7",
|
780
|
+
# "midPx": "3465.05",
|
781
|
+
# "oraclePx": "3460.1", # only in swap
|
782
|
+
# "openInterest": "64638.1108", # only in swap
|
783
|
+
# "premium": "0.00141614", # only in swap
|
784
|
+
# "funding": "0.00008727", # only in swap
|
785
|
+
# "impactPxs": ["3465.0", "3465.1"], # only in swap
|
786
|
+
# "coin": "PURR", # only in spot
|
787
|
+
# "circulatingSupply": "998949190.03400207", # only in spot
|
788
|
+
# },
|
789
|
+
#
|
790
|
+
bidAsk = self.safe_list(ticker, 'impactPxs')
|
791
|
+
return self.safe_ticker({
|
792
|
+
'symbol': market['symbol'],
|
793
|
+
'timestamp': None,
|
794
|
+
'datetime': None,
|
795
|
+
'previousClose': self.safe_number(ticker, 'prevDayPx'),
|
796
|
+
'close': self.safe_number(ticker, 'midPx'),
|
797
|
+
'bid': self.safe_number(bidAsk, 0),
|
798
|
+
'ask': self.safe_number(bidAsk, 1),
|
799
|
+
'quoteVolume': self.safe_number(ticker, 'dayNtlVlm'),
|
800
|
+
'info': ticker,
|
801
|
+
}, market)
|
802
|
+
|
750
803
|
async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
751
804
|
"""
|
752
805
|
fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
ccxt/async_support/kraken.py
CHANGED
@@ -98,6 +98,7 @@ class kraken(Exchange, ImplicitAPI):
|
|
98
98
|
'fetchOrderTrades': 'emulated',
|
99
99
|
'fetchPositions': True,
|
100
100
|
'fetchPremiumIndexOHLCV': False,
|
101
|
+
'fetchStatus': True,
|
101
102
|
'fetchTicker': True,
|
102
103
|
'fetchTickers': True,
|
103
104
|
'fetchTime': True,
|
@@ -645,6 +646,30 @@ class kraken(Exchange, ImplicitAPI):
|
|
645
646
|
result.append(self.extend(defaults, markets[i]))
|
646
647
|
return result
|
647
648
|
|
649
|
+
async def fetch_status(self, params={}):
|
650
|
+
"""
|
651
|
+
the latest known information on the availability of the exchange API
|
652
|
+
:see: https://docs.kraken.com/api/docs/rest-api/get-system-status/
|
653
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
654
|
+
:returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
|
655
|
+
"""
|
656
|
+
response = await self.publicGetSystemStatus(params)
|
657
|
+
#
|
658
|
+
# {
|
659
|
+
# error: [],
|
660
|
+
# result: {status: 'online', timestamp: '2024-07-22T16:34:44Z'}
|
661
|
+
# }
|
662
|
+
#
|
663
|
+
result = self.safe_dict(response, 'result')
|
664
|
+
statusRaw = self.safe_string(result, 'status')
|
665
|
+
return {
|
666
|
+
'status': 'ok' if (statusRaw == 'online') else 'maintenance',
|
667
|
+
'updated': None,
|
668
|
+
'eta': None,
|
669
|
+
'url': None,
|
670
|
+
'info': response,
|
671
|
+
}
|
672
|
+
|
648
673
|
async def fetch_currencies(self, params={}) -> Currencies:
|
649
674
|
"""
|
650
675
|
fetches all available currencies on an exchange
|
ccxt/async_support/whitebit.py
CHANGED
@@ -2404,7 +2404,7 @@ class whitebit(Exchange, ImplicitAPI):
|
|
2404
2404
|
records = self.safe_list(response, 'records')
|
2405
2405
|
return self.parse_transactions(records, currency, since, limit)
|
2406
2406
|
|
2407
|
-
def is_fiat(self, currency: str):
|
2407
|
+
def is_fiat(self, currency: str) -> bool:
|
2408
2408
|
fiatCurrencies = self.safe_value(self.options, 'fiatCurrencies', [])
|
2409
2409
|
return self.in_array(currency, fiatCurrencies)
|
2410
2410
|
|
ccxt/async_support/zonda.py
CHANGED
@@ -1467,7 +1467,7 @@ class zonda(Exchange, ImplicitAPI):
|
|
1467
1467
|
# {status: "Ok", errors: []}
|
1468
1468
|
return self.parse_order(response)
|
1469
1469
|
|
1470
|
-
def is_fiat(self, currency: str):
|
1470
|
+
def is_fiat(self, currency: str) -> bool:
|
1471
1471
|
fiatCurrencies: dict = {
|
1472
1472
|
'USD': True,
|
1473
1473
|
'EUR': True,
|