ccxt 4.2.78__py2.py3-none-any.whl → 4.2.80__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 +1 -0
- ccxt/abstract/gate.py +1 -0
- ccxt/abstract/gateio.py +1 -0
- ccxt/abstract/upbit.py +1 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +10 -1
- ccxt/async_support/base/ws/functions.py +1 -1
- ccxt/async_support/binance.py +3 -3
- ccxt/async_support/bingx.py +37 -5
- ccxt/async_support/bitstamp.py +20 -26
- ccxt/async_support/bybit.py +92 -0
- ccxt/async_support/coinbaseinternational.py +2 -2
- ccxt/async_support/deribit.py +152 -1
- ccxt/async_support/gate.py +11 -4
- ccxt/async_support/hyperliquid.py +42 -9
- ccxt/async_support/mexc.py +2 -2
- ccxt/async_support/upbit.py +2 -0
- ccxt/base/exchange.py +38 -9
- ccxt/base/types.py +23 -0
- ccxt/binance.py +3 -3
- ccxt/bingx.py +37 -5
- ccxt/bitstamp.py +20 -26
- ccxt/bybit.py +92 -0
- ccxt/coinbaseinternational.py +2 -2
- ccxt/deribit.py +152 -1
- ccxt/gate.py +11 -4
- ccxt/hyperliquid.py +42 -9
- ccxt/mexc.py +2 -2
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/alpaca.py +1 -1
- ccxt/pro/binance.py +5 -5
- ccxt/pro/bitfinex2.py +1 -1
- ccxt/pro/bitget.py +1 -1
- ccxt/pro/bitmart.py +1 -1
- ccxt/pro/bitmex.py +1 -1
- ccxt/pro/bitopro.py +2 -1
- ccxt/pro/blockchaincom.py +1 -1
- ccxt/pro/bybit.py +14 -1
- ccxt/pro/cex.py +9 -5
- ccxt/pro/cryptocom.py +1 -1
- ccxt/pro/gemini.py +4 -3
- ccxt/pro/hitbtc.py +1 -1
- ccxt/pro/htx.py +1 -1
- ccxt/pro/okcoin.py +1 -1
- ccxt/pro/onetrading.py +1 -1
- ccxt/pro/phemex.py +6 -1
- ccxt/pro/woo.py +30 -0
- ccxt/test/base/test_ohlcv.py +3 -2
- ccxt/test/base/test_shared_methods.py +8 -0
- ccxt/test/base/test_ticker.py +7 -1
- ccxt/test/test_async.py +26 -25
- ccxt/test/test_sync.py +26 -25
- ccxt/upbit.py +2 -0
- {ccxt-4.2.78.dist-info → ccxt-4.2.80.dist-info}/METADATA +6 -6
- {ccxt-4.2.78.dist-info → ccxt-4.2.80.dist-info}/RECORD +58 -58
- {ccxt-4.2.78.dist-info → ccxt-4.2.80.dist-info}/WHEEL +0 -0
- {ccxt-4.2.78.dist-info → ccxt-4.2.80.dist-info}/top_level.txt +0 -0
ccxt/deribit.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.deribit import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Account, Balances, Currency, Greeks, Int, Market, MarketInterface, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
9
|
+
from ccxt.base.types import Account, Balances, Currency, Greeks, Int, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import PermissionDenied
|
@@ -83,6 +83,8 @@ class deribit(Exchange, ImplicitAPI):
|
|
83
83
|
'fetchMyTrades': True,
|
84
84
|
'fetchOHLCV': True,
|
85
85
|
'fetchOpenOrders': True,
|
86
|
+
'fetchOption': True,
|
87
|
+
'fetchOptionChain': True,
|
86
88
|
'fetchOrder': True,
|
87
89
|
'fetchOrderBook': True,
|
88
90
|
'fetchOrders': False,
|
@@ -3270,6 +3272,155 @@ class deribit(Exchange, ImplicitAPI):
|
|
3270
3272
|
'info': greeks,
|
3271
3273
|
}
|
3272
3274
|
|
3275
|
+
def fetch_option(self, symbol: str, params={}) -> Option:
|
3276
|
+
"""
|
3277
|
+
fetches option data that is commonly found in an option chain
|
3278
|
+
:see: https://docs.deribit.com/#public-get_book_summary_by_instrument
|
3279
|
+
:param str symbol: unified market symbol
|
3280
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3281
|
+
:returns dict: an `option chain structure <https://docs.ccxt.com/#/?id=option-chain-structure>`
|
3282
|
+
"""
|
3283
|
+
self.load_markets()
|
3284
|
+
market = self.market(symbol)
|
3285
|
+
request = {
|
3286
|
+
'instrument_name': market['id'],
|
3287
|
+
}
|
3288
|
+
response = self.publicGetGetBookSummaryByInstrument(self.extend(request, params))
|
3289
|
+
#
|
3290
|
+
# {
|
3291
|
+
# "jsonrpc": "2.0",
|
3292
|
+
# "result": [
|
3293
|
+
# {
|
3294
|
+
# "mid_price": 0.04025,
|
3295
|
+
# "volume_usd": 11045.12,
|
3296
|
+
# "quote_currency": "BTC",
|
3297
|
+
# "estimated_delivery_price": 65444.72,
|
3298
|
+
# "creation_timestamp": 1711100949273,
|
3299
|
+
# "base_currency": "BTC",
|
3300
|
+
# "underlying_index": "BTC-27DEC24",
|
3301
|
+
# "underlying_price": 73742.14,
|
3302
|
+
# "volume": 4.0,
|
3303
|
+
# "interest_rate": 0.0,
|
3304
|
+
# "price_change": -6.9767,
|
3305
|
+
# "open_interest": 274.2,
|
3306
|
+
# "ask_price": 0.042,
|
3307
|
+
# "bid_price": 0.0385,
|
3308
|
+
# "instrument_name": "BTC-27DEC24-240000-C",
|
3309
|
+
# "mark_price": 0.04007735,
|
3310
|
+
# "last": 0.04,
|
3311
|
+
# "low": 0.04,
|
3312
|
+
# "high": 0.043
|
3313
|
+
# }
|
3314
|
+
# ],
|
3315
|
+
# "usIn": 1711100949273223,
|
3316
|
+
# "usOut": 1711100949273580,
|
3317
|
+
# "usDiff": 357,
|
3318
|
+
# "testnet": False
|
3319
|
+
# }
|
3320
|
+
#
|
3321
|
+
result = self.safe_list(response, 'result', [])
|
3322
|
+
chain = self.safe_dict(result, 0, {})
|
3323
|
+
return self.parse_option(chain, None, market)
|
3324
|
+
|
3325
|
+
def fetch_option_chain(self, code: str, params={}) -> OptionChain:
|
3326
|
+
"""
|
3327
|
+
fetches data for an underlying asset that is commonly found in an option chain
|
3328
|
+
:see: https://docs.deribit.com/#public-get_book_summary_by_currency
|
3329
|
+
:param str currency: base currency to fetch an option chain for
|
3330
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3331
|
+
:returns dict: a list of `option chain structures <https://docs.ccxt.com/#/?id=option-chain-structure>`
|
3332
|
+
"""
|
3333
|
+
self.load_markets()
|
3334
|
+
currency = self.currency(code)
|
3335
|
+
request = {
|
3336
|
+
'currency': currency['id'],
|
3337
|
+
'kind': 'option',
|
3338
|
+
}
|
3339
|
+
response = self.publicGetGetBookSummaryByCurrency(self.extend(request, params))
|
3340
|
+
#
|
3341
|
+
# {
|
3342
|
+
# "jsonrpc": "2.0",
|
3343
|
+
# "result": [
|
3344
|
+
# {
|
3345
|
+
# "mid_price": 0.4075,
|
3346
|
+
# "volume_usd": 2836.83,
|
3347
|
+
# "quote_currency": "BTC",
|
3348
|
+
# "estimated_delivery_price": 65479.26,
|
3349
|
+
# "creation_timestamp": 1711101594477,
|
3350
|
+
# "base_currency": "BTC",
|
3351
|
+
# "underlying_index": "BTC-28JUN24",
|
3352
|
+
# "underlying_price": 68827.27,
|
3353
|
+
# "volume": 0.1,
|
3354
|
+
# "interest_rate": 0.0,
|
3355
|
+
# "price_change": 0.0,
|
3356
|
+
# "open_interest": 364.1,
|
3357
|
+
# "ask_price": 0.411,
|
3358
|
+
# "bid_price": 0.404,
|
3359
|
+
# "instrument_name": "BTC-28JUN24-42000-C",
|
3360
|
+
# "mark_price": 0.40752052,
|
3361
|
+
# "last": 0.423,
|
3362
|
+
# "low": 0.423,
|
3363
|
+
# "high": 0.423
|
3364
|
+
# }
|
3365
|
+
# ],
|
3366
|
+
# "usIn": 1711101594456388,
|
3367
|
+
# "usOut": 1711101594484065,
|
3368
|
+
# "usDiff": 27677,
|
3369
|
+
# "testnet": False
|
3370
|
+
# }
|
3371
|
+
#
|
3372
|
+
result = self.safe_list(response, 'result', [])
|
3373
|
+
return self.parse_option_chain(result, 'base_currency', 'instrument_name')
|
3374
|
+
|
3375
|
+
def parse_option(self, chain, currency: Currency = None, market: Market = None):
|
3376
|
+
#
|
3377
|
+
# {
|
3378
|
+
# "mid_price": 0.04025,
|
3379
|
+
# "volume_usd": 11045.12,
|
3380
|
+
# "quote_currency": "BTC",
|
3381
|
+
# "estimated_delivery_price": 65444.72,
|
3382
|
+
# "creation_timestamp": 1711100949273,
|
3383
|
+
# "base_currency": "BTC",
|
3384
|
+
# "underlying_index": "BTC-27DEC24",
|
3385
|
+
# "underlying_price": 73742.14,
|
3386
|
+
# "volume": 4.0,
|
3387
|
+
# "interest_rate": 0.0,
|
3388
|
+
# "price_change": -6.9767,
|
3389
|
+
# "open_interest": 274.2,
|
3390
|
+
# "ask_price": 0.042,
|
3391
|
+
# "bid_price": 0.0385,
|
3392
|
+
# "instrument_name": "BTC-27DEC24-240000-C",
|
3393
|
+
# "mark_price": 0.04007735,
|
3394
|
+
# "last": 0.04,
|
3395
|
+
# "low": 0.04,
|
3396
|
+
# "high": 0.043
|
3397
|
+
# }
|
3398
|
+
#
|
3399
|
+
marketId = self.safe_string(chain, 'instrument_name')
|
3400
|
+
market = self.safe_market(marketId, market)
|
3401
|
+
currencyId = self.safe_string(chain, 'base_currency')
|
3402
|
+
code = self.safe_currency_code(currencyId, currency)
|
3403
|
+
timestamp = self.safe_integer(chain, 'timestamp')
|
3404
|
+
return {
|
3405
|
+
'info': chain,
|
3406
|
+
'currency': code['code'],
|
3407
|
+
'symbol': market['symbol'],
|
3408
|
+
'timestamp': timestamp,
|
3409
|
+
'datetime': self.iso8601(timestamp),
|
3410
|
+
'impliedVolatility': None,
|
3411
|
+
'openInterest': self.safe_number(chain, 'open_interest'),
|
3412
|
+
'bidPrice': self.safe_number(chain, 'bid_price'),
|
3413
|
+
'askPrice': self.safe_number(chain, 'ask_price'),
|
3414
|
+
'midPrice': self.safe_number(chain, 'mid_price'),
|
3415
|
+
'markPrice': self.safe_number(chain, 'mark_price'),
|
3416
|
+
'lastPrice': self.safe_number(chain, 'last'),
|
3417
|
+
'underlyingPrice': self.safe_number(chain, 'underlying_price'),
|
3418
|
+
'change': None,
|
3419
|
+
'percentage': self.safe_number(chain, 'price_change'),
|
3420
|
+
'baseVolume': self.safe_number(chain, 'volume'),
|
3421
|
+
'quoteVolume': self.safe_number(chain, 'volume_usd'),
|
3422
|
+
}
|
3423
|
+
|
3273
3424
|
def nonce(self):
|
3274
3425
|
return self.milliseconds()
|
3275
3426
|
|
ccxt/gate.py
CHANGED
@@ -328,6 +328,7 @@ class gate(Exchange, ImplicitAPI):
|
|
328
328
|
'loan_records': 20 / 15,
|
329
329
|
'interest_records': 20 / 15,
|
330
330
|
'estimate_rate': 20 / 15,
|
331
|
+
'currency_discount_tiers': 20 / 15,
|
331
332
|
},
|
332
333
|
'post': {
|
333
334
|
'account_mode': 20 / 15,
|
@@ -3958,7 +3959,13 @@ class gate(Exchange, ImplicitAPI):
|
|
3958
3959
|
'account': account,
|
3959
3960
|
}
|
3960
3961
|
if amount is not None:
|
3961
|
-
|
3962
|
+
if market['spot']:
|
3963
|
+
request['amount'] = self.amount_to_precision(symbol, amount)
|
3964
|
+
else:
|
3965
|
+
if side == 'sell':
|
3966
|
+
request['size'] = Precise.string_neg(self.amount_to_precision(symbol, amount))
|
3967
|
+
else:
|
3968
|
+
request['size'] = self.amount_to_precision(symbol, amount)
|
3962
3969
|
if price is not None:
|
3963
3970
|
request['price'] = self.price_to_precision(symbol, price)
|
3964
3971
|
response = None
|
@@ -4688,8 +4695,8 @@ class gate(Exchange, ImplicitAPI):
|
|
4688
4695
|
"""
|
4689
4696
|
self.load_markets()
|
4690
4697
|
market = None if (symbol is None) else self.market(symbol)
|
4691
|
-
stop = self.
|
4692
|
-
params = self.omit(params, 'stop')
|
4698
|
+
stop = self.safe_bool_2(params, 'stop', 'trigger')
|
4699
|
+
params = self.omit(params, ['stop', 'trigger'])
|
4693
4700
|
type, query = self.handle_market_type_and_params('cancelAllOrders', market, params)
|
4694
4701
|
request, requestParams = self.multi_order_spot_prepare_request(market, stop, query) if (type == 'spot') else self.prepare_request(market, type, query)
|
4695
4702
|
response = None
|
@@ -4983,7 +4990,7 @@ class gate(Exchange, ImplicitAPI):
|
|
4983
4990
|
'unrealizedPnl': self.parse_number(unrealisedPnl),
|
4984
4991
|
'realizedPnl': self.safe_number(position, 'realised_pnl'),
|
4985
4992
|
'contracts': self.parse_number(Precise.string_abs(size)),
|
4986
|
-
'contractSize': self.
|
4993
|
+
'contractSize': self.safe_number(market, 'contractSize'),
|
4987
4994
|
# 'realisedPnl': position['realised_pnl'],
|
4988
4995
|
'marginRatio': None,
|
4989
4996
|
'liquidationPrice': self.safe_number(position, 'liq_price'),
|
ccxt/hyperliquid.py
CHANGED
@@ -754,6 +754,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
754
754
|
"""
|
755
755
|
self.load_markets()
|
756
756
|
market = self.market(symbol)
|
757
|
+
vaultAddress = self.safe_string(params, 'vaultAddress')
|
758
|
+
params = self.omit(params, 'vaultAddress')
|
757
759
|
symbol = market['symbol']
|
758
760
|
order = {
|
759
761
|
'symbol': symbol,
|
@@ -763,7 +765,10 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
763
765
|
'price': price,
|
764
766
|
'params': params,
|
765
767
|
}
|
766
|
-
|
768
|
+
globalParams = {}
|
769
|
+
if vaultAddress is not None:
|
770
|
+
globalParams['vaultAddress'] = vaultAddress
|
771
|
+
response = self.create_orders([order], globalParams)
|
767
772
|
first = self.safe_dict(response, 0)
|
768
773
|
return first
|
769
774
|
|
@@ -807,7 +812,6 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
807
812
|
amount = self.safe_string(rawOrder, 'amount')
|
808
813
|
price = self.safe_string(rawOrder, 'price')
|
809
814
|
orderParams = self.safe_dict(rawOrder, 'params', {})
|
810
|
-
orderParams = self.extend(params, orderParams)
|
811
815
|
clientOrderId = self.safe_string_2(orderParams, 'clientOrderId', 'client_id')
|
812
816
|
slippage = self.safe_string(orderParams, 'slippage', defaultSlippage)
|
813
817
|
defaultTimeInForce = 'ioc' if (isMarket) else 'gtc'
|
@@ -847,6 +851,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
847
851
|
orderType['limit'] = {
|
848
852
|
'tif': timeInForce,
|
849
853
|
}
|
854
|
+
orderParams = self.omit(orderParams, ['clientOrderId', 'slippage', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'timeInForce', 'client_id'])
|
850
855
|
orderObj = {
|
851
856
|
'a': self.parse_to_int(market['baseId']),
|
852
857
|
'b': isBuy,
|
@@ -858,8 +863,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
858
863
|
}
|
859
864
|
if clientOrderId is not None:
|
860
865
|
orderObj['c'] = clientOrderId
|
861
|
-
orderReq.append(orderObj)
|
862
|
-
vaultAddress = self.safe_string(params, 'vaultAddress')
|
866
|
+
orderReq.append(self.extend(orderObj, orderParams))
|
867
|
+
vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
|
863
868
|
orderAction = {
|
864
869
|
'type': 'order',
|
865
870
|
'orders': orderReq,
|
@@ -875,6 +880,9 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
875
880
|
'signature': signature,
|
876
881
|
# 'vaultAddress': vaultAddress,
|
877
882
|
}
|
883
|
+
if vaultAddress is not None:
|
884
|
+
params = self.omit(params, 'vaultAddress')
|
885
|
+
request['vaultAddress'] = vaultAddress
|
878
886
|
response = self.privatePostExchange(self.extend(request, params))
|
879
887
|
#
|
880
888
|
# {
|
@@ -957,10 +965,13 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
957
965
|
'o': self.parse_to_numeric(ids[i]),
|
958
966
|
})
|
959
967
|
cancelAction['cancels'] = cancelReq
|
960
|
-
vaultAddress = self.safe_string(params, 'vaultAddress')
|
968
|
+
vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
|
961
969
|
signature = self.sign_l1_action(cancelAction, nonce, vaultAddress)
|
962
970
|
request['action'] = cancelAction
|
963
971
|
request['signature'] = signature
|
972
|
+
if vaultAddress is not None:
|
973
|
+
params = self.omit(params, 'vaultAddress')
|
974
|
+
request['vaultAddress'] = vaultAddress
|
964
975
|
response = self.privatePostExchange(self.extend(request, params))
|
965
976
|
#
|
966
977
|
# {
|
@@ -1066,7 +1077,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1066
1077
|
'type': 'batchModify',
|
1067
1078
|
'modifies': [modifyReq],
|
1068
1079
|
}
|
1069
|
-
vaultAddress = self.safe_string(params, 'vaultAddress')
|
1080
|
+
vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
|
1070
1081
|
signature = self.sign_l1_action(modifyAction, nonce, vaultAddress)
|
1071
1082
|
request = {
|
1072
1083
|
'action': modifyAction,
|
@@ -1074,6 +1085,9 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1074
1085
|
'signature': signature,
|
1075
1086
|
# 'vaultAddress': vaultAddress,
|
1076
1087
|
}
|
1088
|
+
if vaultAddress is not None:
|
1089
|
+
params = self.omit(params, 'vaultAddress')
|
1090
|
+
request['vaultAddress'] = vaultAddress
|
1077
1091
|
response = self.privatePostExchange(self.extend(request, params))
|
1078
1092
|
#
|
1079
1093
|
# {
|
@@ -1643,7 +1657,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1643
1657
|
'isolated': isIsolated,
|
1644
1658
|
'hedged': None,
|
1645
1659
|
'side': side,
|
1646
|
-
'contracts': self.
|
1660
|
+
'contracts': self.safe_number(entry, 'szi'),
|
1647
1661
|
'contractSize': None,
|
1648
1662
|
'entryPrice': self.safe_number(entry, 'entryPx'),
|
1649
1663
|
'markPrice': None,
|
@@ -1687,6 +1701,10 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1687
1701
|
'leverage': leverage,
|
1688
1702
|
}
|
1689
1703
|
vaultAddress = self.safe_string(params, 'vaultAddress')
|
1704
|
+
if vaultAddress is not None:
|
1705
|
+
params = self.omit(params, 'vaultAddress')
|
1706
|
+
if vaultAddress.startswith('0x'):
|
1707
|
+
vaultAddress = vaultAddress.replace('0x', '')
|
1690
1708
|
signature = self.sign_l1_action(updateAction, nonce, vaultAddress)
|
1691
1709
|
request = {
|
1692
1710
|
'action': updateAction,
|
@@ -1694,6 +1712,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1694
1712
|
'signature': signature,
|
1695
1713
|
# 'vaultAddress': vaultAddress,
|
1696
1714
|
}
|
1715
|
+
if vaultAddress is not None:
|
1716
|
+
request['vaultAddress'] = vaultAddress
|
1697
1717
|
response = self.privatePostExchange(self.extend(request, params))
|
1698
1718
|
#
|
1699
1719
|
# {
|
@@ -1729,7 +1749,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1729
1749
|
'isCross': isCross,
|
1730
1750
|
'leverage': leverage,
|
1731
1751
|
}
|
1732
|
-
vaultAddress = self.safe_string(params, 'vaultAddress')
|
1752
|
+
vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
|
1733
1753
|
signature = self.sign_l1_action(updateAction, nonce, vaultAddress)
|
1734
1754
|
request = {
|
1735
1755
|
'action': updateAction,
|
@@ -1737,6 +1757,9 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1737
1757
|
'signature': signature,
|
1738
1758
|
# 'vaultAddress': vaultAddress,
|
1739
1759
|
}
|
1760
|
+
if vaultAddress is not None:
|
1761
|
+
params = self.omit(params, 'vaultAddress')
|
1762
|
+
request['vaultAddress'] = vaultAddress
|
1740
1763
|
response = self.privatePostExchange(self.extend(request, params))
|
1741
1764
|
#
|
1742
1765
|
# {
|
@@ -1784,7 +1807,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1784
1807
|
'isBuy': True,
|
1785
1808
|
'ntli': sz,
|
1786
1809
|
}
|
1787
|
-
vaultAddress = self.safe_string(params, 'vaultAddress')
|
1810
|
+
vaultAddress = self.format_vault_address(self.safe_string(params, 'vaultAddress'))
|
1788
1811
|
signature = self.sign_l1_action(updateAction, nonce, vaultAddress)
|
1789
1812
|
request = {
|
1790
1813
|
'action': updateAction,
|
@@ -1792,6 +1815,9 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1792
1815
|
'signature': signature,
|
1793
1816
|
# 'vaultAddress': vaultAddress,
|
1794
1817
|
}
|
1818
|
+
if vaultAddress is not None:
|
1819
|
+
params = self.omit(params, 'vaultAddress')
|
1820
|
+
request['vaultAddress'] = vaultAddress
|
1795
1821
|
response = self.privatePostExchange(self.extend(request, params))
|
1796
1822
|
#
|
1797
1823
|
# {
|
@@ -1882,6 +1908,13 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1882
1908
|
response = self.privatePostExchange(self.extend(request, params))
|
1883
1909
|
return response
|
1884
1910
|
|
1911
|
+
def format_vault_address(self, address: Str = None):
|
1912
|
+
if address is None:
|
1913
|
+
return None
|
1914
|
+
if address.startswith('0x'):
|
1915
|
+
return address.replace('0x', '')
|
1916
|
+
return address
|
1917
|
+
|
1885
1918
|
def handle_public_address(self, methodName: str, params: dict):
|
1886
1919
|
userAux = None
|
1887
1920
|
userAux, params = self.handle_option_and_params(params, methodName, 'user')
|
ccxt/mexc.py
CHANGED
@@ -899,8 +899,8 @@ class mexc(Exchange, ImplicitAPI):
|
|
899
899
|
'30032': InvalidOrder, # Cannot exceed the maximum position
|
900
900
|
'30041': InvalidOrder, # current order type can not place order
|
901
901
|
'60005': ExchangeError, # your account is abnormal
|
902
|
-
'700001': AuthenticationError, # API
|
903
|
-
'700002': AuthenticationError, # Signature for self request is not valid
|
902
|
+
'700001': AuthenticationError, # {"code":700002,"msg":"Signature for self request is not valid."} # same message for expired API keys
|
903
|
+
'700002': AuthenticationError, # Signature for self request is not valid # or the API secret is incorrect
|
904
904
|
'700004': BadRequest, # Param 'origClientOrderId' or 'orderId' must be sent, but both were empty/null
|
905
905
|
'700005': InvalidNonce, # recvWindow must less than 60000
|
906
906
|
'700006': BadRequest, # IP non white list
|
ccxt/pro/__init__.py
CHANGED
ccxt/pro/alpaca.py
CHANGED
ccxt/pro/binance.py
CHANGED
@@ -89,7 +89,7 @@ class binance(ccxt.async_support.binance):
|
|
89
89
|
'future': 200,
|
90
90
|
'delivery': 200,
|
91
91
|
},
|
92
|
-
'streamBySubscriptionsHash':
|
92
|
+
'streamBySubscriptionsHash': self.create_safe_dictionary(),
|
93
93
|
'streamIndex': -1,
|
94
94
|
# get updates every 1000ms or 100ms
|
95
95
|
# or every 0ms in real-time for futures
|
@@ -97,7 +97,7 @@ class binance(ccxt.async_support.binance):
|
|
97
97
|
'tradesLimit': 1000,
|
98
98
|
'ordersLimit': 1000,
|
99
99
|
'OHLCVLimit': 1000,
|
100
|
-
'requestId':
|
100
|
+
'requestId': self.create_safe_dictionary(),
|
101
101
|
'watchOrderBookLimit': 1000, # default limit
|
102
102
|
'watchTrades': {
|
103
103
|
'name': 'trade', # 'trade' or 'aggTrade'
|
@@ -131,14 +131,14 @@ class binance(ccxt.async_support.binance):
|
|
131
131
|
})
|
132
132
|
|
133
133
|
def request_id(self, url):
|
134
|
-
options = self.
|
134
|
+
options = self.safe_dict(self.options, 'requestId', self.create_safe_dictionary())
|
135
135
|
previousValue = self.safe_integer(options, url, 0)
|
136
136
|
newValue = self.sum(previousValue, 1)
|
137
137
|
self.options['requestId'][url] = newValue
|
138
138
|
return newValue
|
139
139
|
|
140
140
|
def stream(self, type, subscriptionHash, numSubscriptions=1):
|
141
|
-
streamBySubscriptionsHash = self.
|
141
|
+
streamBySubscriptionsHash = self.safe_dict(self.options, 'streamBySubscriptionsHash', self.create_safe_dictionary())
|
142
142
|
stream = self.safe_string(streamBySubscriptionsHash, subscriptionHash)
|
143
143
|
if stream is None:
|
144
144
|
streamIndex = self.safe_integer(self.options, 'streamIndex', -1)
|
@@ -151,7 +151,7 @@ class binance(ccxt.async_support.binance):
|
|
151
151
|
self.options['streamBySubscriptionsHash'][subscriptionHash] = stream
|
152
152
|
subscriptionsByStreams = self.safe_value(self.options, 'numSubscriptionsByStream')
|
153
153
|
if subscriptionsByStreams is None:
|
154
|
-
self.options['numSubscriptionsByStream'] =
|
154
|
+
self.options['numSubscriptionsByStream'] = self.create_safe_dictionary()
|
155
155
|
subscriptionsByStream = self.safe_integer(self.options['numSubscriptionsByStream'], stream, 0)
|
156
156
|
newNumSubscriptions = subscriptionsByStream + numSubscriptions
|
157
157
|
subscriptionLimitByStream = self.safe_integer(self.options['subscriptionLimitByStream'], type, 200)
|
ccxt/pro/bitfinex2.py
CHANGED
@@ -812,7 +812,7 @@ class bitfinex2(ccxt.async_support.bitfinex2):
|
|
812
812
|
}
|
813
813
|
message = self.extend(request, params)
|
814
814
|
self.watch(url, messageHash, message, messageHash)
|
815
|
-
return future
|
815
|
+
return await future
|
816
816
|
|
817
817
|
def handle_authentication_message(self, client: Client, message):
|
818
818
|
messageHash = 'authenticated'
|
ccxt/pro/bitget.py
CHANGED
@@ -1523,7 +1523,7 @@ class bitget(ccxt.async_support.bitget):
|
|
1523
1523
|
}
|
1524
1524
|
message = self.extend(request, params)
|
1525
1525
|
self.watch(url, messageHash, message, messageHash)
|
1526
|
-
return future
|
1526
|
+
return await future
|
1527
1527
|
|
1528
1528
|
async def watch_private(self, messageHash, subscriptionHash, args, params={}):
|
1529
1529
|
await self.authenticate()
|
ccxt/pro/bitmart.py
CHANGED
@@ -1312,7 +1312,7 @@ class bitmart(ccxt.async_support.bitmart):
|
|
1312
1312
|
}
|
1313
1313
|
message = self.extend(request, params)
|
1314
1314
|
self.watch(url, messageHash, message, messageHash)
|
1315
|
-
return future
|
1315
|
+
return await future
|
1316
1316
|
|
1317
1317
|
def handle_subscription_status(self, client: Client, message):
|
1318
1318
|
#
|
ccxt/pro/bitmex.py
CHANGED
@@ -599,7 +599,7 @@ class bitmex(ccxt.async_support.bitmex):
|
|
599
599
|
}
|
600
600
|
message = self.extend(request, params)
|
601
601
|
self.watch(url, messageHash, message, messageHash)
|
602
|
-
return future
|
602
|
+
return await future
|
603
603
|
|
604
604
|
def handle_authentication_message(self, client: Client, message):
|
605
605
|
authenticated = self.safe_bool(message, 'success', False)
|
ccxt/pro/bitopro.py
CHANGED
@@ -364,7 +364,8 @@ class bitopro(ccxt.async_support.bitopro):
|
|
364
364
|
},
|
365
365
|
},
|
366
366
|
}
|
367
|
-
self.options = self.extend(defaultOptions, self.options)
|
367
|
+
# self.options = self.extend(defaultOptions, self.options)
|
368
|
+
self.extend_exchange_options(defaultOptions)
|
368
369
|
originalHeaders = self.options['ws']['options']['headers']
|
369
370
|
headers = {
|
370
371
|
'X-BITOPRO-API': 'ccxt',
|
ccxt/pro/blockchaincom.py
CHANGED
ccxt/pro/bybit.py
CHANGED
@@ -974,8 +974,21 @@ class bybit(ccxt.async_support.bybit):
|
|
974
974
|
for i in range(0, len(rawPositions)):
|
975
975
|
rawPosition = rawPositions[i]
|
976
976
|
position = self.parse_position(rawPosition)
|
977
|
+
side = self.safe_string(position, 'side')
|
978
|
+
# hacky solution to handle closing positions
|
979
|
+
# without crashing, we should handle self properly later
|
977
980
|
newPositions.append(position)
|
978
|
-
|
981
|
+
if side is None or side == '':
|
982
|
+
# closing update, adding both sides to "reset" both sides
|
983
|
+
# since we don't know which side is being closed
|
984
|
+
position['side'] = 'long'
|
985
|
+
cache.append(position)
|
986
|
+
position['side'] = 'short'
|
987
|
+
cache.append(position)
|
988
|
+
position['side'] = None
|
989
|
+
else:
|
990
|
+
# regular update
|
991
|
+
cache.append(position)
|
979
992
|
messageHashes = self.find_message_hashes(client, 'positions::')
|
980
993
|
for i in range(0, len(messageHashes)):
|
981
994
|
messageHash = messageHashes[i]
|
ccxt/pro/cex.py
CHANGED
@@ -157,16 +157,20 @@ class cex(ccxt.async_support.cex):
|
|
157
157
|
# {
|
158
158
|
# "e": "history",
|
159
159
|
# "data": [
|
160
|
-
#
|
161
|
-
#
|
160
|
+
# 'buy:1710255706095:444444:71222.2:14892622'
|
161
|
+
# 'sell:1710255658251:42530:71300:14892621'
|
162
|
+
# 'buy:1710252424241:87913:72800:14892620'
|
163
|
+
# ... timestamp descending
|
162
164
|
# ]
|
163
165
|
# }
|
164
166
|
#
|
165
|
-
data = self.
|
167
|
+
data = self.safe_list(message, 'data', [])
|
166
168
|
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
167
169
|
stored = ArrayCache(limit)
|
168
|
-
|
169
|
-
|
170
|
+
dataLength = len(data)
|
171
|
+
for i in range(0, dataLength):
|
172
|
+
index = dataLength - 1 - i
|
173
|
+
rawTrade = data[index]
|
170
174
|
parsed = self.parse_ws_old_trade(rawTrade)
|
171
175
|
stored.append(parsed)
|
172
176
|
messageHash = 'trades'
|
ccxt/pro/cryptocom.py
CHANGED
@@ -931,7 +931,7 @@ class cryptocom(ccxt.async_support.cryptocom):
|
|
931
931
|
}
|
932
932
|
message = self.extend(request, params)
|
933
933
|
self.watch(url, messageHash, message, messageHash)
|
934
|
-
return future
|
934
|
+
return await future
|
935
935
|
|
936
936
|
def handle_ping(self, client: Client, message):
|
937
937
|
self.spawn(self.pong, client, message)
|
ccxt/pro/gemini.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
import ccxt.async_support
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Int, Order, OrderBook, Str, Tickers, Trade
|
9
|
+
from ccxt.base.types import Int, Order, OrderBook, Str, Strings, Tickers, Trade
|
10
10
|
from ccxt.async_support.base.ws.client import Client
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
@@ -393,7 +393,7 @@ class gemini(ccxt.async_support.gemini):
|
|
393
393
|
orderbook = await self.helper_for_watch_multiple_construct('orderbook', symbols, params)
|
394
394
|
return orderbook.limit()
|
395
395
|
|
396
|
-
async def watch_bids_asks(self, symbols:
|
396
|
+
async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
|
397
397
|
"""
|
398
398
|
watches best bid & ask for symbols
|
399
399
|
:see: https://docs.gemini.com/websocket-api/#multi-market-data
|
@@ -851,7 +851,8 @@ class gemini(ccxt.async_support.gemini):
|
|
851
851
|
},
|
852
852
|
},
|
853
853
|
}
|
854
|
-
self.options = self.extend(defaultOptions, self.options)
|
854
|
+
# self.options = self.extend(defaultOptions, self.options)
|
855
|
+
self.extend_exchange_options(defaultOptions)
|
855
856
|
originalHeaders = self.options['ws']['options']['headers']
|
856
857
|
headers = {
|
857
858
|
'X-GEMINI-APIKEY': self.apiKey,
|
ccxt/pro/hitbtc.py
CHANGED
ccxt/pro/htx.py
CHANGED
ccxt/pro/okcoin.py
CHANGED
ccxt/pro/onetrading.py
CHANGED