ccxt 4.4.7__py2.py3-none-any.whl → 4.4.8__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 -0
- ccxt/abstract/binancecoinm.py +1 -0
- ccxt/abstract/binanceus.py +1 -0
- ccxt/abstract/binanceusdm.py +1 -0
- ccxt/abstract/bybit.py +5 -0
- ccxt/abstract/okx.py +2 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +49 -12
- ccxt/async_support/bybit.py +350 -1
- ccxt/async_support/htx.py +20 -0
- ccxt/async_support/okx.py +4 -0
- ccxt/base/exchange.py +1 -1
- ccxt/binance.py +49 -12
- ccxt/bybit.py +350 -1
- ccxt/htx.py +20 -0
- ccxt/okx.py +4 -0
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitmart.py +72 -0
- ccxt/pro/bitvavo.py +87 -2
- ccxt/pro/blofin.py +59 -0
- {ccxt-4.4.7.dist-info → ccxt-4.4.8.dist-info}/METADATA +4 -4
- {ccxt-4.4.7.dist-info → ccxt-4.4.8.dist-info}/RECORD +27 -27
- {ccxt-4.4.7.dist-info → ccxt-4.4.8.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.7.dist-info → ccxt-4.4.8.dist-info}/WHEEL +0 -0
- {ccxt-4.4.7.dist-info → ccxt-4.4.8.dist-info}/top_level.txt +0 -0
ccxt/__init__.py
CHANGED
ccxt/abstract/binance.py
CHANGED
@@ -702,6 +702,7 @@ class ImplicitAPI:
|
|
702
702
|
papi_post_repay_futures_negative_balance = papiPostRepayFuturesNegativeBalance = Entry('repay-futures-negative-balance', 'papi', 'POST', {'cost': 150})
|
703
703
|
papi_post_listenkey = papiPostListenKey = Entry('listenKey', 'papi', 'POST', {'cost': 1})
|
704
704
|
papi_post_asset_collection = papiPostAssetCollection = Entry('asset-collection', 'papi', 'POST', {'cost': 3})
|
705
|
+
papi_post_margin_repay_debt = papiPostMarginRepayDebt = Entry('margin/repay-debt', 'papi', 'POST', {'cost': 0.4})
|
705
706
|
papi_put_listenkey = papiPutListenKey = Entry('listenKey', 'papi', 'PUT', {'cost': 1})
|
706
707
|
papi_delete_um_order = papiDeleteUmOrder = Entry('um/order', 'papi', 'DELETE', {'cost': 1})
|
707
708
|
papi_delete_um_conditional_order = papiDeleteUmConditionalOrder = Entry('um/conditional/order', 'papi', 'DELETE', {'cost': 1})
|
ccxt/abstract/binancecoinm.py
CHANGED
@@ -702,6 +702,7 @@ class ImplicitAPI:
|
|
702
702
|
papi_post_repay_futures_negative_balance = papiPostRepayFuturesNegativeBalance = Entry('repay-futures-negative-balance', 'papi', 'POST', {'cost': 150})
|
703
703
|
papi_post_listenkey = papiPostListenKey = Entry('listenKey', 'papi', 'POST', {'cost': 1})
|
704
704
|
papi_post_asset_collection = papiPostAssetCollection = Entry('asset-collection', 'papi', 'POST', {'cost': 3})
|
705
|
+
papi_post_margin_repay_debt = papiPostMarginRepayDebt = Entry('margin/repay-debt', 'papi', 'POST', {'cost': 0.4})
|
705
706
|
papi_put_listenkey = papiPutListenKey = Entry('listenKey', 'papi', 'PUT', {'cost': 1})
|
706
707
|
papi_delete_um_order = papiDeleteUmOrder = Entry('um/order', 'papi', 'DELETE', {'cost': 1})
|
707
708
|
papi_delete_um_conditional_order = papiDeleteUmConditionalOrder = Entry('um/conditional/order', 'papi', 'DELETE', {'cost': 1})
|
ccxt/abstract/binanceus.py
CHANGED
@@ -754,6 +754,7 @@ class ImplicitAPI:
|
|
754
754
|
papi_post_repay_futures_negative_balance = papiPostRepayFuturesNegativeBalance = Entry('repay-futures-negative-balance', 'papi', 'POST', {'cost': 150})
|
755
755
|
papi_post_listenkey = papiPostListenKey = Entry('listenKey', 'papi', 'POST', {'cost': 1})
|
756
756
|
papi_post_asset_collection = papiPostAssetCollection = Entry('asset-collection', 'papi', 'POST', {'cost': 3})
|
757
|
+
papi_post_margin_repay_debt = papiPostMarginRepayDebt = Entry('margin/repay-debt', 'papi', 'POST', {'cost': 0.4})
|
757
758
|
papi_put_listenkey = papiPutListenKey = Entry('listenKey', 'papi', 'PUT', {'cost': 1})
|
758
759
|
papi_delete_um_order = papiDeleteUmOrder = Entry('um/order', 'papi', 'DELETE', {'cost': 1})
|
759
760
|
papi_delete_um_conditional_order = papiDeleteUmConditionalOrder = Entry('um/conditional/order', 'papi', 'DELETE', {'cost': 1})
|
ccxt/abstract/binanceusdm.py
CHANGED
@@ -702,6 +702,7 @@ class ImplicitAPI:
|
|
702
702
|
papi_post_repay_futures_negative_balance = papiPostRepayFuturesNegativeBalance = Entry('repay-futures-negative-balance', 'papi', 'POST', {'cost': 150})
|
703
703
|
papi_post_listenkey = papiPostListenKey = Entry('listenKey', 'papi', 'POST', {'cost': 1})
|
704
704
|
papi_post_asset_collection = papiPostAssetCollection = Entry('asset-collection', 'papi', 'POST', {'cost': 3})
|
705
|
+
papi_post_margin_repay_debt = papiPostMarginRepayDebt = Entry('margin/repay-debt', 'papi', 'POST', {'cost': 0.4})
|
705
706
|
papi_put_listenkey = papiPutListenKey = Entry('listenKey', 'papi', 'PUT', {'cost': 1})
|
706
707
|
papi_delete_um_order = papiDeleteUmOrder = Entry('um/order', 'papi', 'DELETE', {'cost': 1})
|
707
708
|
papi_delete_um_conditional_order = papiDeleteUmConditionalOrder = Entry('um/conditional/order', 'papi', 'DELETE', {'cost': 1})
|
ccxt/abstract/bybit.py
CHANGED
@@ -132,6 +132,9 @@ class ImplicitAPI:
|
|
132
132
|
private_get_v5_account_contract_transaction_log = privateGetV5AccountContractTransactionLog = Entry('v5/account/contract-transaction-log', 'private', 'GET', {'cost': 1})
|
133
133
|
private_get_v5_account_smp_group = privateGetV5AccountSmpGroup = Entry('v5/account/smp-group', 'private', 'GET', {'cost': 1})
|
134
134
|
private_get_v5_account_mmp_state = privateGetV5AccountMmpState = Entry('v5/account/mmp-state', 'private', 'GET', {'cost': 5})
|
135
|
+
private_get_v5_asset_exchange_query_coin_list = privateGetV5AssetExchangeQueryCoinList = Entry('v5/asset/exchange/query-coin-list', 'private', 'GET', {'cost': 0.5})
|
136
|
+
private_get_v5_asset_exchange_convert_result_query = privateGetV5AssetExchangeConvertResultQuery = Entry('v5/asset/exchange/convert-result-query', 'private', 'GET', {'cost': 0.5})
|
137
|
+
private_get_v5_asset_exchange_query_convert_history = privateGetV5AssetExchangeQueryConvertHistory = Entry('v5/asset/exchange/query-convert-history', 'private', 'GET', {'cost': 0.5})
|
135
138
|
private_get_v5_asset_exchange_order_record = privateGetV5AssetExchangeOrderRecord = Entry('v5/asset/exchange/order-record', 'private', 'GET', {'cost': 5})
|
136
139
|
private_get_v5_asset_delivery_record = privateGetV5AssetDeliveryRecord = Entry('v5/asset/delivery-record', 'private', 'GET', {'cost': 5})
|
137
140
|
private_get_v5_asset_settlement_record = privateGetV5AssetSettlementRecord = Entry('v5/asset/settlement-record', 'private', 'GET', {'cost': 5})
|
@@ -270,6 +273,8 @@ class ImplicitAPI:
|
|
270
273
|
private_post_v5_account_set_hedging_mode = privatePostV5AccountSetHedgingMode = Entry('v5/account/set-hedging-mode', 'private', 'POST', {'cost': 5})
|
271
274
|
private_post_v5_account_mmp_modify = privatePostV5AccountMmpModify = Entry('v5/account/mmp-modify', 'private', 'POST', {'cost': 5})
|
272
275
|
private_post_v5_account_mmp_reset = privatePostV5AccountMmpReset = Entry('v5/account/mmp-reset', 'private', 'POST', {'cost': 5})
|
276
|
+
private_post_v5_asset_exchange_quote_apply = privatePostV5AssetExchangeQuoteApply = Entry('v5/asset/exchange/quote-apply', 'private', 'POST', {'cost': 1})
|
277
|
+
private_post_v5_asset_exchange_convert_execute = privatePostV5AssetExchangeConvertExecute = Entry('v5/asset/exchange/convert-execute', 'private', 'POST', {'cost': 1})
|
273
278
|
private_post_v5_asset_transfer_inter_transfer = privatePostV5AssetTransferInterTransfer = Entry('v5/asset/transfer/inter-transfer', 'private', 'POST', {'cost': 50})
|
274
279
|
private_post_v5_asset_transfer_save_transfer_sub_member = privatePostV5AssetTransferSaveTransferSubMember = Entry('v5/asset/transfer/save-transfer-sub-member', 'private', 'POST', {'cost': 150})
|
275
280
|
private_post_v5_asset_transfer_universal_transfer = privatePostV5AssetTransferUniversalTransfer = Entry('v5/asset/transfer/universal-transfer', 'private', 'POST', {'cost': 10})
|
ccxt/abstract/okx.py
CHANGED
@@ -79,6 +79,7 @@ class ImplicitAPI:
|
|
79
79
|
public_get_copytrading_public_preference_currency = publicGetCopytradingPublicPreferenceCurrency = Entry('copytrading/public-preference-currency', 'public', 'GET', {'cost': 4})
|
80
80
|
public_get_copytrading_public_current_subpositions = publicGetCopytradingPublicCurrentSubpositions = Entry('copytrading/public-current-subpositions', 'public', 'GET', {'cost': 4})
|
81
81
|
public_get_copytrading_public_subpositions_history = publicGetCopytradingPublicSubpositionsHistory = Entry('copytrading/public-subpositions-history', 'public', 'GET', {'cost': 4})
|
82
|
+
public_get_support_announcements_types = publicGetSupportAnnouncementsTypes = Entry('support/announcements-types', 'public', 'GET', {'cost': 20})
|
82
83
|
private_get_rfq_counterparties = privateGetRfqCounterparties = Entry('rfq/counterparties', 'private', 'GET', {'cost': 4})
|
83
84
|
private_get_rfq_maker_instrument_settings = privateGetRfqMakerInstrumentSettings = Entry('rfq/maker-instrument-settings', 'private', 'GET', {'cost': 4})
|
84
85
|
private_get_rfq_mmp_config = privateGetRfqMmpConfig = Entry('rfq/mmp-config', 'private', 'GET', {'cost': 4})
|
@@ -208,6 +209,7 @@ class ImplicitAPI:
|
|
208
209
|
private_get_broker_fd_if_rebate = privateGetBrokerFdIfRebate = Entry('broker/fd/if-rebate', 'private', 'GET', {'cost': 5})
|
209
210
|
private_get_affiliate_invitee_detail = privateGetAffiliateInviteeDetail = Entry('affiliate/invitee/detail', 'private', 'GET', {'cost': 1})
|
210
211
|
private_get_users_partner_if_rebate = privateGetUsersPartnerIfRebate = Entry('users/partner/if-rebate', 'private', 'GET', {'cost': 1})
|
212
|
+
private_get_support_announcements = privateGetSupportAnnouncements = Entry('support/announcements', 'private', 'GET', {'cost': 4})
|
211
213
|
private_post_rfq_create_rfq = privatePostRfqCreateRfq = Entry('rfq/create-rfq', 'private', 'POST', {'cost': 4})
|
212
214
|
private_post_rfq_cancel_rfq = privatePostRfqCancelRfq = Entry('rfq/cancel-rfq', 'private', 'POST', {'cost': 4})
|
213
215
|
private_post_rfq_cancel_batch_rfqs = privatePostRfqCancelBatchRfqs = Entry('rfq/cancel-batch-rfqs', 'private', 'POST', {'cost': 10})
|
ccxt/async_support/__init__.py
CHANGED
ccxt/async_support/binance.py
CHANGED
@@ -1115,6 +1115,7 @@ class binance(Exchange, ImplicitAPI):
|
|
1115
1115
|
'repay-futures-negative-balance': 150, # Weight(IP): 1500 => cost = 0.1 * 1500 = 150
|
1116
1116
|
'listenKey': 1, # 1
|
1117
1117
|
'asset-collection': 3,
|
1118
|
+
'margin/repay-debt': 0.4, # Weight(Order): 0.4 =>(1000 / (50 * 0.4)) * 60 = 3000
|
1118
1119
|
},
|
1119
1120
|
'put': {
|
1120
1121
|
'listenKey': 1, # 1
|
@@ -1232,6 +1233,7 @@ class binance(Exchange, ImplicitAPI):
|
|
1232
1233
|
],
|
1233
1234
|
'fetchCurrencies': True, # self is a private call and it requires API keys
|
1234
1235
|
# 'fetchTradesMethod': 'publicGetAggTrades', # publicGetTrades, publicGetHistoricalTrades, eapiPublicGetTrades
|
1236
|
+
# 'repayCrossMarginMethod': 'papiPostRepayLoan', # papiPostMarginRepayDebt
|
1235
1237
|
'defaultTimeInForce': 'GTC', # 'GTC' = Good To Cancel(default), 'IOC' = Immediate Or Cancel
|
1236
1238
|
'defaultType': 'spot', # 'spot', 'future', 'margin', 'delivery', 'option'
|
1237
1239
|
'defaultSubType': None, # 'linear', 'inverse'
|
@@ -2879,7 +2881,7 @@ class binance(Exchange, ImplicitAPI):
|
|
2879
2881
|
res = self.safe_value(results, i)
|
2880
2882
|
if fetchMargins and isinstance(res, list):
|
2881
2883
|
keysList = list(self.index_by(res, 'symbol').keys())
|
2882
|
-
length = (self.options['crossMarginPairsData'])
|
2884
|
+
length = len(self.options['crossMarginPairsData'])
|
2883
2885
|
# first one is the cross-margin promise
|
2884
2886
|
if length == 0:
|
2885
2887
|
self.options['crossMarginPairsData'] = keysList
|
@@ -11242,10 +11244,13 @@ class binance(Exchange, ImplicitAPI):
|
|
11242
11244
|
repay borrowed margin and interest
|
11243
11245
|
:see: https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Margin-Account-Repay
|
11244
11246
|
:see: https://developers.binance.com/docs/margin_trading/borrow-and-repay/Margin-Account-Borrow-Repay
|
11247
|
+
:see: https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Margin-Account-Repay-Debt
|
11245
11248
|
:param str code: unified currency code of the currency to repay
|
11246
11249
|
:param float amount: the amount to repay
|
11247
11250
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
11248
11251
|
:param boolean [params.portfolioMargin]: set to True if you would like to repay margin in a portfolio margin account
|
11252
|
+
:param str [params.repayCrossMarginMethod]: *portfolio margin only* 'papiPostRepayLoan'(default), 'papiPostMarginRepayDebt'(alternative)
|
11253
|
+
:param str [params.specifyRepayAssets]: *portfolio margin papiPostMarginRepayDebt only* specific asset list to repay debt
|
11249
11254
|
:returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
|
11250
11255
|
"""
|
11251
11256
|
await self.load_markets()
|
@@ -11258,17 +11263,37 @@ class binance(Exchange, ImplicitAPI):
|
|
11258
11263
|
isPortfolioMargin = None
|
11259
11264
|
isPortfolioMargin, params = self.handle_option_and_params_2(params, 'repayCrossMargin', 'papi', 'portfolioMargin', False)
|
11260
11265
|
if isPortfolioMargin:
|
11261
|
-
|
11266
|
+
method = None
|
11267
|
+
method, params = self.handle_option_and_params_2(params, 'repayCrossMargin', 'repayCrossMarginMethod', 'method')
|
11268
|
+
if method == 'papiPostMarginRepayDebt':
|
11269
|
+
response = await self.papiPostMarginRepayDebt(self.extend(request, params))
|
11270
|
+
#
|
11271
|
+
# {
|
11272
|
+
# "asset": "USDC",
|
11273
|
+
# "amount": 10,
|
11274
|
+
# "specifyRepayAssets": null,
|
11275
|
+
# "updateTime": 1727170761267,
|
11276
|
+
# "success": True
|
11277
|
+
# }
|
11278
|
+
#
|
11279
|
+
else:
|
11280
|
+
response = await self.papiPostRepayLoan(self.extend(request, params))
|
11281
|
+
#
|
11282
|
+
# {
|
11283
|
+
# "tranId": 108988250265,
|
11284
|
+
# "clientTag":""
|
11285
|
+
# }
|
11286
|
+
#
|
11262
11287
|
else:
|
11263
11288
|
request['isIsolated'] = 'FALSE'
|
11264
11289
|
request['type'] = 'REPAY'
|
11265
11290
|
response = await self.sapiPostMarginBorrowRepay(self.extend(request, params))
|
11266
|
-
|
11267
|
-
|
11268
|
-
|
11269
|
-
|
11270
|
-
|
11271
|
-
|
11291
|
+
#
|
11292
|
+
# {
|
11293
|
+
# "tranId": 108988250265,
|
11294
|
+
# "clientTag":""
|
11295
|
+
# }
|
11296
|
+
#
|
11272
11297
|
return self.parse_margin_loan(response, currency)
|
11273
11298
|
|
11274
11299
|
async def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
|
@@ -11370,13 +11395,25 @@ class binance(Exchange, ImplicitAPI):
|
|
11370
11395
|
# "clientTag":""
|
11371
11396
|
# }
|
11372
11397
|
#
|
11398
|
+
# repayCrossMargin alternative endpoint
|
11399
|
+
#
|
11400
|
+
# {
|
11401
|
+
# "asset": "USDC",
|
11402
|
+
# "amount": 10,
|
11403
|
+
# "specifyRepayAssets": null,
|
11404
|
+
# "updateTime": 1727170761267,
|
11405
|
+
# "success": True
|
11406
|
+
# }
|
11407
|
+
#
|
11408
|
+
currencyId = self.safe_string(info, 'asset')
|
11409
|
+
timestamp = self.safe_integer(info, 'updateTime')
|
11373
11410
|
return {
|
11374
11411
|
'id': self.safe_integer(info, 'tranId'),
|
11375
|
-
'currency': self.safe_currency_code(
|
11376
|
-
'amount':
|
11412
|
+
'currency': self.safe_currency_code(currencyId, currency),
|
11413
|
+
'amount': self.safe_number(info, 'amount'),
|
11377
11414
|
'symbol': None,
|
11378
|
-
'timestamp':
|
11379
|
-
'datetime':
|
11415
|
+
'timestamp': timestamp,
|
11416
|
+
'datetime': self.iso8601(timestamp),
|
11380
11417
|
'info': info,
|
11381
11418
|
}
|
11382
11419
|
|
ccxt/async_support/bybit.py
CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.bybit import ImplicitAPI
|
8
8
|
import asyncio
|
9
9
|
import hashlib
|
10
|
-
from ccxt.base.types import Balances, CrossBorrowRate, Currencies, Currency, Greeks, Int, LedgerEntry, Leverage, LeverageTier, LeverageTiers, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
|
10
|
+
from ccxt.base.types import Balances, Conversion, CrossBorrowRate, Currencies, Currency, Greeks, Int, LedgerEntry, Leverage, LeverageTier, LeverageTiers, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
13
|
from ccxt.base.errors import AuthenticationError
|
@@ -57,6 +57,7 @@ class bybit(Exchange, ImplicitAPI):
|
|
57
57
|
'cancelOrdersForSymbols': True,
|
58
58
|
'closeAllPositions': False,
|
59
59
|
'closePosition': False,
|
60
|
+
'createConvertTrade': True,
|
60
61
|
'createMarketBuyOrderWithCost': True,
|
61
62
|
'createMarketSellOrderWithCost': True,
|
62
63
|
'createOrder': True,
|
@@ -80,6 +81,10 @@ class bybit(Exchange, ImplicitAPI):
|
|
80
81
|
'fetchCanceledOrders': True,
|
81
82
|
'fetchClosedOrder': True,
|
82
83
|
'fetchClosedOrders': True,
|
84
|
+
'fetchConvertCurrencies': True,
|
85
|
+
'fetchConvertQuote': True,
|
86
|
+
'fetchConvertTrade': True,
|
87
|
+
'fetchConvertTradeHistory': True,
|
83
88
|
'fetchCrossBorrowRate': True,
|
84
89
|
'fetchCrossBorrowRates': False,
|
85
90
|
'fetchCurrencies': True,
|
@@ -346,6 +351,9 @@ class bybit(Exchange, ImplicitAPI):
|
|
346
351
|
'v5/account/smp-group': 1,
|
347
352
|
'v5/account/mmp-state': 5,
|
348
353
|
# asset
|
354
|
+
'v5/asset/exchange/query-coin-list': 0.5, # 100/s => cost = 50 / 100 = 0.5
|
355
|
+
'v5/asset/exchange/convert-result-query': 0.5, # 100/s => cost = 50 / 100 = 0.5
|
356
|
+
'v5/asset/exchange/query-convert-history': 0.5, # 100/s => cost = 50 / 100 = 0.5
|
349
357
|
'v5/asset/exchange/order-record': 5, # 10/s => cost = 50 / 10 = 5
|
350
358
|
'v5/asset/delivery-record': 5,
|
351
359
|
'v5/asset/settlement-record': 5,
|
@@ -504,6 +512,8 @@ class bybit(Exchange, ImplicitAPI):
|
|
504
512
|
'v5/account/mmp-modify': 5,
|
505
513
|
'v5/account/mmp-reset': 5,
|
506
514
|
# asset
|
515
|
+
'v5/asset/exchange/quote-apply': 1, # 50/s
|
516
|
+
'v5/asset/exchange/convert-execute': 1, # 50/s
|
507
517
|
'v5/asset/transfer/inter-transfer': 50, # 1/s => cost = 50 / 1 = 50
|
508
518
|
'v5/asset/transfer/save-transfer-sub-member': 150, # 1/3/s => cost = 50 / 1/3 = 150
|
509
519
|
'v5/asset/transfer/universal-transfer': 10, # 5/s => cost = 50 / 5 = 10
|
@@ -8246,6 +8256,345 @@ class bybit(Exchange, ImplicitAPI):
|
|
8246
8256
|
positions = self.parse_positions(rawPositions, symbols, params)
|
8247
8257
|
return self.filter_by_since_limit(positions, since, limit)
|
8248
8258
|
|
8259
|
+
async def fetch_convert_currencies(self, params={}) -> Currencies:
|
8260
|
+
"""
|
8261
|
+
fetches all available currencies that can be converted
|
8262
|
+
:see: https://bybit-exchange.github.io/docs/v5/asset/convert/convert-coin-list
|
8263
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
8264
|
+
:param str [params.accountType]: eb_convert_uta, eb_convert_spot, eb_convert_funding, eb_convert_inverse, or eb_convert_contract
|
8265
|
+
:returns dict: an associative dictionary of currencies
|
8266
|
+
"""
|
8267
|
+
await self.load_markets()
|
8268
|
+
accountType = None
|
8269
|
+
enableUnifiedMargin, enableUnifiedAccount = await self.is_unified_enabled()
|
8270
|
+
isUnifiedAccount = (enableUnifiedMargin or enableUnifiedAccount)
|
8271
|
+
accountTypeDefault = 'eb_convert_uta' if isUnifiedAccount else 'eb_convert_spot'
|
8272
|
+
accountType, params = self.handle_option_and_params(params, 'fetchConvertCurrencies', 'accountType', accountTypeDefault)
|
8273
|
+
request: dict = {
|
8274
|
+
'accountType': accountType,
|
8275
|
+
}
|
8276
|
+
response = await self.privateGetV5AssetExchangeQueryCoinList(self.extend(request, params))
|
8277
|
+
#
|
8278
|
+
# {
|
8279
|
+
# "retCode": 0,
|
8280
|
+
# "retMsg": "ok",
|
8281
|
+
# "result": {
|
8282
|
+
# "coins": [
|
8283
|
+
# {
|
8284
|
+
# "coin": "MATIC",
|
8285
|
+
# "fullName": "MATIC",
|
8286
|
+
# "icon": "https://s1.bycsi.com/app/assets/token/0552ae79c535c3095fa18f7b377dd2e9.svg",
|
8287
|
+
# "iconNight": "https://t1.bycsi.com/app/assets/token/f59301aef2d6ac2165c4c4603e672fb4.svg",
|
8288
|
+
# "accuracyLength": 8,
|
8289
|
+
# "coinType": "crypto",
|
8290
|
+
# "balance": "0",
|
8291
|
+
# "uBalance": "0",
|
8292
|
+
# "timePeriod": 0,
|
8293
|
+
# "singleFromMinLimit": "1.1",
|
8294
|
+
# "singleFromMaxLimit": "20001",
|
8295
|
+
# "singleToMinLimit": "0",
|
8296
|
+
# "singleToMaxLimit": "0",
|
8297
|
+
# "dailyFromMinLimit": "0",
|
8298
|
+
# "dailyFromMaxLimit": "0",
|
8299
|
+
# "dailyToMinLimit": "0",
|
8300
|
+
# "dailyToMaxLimit": "0",
|
8301
|
+
# "disableFrom": False,
|
8302
|
+
# "disableTo": False
|
8303
|
+
# },
|
8304
|
+
# ]
|
8305
|
+
# },
|
8306
|
+
# "retExtInfo": {},
|
8307
|
+
# "time": 1727256416250
|
8308
|
+
# }
|
8309
|
+
#
|
8310
|
+
result: dict = {}
|
8311
|
+
data = self.safe_dict(response, 'result', {})
|
8312
|
+
coins = self.safe_list(data, 'coins', [])
|
8313
|
+
for i in range(0, len(coins)):
|
8314
|
+
entry = coins[i]
|
8315
|
+
id = self.safe_string(entry, 'coin')
|
8316
|
+
disableFrom = self.safe_bool(entry, 'disableFrom')
|
8317
|
+
disableTo = self.safe_bool(entry, 'disableTo')
|
8318
|
+
inactive = (disableFrom or disableTo)
|
8319
|
+
code = self.safe_currency_code(id)
|
8320
|
+
result[code] = {
|
8321
|
+
'info': entry,
|
8322
|
+
'id': id,
|
8323
|
+
'code': code,
|
8324
|
+
'networks': None,
|
8325
|
+
'type': self.safe_string(entry, 'coinType'),
|
8326
|
+
'name': self.safe_string(entry, 'fullName'),
|
8327
|
+
'active': not inactive,
|
8328
|
+
'deposit': None,
|
8329
|
+
'withdraw': self.safe_number(entry, 'balance'),
|
8330
|
+
'fee': None,
|
8331
|
+
'precision': None,
|
8332
|
+
'limits': {
|
8333
|
+
'amount': {
|
8334
|
+
'min': self.safe_number(entry, 'singleFromMinLimit'),
|
8335
|
+
'max': self.safe_number(entry, 'singleFromMaxLimit'),
|
8336
|
+
},
|
8337
|
+
'withdraw': {
|
8338
|
+
'min': None,
|
8339
|
+
'max': None,
|
8340
|
+
},
|
8341
|
+
'deposit': {
|
8342
|
+
'min': None,
|
8343
|
+
'max': None,
|
8344
|
+
},
|
8345
|
+
},
|
8346
|
+
'created': None,
|
8347
|
+
}
|
8348
|
+
return result
|
8349
|
+
|
8350
|
+
async def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
8351
|
+
"""
|
8352
|
+
fetch a quote for converting from one currency to another
|
8353
|
+
:see: https://bybit-exchange.github.io/docs/v5/asset/convert/apply-quote
|
8354
|
+
:param str fromCode: the currency that you want to sell and convert from
|
8355
|
+
:param str toCode: the currency that you want to buy and convert into
|
8356
|
+
:param float [amount]: how much you want to trade in units of the from currency
|
8357
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
8358
|
+
:param str [params.accountType]: eb_convert_uta, eb_convert_spot, eb_convert_funding, eb_convert_inverse, or eb_convert_contract
|
8359
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
8360
|
+
"""
|
8361
|
+
await self.load_markets()
|
8362
|
+
accountType = None
|
8363
|
+
enableUnifiedMargin, enableUnifiedAccount = await self.is_unified_enabled()
|
8364
|
+
isUnifiedAccount = (enableUnifiedMargin or enableUnifiedAccount)
|
8365
|
+
accountTypeDefault = 'eb_convert_uta' if isUnifiedAccount else 'eb_convert_spot'
|
8366
|
+
accountType, params = self.handle_option_and_params(params, 'fetchConvertQuote', 'accountType', accountTypeDefault)
|
8367
|
+
request: dict = {
|
8368
|
+
'fromCoin': fromCode,
|
8369
|
+
'toCoin': toCode,
|
8370
|
+
'requestAmount': self.number_to_string(amount),
|
8371
|
+
'requestCoin': fromCode,
|
8372
|
+
'accountType': accountType,
|
8373
|
+
}
|
8374
|
+
response = await self.privatePostV5AssetExchangeQuoteApply(self.extend(request, params))
|
8375
|
+
#
|
8376
|
+
# {
|
8377
|
+
# "retCode": 0,
|
8378
|
+
# "retMsg": "ok",
|
8379
|
+
# "result": {
|
8380
|
+
# "quoteTxId": "1010020692439481682687668224",
|
8381
|
+
# "exchangeRate": "0.000015330836780000",
|
8382
|
+
# "fromCoin": "USDT",
|
8383
|
+
# "fromCoinType": "crypto",
|
8384
|
+
# "toCoin": "BTC",
|
8385
|
+
# "toCoinType": "crypto",
|
8386
|
+
# "fromAmount": "10",
|
8387
|
+
# "toAmount": "0.000153308367800000",
|
8388
|
+
# "expiredTime": "1727257413353",
|
8389
|
+
# "requestId": ""
|
8390
|
+
# },
|
8391
|
+
# "retExtInfo": {},
|
8392
|
+
# "time": 1727257398375
|
8393
|
+
# }
|
8394
|
+
#
|
8395
|
+
data = self.safe_dict(response, 'result', {})
|
8396
|
+
fromCurrencyId = self.safe_string(data, 'fromCoin', fromCode)
|
8397
|
+
fromCurrency = self.currency(fromCurrencyId)
|
8398
|
+
toCurrencyId = self.safe_string(data, 'toCoin', toCode)
|
8399
|
+
toCurrency = self.currency(toCurrencyId)
|
8400
|
+
return self.parse_conversion(data, fromCurrency, toCurrency)
|
8401
|
+
|
8402
|
+
async def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
8403
|
+
"""
|
8404
|
+
convert from one currency to another
|
8405
|
+
:see: https://bybit-exchange.github.io/docs/v5/asset/convert/confirm-quote
|
8406
|
+
:param str id: the id of the trade that you want to make
|
8407
|
+
:param str fromCode: the currency that you want to sell and convert from
|
8408
|
+
:param str toCode: the currency that you want to buy and convert into
|
8409
|
+
:param float amount: how much you want to trade in units of the from currency
|
8410
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
8411
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
8412
|
+
"""
|
8413
|
+
await self.load_markets()
|
8414
|
+
request: dict = {
|
8415
|
+
'quoteTxId': id,
|
8416
|
+
}
|
8417
|
+
response = await self.privatePostV5AssetExchangeConvertExecute(self.extend(request, params))
|
8418
|
+
#
|
8419
|
+
# {
|
8420
|
+
# "retCode": 0,
|
8421
|
+
# "retMsg": "ok",
|
8422
|
+
# "result": {
|
8423
|
+
# "exchangeStatus": "processing",
|
8424
|
+
# "quoteTxId": "1010020692439483803499737088"
|
8425
|
+
# },
|
8426
|
+
# "retExtInfo": {},
|
8427
|
+
# "time": 1727257904969
|
8428
|
+
# }
|
8429
|
+
#
|
8430
|
+
data = self.safe_dict(response, 'result', {})
|
8431
|
+
return self.parse_conversion(data)
|
8432
|
+
|
8433
|
+
async def fetch_convert_trade(self, id: str, code: Str = None, params={}) -> Conversion:
|
8434
|
+
"""
|
8435
|
+
fetch the data for a conversion trade
|
8436
|
+
:see: https://bybit-exchange.github.io/docs/v5/asset/convert/get-convert-result
|
8437
|
+
:param str id: the id of the trade that you want to fetch
|
8438
|
+
:param str [code]: the unified currency code of the conversion trade
|
8439
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
8440
|
+
:param str [params.accountType]: eb_convert_uta, eb_convert_spot, eb_convert_funding, eb_convert_inverse, or eb_convert_contract
|
8441
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
8442
|
+
"""
|
8443
|
+
await self.load_markets()
|
8444
|
+
accountType = None
|
8445
|
+
enableUnifiedMargin, enableUnifiedAccount = await self.is_unified_enabled()
|
8446
|
+
isUnifiedAccount = (enableUnifiedMargin or enableUnifiedAccount)
|
8447
|
+
accountTypeDefault = 'eb_convert_uta' if isUnifiedAccount else 'eb_convert_spot'
|
8448
|
+
accountType, params = self.handle_option_and_params(params, 'fetchConvertQuote', 'accountType', accountTypeDefault)
|
8449
|
+
request: dict = {
|
8450
|
+
'quoteTxId': id,
|
8451
|
+
'accountType': accountType,
|
8452
|
+
}
|
8453
|
+
response = await self.privateGetV5AssetExchangeConvertResultQuery(self.extend(request, params))
|
8454
|
+
#
|
8455
|
+
# {
|
8456
|
+
# "retCode": 0,
|
8457
|
+
# "retMsg": "ok",
|
8458
|
+
# "result": {
|
8459
|
+
# "result": {
|
8460
|
+
# "accountType": "eb_convert_uta",
|
8461
|
+
# "exchangeTxId": "1010020692439483803499737088",
|
8462
|
+
# "userId": "100406395",
|
8463
|
+
# "fromCoin": "USDT",
|
8464
|
+
# "fromCoinType": "crypto",
|
8465
|
+
# "fromAmount": "10",
|
8466
|
+
# "toCoin": "BTC",
|
8467
|
+
# "toCoinType": "crypto",
|
8468
|
+
# "toAmount": "0.00015344889",
|
8469
|
+
# "exchangeStatus": "success",
|
8470
|
+
# "extInfo": {},
|
8471
|
+
# "convertRate": "0.000015344889",
|
8472
|
+
# "createdAt": "1727257904726"
|
8473
|
+
# }
|
8474
|
+
# },
|
8475
|
+
# "retExtInfo": {},
|
8476
|
+
# "time": 1727258257216
|
8477
|
+
# }
|
8478
|
+
#
|
8479
|
+
data = self.safe_dict(response, 'result', {})
|
8480
|
+
result = self.safe_dict(data, 'result', {})
|
8481
|
+
fromCurrencyId = self.safe_string(result, 'fromCoin')
|
8482
|
+
toCurrencyId = self.safe_string(result, 'toCoin')
|
8483
|
+
fromCurrency = None
|
8484
|
+
toCurrency = None
|
8485
|
+
if fromCurrencyId is not None:
|
8486
|
+
fromCurrency = self.currency(fromCurrencyId)
|
8487
|
+
if toCurrencyId is not None:
|
8488
|
+
toCurrency = self.currency(toCurrencyId)
|
8489
|
+
return self.parse_conversion(result, fromCurrency, toCurrency)
|
8490
|
+
|
8491
|
+
async def fetch_convert_trade_history(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Conversion]:
|
8492
|
+
"""
|
8493
|
+
fetch the users history of conversion trades
|
8494
|
+
:see: https://bybit-exchange.github.io/docs/v5/asset/convert/get-convert-history
|
8495
|
+
:param str [code]: the unified currency code
|
8496
|
+
:param int [since]: the earliest time in ms to fetch conversions for
|
8497
|
+
:param int [limit]: the maximum number of conversion structures to retrieve
|
8498
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
8499
|
+
:param str [params.accountType]: eb_convert_uta, eb_convert_spot, eb_convert_funding, eb_convert_inverse, or eb_convert_contract
|
8500
|
+
:returns dict[]: a list of `conversion structures <https://docs.ccxt.com/#/?id=conversion-structure>`
|
8501
|
+
"""
|
8502
|
+
await self.load_markets()
|
8503
|
+
request: dict = {}
|
8504
|
+
if limit is not None:
|
8505
|
+
request['limit'] = limit
|
8506
|
+
response = await self.privateGetV5AssetExchangeQueryConvertHistory(self.extend(request, params))
|
8507
|
+
#
|
8508
|
+
# {
|
8509
|
+
# "retCode": 0,
|
8510
|
+
# "retMsg": "ok",
|
8511
|
+
# "result": {
|
8512
|
+
# "list": [
|
8513
|
+
# {
|
8514
|
+
# "accountType": "eb_convert_uta",
|
8515
|
+
# "exchangeTxId": "1010020692439483803499737088",
|
8516
|
+
# "userId": "100406395",
|
8517
|
+
# "fromCoin": "USDT",
|
8518
|
+
# "fromCoinType": "crypto",
|
8519
|
+
# "fromAmount": "10",
|
8520
|
+
# "toCoin": "BTC",
|
8521
|
+
# "toCoinType": "crypto",
|
8522
|
+
# "toAmount": "0.00015344889",
|
8523
|
+
# "exchangeStatus": "success",
|
8524
|
+
# "extInfo": {},
|
8525
|
+
# "convertRate": "0.000015344889",
|
8526
|
+
# "createdAt": "1727257904726"
|
8527
|
+
# }
|
8528
|
+
# ]
|
8529
|
+
# },
|
8530
|
+
# "retExtInfo": {},
|
8531
|
+
# "time": 1727258761874
|
8532
|
+
# }
|
8533
|
+
#
|
8534
|
+
data = self.safe_dict(response, 'result', {})
|
8535
|
+
dataList = self.safe_list(data, 'list', [])
|
8536
|
+
return self.parse_conversions(dataList, code, 'fromCoin', 'toCoin', since, limit)
|
8537
|
+
|
8538
|
+
def parse_conversion(self, conversion: dict, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
|
8539
|
+
#
|
8540
|
+
# fetchConvertQuote
|
8541
|
+
#
|
8542
|
+
# {
|
8543
|
+
# "quoteTxId": "1010020692439481682687668224",
|
8544
|
+
# "exchangeRate": "0.000015330836780000",
|
8545
|
+
# "fromCoin": "USDT",
|
8546
|
+
# "fromCoinType": "crypto",
|
8547
|
+
# "toCoin": "BTC",
|
8548
|
+
# "toCoinType": "crypto",
|
8549
|
+
# "fromAmount": "10",
|
8550
|
+
# "toAmount": "0.000153308367800000",
|
8551
|
+
# "expiredTime": "1727257413353",
|
8552
|
+
# "requestId": ""
|
8553
|
+
# }
|
8554
|
+
#
|
8555
|
+
# createConvertTrade
|
8556
|
+
#
|
8557
|
+
# {
|
8558
|
+
# "exchangeStatus": "processing",
|
8559
|
+
# "quoteTxId": "1010020692439483803499737088"
|
8560
|
+
# }
|
8561
|
+
#
|
8562
|
+
# fetchConvertTrade, fetchConvertTradeHistory
|
8563
|
+
#
|
8564
|
+
# {
|
8565
|
+
# "accountType": "eb_convert_uta",
|
8566
|
+
# "exchangeTxId": "1010020692439483803499737088",
|
8567
|
+
# "userId": "100406395",
|
8568
|
+
# "fromCoin": "USDT",
|
8569
|
+
# "fromCoinType": "crypto",
|
8570
|
+
# "fromAmount": "10",
|
8571
|
+
# "toCoin": "BTC",
|
8572
|
+
# "toCoinType": "crypto",
|
8573
|
+
# "toAmount": "0.00015344889",
|
8574
|
+
# "exchangeStatus": "success",
|
8575
|
+
# "extInfo": {},
|
8576
|
+
# "convertRate": "0.000015344889",
|
8577
|
+
# "createdAt": "1727257904726"
|
8578
|
+
# }
|
8579
|
+
#
|
8580
|
+
timestamp = self.safe_integer_2(conversion, 'expiredTime', 'createdAt')
|
8581
|
+
fromCoin = self.safe_string(conversion, 'fromCoin')
|
8582
|
+
fromCode = self.safe_currency_code(fromCoin, fromCurrency)
|
8583
|
+
to = self.safe_string(conversion, 'toCoin')
|
8584
|
+
toCode = self.safe_currency_code(to, toCurrency)
|
8585
|
+
return {
|
8586
|
+
'info': conversion,
|
8587
|
+
'timestamp': timestamp,
|
8588
|
+
'datetime': self.iso8601(timestamp),
|
8589
|
+
'id': self.safe_string_2(conversion, 'quoteTxId', 'exchangeTxId'),
|
8590
|
+
'fromCurrency': fromCode,
|
8591
|
+
'fromAmount': self.safe_number(conversion, 'fromAmount'),
|
8592
|
+
'toCurrency': toCode,
|
8593
|
+
'toAmount': self.safe_number(conversion, 'toAmount'),
|
8594
|
+
'price': None,
|
8595
|
+
'fee': None,
|
8596
|
+
}
|
8597
|
+
|
8249
8598
|
def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
|
8250
8599
|
url = self.implode_hostname(self.urls['api'][api]) + '/' + path
|
8251
8600
|
if api == 'public':
|