ccxt 4.4.68__py2.py3-none-any.whl → 4.4.70__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/bybit.py +4 -0
- ccxt/abstract/myokx.py +3 -0
- ccxt/abstract/okx.py +3 -0
- ccxt/abstract/paradex.py +23 -0
- ccxt/abstract/tradeogre.py +2 -1
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +5 -1
- ccxt/async_support/binance.py +17 -3
- ccxt/async_support/bitget.py +47 -262
- ccxt/async_support/bitstamp.py +2 -3
- ccxt/async_support/bybit.py +7 -0
- ccxt/async_support/coinbase.py +24 -9
- ccxt/async_support/cryptomus.py +122 -6
- ccxt/async_support/hyperliquid.py +17 -8
- ccxt/async_support/okx.py +4 -0
- ccxt/async_support/paradex.py +173 -5
- ccxt/async_support/phemex.py +2 -2
- ccxt/async_support/tradeogre.py +31 -11
- ccxt/async_support/whitebit.py +210 -2
- ccxt/base/exchange.py +1 -2
- ccxt/binance.py +17 -3
- ccxt/bitget.py +47 -262
- ccxt/bitstamp.py +2 -3
- ccxt/bybit.py +7 -0
- ccxt/coinbase.py +24 -9
- ccxt/cryptomus.py +122 -6
- ccxt/hyperliquid.py +17 -8
- ccxt/okx.py +4 -0
- ccxt/paradex.py +173 -5
- ccxt/phemex.py +2 -2
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitget.py +28 -3
- ccxt/pro/bybit.py +81 -37
- ccxt/test/tests_async.py +25 -3
- ccxt/test/tests_sync.py +25 -3
- ccxt/tradeogre.py +31 -11
- ccxt/whitebit.py +210 -2
- {ccxt-4.4.68.dist-info → ccxt-4.4.70.dist-info}/METADATA +4 -4
- {ccxt-4.4.68.dist-info → ccxt-4.4.70.dist-info}/RECORD +43 -43
- {ccxt-4.4.68.dist-info → ccxt-4.4.70.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.68.dist-info → ccxt-4.4.70.dist-info}/WHEEL +0 -0
- {ccxt-4.4.68.dist-info → ccxt-4.4.70.dist-info}/top_level.txt +0 -0
ccxt/async_support/coinbase.py
CHANGED
@@ -336,6 +336,7 @@ class coinbase(Exchange, ImplicitAPI):
|
|
336
336
|
'INSUFFICIENT_FUND': BadRequest,
|
337
337
|
'PERMISSION_DENIED': PermissionDenied,
|
338
338
|
'INVALID_ARGUMENT': BadRequest,
|
339
|
+
'PREVIEW_STOP_PRICE_ABOVE_LAST_TRADE_PRICE': InvalidOrder,
|
339
340
|
},
|
340
341
|
'broad': {
|
341
342
|
'request timestamp expired': InvalidNonce, # {"errors":[{"id":"authentication_error","message":"request timestamp expired"}]}
|
@@ -4089,6 +4090,7 @@ class coinbase(Exchange, ImplicitAPI):
|
|
4089
4090
|
'amount': self.number_to_string(amount),
|
4090
4091
|
'currency': code.upper(), # need to use code in case depositing USD etc.
|
4091
4092
|
'payment_method': id,
|
4093
|
+
'commit': True, # otheriwse the deposit does not go through
|
4092
4094
|
}
|
4093
4095
|
response = await self.v2PrivatePostAccountsAccountIdDeposits(self.extend(request, params))
|
4094
4096
|
#
|
@@ -4691,11 +4693,6 @@ class coinbase(Exchange, ImplicitAPI):
|
|
4691
4693
|
return result
|
4692
4694
|
|
4693
4695
|
def parse_portfolio_details(self, portfolioData: dict):
|
4694
|
-
"""
|
4695
|
-
Parse a Coinbase portfolio JSON object and extract relevant trading information.
|
4696
|
-
:param Dict portfolioData: The JSON response containing portfolio details
|
4697
|
-
:returns any[]: List of dictionaries with parsed portfolio position data
|
4698
|
-
"""
|
4699
4696
|
breakdown = portfolioData['breakdown']
|
4700
4697
|
portfolioInfo = self.safe_dict(breakdown, 'portfolio', {})
|
4701
4698
|
portfolioName = self.safe_string(portfolioInfo, 'name', 'Unknown')
|
@@ -4868,19 +4865,37 @@ class coinbase(Exchange, ImplicitAPI):
|
|
4868
4865
|
# ]
|
4869
4866
|
# }
|
4870
4867
|
# or
|
4871
|
-
#
|
4868
|
+
# {
|
4869
|
+
# "success": False,
|
4870
|
+
# "error_response": {
|
4872
4871
|
# "error": "UNKNOWN_FAILURE_REASON",
|
4873
4872
|
# "message": "",
|
4874
4873
|
# "error_details": "",
|
4875
|
-
# "preview_failure_reason": "
|
4876
|
-
#
|
4874
|
+
# "preview_failure_reason": "PREVIEW_STOP_PRICE_ABOVE_LAST_TRADE_PRICE"
|
4875
|
+
# },
|
4876
|
+
# "order_configuration": {
|
4877
|
+
# "stop_limit_stop_limit_gtc": {
|
4878
|
+
# "base_size": "0.0001",
|
4879
|
+
# "limit_price": "2000",
|
4880
|
+
# "stop_price": "2005",
|
4881
|
+
# "stop_direction": "STOP_DIRECTION_STOP_DOWN",
|
4882
|
+
# "reduce_only": False
|
4883
|
+
# }
|
4884
|
+
# }
|
4885
|
+
# }
|
4877
4886
|
#
|
4878
4887
|
errorCode = self.safe_string(response, 'error')
|
4879
4888
|
if errorCode is not None:
|
4880
|
-
errorMessage = self.safe_string_2(response, 'error_description', '
|
4889
|
+
errorMessage = self.safe_string_2(response, 'error_description', 'error')
|
4881
4890
|
self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
|
4882
4891
|
self.throw_broadly_matched_exception(self.exceptions['broad'], errorMessage, feedback)
|
4883
4892
|
raise ExchangeError(feedback)
|
4893
|
+
errorResponse = self.safe_dict(response, 'error_response')
|
4894
|
+
if errorResponse is not None:
|
4895
|
+
errorMessageInner = self.safe_string_2(errorResponse, 'preview_failure_reason', 'preview_failure_reason')
|
4896
|
+
self.throw_exactly_matched_exception(self.exceptions['exact'], errorMessageInner, feedback)
|
4897
|
+
self.throw_broadly_matched_exception(self.exceptions['broad'], errorMessageInner, feedback)
|
4898
|
+
raise ExchangeError(feedback)
|
4884
4899
|
errors = self.safe_list(response, 'errors')
|
4885
4900
|
if errors is not None:
|
4886
4901
|
if isinstance(errors, list):
|
ccxt/async_support/cryptomus.py
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.cryptomus import ImplicitAPI
|
8
|
-
from ccxt.base.types import Any, Balances, Currencies, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade
|
8
|
+
from ccxt.base.types import Any, Balances, Currencies, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees
|
9
9
|
from typing import List
|
10
10
|
from ccxt.base.errors import ExchangeError
|
11
11
|
from ccxt.base.errors import ArgumentsRequired
|
@@ -23,7 +23,7 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
23
23
|
'name': 'Cryptomus',
|
24
24
|
'countries': ['CA'],
|
25
25
|
'rateLimit': 100, # todo check
|
26
|
-
'version': '
|
26
|
+
'version': 'v2',
|
27
27
|
'certified': False,
|
28
28
|
'pro': False,
|
29
29
|
'has': {
|
@@ -105,7 +105,7 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
105
105
|
'fetchTime': False,
|
106
106
|
'fetchTrades': True,
|
107
107
|
'fetchTradingFee': False,
|
108
|
-
'fetchTradingFees':
|
108
|
+
'fetchTradingFees': True,
|
109
109
|
'fetchTransactions': False,
|
110
110
|
'fetchTransfers': False,
|
111
111
|
'fetchWithdrawals': False,
|
@@ -143,9 +143,9 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
143
143
|
'private': {
|
144
144
|
'get': {
|
145
145
|
'v2/user-api/exchange/orders': 1, # done
|
146
|
-
'v2/user-api/exchange/orders/history': 1,
|
146
|
+
'v2/user-api/exchange/orders/history': 1, # done
|
147
147
|
'v2/user-api/exchange/account/balance': 1, # done
|
148
|
-
'v2/user-api/exchange/account/tariffs': 1,
|
148
|
+
'v2/user-api/exchange/account/tariffs': 1, # done
|
149
149
|
'v2/user-api/payment/services': 1,
|
150
150
|
'v2/user-api/payout/services': 1,
|
151
151
|
'v2/user-api/transaction/list': 1,
|
@@ -231,7 +231,9 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
231
231
|
async def fetch_markets(self, params={}) -> List[Market]:
|
232
232
|
"""
|
233
233
|
retrieves data on all markets for the exchange
|
234
|
+
|
234
235
|
https://doc.cryptomus.com/personal/market-cap/tickers
|
236
|
+
|
235
237
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
236
238
|
:returns dict[]: an array of objects representing market data
|
237
239
|
"""
|
@@ -339,7 +341,9 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
339
341
|
async def fetch_currencies(self, params={}) -> Currencies:
|
340
342
|
"""
|
341
343
|
fetches all available currencies on an exchange
|
344
|
+
|
342
345
|
https://doc.cryptomus.com/personal/market-cap/assets
|
346
|
+
|
343
347
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
344
348
|
:returns dict: an associative dictionary of currencies
|
345
349
|
"""
|
@@ -466,7 +470,9 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
466
470
|
async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
467
471
|
"""
|
468
472
|
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
473
|
+
|
469
474
|
https://doc.cryptomus.com/personal/market-cap/tickers
|
475
|
+
|
470
476
|
:param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
471
477
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
472
478
|
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
@@ -528,7 +534,9 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
528
534
|
async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
529
535
|
"""
|
530
536
|
fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
537
|
+
|
531
538
|
https://doc.cryptomus.com/personal/market-cap/orderbook
|
539
|
+
|
532
540
|
:param str symbol: unified symbol of the market to fetch the order book for
|
533
541
|
:param int [limit]: the maximum amount of order book entries to return
|
534
542
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -570,7 +578,9 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
570
578
|
async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
571
579
|
"""
|
572
580
|
get the list of most recent trades for a particular symbol
|
581
|
+
|
573
582
|
https://doc.cryptomus.com/personal/market-cap/trades
|
583
|
+
|
574
584
|
:param str symbol: unified symbol of the market to fetch trades for
|
575
585
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
576
586
|
:param int [limit]: the maximum amount of trades to fetch(maximum value is 100)
|
@@ -634,7 +644,9 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
634
644
|
async def fetch_balance(self, params={}) -> Balances:
|
635
645
|
"""
|
636
646
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
647
|
+
|
637
648
|
https://doc.cryptomus.com/personal/converts/balance
|
649
|
+
|
638
650
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
639
651
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
640
652
|
"""
|
@@ -679,8 +691,10 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
679
691
|
async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
|
680
692
|
"""
|
681
693
|
create a trade order
|
694
|
+
|
682
695
|
https://doc.cryptomus.com/personal/exchange/market-order-creation
|
683
696
|
https://doc.cryptomus.com/personal/exchange/limit-order-creation
|
697
|
+
|
684
698
|
:param str symbol: unified symbol of the market to create an order in
|
685
699
|
:param str type: 'market' or 'limit' or for spot
|
686
700
|
:param str side: 'buy' or 'sell'
|
@@ -688,7 +702,6 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
688
702
|
:param float [price]: the price that the order is to be fulfilled, in units of the quote currency, ignored in market orders(only for limit orders)
|
689
703
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
690
704
|
:param float [params.cost]: *market buy only* the quote quantity that can be used alternative for the amount
|
691
|
-
:param dict [params]: extra parameters specific to the exchange API endpoint
|
692
705
|
:param str [params.clientOrderId]: a unique identifier for the order(optional)
|
693
706
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
694
707
|
"""
|
@@ -742,7 +755,9 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
742
755
|
async def cancel_order(self, id: str, symbol: Str = None, params={}):
|
743
756
|
"""
|
744
757
|
cancels an open limit order
|
758
|
+
|
745
759
|
https://doc.cryptomus.com/personal/exchange/limit-order-cancellation
|
760
|
+
|
746
761
|
:param str id: order id
|
747
762
|
:param str symbol: unified symbol of the market the order was made in(not used in cryptomus)
|
748
763
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -762,7 +777,9 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
762
777
|
async def fetch_canceled_and_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
763
778
|
"""
|
764
779
|
fetches information on multiple orders made by the user
|
780
|
+
|
765
781
|
https://doc.cryptomus.com/personal/exchange/history-of-completed-orders
|
782
|
+
|
766
783
|
:param str symbol: unified market symbol of the market orders were made in(not used in cryptomus)
|
767
784
|
:param int [since]: the earliest time in ms to fetch orders for(not used in cryptomus)
|
768
785
|
:param int [limit]: the maximum number of order structures to retrieve(not used in cryptomus)
|
@@ -832,7 +849,9 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
832
849
|
async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
833
850
|
"""
|
834
851
|
fetch all unfilled currently open orders
|
852
|
+
|
835
853
|
https://doc.cryptomus.com/personal/exchange/list-of-active-orders
|
854
|
+
|
836
855
|
:param str symbol: unified market symbol
|
837
856
|
:param int [since]: the earliest time in ms to fetch open orders for(not used in cryptomus)
|
838
857
|
:param int [limit]: the maximum number of open orders structures to retrieve(not used in cryptomus)
|
@@ -993,6 +1012,103 @@ class cryptomus(Exchange, ImplicitAPI):
|
|
993
1012
|
}
|
994
1013
|
return self.safe_string(statuses, status, status)
|
995
1014
|
|
1015
|
+
async def fetch_trading_fees(self, params={}) -> TradingFees:
|
1016
|
+
"""
|
1017
|
+
fetch the trading fees for multiple markets
|
1018
|
+
|
1019
|
+
https://trade-docs.coinlist.co/?javascript--nodejs#list-fees
|
1020
|
+
|
1021
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1022
|
+
:returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
|
1023
|
+
"""
|
1024
|
+
response = await self.privateGetV2UserApiExchangeAccountTariffs(params)
|
1025
|
+
#
|
1026
|
+
# {
|
1027
|
+
# result: {
|
1028
|
+
# equivalent_currency_code: 'USD',
|
1029
|
+
# current_tariff_step: {
|
1030
|
+
# step: '0',
|
1031
|
+
# from_turnover: '0.00000000',
|
1032
|
+
# maker_percent: '0.08',
|
1033
|
+
# taker_percent: '0.1'
|
1034
|
+
# },
|
1035
|
+
# tariff_steps: [
|
1036
|
+
# {
|
1037
|
+
# step: '0',
|
1038
|
+
# from_turnover: '0.00000000',
|
1039
|
+
# maker_percent: '0.08',
|
1040
|
+
# taker_percent: '0.1'
|
1041
|
+
# },
|
1042
|
+
# {
|
1043
|
+
# step: '1',
|
1044
|
+
# from_turnover: '100001.00000000',
|
1045
|
+
# maker_percent: '0.06',
|
1046
|
+
# taker_percent: '0.095'
|
1047
|
+
# },
|
1048
|
+
# {
|
1049
|
+
# step: '2',
|
1050
|
+
# from_turnover: '250001.00000000',
|
1051
|
+
# maker_percent: '0.055',
|
1052
|
+
# taker_percent: '0.085'
|
1053
|
+
# },
|
1054
|
+
# {
|
1055
|
+
# step: '3',
|
1056
|
+
# from_turnover: '500001.00000000',
|
1057
|
+
# maker_percent: '0.05',
|
1058
|
+
# taker_percent: '0.075'
|
1059
|
+
# },
|
1060
|
+
# {
|
1061
|
+
# step: '4',
|
1062
|
+
# from_turnover: '2500001.00000000',
|
1063
|
+
# maker_percent: '0.04',
|
1064
|
+
# taker_percent: '0.07'
|
1065
|
+
# }
|
1066
|
+
# ],
|
1067
|
+
# daily_turnover: '0.00000000',
|
1068
|
+
# monthly_turnover: '77.52062617',
|
1069
|
+
# circulation_funds: '25.48900443'
|
1070
|
+
# }
|
1071
|
+
# }
|
1072
|
+
#
|
1073
|
+
data = self.safe_dict(response, 'result', {})
|
1074
|
+
currentFeeTier = self.safe_dict(data, 'current_tariff_step', {})
|
1075
|
+
makerFee = self.safe_string(currentFeeTier, 'maker_percent')
|
1076
|
+
takerFee = self.safe_string(currentFeeTier, 'taker_percent')
|
1077
|
+
makerFee = Precise.string_div(makerFee, '100')
|
1078
|
+
takerFee = Precise.string_div(takerFee, '100')
|
1079
|
+
feeTiers = self.safe_list(data, 'tariff_steps', [])
|
1080
|
+
result: dict = {}
|
1081
|
+
tiers = self.parse_fee_tiers(feeTiers)
|
1082
|
+
for i in range(0, len(self.symbols)):
|
1083
|
+
symbol = self.symbols[i]
|
1084
|
+
result[symbol] = {
|
1085
|
+
'info': response,
|
1086
|
+
'symbol': symbol,
|
1087
|
+
'maker': self.parse_number(makerFee),
|
1088
|
+
'taker': self.parse_number(takerFee),
|
1089
|
+
'percentage': True,
|
1090
|
+
'tierBased': True,
|
1091
|
+
'tiers': tiers,
|
1092
|
+
}
|
1093
|
+
return result
|
1094
|
+
|
1095
|
+
def parse_fee_tiers(self, feeTiers, market: Market = None):
|
1096
|
+
takerFees = []
|
1097
|
+
makerFees = []
|
1098
|
+
for i in range(0, len(feeTiers)):
|
1099
|
+
tier = feeTiers[i]
|
1100
|
+
turnover = self.safe_number(tier, 'from_turnover')
|
1101
|
+
taker = self.safe_string(tier, 'taker_percent')
|
1102
|
+
maker = self.safe_string(tier, 'maker_percent')
|
1103
|
+
maker = Precise.string_div(maker, '100')
|
1104
|
+
taker = Precise.string_div(taker, '100')
|
1105
|
+
makerFees.append([turnover, self.parse_number(maker)])
|
1106
|
+
takerFees.append([turnover, self.parse_number(taker)])
|
1107
|
+
return {
|
1108
|
+
'maker': makerFees,
|
1109
|
+
'taker': takerFees,
|
1110
|
+
}
|
1111
|
+
|
996
1112
|
def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
|
997
1113
|
endpoint = self.implode_params(path, params)
|
998
1114
|
params = self.omit(params, self.extract_params(path))
|
@@ -838,7 +838,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
838
838
|
'info': response,
|
839
839
|
'USDC': {
|
840
840
|
'total': self.safe_number(data, 'accountValue'),
|
841
|
-
'
|
841
|
+
'used': self.safe_number(data, 'totalMarginUsed'),
|
842
842
|
},
|
843
843
|
}
|
844
844
|
timestamp = self.safe_integer(response, 'time')
|
@@ -1757,11 +1757,12 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1757
1757
|
isTrigger = (stopLossPrice or takeProfitPrice)
|
1758
1758
|
reduceOnly = self.safe_bool(orderParams, 'reduceOnly', False)
|
1759
1759
|
orderParams = self.omit(orderParams, ['slippage', 'timeInForce', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice', 'clientOrderId', 'client_id', 'postOnly', 'reduceOnly'])
|
1760
|
-
px =
|
1760
|
+
px = self.number_to_string(price)
|
1761
1761
|
if isMarket:
|
1762
|
-
px =
|
1762
|
+
px = Precise.string_mul(px, Precise.string_add('1', slippage)) if (isBuy) else Precise.string_mul(px, Precise.string_sub('1', slippage))
|
1763
|
+
px = self.price_to_precision(symbol, px)
|
1763
1764
|
else:
|
1764
|
-
px = self.price_to_precision(symbol,
|
1765
|
+
px = self.price_to_precision(symbol, px)
|
1765
1766
|
sz = self.amount_to_precision(symbol, amount)
|
1766
1767
|
orderType: dict = {}
|
1767
1768
|
if isTrigger:
|
@@ -2243,6 +2244,10 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2243
2244
|
side = 'sell' if (side == 'A') else 'buy'
|
2244
2245
|
totalAmount = self.safe_string_2(entry, 'origSz', 'totalSz')
|
2245
2246
|
remaining = self.safe_string(entry, 'sz')
|
2247
|
+
tif = self.safe_string_upper(entry, 'tif')
|
2248
|
+
postOnly = None
|
2249
|
+
if tif is not None:
|
2250
|
+
postOnly = (tif == 'ALO')
|
2246
2251
|
return self.safe_order({
|
2247
2252
|
'info': order,
|
2248
2253
|
'id': self.safe_string(entry, 'oid'),
|
@@ -2253,8 +2258,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2253
2258
|
'lastUpdateTimestamp': self.safe_integer(order, 'statusTimestamp'),
|
2254
2259
|
'symbol': symbol,
|
2255
2260
|
'type': self.parse_order_type(self.safe_string_lower(entry, 'orderType')),
|
2256
|
-
'timeInForce':
|
2257
|
-
'postOnly':
|
2261
|
+
'timeInForce': tif,
|
2262
|
+
'postOnly': postOnly,
|
2258
2263
|
'reduceOnly': self.safe_bool(entry, 'reduceOnly'),
|
2259
2264
|
'side': side,
|
2260
2265
|
'price': self.safe_string(entry, 'limitPx'),
|
@@ -2372,6 +2377,10 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2372
2377
|
if side is not None:
|
2373
2378
|
side = 'sell' if (side == 'A') else 'buy'
|
2374
2379
|
fee = self.safe_string(trade, 'fee')
|
2380
|
+
takerOrMaker = None
|
2381
|
+
crossed = self.safe_bool(trade, 'crossed')
|
2382
|
+
if crossed is not None:
|
2383
|
+
takerOrMaker = 'taker' if crossed else 'maker'
|
2375
2384
|
return self.safe_trade({
|
2376
2385
|
'info': trade,
|
2377
2386
|
'timestamp': timestamp,
|
@@ -2381,7 +2390,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2381
2390
|
'order': self.safe_string(trade, 'oid'),
|
2382
2391
|
'type': None,
|
2383
2392
|
'side': side,
|
2384
|
-
'takerOrMaker':
|
2393
|
+
'takerOrMaker': takerOrMaker,
|
2385
2394
|
'price': price,
|
2386
2395
|
'amount': amount,
|
2387
2396
|
'cost': None,
|
@@ -2928,7 +2937,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2928
2937
|
'tagTo': None,
|
2929
2938
|
'tagFrom': None,
|
2930
2939
|
'type': None,
|
2931
|
-
'amount': self.
|
2940
|
+
'amount': self.safe_number(delta, 'usdc'),
|
2932
2941
|
'currency': None,
|
2933
2942
|
'status': self.safe_string(transaction, 'status'),
|
2934
2943
|
'updated': None,
|
ccxt/async_support/okx.py
CHANGED
@@ -333,7 +333,9 @@ class okx(Exchange, ImplicitAPI):
|
|
333
333
|
'trade/easy-convert-currency-list': 20,
|
334
334
|
'trade/easy-convert-history': 20,
|
335
335
|
'trade/one-click-repay-currency-list': 20,
|
336
|
+
'trade/one-click-repay-currency-list-v2': 20,
|
336
337
|
'trade/one-click-repay-history': 20,
|
338
|
+
'trade/one-click-repay-history-v2': 20,
|
337
339
|
'trade/account-rate-limit': 1,
|
338
340
|
# asset
|
339
341
|
'asset/currencies': 5 / 3,
|
@@ -490,6 +492,7 @@ class okx(Exchange, ImplicitAPI):
|
|
490
492
|
'trade/cancel-advance-algos': 1,
|
491
493
|
'trade/easy-convert': 20,
|
492
494
|
'trade/one-click-repay': 20,
|
495
|
+
'trade/one-click-repay-v2': 20,
|
493
496
|
'trade/mass-cancel': 4,
|
494
497
|
'trade/cancel-all-after': 10,
|
495
498
|
# asset
|
@@ -3044,6 +3047,7 @@ class okx(Exchange, ImplicitAPI):
|
|
3044
3047
|
:param str [params.trailingPercent]: the percent to trail away from the current market price
|
3045
3048
|
:param str [params.tpOrdKind]: 'condition' or 'limit', the default is 'condition'
|
3046
3049
|
:param bool [params.hedged]: *swap and future only* True for hedged mode, False for one way mode
|
3050
|
+
:param str [params.marginMode]: 'cross' or 'isolated', the default is 'cross'
|
3047
3051
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
3048
3052
|
"""
|
3049
3053
|
await self.load_markets()
|
ccxt/async_support/paradex.py
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.paradex import ImplicitAPI
|
8
|
-
from ccxt.base.types import Any, Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
|
8
|
+
from ccxt.base.types import Any, Balances, Currency, Int, Leverage, MarginMode, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
|
9
9
|
from typing import List
|
10
10
|
from ccxt.base.errors import ExchangeError
|
11
11
|
from ccxt.base.errors import AuthenticationError
|
@@ -79,10 +79,10 @@ class paradex(Exchange, ImplicitAPI):
|
|
79
79
|
'fetchIsolatedBorrowRate': False,
|
80
80
|
'fetchIsolatedBorrowRates': False,
|
81
81
|
'fetchLedger': False,
|
82
|
-
'fetchLeverage':
|
82
|
+
'fetchLeverage': True,
|
83
83
|
'fetchLeverageTiers': False,
|
84
84
|
'fetchLiquidations': True,
|
85
|
-
'fetchMarginMode':
|
85
|
+
'fetchMarginMode': True,
|
86
86
|
'fetchMarketLeverageTiers': False,
|
87
87
|
'fetchMarkets': True,
|
88
88
|
'fetchMarkOHLCV': False,
|
@@ -116,8 +116,8 @@ class paradex(Exchange, ImplicitAPI):
|
|
116
116
|
'repayCrossMargin': False,
|
117
117
|
'repayIsolatedMargin': False,
|
118
118
|
'sandbox': True,
|
119
|
-
'setLeverage':
|
120
|
-
'setMarginMode':
|
119
|
+
'setLeverage': True,
|
120
|
+
'setMarginMode': True,
|
121
121
|
'setPositionMode': False,
|
122
122
|
'transfer': False,
|
123
123
|
'withdraw': False,
|
@@ -159,12 +159,23 @@ class paradex(Exchange, ImplicitAPI):
|
|
159
159
|
'system/state': 1,
|
160
160
|
'system/time': 1,
|
161
161
|
'trades': 1,
|
162
|
+
'vaults': 1,
|
163
|
+
'vaults/balance': 1,
|
164
|
+
'vaults/config': 1,
|
165
|
+
'vaults/history': 1,
|
166
|
+
'vaults/positions': 1,
|
167
|
+
'vaults/summary': 1,
|
168
|
+
'vaults/transfers': 1,
|
162
169
|
},
|
163
170
|
},
|
164
171
|
'private': {
|
165
172
|
'get': {
|
166
173
|
'account': 1,
|
174
|
+
'account/info': 1,
|
175
|
+
'account/history': 1,
|
176
|
+
'account/margin': 1,
|
167
177
|
'account/profile': 1,
|
178
|
+
'account/subaccounts': 1,
|
168
179
|
'balance': 1,
|
169
180
|
'fills': 1,
|
170
181
|
'funding/payments': 1,
|
@@ -177,20 +188,34 @@ class paradex(Exchange, ImplicitAPI):
|
|
177
188
|
'orders/by_client_id/{client_id}': 1,
|
178
189
|
'orders/{order_id}': 1,
|
179
190
|
'points_data/{market}/{program}': 1,
|
191
|
+
'referrals/qr-code': 1,
|
180
192
|
'referrals/summary': 1,
|
181
193
|
'transfers': 1,
|
194
|
+
'algo/orders': 1,
|
195
|
+
'algo/orders-history': 1,
|
196
|
+
'algo/orders/{algo_id}': 1,
|
197
|
+
'vaults/account-summary': 1,
|
182
198
|
},
|
183
199
|
'post': {
|
200
|
+
'account/margin/{market}': 1,
|
201
|
+
'account/profile/max_slippage': 1,
|
184
202
|
'account/profile/referral_code': 1,
|
185
203
|
'account/profile/username': 1,
|
186
204
|
'auth': 1,
|
187
205
|
'onboarding': 1,
|
188
206
|
'orders': 1,
|
207
|
+
'orders/batch': 1,
|
208
|
+
'algo/orders': 1,
|
209
|
+
'vaults': 1,
|
210
|
+
},
|
211
|
+
'put': {
|
212
|
+
'orders/{order_id}': 1,
|
189
213
|
},
|
190
214
|
'delete': {
|
191
215
|
'orders': 1,
|
192
216
|
'orders/by_client_id/{client_id}': 1,
|
193
217
|
'orders/{order_id}': 1,
|
218
|
+
'algo/orders/{algo_id}': 1,
|
194
219
|
},
|
195
220
|
},
|
196
221
|
},
|
@@ -2063,6 +2088,149 @@ class paradex(Exchange, ImplicitAPI):
|
|
2063
2088
|
}
|
2064
2089
|
return self.safe_string(statuses, status, status)
|
2065
2090
|
|
2091
|
+
async def fetch_margin_mode(self, symbol: str, params={}) -> MarginMode:
|
2092
|
+
"""
|
2093
|
+
fetches the margin mode of a specific symbol
|
2094
|
+
|
2095
|
+
https://docs.api.testnet.paradex.trade/#get-account-margin-configuration
|
2096
|
+
|
2097
|
+
:param str symbol: unified symbol of the market the order was made in
|
2098
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2099
|
+
:returns dict: a `margin mode structure <https://docs.ccxt.com/#/?id=margin-mode-structure>`
|
2100
|
+
"""
|
2101
|
+
await self.authenticate_rest()
|
2102
|
+
await self.load_markets()
|
2103
|
+
market = self.market(symbol)
|
2104
|
+
request: dict = {
|
2105
|
+
'market': market['id'],
|
2106
|
+
}
|
2107
|
+
response = await self.privateGetAccountMargin(self.extend(request, params))
|
2108
|
+
#
|
2109
|
+
# {
|
2110
|
+
# "account": "0x6343248026a845b39a8a73fbe9c7ef0a841db31ed5c61ec1446aa9d25e54dbc",
|
2111
|
+
# "configs": [
|
2112
|
+
# {
|
2113
|
+
# "market": "SOL-USD-PERP",
|
2114
|
+
# "leverage": 50,
|
2115
|
+
# "margin_type": "CROSS"
|
2116
|
+
# }
|
2117
|
+
# ]
|
2118
|
+
# }
|
2119
|
+
#
|
2120
|
+
configs = self.safe_list(response, 'configs')
|
2121
|
+
return self.parse_margin_mode(self.safe_dict(configs, 0), market)
|
2122
|
+
|
2123
|
+
def parse_margin_mode(self, rawMarginMode: dict, market=None) -> MarginMode:
|
2124
|
+
marketId = self.safe_string(rawMarginMode, 'market')
|
2125
|
+
market = self.safe_market(marketId, market)
|
2126
|
+
marginMode = self.safe_string_lower(rawMarginMode, 'margin_type')
|
2127
|
+
return {
|
2128
|
+
'info': rawMarginMode,
|
2129
|
+
'symbol': market['symbol'],
|
2130
|
+
'marginMode': marginMode,
|
2131
|
+
}
|
2132
|
+
|
2133
|
+
async def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
|
2134
|
+
"""
|
2135
|
+
set margin mode to 'cross' or 'isolated'
|
2136
|
+
|
2137
|
+
https://docs.api.testnet.paradex.trade/#set-margin-configuration
|
2138
|
+
|
2139
|
+
:param str marginMode: 'cross' or 'isolated'
|
2140
|
+
:param str symbol: unified market symbol
|
2141
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2142
|
+
:param float [params.leverage]: the rate of leverage
|
2143
|
+
:returns dict: response from the exchange
|
2144
|
+
"""
|
2145
|
+
self.check_required_argument('setMarginMode', symbol, 'symbol')
|
2146
|
+
await self.authenticate_rest()
|
2147
|
+
await self.load_markets()
|
2148
|
+
market: Market = self.market(symbol)
|
2149
|
+
leverage: Str = None
|
2150
|
+
leverage, params = self.handle_option_and_params(params, 'setMarginMode', 'leverage', 1)
|
2151
|
+
request: dict = {
|
2152
|
+
'market': market['id'],
|
2153
|
+
'leverage': leverage,
|
2154
|
+
'margin_type': self.encode_margin_mode(marginMode),
|
2155
|
+
}
|
2156
|
+
return await self.privatePostAccountMarginMarket(self.extend(request, params))
|
2157
|
+
|
2158
|
+
async def fetch_leverage(self, symbol: str, params={}) -> Leverage:
|
2159
|
+
"""
|
2160
|
+
fetch the set leverage for a market
|
2161
|
+
|
2162
|
+
https://docs.api.testnet.paradex.trade/#get-account-margin-configuration
|
2163
|
+
|
2164
|
+
:param str symbol: unified market symbol
|
2165
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2166
|
+
:returns dict: a `leverage structure <https://docs.ccxt.com/#/?id=leverage-structure>`
|
2167
|
+
"""
|
2168
|
+
await self.authenticate_rest()
|
2169
|
+
await self.load_markets()
|
2170
|
+
market = self.market(symbol)
|
2171
|
+
request: dict = {
|
2172
|
+
'market': market['id'],
|
2173
|
+
}
|
2174
|
+
response = await self.privateGetAccountMargin(self.extend(request, params))
|
2175
|
+
#
|
2176
|
+
# {
|
2177
|
+
# "account": "0x6343248026a845b39a8a73fbe9c7ef0a841db31ed5c61ec1446aa9d25e54dbc",
|
2178
|
+
# "configs": [
|
2179
|
+
# {
|
2180
|
+
# "market": "SOL-USD-PERP",
|
2181
|
+
# "leverage": 50,
|
2182
|
+
# "margin_type": "CROSS"
|
2183
|
+
# }
|
2184
|
+
# ]
|
2185
|
+
# }
|
2186
|
+
#
|
2187
|
+
configs = self.safe_list(response, 'configs')
|
2188
|
+
return self.parse_leverage(self.safe_dict(configs, 0), market)
|
2189
|
+
|
2190
|
+
def parse_leverage(self, leverage: dict, market: Market = None) -> Leverage:
|
2191
|
+
marketId = self.safe_string(leverage, 'market')
|
2192
|
+
market = self.safe_market(marketId, market)
|
2193
|
+
marginMode = self.safe_string_lower(leverage, 'margin_type')
|
2194
|
+
return {
|
2195
|
+
'info': leverage,
|
2196
|
+
'symbol': self.safe_symbol(marketId, market),
|
2197
|
+
'marginMode': marginMode,
|
2198
|
+
'longLeverage': self.safe_integer(leverage, 'leverage'),
|
2199
|
+
'shortLeverage': self.safe_integer(leverage, 'leverage'),
|
2200
|
+
}
|
2201
|
+
|
2202
|
+
def encode_margin_mode(self, mode):
|
2203
|
+
modes = {
|
2204
|
+
'cross': 'CROSS',
|
2205
|
+
'isolated': 'ISOLATED',
|
2206
|
+
}
|
2207
|
+
return self.safe_string(modes, mode, mode)
|
2208
|
+
|
2209
|
+
async def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
|
2210
|
+
"""
|
2211
|
+
set the level of leverage for a market
|
2212
|
+
|
2213
|
+
https://docs.api.testnet.paradex.trade/#set-margin-configuration
|
2214
|
+
|
2215
|
+
:param float leverage: the rate of leverage
|
2216
|
+
:param str [symbol]: unified market symbol(is mandatory for swap markets)
|
2217
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2218
|
+
:param str [params.marginMode]: 'cross' or 'isolated'
|
2219
|
+
:returns dict: response from the exchange
|
2220
|
+
"""
|
2221
|
+
self.check_required_argument('setLeverage', symbol, 'symbol')
|
2222
|
+
await self.authenticate_rest()
|
2223
|
+
await self.load_markets()
|
2224
|
+
market: Market = self.market(symbol)
|
2225
|
+
marginMode: Str = None
|
2226
|
+
marginMode, params = self.handle_margin_mode_and_params('setLeverage', params, 'cross')
|
2227
|
+
request: dict = {
|
2228
|
+
'market': market['id'],
|
2229
|
+
'leverage': leverage,
|
2230
|
+
'margin_type': self.encode_margin_mode(marginMode),
|
2231
|
+
}
|
2232
|
+
return await self.privatePostAccountMarginMarket(self.extend(request, params))
|
2233
|
+
|
2066
2234
|
def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
|
2067
2235
|
url = self.implode_hostname(self.urls['api'][self.version]) + '/' + self.implode_params(path, params)
|
2068
2236
|
query = self.omit(params, self.extract_params(path))
|