ccxt 4.4.23__py2.py3-none-any.whl → 4.4.25__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/binance.py +1 -1
- ccxt/abstract/binancecoinm.py +1 -1
- ccxt/abstract/binanceus.py +1 -1
- ccxt/abstract/binanceusdm.py +1 -1
- ccxt/abstract/kucoin.py +1 -0
- ccxt/abstract/kucoinfutures.py +1 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +1 -1
- ccxt/async_support/bitmex.py +8 -7
- ccxt/async_support/bybit.py +37 -4
- ccxt/async_support/coincatch.py +1 -1
- ccxt/async_support/coinex.py +45 -21
- ccxt/async_support/gate.py +177 -59
- ccxt/async_support/hitbtc.py +5 -9
- ccxt/async_support/htx.py +16 -16
- ccxt/async_support/hyperliquid.py +1 -1
- ccxt/async_support/kucoin.py +15 -8
- ccxt/async_support/woofipro.py +1 -1
- ccxt/async_support/xt.py +4 -1
- ccxt/async_support/yobit.py +1 -1
- ccxt/base/exchange.py +5 -4
- ccxt/binance.py +1 -1
- ccxt/bitmex.py +8 -7
- ccxt/bybit.py +37 -4
- ccxt/coincatch.py +1 -1
- ccxt/coinex.py +45 -21
- ccxt/gate.py +177 -59
- ccxt/hitbtc.py +5 -9
- ccxt/htx.py +16 -16
- ccxt/hyperliquid.py +1 -1
- ccxt/kucoin.py +15 -8
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/kucoin.py +2 -1
- ccxt/pro/onetrading.py +2 -1
- ccxt/test/tests_async.py +14 -5
- ccxt/test/tests_sync.py +14 -5
- ccxt/woofipro.py +1 -1
- ccxt/xt.py +4 -1
- ccxt/yobit.py +1 -1
- ccxt-4.4.25.dist-info/METADATA +636 -0
- {ccxt-4.4.23.dist-info → ccxt-4.4.25.dist-info}/RECORD +46 -46
- ccxt-4.4.23.dist-info/METADATA +0 -636
- {ccxt-4.4.23.dist-info → ccxt-4.4.25.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.23.dist-info → ccxt-4.4.25.dist-info}/WHEEL +0 -0
- {ccxt-4.4.23.dist-info → ccxt-4.4.25.dist-info}/top_level.txt +0 -0
ccxt/async_support/htx.py
CHANGED
@@ -4905,15 +4905,15 @@ class htx(Exchange, ImplicitAPI):
|
|
4905
4905
|
orderType = type.replace('buy-', '')
|
4906
4906
|
orderType = orderType.replace('sell-', '')
|
4907
4907
|
options = self.safe_value(self.options, market['type'], {})
|
4908
|
-
|
4909
|
-
if
|
4908
|
+
triggerPrice = self.safe_string_n(params, ['triggerPrice', 'stopPrice', 'stop-price'])
|
4909
|
+
if triggerPrice is None:
|
4910
4910
|
stopOrderTypes = self.safe_value(options, 'stopOrderTypes', {})
|
4911
4911
|
if orderType in stopOrderTypes:
|
4912
|
-
raise ArgumentsRequired(self.id + ' createOrder() requires a
|
4912
|
+
raise ArgumentsRequired(self.id + ' createOrder() requires a triggerPrice for a stop order')
|
4913
4913
|
else:
|
4914
4914
|
defaultOperator = 'lte' if (side == 'sell') else 'gte'
|
4915
4915
|
stopOperator = self.safe_string(params, 'operator', defaultOperator)
|
4916
|
-
request['stop-price'] = self.price_to_precision(symbol,
|
4916
|
+
request['stop-price'] = self.price_to_precision(symbol, triggerPrice)
|
4917
4917
|
request['operator'] = stopOperator
|
4918
4918
|
if (orderType == 'limit') or (orderType == 'limit-fok'):
|
4919
4919
|
orderType = 'stop-' + orderType
|
@@ -4971,7 +4971,7 @@ class htx(Exchange, ImplicitAPI):
|
|
4971
4971
|
limitOrderTypes = self.safe_value(options, 'limitOrderTypes', {})
|
4972
4972
|
if orderType in limitOrderTypes:
|
4973
4973
|
request['price'] = self.price_to_precision(symbol, price)
|
4974
|
-
params = self.omit(params, ['stopPrice', 'stop-price', 'clientOrderId', 'client-order-id', 'operator', 'timeInForce'])
|
4974
|
+
params = self.omit(params, ['triggerPrice', 'stopPrice', 'stop-price', 'clientOrderId', 'client-order-id', 'operator', 'timeInForce'])
|
4975
4975
|
return self.extend(request, params)
|
4976
4976
|
|
4977
4977
|
def create_contract_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
@@ -5004,16 +5004,16 @@ class htx(Exchange, ImplicitAPI):
|
|
5004
5004
|
type = 'fok'
|
5005
5005
|
elif timeInForce == 'IOC':
|
5006
5006
|
type = 'ioc'
|
5007
|
-
triggerPrice = self.
|
5007
|
+
triggerPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'trigger_price'])
|
5008
5008
|
stopLossTriggerPrice = self.safe_number_2(params, 'stopLossPrice', 'sl_trigger_price')
|
5009
5009
|
takeProfitTriggerPrice = self.safe_number_2(params, 'takeProfitPrice', 'tp_trigger_price')
|
5010
5010
|
trailingPercent = self.safe_string_2(params, 'trailingPercent', 'callback_rate')
|
5011
5011
|
trailingTriggerPrice = self.safe_number(params, 'trailingTriggerPrice', price)
|
5012
5012
|
isTrailingPercentOrder = trailingPercent is not None
|
5013
|
-
|
5013
|
+
isTrigger = triggerPrice is not None
|
5014
5014
|
isStopLossTriggerOrder = stopLossTriggerPrice is not None
|
5015
5015
|
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
5016
|
-
if
|
5016
|
+
if isTrigger:
|
5017
5017
|
triggerType = self.safe_string_2(params, 'triggerType', 'trigger_type', 'le')
|
5018
5018
|
request['trigger_type'] = triggerType
|
5019
5019
|
request['trigger_price'] = self.price_to_precision(symbol, triggerPrice)
|
@@ -5052,7 +5052,7 @@ class htx(Exchange, ImplicitAPI):
|
|
5052
5052
|
broker = self.safe_value(self.options, 'broker', {})
|
5053
5053
|
brokerId = self.safe_string(broker, 'id')
|
5054
5054
|
request['channel_code'] = brokerId
|
5055
|
-
params = self.omit(params, ['reduceOnly', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerType', 'leverRate', 'timeInForce', 'leverage', 'trailingPercent', 'trailingTriggerPrice'])
|
5055
|
+
params = self.omit(params, ['reduceOnly', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerType', 'leverRate', 'timeInForce', 'leverage', 'trailingPercent', 'trailingTriggerPrice'])
|
5056
5056
|
return self.extend(request, params)
|
5057
5057
|
|
5058
5058
|
async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
@@ -5073,7 +5073,7 @@ class htx(Exchange, ImplicitAPI):
|
|
5073
5073
|
:param float amount: how much you want to trade in units of the base currency
|
5074
5074
|
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
5075
5075
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
5076
|
-
:param float [params.
|
5076
|
+
:param float [params.triggerPrice]: the price a trigger order is triggered at
|
5077
5077
|
:param str [params.triggerType]: *contract trigger orders only* ge: greater than or equal to, le: less than or equal to
|
5078
5078
|
:param float [params.stopLossPrice]: *contract only* the price a stop-loss order is triggered at
|
5079
5079
|
:param float [params.takeProfitPrice]: *contract only* the price a take-profit order is triggered at
|
@@ -5089,12 +5089,12 @@ class htx(Exchange, ImplicitAPI):
|
|
5089
5089
|
"""
|
5090
5090
|
await self.load_markets()
|
5091
5091
|
market = self.market(symbol)
|
5092
|
-
triggerPrice = self.
|
5092
|
+
triggerPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'trigger_price'])
|
5093
5093
|
stopLossTriggerPrice = self.safe_number_2(params, 'stopLossPrice', 'sl_trigger_price')
|
5094
5094
|
takeProfitTriggerPrice = self.safe_number_2(params, 'takeProfitPrice', 'tp_trigger_price')
|
5095
5095
|
trailingPercent = self.safe_number(params, 'trailingPercent')
|
5096
5096
|
isTrailingPercentOrder = trailingPercent is not None
|
5097
|
-
|
5097
|
+
isTrigger = triggerPrice is not None
|
5098
5098
|
isStopLossTriggerOrder = stopLossTriggerPrice is not None
|
5099
5099
|
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
5100
5100
|
response = None
|
@@ -5110,7 +5110,7 @@ class htx(Exchange, ImplicitAPI):
|
|
5110
5110
|
marginMode, contractRequest = self.handle_margin_mode_and_params('createOrder', contractRequest)
|
5111
5111
|
marginMode = 'cross' if (marginMode is None) else marginMode
|
5112
5112
|
if marginMode == 'isolated':
|
5113
|
-
if
|
5113
|
+
if isTrigger:
|
5114
5114
|
response = await self.contractPrivatePostLinearSwapApiV1SwapTriggerOrder(contractRequest)
|
5115
5115
|
elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
|
5116
5116
|
response = await self.contractPrivatePostLinearSwapApiV1SwapTpslOrder(contractRequest)
|
@@ -5119,7 +5119,7 @@ class htx(Exchange, ImplicitAPI):
|
|
5119
5119
|
else:
|
5120
5120
|
response = await self.contractPrivatePostLinearSwapApiV1SwapOrder(contractRequest)
|
5121
5121
|
elif marginMode == 'cross':
|
5122
|
-
if
|
5122
|
+
if isTrigger:
|
5123
5123
|
response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerOrder(contractRequest)
|
5124
5124
|
elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
|
5125
5125
|
response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTpslOrder(contractRequest)
|
@@ -5132,7 +5132,7 @@ class htx(Exchange, ImplicitAPI):
|
|
5132
5132
|
if offset is None:
|
5133
5133
|
raise ArgumentsRequired(self.id + ' createOrder() requires an extra parameter params["offset"] to be set to "open" or "close" when placing orders in inverse markets')
|
5134
5134
|
if market['swap']:
|
5135
|
-
if
|
5135
|
+
if isTrigger:
|
5136
5136
|
response = await self.contractPrivatePostSwapApiV1SwapTriggerOrder(contractRequest)
|
5137
5137
|
elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
|
5138
5138
|
response = await self.contractPrivatePostSwapApiV1SwapTpslOrder(contractRequest)
|
@@ -5141,7 +5141,7 @@ class htx(Exchange, ImplicitAPI):
|
|
5141
5141
|
else:
|
5142
5142
|
response = await self.contractPrivatePostSwapApiV1SwapOrder(contractRequest)
|
5143
5143
|
elif market['future']:
|
5144
|
-
if
|
5144
|
+
if isTrigger:
|
5145
5145
|
response = await self.contractPrivatePostApiV1ContractTriggerOrder(contractRequest)
|
5146
5146
|
elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
|
5147
5147
|
response = await self.contractPrivatePostApiV1ContractTpslOrder(contractRequest)
|
@@ -2139,7 +2139,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2139
2139
|
'notional': self.safe_number(entry, 'positionValue'),
|
2140
2140
|
'leverage': self.safe_number(leverage, 'value'),
|
2141
2141
|
'collateral': self.safe_number(entry, 'marginUsed'),
|
2142
|
-
'initialMargin': initialMargin,
|
2142
|
+
'initialMargin': self.parse_number(initialMargin),
|
2143
2143
|
'maintenanceMargin': None,
|
2144
2144
|
'initialMarginPercentage': None,
|
2145
2145
|
'maintenanceMarginPercentage': None,
|
ccxt/async_support/kucoin.py
CHANGED
@@ -223,6 +223,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
223
223
|
'market/orderbook/level{level}': 3, # 3SW
|
224
224
|
'market/orderbook/level2': 3, # 3SW
|
225
225
|
'market/orderbook/level3': 3, # 3SW
|
226
|
+
'hf/accounts/opened': 2, #
|
226
227
|
'hf/orders/active': 2, # 2SW
|
227
228
|
'hf/orders/active/symbols': 2, # 2SW
|
228
229
|
'hf/margin/order/active/symbols': 2, # 2SW
|
@@ -652,7 +653,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
652
653
|
'FUD': 'FTX Users\' Debt',
|
653
654
|
},
|
654
655
|
'options': {
|
655
|
-
'hf':
|
656
|
+
'hf': None, # would be auto set to `true/false` after first load
|
656
657
|
'version': 'v1',
|
657
658
|
'symbolSeparator': '-',
|
658
659
|
'fetchMyTradesMethod': 'private_get_fills',
|
@@ -1084,7 +1085,8 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1084
1085
|
# "enableTrading": True
|
1085
1086
|
# },
|
1086
1087
|
#
|
1087
|
-
|
1088
|
+
credentialsSet = self.check_required_credentials(False)
|
1089
|
+
requestMarginables = credentialsSet and self.safe_bool(params, 'marginables', True)
|
1088
1090
|
if requestMarginables:
|
1089
1091
|
promises.append(self.privateGetMarginSymbols(params)) # cross margin symbols
|
1090
1092
|
#
|
@@ -1147,6 +1149,9 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1147
1149
|
# "makerCoefficient": "1" # Maker Fee Coefficient
|
1148
1150
|
# }
|
1149
1151
|
#
|
1152
|
+
if credentialsSet:
|
1153
|
+
# load migration status for account
|
1154
|
+
promises.append(self.load_migration_status())
|
1150
1155
|
responses = await asyncio.gather(*promises)
|
1151
1156
|
symbolsData = self.safe_list(responses[0], 'data')
|
1152
1157
|
crossData = self.safe_dict(responses[1], 'data', {}) if requestMarginables else {}
|
@@ -1233,14 +1238,16 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1233
1238
|
return result
|
1234
1239
|
|
1235
1240
|
async def load_migration_status(self, force: bool = False):
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1241
|
+
"""
|
1242
|
+
loads the migration status for the account(hf or not)
|
1243
|
+
:see: https://www.kucoin.com/docs/rest/spot-trading/spot-hf-trade-pro-account/get-user-type
|
1244
|
+
"""
|
1245
|
+
if not ('hf' in self.options) or (self.options['hf'] is None) or force:
|
1246
|
+
result: dict = await self.privateGetHfAccountsOpened()
|
1247
|
+
self.options['hf'] = self.safe_bool(result, 'data')
|
1241
1248
|
|
1242
1249
|
def handle_hf_and_params(self, params={}):
|
1243
|
-
migrated: Bool = self.
|
1250
|
+
migrated: Bool = self.safe_bool(self.options, 'hf', False)
|
1244
1251
|
loadedHf: Bool = None
|
1245
1252
|
if migrated is not None:
|
1246
1253
|
if migrated:
|
ccxt/async_support/woofipro.py
CHANGED
@@ -133,7 +133,7 @@ class woofipro(Exchange, ImplicitAPI):
|
|
133
133
|
'1y': '1y',
|
134
134
|
},
|
135
135
|
'urls': {
|
136
|
-
'logo': 'https://github.com/
|
136
|
+
'logo': 'https://github.com/user-attachments/assets/9ba21b8a-a9c7-4770-b7f1-ce3bcbde68c1',
|
137
137
|
'api': {
|
138
138
|
'public': 'https://api-evm.orderly.org',
|
139
139
|
'private': 'https://api-evm.orderly.org',
|
ccxt/async_support/xt.py
CHANGED
@@ -1699,6 +1699,9 @@ class xt(Exchange, ImplicitAPI):
|
|
1699
1699
|
market = self.safe_market(marketId, market, '_', marketType)
|
1700
1700
|
symbol = market['symbol']
|
1701
1701
|
timestamp = self.safe_integer(ticker, 't')
|
1702
|
+
percentage = self.safe_string_2(ticker, 'cr', 'r')
|
1703
|
+
if percentage is not None:
|
1704
|
+
percentage = Precise.string_mul(percentage, '100')
|
1702
1705
|
return self.safe_ticker({
|
1703
1706
|
'symbol': symbol,
|
1704
1707
|
'timestamp': timestamp,
|
@@ -1715,7 +1718,7 @@ class xt(Exchange, ImplicitAPI):
|
|
1715
1718
|
'last': self.safe_string(ticker, 'c'),
|
1716
1719
|
'previousClose': None,
|
1717
1720
|
'change': self.safe_number(ticker, 'cv'),
|
1718
|
-
'percentage': self.
|
1721
|
+
'percentage': self.parse_number(percentage),
|
1719
1722
|
'average': None,
|
1720
1723
|
'baseVolume': None,
|
1721
1724
|
'quoteVolume': self.safe_number_2(ticker, 'a', 'v'),
|
ccxt/async_support/yobit.py
CHANGED
@@ -1125,7 +1125,7 @@ class yobit(Exchange, ImplicitAPI):
|
|
1125
1125
|
ids = list(trades.keys())
|
1126
1126
|
result = []
|
1127
1127
|
for i in range(0, len(ids)):
|
1128
|
-
id = ids
|
1128
|
+
id = self.safe_string(ids, i)
|
1129
1129
|
trade = self.parse_trade(self.extend(trades[id], {
|
1130
1130
|
'trade_id': id,
|
1131
1131
|
}), market)
|
ccxt/base/exchange.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
|
7
|
-
__version__ = '4.4.
|
7
|
+
__version__ = '4.4.25'
|
8
8
|
|
9
9
|
# -----------------------------------------------------------------------------
|
10
10
|
|
@@ -3001,9 +3001,10 @@ class Exchange(object):
|
|
3001
3001
|
isTriggerOrSLTpOrder = ((self.safe_string(order, 'triggerPrice') is not None or (self.safe_string(order, 'stopLossPrice') is not None)) or (self.safe_string(order, 'takeProfitPrice') is not None))
|
3002
3002
|
if parseFilled or parseCost or shouldParseFees:
|
3003
3003
|
rawTrades = self.safe_value(order, 'trades', trades)
|
3004
|
-
oldNumber = self.number
|
3004
|
+
# oldNumber = self.number
|
3005
3005
|
# we parse trades here!
|
3006
|
-
self
|
3006
|
+
# i don't think self is needed anymore
|
3007
|
+
# self.number = str
|
3007
3008
|
firstTrade = self.safe_value(rawTrades, 0)
|
3008
3009
|
# parse trades if they haven't already been parsed
|
3009
3010
|
tradesAreParsed = ((firstTrade is not None) and ('info' in firstTrade) and ('id' in firstTrade))
|
@@ -3011,7 +3012,7 @@ class Exchange(object):
|
|
3011
3012
|
trades = self.parse_trades(rawTrades, market)
|
3012
3013
|
else:
|
3013
3014
|
trades = rawTrades
|
3014
|
-
self.number = oldNumber
|
3015
|
+
# self.number = oldNumber; why parse trades if you read the value using `safeString` ?
|
3015
3016
|
tradesLength = 0
|
3016
3017
|
isArray = isinstance(trades, list)
|
3017
3018
|
if isArray:
|
ccxt/binance.py
CHANGED
@@ -1117,7 +1117,7 @@ class binance(Exchange, ImplicitAPI):
|
|
1117
1117
|
'cm/adlQuantile': 5,
|
1118
1118
|
'um/trade/asyn': 300,
|
1119
1119
|
'um/trade/asyn/id': 2,
|
1120
|
-
'um/order/asyn
|
1120
|
+
'um/order/asyn': 300,
|
1121
1121
|
'um/order/asyn/id': 2,
|
1122
1122
|
'um/income/asyn': 300,
|
1123
1123
|
'um/income/asyn/id': 2,
|
ccxt/bitmex.py
CHANGED
@@ -1108,17 +1108,18 @@ class bitmex(Exchange, ImplicitAPI):
|
|
1108
1108
|
# set the timestamp to zero, 1970 Jan 1 00:00:00
|
1109
1109
|
# for unrealized pnl and other transactions without a timestamp
|
1110
1110
|
timestamp = 0 # see comments above
|
1111
|
+
fee = None
|
1111
1112
|
feeCost = self.safe_string(item, 'fee')
|
1112
1113
|
if feeCost is not None:
|
1113
1114
|
feeCost = self.convert_to_real_amount(code, feeCost)
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1115
|
+
fee = {
|
1116
|
+
'cost': self.parse_number(feeCost),
|
1117
|
+
'currency': code,
|
1118
|
+
}
|
1118
1119
|
after = self.safe_string(item, 'walletBalance')
|
1119
1120
|
if after is not None:
|
1120
1121
|
after = self.convert_to_real_amount(code, after)
|
1121
|
-
before = self.
|
1122
|
+
before = self.parse_number(Precise.string_sub(self.number_to_string(after), self.number_to_string(amount)))
|
1122
1123
|
direction = None
|
1123
1124
|
if Precise.string_lt(amountString, '0'):
|
1124
1125
|
direction = 'out'
|
@@ -1137,9 +1138,9 @@ class bitmex(Exchange, ImplicitAPI):
|
|
1137
1138
|
'referenceAccount': referenceAccount,
|
1138
1139
|
'type': type,
|
1139
1140
|
'currency': code,
|
1140
|
-
'amount': self.
|
1141
|
+
'amount': self.parse_number(amount),
|
1141
1142
|
'before': before,
|
1142
|
-
'after': self.
|
1143
|
+
'after': self.parse_number(after),
|
1143
1144
|
'status': status,
|
1144
1145
|
'fee': fee,
|
1145
1146
|
}, currency)
|
ccxt/bybit.py
CHANGED
@@ -1026,6 +1026,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
1026
1026
|
},
|
1027
1027
|
'enableUnifiedMargin': None,
|
1028
1028
|
'enableUnifiedAccount': None,
|
1029
|
+
'unifiedMarginStatus': None,
|
1029
1030
|
'createMarketBuyOrderRequiresPrice': True, # only True for classic accounts
|
1030
1031
|
'createUnifiedMarginAccount': False,
|
1031
1032
|
'defaultType': 'swap', # 'swap', 'future', 'option', 'spot'
|
@@ -1145,6 +1146,8 @@ class bybit(Exchange, ImplicitAPI):
|
|
1145
1146
|
|
1146
1147
|
def is_unified_enabled(self, params={}):
|
1147
1148
|
"""
|
1149
|
+
:see: https://bybit-exchange.github.io/docs/v5/user/apikey-info#http-request
|
1150
|
+
:see: https://bybit-exchange.github.io/docs/v5/account/account-info
|
1148
1151
|
returns [enableUnifiedMargin, enableUnifiedAccount] so the user can check if unified account is enabled
|
1149
1152
|
"""
|
1150
1153
|
# The API key of user id must own one of permissions will be allowed to call following API endpoints.
|
@@ -1158,8 +1161,12 @@ class bybit(Exchange, ImplicitAPI):
|
|
1158
1161
|
# so we're assuming UTA is enabled
|
1159
1162
|
self.options['enableUnifiedMargin'] = False
|
1160
1163
|
self.options['enableUnifiedAccount'] = True
|
1164
|
+
self.options['unifiedMarginStatus'] = 3
|
1161
1165
|
return [self.options['enableUnifiedMargin'], self.options['enableUnifiedAccount']]
|
1162
|
-
|
1166
|
+
rawPromises = [self.privateGetV5UserQueryApi(params), self.privateGetV5AccountInfo(params)]
|
1167
|
+
promises = rawPromises
|
1168
|
+
response = promises[0]
|
1169
|
+
accountInfo = promises[1]
|
1163
1170
|
#
|
1164
1171
|
# {
|
1165
1172
|
# "retCode": 0,
|
@@ -1199,13 +1206,34 @@ class bybit(Exchange, ImplicitAPI):
|
|
1199
1206
|
# "retExtInfo": {},
|
1200
1207
|
# "time": 1676891757649
|
1201
1208
|
# }
|
1209
|
+
# account info
|
1210
|
+
# {
|
1211
|
+
# "retCode": 0,
|
1212
|
+
# "retMsg": "OK",
|
1213
|
+
# "result": {
|
1214
|
+
# "marginMode": "REGULAR_MARGIN",
|
1215
|
+
# "updatedTime": "1697078946000",
|
1216
|
+
# "unifiedMarginStatus": 4,
|
1217
|
+
# "dcpStatus": "OFF",
|
1218
|
+
# "timeWindow": 10,
|
1219
|
+
# "smpGroup": 0,
|
1220
|
+
# "isMasterTrader": False,
|
1221
|
+
# "spotHedgingStatus": "OFF"
|
1222
|
+
# }
|
1223
|
+
# }
|
1202
1224
|
#
|
1203
1225
|
result = self.safe_dict(response, 'result', {})
|
1226
|
+
accountResult = self.safe_dict(accountInfo, 'result', {})
|
1204
1227
|
self.options['enableUnifiedMargin'] = self.safe_integer(result, 'unified') == 1
|
1205
1228
|
self.options['enableUnifiedAccount'] = self.safe_integer(result, 'uta') == 1
|
1229
|
+
self.options['unifiedMarginStatus'] = self.safe_integer(accountResult, 'unifiedMarginStatus', 3) # default to uta.1 if not found
|
1206
1230
|
return [self.options['enableUnifiedMargin'], self.options['enableUnifiedAccount']]
|
1207
1231
|
|
1208
1232
|
def upgrade_unified_trade_account(self, params={}):
|
1233
|
+
"""
|
1234
|
+
:see: https://bybit-exchange.github.io/docs/v5/account/upgrade-unified-account
|
1235
|
+
upgrades the account to unified trade account *warning* self is irreversible
|
1236
|
+
"""
|
1209
1237
|
return self.privatePostV5AccountUpgradeToUta(params)
|
1210
1238
|
|
1211
1239
|
def create_expired_option_market(self, symbol: str):
|
@@ -3018,10 +3046,15 @@ class bybit(Exchange, ImplicitAPI):
|
|
3018
3046
|
isInverse = (type == 'inverse')
|
3019
3047
|
isFunding = (lowercaseRawType == 'fund') or (lowercaseRawType == 'funding')
|
3020
3048
|
if isUnifiedAccount:
|
3021
|
-
|
3022
|
-
|
3049
|
+
unifiedMarginStatus = self.safe_integer(self.options, 'unifiedMarginStatus', 3)
|
3050
|
+
if unifiedMarginStatus < 5:
|
3051
|
+
# it's not uta.20 where inverse are unified
|
3052
|
+
if isInverse:
|
3053
|
+
type = 'contract'
|
3054
|
+
else:
|
3055
|
+
type = 'unified'
|
3023
3056
|
else:
|
3024
|
-
type = 'unified'
|
3057
|
+
type = 'unified' # uta.20 where inverse are unified
|
3025
3058
|
else:
|
3026
3059
|
if isLinear or isInverse:
|
3027
3060
|
type = 'contract'
|
ccxt/coincatch.py
CHANGED
@@ -154,7 +154,7 @@ class coincatch(Exchange, ImplicitAPI):
|
|
154
154
|
'1M': '1M',
|
155
155
|
},
|
156
156
|
'urls': {
|
157
|
-
'logo': 'https://
|
157
|
+
'logo': 'https://github.com/user-attachments/assets/3d49065f-f05d-4573-88a2-1b5201ec6ff3',
|
158
158
|
'api': {
|
159
159
|
'public': 'https://api.coincatch.com',
|
160
160
|
'private': 'https://api.coincatch.com',
|
ccxt/coinex.py
CHANGED
@@ -473,9 +473,43 @@ class coinex(Exchange, ImplicitAPI):
|
|
473
473
|
'FUTURES': 'swap',
|
474
474
|
},
|
475
475
|
'networks': {
|
476
|
+
'BTC': 'BTC',
|
476
477
|
'BEP20': 'BSC',
|
477
|
-
'
|
478
|
-
'
|
478
|
+
'TRC20': 'TRC20',
|
479
|
+
'ERC20': 'ERC20',
|
480
|
+
'BRC20': 'BRC20',
|
481
|
+
'SOL': 'SOL',
|
482
|
+
'TON': 'SOL',
|
483
|
+
'BSV': 'BSV',
|
484
|
+
'AVAXC': 'AVA_C',
|
485
|
+
'AVAXX': 'AVA',
|
486
|
+
'SUI': 'SUI',
|
487
|
+
'ACA': 'ACA',
|
488
|
+
'CHZ': 'CHILIZ',
|
489
|
+
'ADA': 'ADA',
|
490
|
+
'ARB': 'ARBITRUM',
|
491
|
+
'ARBNOVA': 'ARBITRUM_NOVA',
|
492
|
+
'OP': 'OPTIMISM',
|
493
|
+
'APT': 'APTOS',
|
494
|
+
'ATOM': 'ATOM',
|
495
|
+
'FTM': 'FTM',
|
496
|
+
'BCH': 'BCH',
|
497
|
+
'ASTR': 'ASTR',
|
498
|
+
'LTC': 'LTC',
|
499
|
+
'MATIC': 'MATIC',
|
500
|
+
'CRONOS': 'CRONOS',
|
501
|
+
'DASH': 'DASH',
|
502
|
+
'DOT': 'DOT',
|
503
|
+
'ETC': 'ETC',
|
504
|
+
'ETHW': 'ETHPOW',
|
505
|
+
'FIL': 'FIL',
|
506
|
+
'ZIL': 'ZIL',
|
507
|
+
'DOGE': 'DOGE',
|
508
|
+
'TIA': 'CELESTIA',
|
509
|
+
'SEI': 'SEI',
|
510
|
+
'XRP': 'XRP',
|
511
|
+
'XMR': 'XMR',
|
512
|
+
# CSC, AE, BASE, AIPG, AKASH, POLKADOTASSETHUB ?, ALEO, STX, ALGO, ALPH, BLAST, AR, ARCH, ARDR, ARK, ARRR, MANTA, NTRN, LUNA, AURORA, AVAIL, ASC20, AVA, AYA, AZERO, BAN, BAND, BB, RUNES, BEAM, BELLSCOIN, BITCI, NEAR, AGORIC, BLOCX, BNC, BOBA, BRISE, KRC20, CANTO, CAPS, CCD, CELO, CFX, CHI, CKB, CLORE, CLV, CORE, CSPR, CTXC, DAG, DCR, DERO, DESO, DEFI, DGB, DNX, DOCK, DOGECHAIN, DYDX, DYMENSION, EGLD, ELA, ELF, ENJIN, EOSIO, ERG, ETN_SC, EVMOS, EWC, SGB, FACT, FB, FET, FIO, FIRO, NEO3, FLOW, FLARE, FLUX, LINEA, FREN, FSN, FB_BRC20, GLMR, GRIN, GRS, HACASH, HBAR, HERB, HIVE, MAPO, HMND, HNS, ZKSYNC, HTR, HUAHUA, MERLIN, ICP, ICX, INJ, IOST, IOTA, IOTX, IRIS, IRON, ONE, JOYSTREAM, KAI, KAR, KAS, KAVA, KCN, KDA, KLAY, KLY, KMD, KSM, KUB, KUJIRA, LAT, LBC, LUNC, LUKSO, MARS, METIS, MINA, MANTLE, MOB, MODE, MONA, MOVR, MTL, NEOX, NEXA, NIBI, NIMIQ, NMC, ONOMY, NRG, WAVES, NULS, OAS, OCTA, OLT, ONT, OORT, ORAI, OSMO, P3D, COMPOSABLE, PIVX, RON, POKT, POLYMESH, PRE_MARKET, PYI, QKC, QTUM, QUBIC, RSK, ROSE, ROUTE, RTM, THORCHAIN, RVN, RADIANT, SAGA, SALVIUM, SATOX, SC, SCP, _NULL, SCRT, SDN, RGBPP, SELF, SMH, SPACE, STARGAZE, STC, STEEM, STRATISEVM, STRD, STARKNET, SXP, SYS, TAIKO, TAO, TARA, TENET, THETA, TT, VENOM, VECHAIN, TOMO, VITE, VLX, VSYS, VTC, WAN, WAXP, WEMIX, XCH, XDC, XEC, XELIS, NEM, XHV, XLM, XNA, NANO, XPLA, XPR, XPRT, XRD, XTZ, XVG, XYM, ZANO, ZEC, ZEN, ZEPH, ZETA
|
479
513
|
},
|
480
514
|
},
|
481
515
|
'commonCurrencies': {
|
@@ -3546,20 +3580,14 @@ class coinex(Exchange, ImplicitAPI):
|
|
3546
3580
|
"""
|
3547
3581
|
self.load_markets()
|
3548
3582
|
currency = self.currency(code)
|
3549
|
-
networks = self.safe_dict(currency, 'networks', {})
|
3550
|
-
network = self.safe_string_2(params, 'network', 'chain')
|
3551
|
-
params = self.omit(params, 'network')
|
3552
|
-
networksKeys = list(networks.keys())
|
3553
|
-
numOfNetworks = len(networksKeys)
|
3554
|
-
if networks is not None and numOfNetworks > 1:
|
3555
|
-
if network is None:
|
3556
|
-
raise ArgumentsRequired(self.id + ' fetchDepositAddress() ' + code + ' requires a network parameter')
|
3557
|
-
if not (network in networks):
|
3558
|
-
raise ExchangeError(self.id + ' fetchDepositAddress() ' + network + ' network not supported for ' + code)
|
3559
3583
|
request: dict = {
|
3560
3584
|
'ccy': currency['id'],
|
3561
|
-
'chain': network,
|
3562
3585
|
}
|
3586
|
+
networkCode = None
|
3587
|
+
networkCode, params = self.handle_network_code_and_params(params)
|
3588
|
+
if networkCode is None:
|
3589
|
+
raise ArgumentsRequired(self.id + ' fetchDepositAddress() requires a "network" parameter')
|
3590
|
+
request['chain'] = self.network_code_to_id(networkCode) # required for on-chain, not required for inter-user transfer
|
3563
3591
|
response = self.v2PrivateGetAssetsDepositAddress(self.extend(request, params))
|
3564
3592
|
#
|
3565
3593
|
# {
|
@@ -3572,12 +3600,7 @@ class coinex(Exchange, ImplicitAPI):
|
|
3572
3600
|
# }
|
3573
3601
|
#
|
3574
3602
|
data = self.safe_dict(response, 'data', {})
|
3575
|
-
|
3576
|
-
options = self.safe_dict(self.options, 'fetchDepositAddress', {})
|
3577
|
-
fillResponseFromRequest = self.safe_bool(options, 'fillResponseFromRequest', True)
|
3578
|
-
if fillResponseFromRequest:
|
3579
|
-
depositAddress['network'] = self.network_id_to_code(network, currency).upper()
|
3580
|
-
return depositAddress
|
3603
|
+
return self.parse_deposit_address(data, currency)
|
3581
3604
|
|
3582
3605
|
def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
|
3583
3606
|
#
|
@@ -4417,8 +4440,6 @@ class coinex(Exchange, ImplicitAPI):
|
|
4417
4440
|
self.check_address(address)
|
4418
4441
|
self.load_markets()
|
4419
4442
|
currency = self.currency(code)
|
4420
|
-
networkCode = self.safe_string_upper_2(params, 'network', 'chain')
|
4421
|
-
params = self.omit(params, 'network')
|
4422
4443
|
if tag:
|
4423
4444
|
address = address + ':' + tag
|
4424
4445
|
request: dict = {
|
@@ -4426,6 +4447,8 @@ class coinex(Exchange, ImplicitAPI):
|
|
4426
4447
|
'to_address': address, # must be authorized, inter-user transfer by a registered mobile phone number or an email address is supported
|
4427
4448
|
'amount': self.number_to_string(amount), # the actual amount without fees, https://www.coinex.com/fees
|
4428
4449
|
}
|
4450
|
+
networkCode = None
|
4451
|
+
networkCode, params = self.handle_network_code_and_params(params)
|
4429
4452
|
if networkCode is not None:
|
4430
4453
|
request['chain'] = self.network_code_to_id(networkCode) # required for on-chain, not required for inter-user transfer
|
4431
4454
|
response = self.v2PrivatePostAssetsWithdraw(self.extend(request, params))
|
@@ -4462,6 +4485,7 @@ class coinex(Exchange, ImplicitAPI):
|
|
4462
4485
|
statuses: dict = {
|
4463
4486
|
'audit': 'pending',
|
4464
4487
|
'pass': 'pending',
|
4488
|
+
'audit_required': 'pending',
|
4465
4489
|
'processing': 'pending',
|
4466
4490
|
'confirming': 'pending',
|
4467
4491
|
'not_pass': 'failed',
|