ccxt 4.4.33__py2.py3-none-any.whl → 4.4.35__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 +3 -1
- ccxt/abstract/bingx.py +17 -0
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex2.py +1 -0
- ccxt/abstract/bitpanda.py +0 -12
- ccxt/abstract/bitrue.py +3 -3
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/okx.py +1 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/xt.py +5 -5
- ccxt/alpaca.py +2 -0
- ccxt/async_support/__init__.py +3 -1
- ccxt/async_support/alpaca.py +2 -0
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +19 -15
- ccxt/async_support/bingx.py +479 -146
- ccxt/async_support/bitbank.py +5 -0
- ccxt/async_support/bitbns.py +2 -0
- ccxt/async_support/bitfinex2.py +1 -0
- ccxt/async_support/bitget.py +174 -40
- ccxt/async_support/bitmex.py +3 -1
- ccxt/async_support/bitopro.py +3 -0
- ccxt/async_support/bitrue.py +3 -2
- ccxt/async_support/btcmarkets.py +5 -3
- ccxt/async_support/btcturk.py +19 -19
- ccxt/async_support/bybit.py +13 -10
- ccxt/async_support/cex.py +13 -4
- ccxt/async_support/coinbase.py +3 -2
- ccxt/async_support/coinex.py +1 -0
- ccxt/async_support/coinone.py +7 -7
- ccxt/async_support/coinsph.py +7 -7
- ccxt/async_support/coinspot.py +39 -39
- ccxt/async_support/cryptocom.py +36 -34
- ccxt/async_support/ellipx.py +1828 -0
- ccxt/async_support/gate.py +143 -39
- ccxt/async_support/hyperliquid.py +70 -11
- ccxt/async_support/idex.py +3 -4
- ccxt/async_support/kraken.py +58 -49
- ccxt/async_support/krakenfutures.py +3 -1
- ccxt/async_support/kucoin.py +1 -1
- ccxt/async_support/okcoin.py +2 -0
- ccxt/async_support/okx.py +15 -10
- ccxt/async_support/onetrading.py +67 -370
- ccxt/async_support/paradex.py +2 -0
- ccxt/async_support/phemex.py +16 -0
- ccxt/async_support/poloniex.py +3 -1
- ccxt/async_support/poloniexfutures.py +3 -1
- ccxt/async_support/vertex.py +2 -0
- ccxt/async_support/woo.py +69 -69
- ccxt/async_support/xt.py +10 -10
- ccxt/base/exchange.py +28 -7
- ccxt/binance.py +19 -15
- ccxt/bingx.py +479 -146
- ccxt/bitbank.py +5 -0
- ccxt/bitbns.py +2 -0
- ccxt/bitfinex2.py +1 -0
- ccxt/bitget.py +174 -40
- ccxt/bitmex.py +3 -1
- ccxt/bitopro.py +3 -0
- ccxt/bitrue.py +3 -2
- ccxt/btcmarkets.py +5 -3
- ccxt/btcturk.py +19 -19
- ccxt/bybit.py +13 -10
- ccxt/cex.py +13 -4
- ccxt/coinbase.py +3 -2
- ccxt/coinex.py +1 -0
- ccxt/coinone.py +7 -7
- ccxt/coinsph.py +7 -7
- ccxt/coinspot.py +39 -39
- ccxt/cryptocom.py +36 -34
- ccxt/ellipx.py +1828 -0
- ccxt/gate.py +143 -39
- ccxt/hyperliquid.py +70 -11
- ccxt/idex.py +3 -4
- ccxt/kraken.py +58 -49
- ccxt/krakenfutures.py +3 -1
- ccxt/kucoin.py +1 -1
- ccxt/okcoin.py +2 -0
- ccxt/okx.py +15 -10
- ccxt/onetrading.py +67 -370
- ccxt/paradex.py +2 -0
- ccxt/phemex.py +16 -0
- ccxt/poloniex.py +3 -1
- ccxt/poloniexfutures.py +3 -1
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitrue.py +13 -11
- ccxt/pro/idex.py +15 -0
- ccxt/pro/probit.py +58 -68
- ccxt/pro/woo.py +15 -15
- ccxt/test/tests_async.py +29 -2
- ccxt/test/tests_helpers.py +0 -2
- ccxt/test/tests_sync.py +29 -2
- ccxt/vertex.py +2 -0
- ccxt/woo.py +69 -69
- ccxt/xt.py +10 -10
- {ccxt-4.4.33.dist-info → ccxt-4.4.35.dist-info}/METADATA +9 -8
- {ccxt-4.4.33.dist-info → ccxt-4.4.35.dist-info}/RECORD +100 -97
- {ccxt-4.4.33.dist-info → ccxt-4.4.35.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.33.dist-info → ccxt-4.4.35.dist-info}/WHEEL +0 -0
- {ccxt-4.4.33.dist-info → ccxt-4.4.35.dist-info}/top_level.txt +0 -0
ccxt/gate.py
CHANGED
@@ -708,6 +708,110 @@ class gate(Exchange, ImplicitAPI):
|
|
708
708
|
},
|
709
709
|
},
|
710
710
|
},
|
711
|
+
'features': {
|
712
|
+
'spot': {
|
713
|
+
'sandbox': True,
|
714
|
+
'createOrder': {
|
715
|
+
'marginMode': True,
|
716
|
+
'triggerPrice': True,
|
717
|
+
'triggerDirection': True, # todo: implementation edit needed
|
718
|
+
'triggerPriceType': None,
|
719
|
+
'stopLossPrice': True,
|
720
|
+
'takeProfitPrice': True,
|
721
|
+
'attachedStopLossTakeProfit': None,
|
722
|
+
'timeInForce': {
|
723
|
+
'GTC': True,
|
724
|
+
'IOC': True,
|
725
|
+
'FOK': True,
|
726
|
+
'PO': True,
|
727
|
+
'GTD': False,
|
728
|
+
},
|
729
|
+
'hedged': False,
|
730
|
+
'trailing': False,
|
731
|
+
# exchange-specific features
|
732
|
+
'iceberg': True,
|
733
|
+
'selfTradePrevention': True,
|
734
|
+
},
|
735
|
+
'createOrders': {
|
736
|
+
'max': 40, # NOTE! max 10 per symbol
|
737
|
+
},
|
738
|
+
'fetchMyTrades': {
|
739
|
+
'marginMode': True,
|
740
|
+
'limit': 1000,
|
741
|
+
'daysBack': None,
|
742
|
+
'untilDays': 30,
|
743
|
+
},
|
744
|
+
'fetchOrder': {
|
745
|
+
'marginMode': False,
|
746
|
+
'trigger': True,
|
747
|
+
'trailing': False,
|
748
|
+
},
|
749
|
+
'fetchOpenOrders': {
|
750
|
+
'marginMode': True,
|
751
|
+
'trigger': True,
|
752
|
+
'trailing': False,
|
753
|
+
'limit': 100,
|
754
|
+
},
|
755
|
+
'fetchOrders': None,
|
756
|
+
'fetchClosedOrders': {
|
757
|
+
'marginMode': True,
|
758
|
+
'trigger': True,
|
759
|
+
'trailing': False,
|
760
|
+
'limit': 100,
|
761
|
+
'untilDays': 30,
|
762
|
+
'daysBackClosed': None,
|
763
|
+
'daysBackCanceled': None,
|
764
|
+
},
|
765
|
+
'fetchOHLCV': {
|
766
|
+
'limit': 1000,
|
767
|
+
},
|
768
|
+
},
|
769
|
+
'forDerivatives': {
|
770
|
+
'extends': 'spot',
|
771
|
+
'createOrder': {
|
772
|
+
'marginMode': False,
|
773
|
+
'triggerPriceType': {
|
774
|
+
'last': True,
|
775
|
+
'mark': True,
|
776
|
+
'index': True,
|
777
|
+
},
|
778
|
+
},
|
779
|
+
'createOrders': {
|
780
|
+
'max': 10,
|
781
|
+
},
|
782
|
+
'fetchMyTrades': {
|
783
|
+
'marginMode': False,
|
784
|
+
'untilDays': None,
|
785
|
+
},
|
786
|
+
'fetchOpenOrders': {
|
787
|
+
'marginMode': False,
|
788
|
+
},
|
789
|
+
'fetchClosedOrders': {
|
790
|
+
'marginMode': False,
|
791
|
+
'untilDays': None,
|
792
|
+
'limit': 1000,
|
793
|
+
},
|
794
|
+
'fetchOHLCV': {
|
795
|
+
'limit': 1999,
|
796
|
+
},
|
797
|
+
},
|
798
|
+
'swap': {
|
799
|
+
'linear': {
|
800
|
+
'extends': 'forDerivatives',
|
801
|
+
},
|
802
|
+
'inverse': {
|
803
|
+
'extends': 'forDerivatives',
|
804
|
+
},
|
805
|
+
},
|
806
|
+
'future': {
|
807
|
+
'linear': {
|
808
|
+
'extends': 'forDerivatives',
|
809
|
+
},
|
810
|
+
'inverse': {
|
811
|
+
'extends': 'forDerivatives',
|
812
|
+
},
|
813
|
+
},
|
814
|
+
},
|
711
815
|
'precisionMode': TICK_SIZE,
|
712
816
|
'fees': {
|
713
817
|
'trading': {
|
@@ -945,6 +1049,7 @@ class gate(Exchange, ImplicitAPI):
|
|
945
1049
|
except Exception as e:
|
946
1050
|
# if the request fails, the unifiedAccount is disabled
|
947
1051
|
self.options['unifiedAccount'] = False
|
1052
|
+
return self.options['unifiedAccount']
|
948
1053
|
|
949
1054
|
def upgrade_unified_trade_account(self, params={}):
|
950
1055
|
return self.privateUnifiedPutUnifiedMode(params)
|
@@ -1531,22 +1636,22 @@ class gate(Exchange, ImplicitAPI):
|
|
1531
1636
|
request['settle'] = settle
|
1532
1637
|
return [request, params]
|
1533
1638
|
|
1534
|
-
def spot_order_prepare_request(self, market=None,
|
1639
|
+
def spot_order_prepare_request(self, market=None, trigger=False, params={}):
|
1535
1640
|
"""
|
1536
1641
|
@ignore
|
1537
1642
|
Fills request params currency_pair, market and account where applicable for spot order methods like fetchOpenOrders, cancelAllOrders
|
1538
1643
|
:param dict market: CCXT market
|
1539
|
-
:param bool
|
1644
|
+
:param bool trigger: True if for a trigger order
|
1540
1645
|
:param dict [params]: request parameters
|
1541
1646
|
:returns: the api request object, and the new params object with non-needed parameters removed
|
1542
1647
|
"""
|
1543
|
-
marginMode, query = self.get_margin_mode(
|
1648
|
+
marginMode, query = self.get_margin_mode(trigger, params)
|
1544
1649
|
request: dict = {}
|
1545
|
-
if not
|
1650
|
+
if not trigger:
|
1546
1651
|
if market is None:
|
1547
|
-
raise ArgumentsRequired(self.id + ' spotOrderPrepareRequest() requires a market argument for non-
|
1652
|
+
raise ArgumentsRequired(self.id + ' spotOrderPrepareRequest() requires a market argument for non-trigger orders')
|
1548
1653
|
request['account'] = marginMode
|
1549
|
-
request['currency_pair'] = market['id'] # Should always be set for non-
|
1654
|
+
request['currency_pair'] = market['id'] # Should always be set for non-trigger
|
1550
1655
|
return [request, query]
|
1551
1656
|
|
1552
1657
|
def multi_order_spot_prepare_request(self, market=None, trigger=False, params={}):
|
@@ -1554,7 +1659,7 @@ class gate(Exchange, ImplicitAPI):
|
|
1554
1659
|
@ignore
|
1555
1660
|
Fills request params currency_pair, market and account where applicable for spot order methods like fetchOpenOrders, cancelAllOrders
|
1556
1661
|
:param dict market: CCXT market
|
1557
|
-
:param bool
|
1662
|
+
:param bool trigger: True if for a trigger order
|
1558
1663
|
:param dict [params]: request parameters
|
1559
1664
|
:returns: the api request object, and the new params object with non-needed parameters removed
|
1560
1665
|
"""
|
@@ -1564,17 +1669,17 @@ class gate(Exchange, ImplicitAPI):
|
|
1564
1669
|
}
|
1565
1670
|
if market is not None:
|
1566
1671
|
if trigger:
|
1567
|
-
# gate spot and margin
|
1672
|
+
# gate spot and margin trigger orders use the term market instead of currency_pair, and normal instead of spot. Neither parameter is used when fetching/cancelling a single order. They are used for creating a single trigger order, but createOrder does not call self method
|
1568
1673
|
request['market'] = market['id']
|
1569
1674
|
else:
|
1570
1675
|
request['currency_pair'] = market['id']
|
1571
1676
|
return [request, query]
|
1572
1677
|
|
1573
|
-
def get_margin_mode(self,
|
1678
|
+
def get_margin_mode(self, trigger, params):
|
1574
1679
|
"""
|
1575
1680
|
@ignore
|
1576
1681
|
Gets the margin type for self api call
|
1577
|
-
:param bool
|
1682
|
+
:param bool trigger: True if for a trigger order
|
1578
1683
|
:param dict [params]: Request params
|
1579
1684
|
:returns: The marginMode and the updated request params with marginMode removed, marginMode value is the value that can be read by the "account" property specified in gates api docs
|
1580
1685
|
"""
|
@@ -1587,12 +1692,12 @@ class gate(Exchange, ImplicitAPI):
|
|
1587
1692
|
marginMode = 'margin'
|
1588
1693
|
elif marginMode == '':
|
1589
1694
|
marginMode = 'spot'
|
1590
|
-
if
|
1695
|
+
if trigger:
|
1591
1696
|
if marginMode == 'spot':
|
1592
|
-
# gate spot
|
1697
|
+
# gate spot trigger orders use the term normal instead of spot
|
1593
1698
|
marginMode = 'normal'
|
1594
1699
|
if marginMode == 'cross_margin':
|
1595
|
-
raise BadRequest(self.id + ' getMarginMode() does not support
|
1700
|
+
raise BadRequest(self.id + ' getMarginMode() does not support trigger orders for cross margin')
|
1596
1701
|
isUnifiedAccount = False
|
1597
1702
|
isUnifiedAccount, params = self.handle_option_and_params(params, 'getMarginMode', 'unifiedAccount')
|
1598
1703
|
if isUnifiedAccount:
|
@@ -2988,7 +3093,6 @@ class gate(Exchange, ImplicitAPI):
|
|
2988
3093
|
request['limit'] = limit
|
2989
3094
|
response = None
|
2990
3095
|
if market['contract']:
|
2991
|
-
maxLimit = 1999
|
2992
3096
|
isMark = (price == 'mark')
|
2993
3097
|
isIndex = (price == 'index')
|
2994
3098
|
if isMark or isIndex:
|
@@ -3305,7 +3409,7 @@ class gate(Exchange, ImplicitAPI):
|
|
3305
3409
|
params = self.omit(params, 'order_id')
|
3306
3410
|
else:
|
3307
3411
|
if market is not None:
|
3308
|
-
request['currency_pair'] = market['id'] # Should always be set for non-
|
3412
|
+
request['currency_pair'] = market['id'] # Should always be set for non-trigger
|
3309
3413
|
marginMode, params = self.get_margin_mode(False, params)
|
3310
3414
|
request['account'] = marginMode
|
3311
3415
|
if limit is not None:
|
@@ -3824,8 +3928,8 @@ class gate(Exchange, ImplicitAPI):
|
|
3824
3928
|
takeProfitPrice = self.safe_value(params, 'takeProfitPrice')
|
3825
3929
|
isStopLossOrder = stopLossPrice is not None
|
3826
3930
|
isTakeProfitOrder = takeProfitPrice is not None
|
3827
|
-
|
3828
|
-
nonTriggerOrder = not
|
3931
|
+
isTpsl = isStopLossOrder or isTakeProfitOrder
|
3932
|
+
nonTriggerOrder = not isTpsl and (trigger is None)
|
3829
3933
|
orderRequest = self.create_order_request(symbol, type, side, amount, price, params)
|
3830
3934
|
response = None
|
3831
3935
|
if market['spot'] or market['margin']:
|
@@ -3974,7 +4078,7 @@ class gate(Exchange, ImplicitAPI):
|
|
3974
4078
|
takeProfitPrice = self.safe_value(params, 'takeProfitPrice')
|
3975
4079
|
isStopLossOrder = stopLossPrice is not None
|
3976
4080
|
isTakeProfitOrder = takeProfitPrice is not None
|
3977
|
-
|
4081
|
+
isTpsl = isStopLossOrder or isTakeProfitOrder
|
3978
4082
|
if isStopLossOrder and isTakeProfitOrder:
|
3979
4083
|
raise ExchangeError(self.id + ' createOrder() stopLossPrice and takeProfitPrice cannot both be defined')
|
3980
4084
|
reduceOnly = self.safe_value(params, 'reduceOnly')
|
@@ -4010,7 +4114,7 @@ class gate(Exchange, ImplicitAPI):
|
|
4010
4114
|
signedAmount = Precise.string_neg(amountToPrecision) if (side == 'sell') else amountToPrecision
|
4011
4115
|
amount = int(signedAmount)
|
4012
4116
|
request = None
|
4013
|
-
nonTriggerOrder = not
|
4117
|
+
nonTriggerOrder = not isTpsl and (trigger is None)
|
4014
4118
|
if nonTriggerOrder:
|
4015
4119
|
if contract:
|
4016
4120
|
# contract order
|
@@ -4560,7 +4664,7 @@ class gate(Exchange, ImplicitAPI):
|
|
4560
4664
|
|
4561
4665
|
def fetch_order_request(self, id: str, symbol: Str = None, params={}):
|
4562
4666
|
market = None if (symbol is None) else self.market(symbol)
|
4563
|
-
|
4667
|
+
trigger = self.safe_bool_n(params, ['trigger', 'is_stop_order', 'stop'], False)
|
4564
4668
|
params = self.omit(params, ['is_stop_order', 'stop', 'trigger'])
|
4565
4669
|
clientOrderId = self.safe_string_2(params, 'text', 'clientOrderId')
|
4566
4670
|
orderId = id
|
@@ -4571,7 +4675,7 @@ class gate(Exchange, ImplicitAPI):
|
|
4571
4675
|
orderId = clientOrderId
|
4572
4676
|
type, query = self.handle_market_type_and_params('fetchOrder', market, params)
|
4573
4677
|
contract = (type == 'swap') or (type == 'future') or (type == 'option')
|
4574
|
-
request, requestParams = self.prepare_request(market, type, query) if contract else self.spot_order_prepare_request(market,
|
4678
|
+
request, requestParams = self.prepare_request(market, type, query) if contract else self.spot_order_prepare_request(market, trigger, query)
|
4575
4679
|
request['order_id'] = str(orderId)
|
4576
4680
|
return [request, requestParams]
|
4577
4681
|
|
@@ -4599,21 +4703,21 @@ class gate(Exchange, ImplicitAPI):
|
|
4599
4703
|
market = None if (symbol is None) else self.market(symbol)
|
4600
4704
|
result = self.handle_market_type_and_params('fetchOrder', market, params)
|
4601
4705
|
type = self.safe_string(result, 0)
|
4602
|
-
|
4706
|
+
trigger = self.safe_bool_n(params, ['trigger', 'is_stop_order', 'stop'], False)
|
4603
4707
|
request, requestParams = self.fetch_order_request(id, symbol, params)
|
4604
4708
|
response = None
|
4605
4709
|
if type == 'spot' or type == 'margin':
|
4606
|
-
if
|
4710
|
+
if trigger:
|
4607
4711
|
response = self.privateSpotGetPriceOrdersOrderId(self.extend(request, requestParams))
|
4608
4712
|
else:
|
4609
4713
|
response = self.privateSpotGetOrdersOrderId(self.extend(request, requestParams))
|
4610
4714
|
elif type == 'swap':
|
4611
|
-
if
|
4715
|
+
if trigger:
|
4612
4716
|
response = self.privateFuturesGetSettlePriceOrdersOrderId(self.extend(request, requestParams))
|
4613
4717
|
else:
|
4614
4718
|
response = self.privateFuturesGetSettleOrdersOrderId(self.extend(request, requestParams))
|
4615
4719
|
elif type == 'future':
|
4616
|
-
if
|
4720
|
+
if trigger:
|
4617
4721
|
response = self.privateDeliveryGetSettlePriceOrdersOrderId(self.extend(request, requestParams))
|
4618
4722
|
else:
|
4619
4723
|
response = self.privateDeliveryGetSettleOrdersOrderId(self.extend(request, requestParams))
|
@@ -4634,7 +4738,7 @@ class gate(Exchange, ImplicitAPI):
|
|
4634
4738
|
:param int [since]: the earliest time in ms to fetch open orders for
|
4635
4739
|
:param int [limit]: the maximum number of open orders structures to retrieve
|
4636
4740
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4637
|
-
:param bool [params.
|
4741
|
+
:param bool [params.trigger]: True for fetching trigger orders
|
4638
4742
|
:param str [params.type]: spot, margin, swap or future, if not provided self.options['defaultType'] is used
|
4639
4743
|
:param str [params.marginMode]: 'cross' or 'isolated' - marginMode for type='margin', if not provided self.options['defaultMarginMode'] is used
|
4640
4744
|
:param bool [params.unifiedAccount]: set to True for fetching unified account orders
|
@@ -4659,7 +4763,7 @@ class gate(Exchange, ImplicitAPI):
|
|
4659
4763
|
:param int [since]: the earliest time in ms to fetch orders for
|
4660
4764
|
:param int [limit]: the maximum number of order structures to retrieve
|
4661
4765
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4662
|
-
:param bool [params.
|
4766
|
+
:param bool [params.trigger]: True for fetching trigger orders
|
4663
4767
|
:param str [params.type]: spot, swap or future, if not provided self.options['defaultType'] is used
|
4664
4768
|
:param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
|
4665
4769
|
:param boolean [params.historical]: *swap only* True for using historical endpoint
|
@@ -4833,7 +4937,7 @@ class gate(Exchange, ImplicitAPI):
|
|
4833
4937
|
# }
|
4834
4938
|
# ]
|
4835
4939
|
#
|
4836
|
-
# spot
|
4940
|
+
# spot trigger
|
4837
4941
|
#
|
4838
4942
|
# [
|
4839
4943
|
# {
|
@@ -4928,31 +5032,31 @@ class gate(Exchange, ImplicitAPI):
|
|
4928
5032
|
:param str id: Order id
|
4929
5033
|
:param str symbol: Unified market symbol
|
4930
5034
|
:param dict [params]: Parameters specified by the exchange api
|
4931
|
-
:param bool [params.
|
5035
|
+
:param bool [params.trigger]: True if the order to be cancelled is a trigger order
|
4932
5036
|
:param bool [params.unifiedAccount]: set to True for canceling unified account orders
|
4933
5037
|
:returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
4934
5038
|
"""
|
4935
5039
|
self.load_markets()
|
4936
5040
|
self.load_unified_status()
|
4937
5041
|
market = None if (symbol is None) else self.market(symbol)
|
4938
|
-
|
5042
|
+
trigger = self.safe_bool_n(params, ['is_stop_order', 'stop', 'trigger'], False)
|
4939
5043
|
params = self.omit(params, ['is_stop_order', 'stop', 'trigger'])
|
4940
5044
|
type, query = self.handle_market_type_and_params('cancelOrder', market, params)
|
4941
|
-
request, requestParams = self.spot_order_prepare_request(market,
|
5045
|
+
request, requestParams = self.spot_order_prepare_request(market, trigger, query) if (type == 'spot' or type == 'margin') else self.prepare_request(market, type, query)
|
4942
5046
|
request['order_id'] = id
|
4943
5047
|
response = None
|
4944
5048
|
if type == 'spot' or type == 'margin':
|
4945
|
-
if
|
5049
|
+
if trigger:
|
4946
5050
|
response = self.privateSpotDeletePriceOrdersOrderId(self.extend(request, requestParams))
|
4947
5051
|
else:
|
4948
5052
|
response = self.privateSpotDeleteOrdersOrderId(self.extend(request, requestParams))
|
4949
5053
|
elif type == 'swap':
|
4950
|
-
if
|
5054
|
+
if trigger:
|
4951
5055
|
response = self.privateFuturesDeleteSettlePriceOrdersOrderId(self.extend(request, requestParams))
|
4952
5056
|
else:
|
4953
5057
|
response = self.privateFuturesDeleteSettleOrdersOrderId(self.extend(request, requestParams))
|
4954
5058
|
elif type == 'future':
|
4955
|
-
if
|
5059
|
+
if trigger:
|
4956
5060
|
response = self.privateDeliveryDeleteSettlePriceOrdersOrderId(self.extend(request, requestParams))
|
4957
5061
|
else:
|
4958
5062
|
response = self.privateDeliveryDeleteSettleOrdersOrderId(self.extend(request, requestParams))
|
@@ -5142,23 +5246,23 @@ class gate(Exchange, ImplicitAPI):
|
|
5142
5246
|
self.load_markets()
|
5143
5247
|
self.load_unified_status()
|
5144
5248
|
market = None if (symbol is None) else self.market(symbol)
|
5145
|
-
|
5249
|
+
trigger = self.safe_bool_2(params, 'stop', 'trigger')
|
5146
5250
|
params = self.omit(params, ['stop', 'trigger'])
|
5147
5251
|
type, query = self.handle_market_type_and_params('cancelAllOrders', market, params)
|
5148
|
-
request, requestParams = self.multi_order_spot_prepare_request(market,
|
5252
|
+
request, requestParams = self.multi_order_spot_prepare_request(market, trigger, query) if (type == 'spot') else self.prepare_request(market, type, query)
|
5149
5253
|
response = None
|
5150
5254
|
if type == 'spot' or type == 'margin':
|
5151
|
-
if
|
5255
|
+
if trigger:
|
5152
5256
|
response = self.privateSpotDeletePriceOrders(self.extend(request, requestParams))
|
5153
5257
|
else:
|
5154
5258
|
response = self.privateSpotDeleteOrders(self.extend(request, requestParams))
|
5155
5259
|
elif type == 'swap':
|
5156
|
-
if
|
5260
|
+
if trigger:
|
5157
5261
|
response = self.privateFuturesDeleteSettlePriceOrders(self.extend(request, requestParams))
|
5158
5262
|
else:
|
5159
5263
|
response = self.privateFuturesDeleteSettleOrders(self.extend(request, requestParams))
|
5160
5264
|
elif type == 'future':
|
5161
|
-
if
|
5265
|
+
if trigger:
|
5162
5266
|
response = self.privateDeliveryDeleteSettlePriceOrders(self.extend(request, requestParams))
|
5163
5267
|
else:
|
5164
5268
|
response = self.privateDeliveryDeleteSettleOrders(self.extend(request, requestParams))
|
ccxt/hyperliquid.py
CHANGED
@@ -11,12 +11,14 @@ from typing import List
|
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
12
|
from ccxt.base.errors import ArgumentsRequired
|
13
13
|
from ccxt.base.errors import BadRequest
|
14
|
+
from ccxt.base.errors import InsufficientFunds
|
14
15
|
from ccxt.base.errors import InvalidOrder
|
15
16
|
from ccxt.base.errors import OrderNotFound
|
16
17
|
from ccxt.base.errors import NotSupported
|
17
18
|
from ccxt.base.decimal_to_precision import ROUND
|
18
19
|
from ccxt.base.decimal_to_precision import DECIMAL_PLACES
|
19
20
|
from ccxt.base.decimal_to_precision import SIGNIFICANT_DIGITS
|
21
|
+
from ccxt.base.decimal_to_precision import TICK_SIZE
|
20
22
|
from ccxt.base.precise import Precise
|
21
23
|
|
22
24
|
|
@@ -55,6 +57,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
55
57
|
'createOrder': True,
|
56
58
|
'createOrders': True,
|
57
59
|
'createReduceOnlyOrder': True,
|
60
|
+
'createStopOrder': True,
|
61
|
+
'createTriggerOrder': True,
|
58
62
|
'editOrder': True,
|
59
63
|
'fetchAccounts': False,
|
60
64
|
'fetchBalance': True,
|
@@ -208,9 +212,11 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
208
212
|
'User or API Wallet ': InvalidOrder,
|
209
213
|
'Order has invalid size': InvalidOrder,
|
210
214
|
'Order price cannot be more than 80% away from the reference price': InvalidOrder,
|
215
|
+
'Order has zero size.': InvalidOrder,
|
216
|
+
'Insufficient spot balance asset': InsufficientFunds,
|
211
217
|
},
|
212
218
|
},
|
213
|
-
'precisionMode':
|
219
|
+
'precisionMode': TICK_SIZE,
|
214
220
|
'commonCurrencies': {
|
215
221
|
},
|
216
222
|
'options': {
|
@@ -359,6 +365,48 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
359
365
|
result.append(data)
|
360
366
|
return self.parse_markets(result)
|
361
367
|
|
368
|
+
def calculate_price_precision(self, price: float, amountPrecision: float, maxDecimals: float):
|
369
|
+
"""
|
370
|
+
Helper function to calculate the Hyperliquid DECIMAL_PLACES price precision
|
371
|
+
:param float price: the price to use in the calculation
|
372
|
+
:param int amountPrecision: the amountPrecision to use in the calculation
|
373
|
+
:param int maxDecimals: the maxDecimals to use in the calculation
|
374
|
+
:returns int: The calculated price precision
|
375
|
+
"""
|
376
|
+
pricePrecision = 0
|
377
|
+
priceStr = self.number_to_string(price)
|
378
|
+
if priceStr is None:
|
379
|
+
return 0
|
380
|
+
priceSplitted = priceStr.split('.')
|
381
|
+
if Precise.string_eq(priceStr, '0'):
|
382
|
+
# Significant digits is always hasattr(self, 5) case
|
383
|
+
significantDigits = 5
|
384
|
+
# Integer digits is always hasattr(self, 0) case(0 doesn't count)
|
385
|
+
integerDigits = 0
|
386
|
+
# Calculate the price precision
|
387
|
+
pricePrecision = min(maxDecimals - amountPrecision, significantDigits - integerDigits)
|
388
|
+
elif Precise.string_gt(priceStr, '0') and Precise.string_lt(priceStr, '1'):
|
389
|
+
# Significant digits, always hasattr(self, 5) case
|
390
|
+
significantDigits = 5
|
391
|
+
# Get the part after the decimal separator
|
392
|
+
decimalPart = self.safe_string(priceSplitted, 1, '')
|
393
|
+
# Count the number of leading zeros in the decimal part
|
394
|
+
leadingZeros = 0
|
395
|
+
while((leadingZeros <= len(decimalPart)) and (decimalPart[leadingZeros] == '0')):
|
396
|
+
leadingZeros = leadingZeros + 1
|
397
|
+
# Calculate price precision based on leading zeros and significant digits
|
398
|
+
pricePrecision = leadingZeros + significantDigits
|
399
|
+
# Calculate the price precision based on maxDecimals - szDecimals and the calculated price precision from the previous step
|
400
|
+
pricePrecision = min(maxDecimals - amountPrecision, pricePrecision)
|
401
|
+
else:
|
402
|
+
# Count the numbers before the decimal separator
|
403
|
+
integerPart = self.safe_string(priceSplitted, 0, '')
|
404
|
+
# Get significant digits, take the max() of 5 and the integer digits count
|
405
|
+
significantDigits = max(5, len(integerPart))
|
406
|
+
# Calculate price precision based on maxDecimals - szDecimals and significantDigits - len(integerPart)
|
407
|
+
pricePrecision = min(maxDecimals - amountPrecision, significantDigits - len(integerPart))
|
408
|
+
return self.parse_to_int(pricePrecision)
|
409
|
+
|
362
410
|
def fetch_spot_markets(self, params={}) -> List[Market]:
|
363
411
|
"""
|
364
412
|
retrieves data on all spot markets for hyperliquid
|
@@ -448,7 +496,11 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
448
496
|
symbol = base + '/' + quote
|
449
497
|
innerBaseTokenInfo = self.safe_dict(baseTokenInfo, 'spec', baseTokenInfo)
|
450
498
|
# innerQuoteTokenInfo = self.safe_dict(quoteTokenInfo, 'spec', quoteTokenInfo)
|
451
|
-
|
499
|
+
amountPrecisionStr = self.safe_string(innerBaseTokenInfo, 'szDecimals')
|
500
|
+
amountPrecision = int(amountPrecisionStr)
|
501
|
+
price = self.safe_number(extraData, 'midPx')
|
502
|
+
pricePrecision = self.calculate_price_precision(price, amountPrecision, 8)
|
503
|
+
pricePrecisionStr = self.number_to_string(pricePrecision)
|
452
504
|
# quotePrecision = self.parse_number(self.parse_precision(self.safe_string(innerQuoteTokenInfo, 'szDecimals')))
|
453
505
|
baseId = self.number_to_string(i + 10000)
|
454
506
|
markets.append(self.safe_market_structure({
|
@@ -479,8 +531,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
479
531
|
'strike': None,
|
480
532
|
'optionType': None,
|
481
533
|
'precision': {
|
482
|
-
'amount':
|
483
|
-
'price':
|
534
|
+
'amount': self.parse_number(self.parse_precision(amountPrecisionStr)),
|
535
|
+
'price': self.parse_number(self.parse_precision(pricePrecisionStr)),
|
484
536
|
},
|
485
537
|
'limits': {
|
486
538
|
'leverage': {
|
@@ -541,7 +593,11 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
541
593
|
fees = self.safe_dict(self.fees, 'swap', {})
|
542
594
|
taker = self.safe_number(fees, 'taker')
|
543
595
|
maker = self.safe_number(fees, 'maker')
|
544
|
-
|
596
|
+
amountPrecisionStr = self.safe_string(market, 'szDecimals')
|
597
|
+
amountPrecision = int(amountPrecisionStr)
|
598
|
+
price = self.safe_number(market, 'markPx', 0)
|
599
|
+
pricePrecision = self.calculate_price_precision(price, amountPrecision, 6)
|
600
|
+
pricePrecisionStr = self.number_to_string(pricePrecision)
|
545
601
|
return self.safe_market_structure({
|
546
602
|
'id': baseId,
|
547
603
|
'symbol': symbol,
|
@@ -569,8 +625,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
569
625
|
'strike': None,
|
570
626
|
'optionType': None,
|
571
627
|
'precision': {
|
572
|
-
'amount':
|
573
|
-
'price':
|
628
|
+
'amount': self.parse_number(self.parse_precision(amountPrecisionStr)),
|
629
|
+
'price': self.parse_number(self.parse_precision(pricePrecisionStr)),
|
574
630
|
},
|
575
631
|
'limits': {
|
576
632
|
'leverage': {
|
@@ -1037,10 +1093,13 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1037
1093
|
|
1038
1094
|
def price_to_precision(self, symbol: str, price) -> str:
|
1039
1095
|
market = self.market(symbol)
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1096
|
+
priceStr = self.number_to_string(price)
|
1097
|
+
integerPart = priceStr.split('.')[0]
|
1098
|
+
significantDigits = max(5, len(integerPart))
|
1099
|
+
result = self.decimal_to_precision(price, ROUND, significantDigits, SIGNIFICANT_DIGITS, self.paddingMode)
|
1100
|
+
maxDecimals = 8 if market['spot'] else 6
|
1101
|
+
subtractedValue = maxDecimals - self.precision_from_string(self.safe_string(market['precision'], 'amount'))
|
1102
|
+
return self.decimal_to_precision(result, ROUND, subtractedValue, DECIMAL_PLACES, self.paddingMode)
|
1044
1103
|
|
1045
1104
|
def hash_message(self, message):
|
1046
1105
|
return '0x' + self.hash(message, 'keccak', 'hex')
|
ccxt/idex.py
CHANGED
@@ -19,7 +19,6 @@ from ccxt.base.errors import DDoSProtection
|
|
19
19
|
from ccxt.base.errors import ExchangeNotAvailable
|
20
20
|
from ccxt.base.decimal_to_precision import ROUND
|
21
21
|
from ccxt.base.decimal_to_precision import TRUNCATE
|
22
|
-
from ccxt.base.decimal_to_precision import DECIMAL_PLACES
|
23
22
|
from ccxt.base.decimal_to_precision import TICK_SIZE
|
24
23
|
from ccxt.base.decimal_to_precision import PAD_WITH_ZERO
|
25
24
|
from ccxt.base.precise import Precise
|
@@ -206,10 +205,8 @@ class idex(Exchange, ImplicitAPI):
|
|
206
205
|
# {"code":"INVALID_PARAMETER","message":"invalid value provided for request parameter \"price\": all quantities and prices must be below 100 billion, above 0, need to be provided, and always require 4 decimals ending with 4 zeroes"}
|
207
206
|
#
|
208
207
|
market = self.market(symbol)
|
209
|
-
info = self.safe_value(market, 'info', {})
|
210
|
-
quoteAssetPrecision = self.safe_integer(info, 'quoteAssetPrecision')
|
211
208
|
price = self.decimal_to_precision(price, ROUND, market['precision']['price'], self.precisionMode)
|
212
|
-
return self.decimal_to_precision(price, TRUNCATE,
|
209
|
+
return self.decimal_to_precision(price, TRUNCATE, market['precision']['quote'], TICK_SIZE, PAD_WITH_ZERO)
|
213
210
|
|
214
211
|
def fetch_markets(self, params={}) -> List[Market]:
|
215
212
|
"""
|
@@ -316,6 +313,8 @@ class idex(Exchange, ImplicitAPI):
|
|
316
313
|
'precision': {
|
317
314
|
'amount': basePrecision,
|
318
315
|
'price': self.safe_number(entry, 'tickSize'),
|
316
|
+
'base': basePrecision,
|
317
|
+
'quote': quotePrecision,
|
319
318
|
},
|
320
319
|
'limits': {
|
321
320
|
'leverage': {
|