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/async_support/htx.py CHANGED
@@ -2031,6 +2031,10 @@ class htx(Exchange, ImplicitAPI):
2031
2031
  async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
2032
2032
  """
2033
2033
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
2034
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#get-latest-aggregated-ticker
2035
+ :see: https://huobiapi.github.io/docs/dm/v1/en/#get-market-data-overview
2036
+ :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-market-data-overview
2037
+ :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-market-data-overview
2034
2038
  :param str symbol: unified symbol of the market to fetch the ticker for
2035
2039
  :param dict [params]: extra parameters specific to the exchange API endpoint
2036
2040
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -2324,6 +2328,10 @@ class htx(Exchange, ImplicitAPI):
2324
2328
  async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
2325
2329
  """
2326
2330
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
2331
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#get-market-depth
2332
+ :see: https://huobiapi.github.io/docs/dm/v1/en/#get-market-depth
2333
+ :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-market-depth
2334
+ :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-market-depth
2327
2335
  :param str symbol: unified symbol of the market to fetch the order book for
2328
2336
  :param int [limit]: the maximum amount of order book entries to return
2329
2337
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2535,6 +2543,7 @@ class htx(Exchange, ImplicitAPI):
2535
2543
  async def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2536
2544
  """
2537
2545
  fetch all the trades made from a single order
2546
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#get-the-match-result-of-an-order
2538
2547
  :param str id: order id
2539
2548
  :param str symbol: unified market symbol
2540
2549
  :param int [since]: the earliest time in ms to fetch trades for
@@ -2552,6 +2561,17 @@ class htx(Exchange, ImplicitAPI):
2552
2561
  return await self.fetch_spot_order_trades(id, symbol, since, limit, params)
2553
2562
 
2554
2563
  async def fetch_spot_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2564
+ """
2565
+ * @ignore
2566
+ fetch all the trades made from a single order
2567
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#get-the-match-result-of-an-order
2568
+ :param str id: order id
2569
+ :param str symbol: unified market symbol
2570
+ :param int [since]: the earliest time in ms to fetch trades for
2571
+ :param int [limit]: the maximum number of trades to retrieve
2572
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2573
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
2574
+ """
2555
2575
  await self.load_markets()
2556
2576
  request: dict = {
2557
2577
  'order-id': id,
ccxt/async_support/okx.py CHANGED
@@ -291,6 +291,7 @@ class okx(Exchange, ImplicitAPI):
291
291
  'copytrading/public-preference-currency': 4,
292
292
  'copytrading/public-current-subpositions': 4,
293
293
  'copytrading/public-subpositions-history': 4,
294
+ 'support/announcements-types': 20,
294
295
  },
295
296
  },
296
297
  'private': {
@@ -436,6 +437,7 @@ class okx(Exchange, ImplicitAPI):
436
437
  # affiliate
437
438
  'affiliate/invitee/detail': 1,
438
439
  'users/partner/if-rebate': 1,
440
+ 'support/announcements': 4,
439
441
  },
440
442
  'post': {
441
443
  # rfq
@@ -815,6 +817,8 @@ class okx(Exchange, ImplicitAPI):
815
817
  # SPOT/MARGIN error codes 54000-54999
816
818
  '54000': ExchangeError, # Margin transactions unavailable
817
819
  '54001': ExchangeError, # Only Multi-currency margin account can be set to borrow coins automatically
820
+ '54008': InvalidOrder, # This operation is disabled by the 'mass cancel order' endpoint. Please enable it using self endpoint.
821
+ '54009': InvalidOrder, # The range of {param0} should be [{param1}, {param2}].
818
822
  '54011': InvalidOrder, # 200 Pre-market trading contracts are only allowed to reduce the number of positions within 1 hour before delivery. Please modify or cancel the order.
819
823
  # Trading bot Error Code from 55100 to 55999
820
824
  '55100': InvalidOrder, # Take profit % should be within the range of {parameter1}-{parameter2}
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.7'
7
+ __version__ = '4.4.8'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
ccxt/binance.py CHANGED
@@ -1114,6 +1114,7 @@ class binance(Exchange, ImplicitAPI):
1114
1114
  'repay-futures-negative-balance': 150, # Weight(IP): 1500 => cost = 0.1 * 1500 = 150
1115
1115
  'listenKey': 1, # 1
1116
1116
  'asset-collection': 3,
1117
+ 'margin/repay-debt': 0.4, # Weight(Order): 0.4 =>(1000 / (50 * 0.4)) * 60 = 3000
1117
1118
  },
1118
1119
  'put': {
1119
1120
  'listenKey': 1, # 1
@@ -1231,6 +1232,7 @@ class binance(Exchange, ImplicitAPI):
1231
1232
  ],
1232
1233
  'fetchCurrencies': True, # self is a private call and it requires API keys
1233
1234
  # 'fetchTradesMethod': 'publicGetAggTrades', # publicGetTrades, publicGetHistoricalTrades, eapiPublicGetTrades
1235
+ # 'repayCrossMarginMethod': 'papiPostRepayLoan', # papiPostMarginRepayDebt
1234
1236
  'defaultTimeInForce': 'GTC', # 'GTC' = Good To Cancel(default), 'IOC' = Immediate Or Cancel
1235
1237
  'defaultType': 'spot', # 'spot', 'future', 'margin', 'delivery', 'option'
1236
1238
  'defaultSubType': None, # 'linear', 'inverse'
@@ -2878,7 +2880,7 @@ class binance(Exchange, ImplicitAPI):
2878
2880
  res = self.safe_value(results, i)
2879
2881
  if fetchMargins and isinstance(res, list):
2880
2882
  keysList = list(self.index_by(res, 'symbol').keys())
2881
- length = (self.options['crossMarginPairsData'])
2883
+ length = len(self.options['crossMarginPairsData'])
2882
2884
  # first one is the cross-margin promise
2883
2885
  if length == 0:
2884
2886
  self.options['crossMarginPairsData'] = keysList
@@ -11241,10 +11243,13 @@ class binance(Exchange, ImplicitAPI):
11241
11243
  repay borrowed margin and interest
11242
11244
  :see: https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Margin-Account-Repay
11243
11245
  :see: https://developers.binance.com/docs/margin_trading/borrow-and-repay/Margin-Account-Borrow-Repay
11246
+ :see: https://developers.binance.com/docs/derivatives/portfolio-margin/trade/Margin-Account-Repay-Debt
11244
11247
  :param str code: unified currency code of the currency to repay
11245
11248
  :param float amount: the amount to repay
11246
11249
  :param dict [params]: extra parameters specific to the exchange API endpoint
11247
11250
  :param boolean [params.portfolioMargin]: set to True if you would like to repay margin in a portfolio margin account
11251
+ :param str [params.repayCrossMarginMethod]: *portfolio margin only* 'papiPostRepayLoan'(default), 'papiPostMarginRepayDebt'(alternative)
11252
+ :param str [params.specifyRepayAssets]: *portfolio margin papiPostMarginRepayDebt only* specific asset list to repay debt
11248
11253
  :returns dict: a `margin loan structure <https://docs.ccxt.com/#/?id=margin-loan-structure>`
11249
11254
  """
11250
11255
  self.load_markets()
@@ -11257,17 +11262,37 @@ class binance(Exchange, ImplicitAPI):
11257
11262
  isPortfolioMargin = None
11258
11263
  isPortfolioMargin, params = self.handle_option_and_params_2(params, 'repayCrossMargin', 'papi', 'portfolioMargin', False)
11259
11264
  if isPortfolioMargin:
11260
- response = self.papiPostRepayLoan(self.extend(request, params))
11265
+ method = None
11266
+ method, params = self.handle_option_and_params_2(params, 'repayCrossMargin', 'repayCrossMarginMethod', 'method')
11267
+ if method == 'papiPostMarginRepayDebt':
11268
+ response = self.papiPostMarginRepayDebt(self.extend(request, params))
11269
+ #
11270
+ # {
11271
+ # "asset": "USDC",
11272
+ # "amount": 10,
11273
+ # "specifyRepayAssets": null,
11274
+ # "updateTime": 1727170761267,
11275
+ # "success": True
11276
+ # }
11277
+ #
11278
+ else:
11279
+ response = self.papiPostRepayLoan(self.extend(request, params))
11280
+ #
11281
+ # {
11282
+ # "tranId": 108988250265,
11283
+ # "clientTag":""
11284
+ # }
11285
+ #
11261
11286
  else:
11262
11287
  request['isIsolated'] = 'FALSE'
11263
11288
  request['type'] = 'REPAY'
11264
11289
  response = self.sapiPostMarginBorrowRepay(self.extend(request, params))
11265
- #
11266
- # {
11267
- # "tranId": 108988250265,
11268
- # "clientTag":""
11269
- # }
11270
- #
11290
+ #
11291
+ # {
11292
+ # "tranId": 108988250265,
11293
+ # "clientTag":""
11294
+ # }
11295
+ #
11271
11296
  return self.parse_margin_loan(response, currency)
11272
11297
 
11273
11298
  def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
@@ -11369,13 +11394,25 @@ class binance(Exchange, ImplicitAPI):
11369
11394
  # "clientTag":""
11370
11395
  # }
11371
11396
  #
11397
+ # repayCrossMargin alternative endpoint
11398
+ #
11399
+ # {
11400
+ # "asset": "USDC",
11401
+ # "amount": 10,
11402
+ # "specifyRepayAssets": null,
11403
+ # "updateTime": 1727170761267,
11404
+ # "success": True
11405
+ # }
11406
+ #
11407
+ currencyId = self.safe_string(info, 'asset')
11408
+ timestamp = self.safe_integer(info, 'updateTime')
11372
11409
  return {
11373
11410
  'id': self.safe_integer(info, 'tranId'),
11374
- 'currency': self.safe_currency_code(None, currency),
11375
- 'amount': None,
11411
+ 'currency': self.safe_currency_code(currencyId, currency),
11412
+ 'amount': self.safe_number(info, 'amount'),
11376
11413
  'symbol': None,
11377
- 'timestamp': None,
11378
- 'datetime': None,
11414
+ 'timestamp': timestamp,
11415
+ 'datetime': self.iso8601(timestamp),
11379
11416
  'info': info,
11380
11417
  }
11381
11418
 
ccxt/bybit.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.bybit import ImplicitAPI
8
8
  import hashlib
9
- 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
9
+ 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
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -56,6 +56,7 @@ class bybit(Exchange, ImplicitAPI):
56
56
  'cancelOrdersForSymbols': True,
57
57
  'closeAllPositions': False,
58
58
  'closePosition': False,
59
+ 'createConvertTrade': True,
59
60
  'createMarketBuyOrderWithCost': True,
60
61
  'createMarketSellOrderWithCost': True,
61
62
  'createOrder': True,
@@ -79,6 +80,10 @@ class bybit(Exchange, ImplicitAPI):
79
80
  'fetchCanceledOrders': True,
80
81
  'fetchClosedOrder': True,
81
82
  'fetchClosedOrders': True,
83
+ 'fetchConvertCurrencies': True,
84
+ 'fetchConvertQuote': True,
85
+ 'fetchConvertTrade': True,
86
+ 'fetchConvertTradeHistory': True,
82
87
  'fetchCrossBorrowRate': True,
83
88
  'fetchCrossBorrowRates': False,
84
89
  'fetchCurrencies': True,
@@ -345,6 +350,9 @@ class bybit(Exchange, ImplicitAPI):
345
350
  'v5/account/smp-group': 1,
346
351
  'v5/account/mmp-state': 5,
347
352
  # asset
353
+ 'v5/asset/exchange/query-coin-list': 0.5, # 100/s => cost = 50 / 100 = 0.5
354
+ 'v5/asset/exchange/convert-result-query': 0.5, # 100/s => cost = 50 / 100 = 0.5
355
+ 'v5/asset/exchange/query-convert-history': 0.5, # 100/s => cost = 50 / 100 = 0.5
348
356
  'v5/asset/exchange/order-record': 5, # 10/s => cost = 50 / 10 = 5
349
357
  'v5/asset/delivery-record': 5,
350
358
  'v5/asset/settlement-record': 5,
@@ -503,6 +511,8 @@ class bybit(Exchange, ImplicitAPI):
503
511
  'v5/account/mmp-modify': 5,
504
512
  'v5/account/mmp-reset': 5,
505
513
  # asset
514
+ 'v5/asset/exchange/quote-apply': 1, # 50/s
515
+ 'v5/asset/exchange/convert-execute': 1, # 50/s
506
516
  'v5/asset/transfer/inter-transfer': 50, # 1/s => cost = 50 / 1 = 50
507
517
  'v5/asset/transfer/save-transfer-sub-member': 150, # 1/3/s => cost = 50 / 1/3 = 150
508
518
  'v5/asset/transfer/universal-transfer': 10, # 5/s => cost = 50 / 5 = 10
@@ -8245,6 +8255,345 @@ class bybit(Exchange, ImplicitAPI):
8245
8255
  positions = self.parse_positions(rawPositions, symbols, params)
8246
8256
  return self.filter_by_since_limit(positions, since, limit)
8247
8257
 
8258
+ def fetch_convert_currencies(self, params={}) -> Currencies:
8259
+ """
8260
+ fetches all available currencies that can be converted
8261
+ :see: https://bybit-exchange.github.io/docs/v5/asset/convert/convert-coin-list
8262
+ :param dict [params]: extra parameters specific to the exchange API endpoint
8263
+ :param str [params.accountType]: eb_convert_uta, eb_convert_spot, eb_convert_funding, eb_convert_inverse, or eb_convert_contract
8264
+ :returns dict: an associative dictionary of currencies
8265
+ """
8266
+ self.load_markets()
8267
+ accountType = None
8268
+ enableUnifiedMargin, enableUnifiedAccount = self.is_unified_enabled()
8269
+ isUnifiedAccount = (enableUnifiedMargin or enableUnifiedAccount)
8270
+ accountTypeDefault = 'eb_convert_uta' if isUnifiedAccount else 'eb_convert_spot'
8271
+ accountType, params = self.handle_option_and_params(params, 'fetchConvertCurrencies', 'accountType', accountTypeDefault)
8272
+ request: dict = {
8273
+ 'accountType': accountType,
8274
+ }
8275
+ response = self.privateGetV5AssetExchangeQueryCoinList(self.extend(request, params))
8276
+ #
8277
+ # {
8278
+ # "retCode": 0,
8279
+ # "retMsg": "ok",
8280
+ # "result": {
8281
+ # "coins": [
8282
+ # {
8283
+ # "coin": "MATIC",
8284
+ # "fullName": "MATIC",
8285
+ # "icon": "https://s1.bycsi.com/app/assets/token/0552ae79c535c3095fa18f7b377dd2e9.svg",
8286
+ # "iconNight": "https://t1.bycsi.com/app/assets/token/f59301aef2d6ac2165c4c4603e672fb4.svg",
8287
+ # "accuracyLength": 8,
8288
+ # "coinType": "crypto",
8289
+ # "balance": "0",
8290
+ # "uBalance": "0",
8291
+ # "timePeriod": 0,
8292
+ # "singleFromMinLimit": "1.1",
8293
+ # "singleFromMaxLimit": "20001",
8294
+ # "singleToMinLimit": "0",
8295
+ # "singleToMaxLimit": "0",
8296
+ # "dailyFromMinLimit": "0",
8297
+ # "dailyFromMaxLimit": "0",
8298
+ # "dailyToMinLimit": "0",
8299
+ # "dailyToMaxLimit": "0",
8300
+ # "disableFrom": False,
8301
+ # "disableTo": False
8302
+ # },
8303
+ # ]
8304
+ # },
8305
+ # "retExtInfo": {},
8306
+ # "time": 1727256416250
8307
+ # }
8308
+ #
8309
+ result: dict = {}
8310
+ data = self.safe_dict(response, 'result', {})
8311
+ coins = self.safe_list(data, 'coins', [])
8312
+ for i in range(0, len(coins)):
8313
+ entry = coins[i]
8314
+ id = self.safe_string(entry, 'coin')
8315
+ disableFrom = self.safe_bool(entry, 'disableFrom')
8316
+ disableTo = self.safe_bool(entry, 'disableTo')
8317
+ inactive = (disableFrom or disableTo)
8318
+ code = self.safe_currency_code(id)
8319
+ result[code] = {
8320
+ 'info': entry,
8321
+ 'id': id,
8322
+ 'code': code,
8323
+ 'networks': None,
8324
+ 'type': self.safe_string(entry, 'coinType'),
8325
+ 'name': self.safe_string(entry, 'fullName'),
8326
+ 'active': not inactive,
8327
+ 'deposit': None,
8328
+ 'withdraw': self.safe_number(entry, 'balance'),
8329
+ 'fee': None,
8330
+ 'precision': None,
8331
+ 'limits': {
8332
+ 'amount': {
8333
+ 'min': self.safe_number(entry, 'singleFromMinLimit'),
8334
+ 'max': self.safe_number(entry, 'singleFromMaxLimit'),
8335
+ },
8336
+ 'withdraw': {
8337
+ 'min': None,
8338
+ 'max': None,
8339
+ },
8340
+ 'deposit': {
8341
+ 'min': None,
8342
+ 'max': None,
8343
+ },
8344
+ },
8345
+ 'created': None,
8346
+ }
8347
+ return result
8348
+
8349
+ def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
8350
+ """
8351
+ fetch a quote for converting from one currency to another
8352
+ :see: https://bybit-exchange.github.io/docs/v5/asset/convert/apply-quote
8353
+ :param str fromCode: the currency that you want to sell and convert from
8354
+ :param str toCode: the currency that you want to buy and convert into
8355
+ :param float [amount]: how much you want to trade in units of the from currency
8356
+ :param dict [params]: extra parameters specific to the exchange API endpoint
8357
+ :param str [params.accountType]: eb_convert_uta, eb_convert_spot, eb_convert_funding, eb_convert_inverse, or eb_convert_contract
8358
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
8359
+ """
8360
+ self.load_markets()
8361
+ accountType = None
8362
+ enableUnifiedMargin, enableUnifiedAccount = self.is_unified_enabled()
8363
+ isUnifiedAccount = (enableUnifiedMargin or enableUnifiedAccount)
8364
+ accountTypeDefault = 'eb_convert_uta' if isUnifiedAccount else 'eb_convert_spot'
8365
+ accountType, params = self.handle_option_and_params(params, 'fetchConvertQuote', 'accountType', accountTypeDefault)
8366
+ request: dict = {
8367
+ 'fromCoin': fromCode,
8368
+ 'toCoin': toCode,
8369
+ 'requestAmount': self.number_to_string(amount),
8370
+ 'requestCoin': fromCode,
8371
+ 'accountType': accountType,
8372
+ }
8373
+ response = self.privatePostV5AssetExchangeQuoteApply(self.extend(request, params))
8374
+ #
8375
+ # {
8376
+ # "retCode": 0,
8377
+ # "retMsg": "ok",
8378
+ # "result": {
8379
+ # "quoteTxId": "1010020692439481682687668224",
8380
+ # "exchangeRate": "0.000015330836780000",
8381
+ # "fromCoin": "USDT",
8382
+ # "fromCoinType": "crypto",
8383
+ # "toCoin": "BTC",
8384
+ # "toCoinType": "crypto",
8385
+ # "fromAmount": "10",
8386
+ # "toAmount": "0.000153308367800000",
8387
+ # "expiredTime": "1727257413353",
8388
+ # "requestId": ""
8389
+ # },
8390
+ # "retExtInfo": {},
8391
+ # "time": 1727257398375
8392
+ # }
8393
+ #
8394
+ data = self.safe_dict(response, 'result', {})
8395
+ fromCurrencyId = self.safe_string(data, 'fromCoin', fromCode)
8396
+ fromCurrency = self.currency(fromCurrencyId)
8397
+ toCurrencyId = self.safe_string(data, 'toCoin', toCode)
8398
+ toCurrency = self.currency(toCurrencyId)
8399
+ return self.parse_conversion(data, fromCurrency, toCurrency)
8400
+
8401
+ def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
8402
+ """
8403
+ convert from one currency to another
8404
+ :see: https://bybit-exchange.github.io/docs/v5/asset/convert/confirm-quote
8405
+ :param str id: the id of the trade that you want to make
8406
+ :param str fromCode: the currency that you want to sell and convert from
8407
+ :param str toCode: the currency that you want to buy and convert into
8408
+ :param float amount: how much you want to trade in units of the from currency
8409
+ :param dict [params]: extra parameters specific to the exchange API endpoint
8410
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
8411
+ """
8412
+ self.load_markets()
8413
+ request: dict = {
8414
+ 'quoteTxId': id,
8415
+ }
8416
+ response = self.privatePostV5AssetExchangeConvertExecute(self.extend(request, params))
8417
+ #
8418
+ # {
8419
+ # "retCode": 0,
8420
+ # "retMsg": "ok",
8421
+ # "result": {
8422
+ # "exchangeStatus": "processing",
8423
+ # "quoteTxId": "1010020692439483803499737088"
8424
+ # },
8425
+ # "retExtInfo": {},
8426
+ # "time": 1727257904969
8427
+ # }
8428
+ #
8429
+ data = self.safe_dict(response, 'result', {})
8430
+ return self.parse_conversion(data)
8431
+
8432
+ def fetch_convert_trade(self, id: str, code: Str = None, params={}) -> Conversion:
8433
+ """
8434
+ fetch the data for a conversion trade
8435
+ :see: https://bybit-exchange.github.io/docs/v5/asset/convert/get-convert-result
8436
+ :param str id: the id of the trade that you want to fetch
8437
+ :param str [code]: the unified currency code of the conversion trade
8438
+ :param dict [params]: extra parameters specific to the exchange API endpoint
8439
+ :param str [params.accountType]: eb_convert_uta, eb_convert_spot, eb_convert_funding, eb_convert_inverse, or eb_convert_contract
8440
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
8441
+ """
8442
+ self.load_markets()
8443
+ accountType = None
8444
+ enableUnifiedMargin, enableUnifiedAccount = self.is_unified_enabled()
8445
+ isUnifiedAccount = (enableUnifiedMargin or enableUnifiedAccount)
8446
+ accountTypeDefault = 'eb_convert_uta' if isUnifiedAccount else 'eb_convert_spot'
8447
+ accountType, params = self.handle_option_and_params(params, 'fetchConvertQuote', 'accountType', accountTypeDefault)
8448
+ request: dict = {
8449
+ 'quoteTxId': id,
8450
+ 'accountType': accountType,
8451
+ }
8452
+ response = self.privateGetV5AssetExchangeConvertResultQuery(self.extend(request, params))
8453
+ #
8454
+ # {
8455
+ # "retCode": 0,
8456
+ # "retMsg": "ok",
8457
+ # "result": {
8458
+ # "result": {
8459
+ # "accountType": "eb_convert_uta",
8460
+ # "exchangeTxId": "1010020692439483803499737088",
8461
+ # "userId": "100406395",
8462
+ # "fromCoin": "USDT",
8463
+ # "fromCoinType": "crypto",
8464
+ # "fromAmount": "10",
8465
+ # "toCoin": "BTC",
8466
+ # "toCoinType": "crypto",
8467
+ # "toAmount": "0.00015344889",
8468
+ # "exchangeStatus": "success",
8469
+ # "extInfo": {},
8470
+ # "convertRate": "0.000015344889",
8471
+ # "createdAt": "1727257904726"
8472
+ # }
8473
+ # },
8474
+ # "retExtInfo": {},
8475
+ # "time": 1727258257216
8476
+ # }
8477
+ #
8478
+ data = self.safe_dict(response, 'result', {})
8479
+ result = self.safe_dict(data, 'result', {})
8480
+ fromCurrencyId = self.safe_string(result, 'fromCoin')
8481
+ toCurrencyId = self.safe_string(result, 'toCoin')
8482
+ fromCurrency = None
8483
+ toCurrency = None
8484
+ if fromCurrencyId is not None:
8485
+ fromCurrency = self.currency(fromCurrencyId)
8486
+ if toCurrencyId is not None:
8487
+ toCurrency = self.currency(toCurrencyId)
8488
+ return self.parse_conversion(result, fromCurrency, toCurrency)
8489
+
8490
+ def fetch_convert_trade_history(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Conversion]:
8491
+ """
8492
+ fetch the users history of conversion trades
8493
+ :see: https://bybit-exchange.github.io/docs/v5/asset/convert/get-convert-history
8494
+ :param str [code]: the unified currency code
8495
+ :param int [since]: the earliest time in ms to fetch conversions for
8496
+ :param int [limit]: the maximum number of conversion structures to retrieve
8497
+ :param dict [params]: extra parameters specific to the exchange API endpoint
8498
+ :param str [params.accountType]: eb_convert_uta, eb_convert_spot, eb_convert_funding, eb_convert_inverse, or eb_convert_contract
8499
+ :returns dict[]: a list of `conversion structures <https://docs.ccxt.com/#/?id=conversion-structure>`
8500
+ """
8501
+ self.load_markets()
8502
+ request: dict = {}
8503
+ if limit is not None:
8504
+ request['limit'] = limit
8505
+ response = self.privateGetV5AssetExchangeQueryConvertHistory(self.extend(request, params))
8506
+ #
8507
+ # {
8508
+ # "retCode": 0,
8509
+ # "retMsg": "ok",
8510
+ # "result": {
8511
+ # "list": [
8512
+ # {
8513
+ # "accountType": "eb_convert_uta",
8514
+ # "exchangeTxId": "1010020692439483803499737088",
8515
+ # "userId": "100406395",
8516
+ # "fromCoin": "USDT",
8517
+ # "fromCoinType": "crypto",
8518
+ # "fromAmount": "10",
8519
+ # "toCoin": "BTC",
8520
+ # "toCoinType": "crypto",
8521
+ # "toAmount": "0.00015344889",
8522
+ # "exchangeStatus": "success",
8523
+ # "extInfo": {},
8524
+ # "convertRate": "0.000015344889",
8525
+ # "createdAt": "1727257904726"
8526
+ # }
8527
+ # ]
8528
+ # },
8529
+ # "retExtInfo": {},
8530
+ # "time": 1727258761874
8531
+ # }
8532
+ #
8533
+ data = self.safe_dict(response, 'result', {})
8534
+ dataList = self.safe_list(data, 'list', [])
8535
+ return self.parse_conversions(dataList, code, 'fromCoin', 'toCoin', since, limit)
8536
+
8537
+ def parse_conversion(self, conversion: dict, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
8538
+ #
8539
+ # fetchConvertQuote
8540
+ #
8541
+ # {
8542
+ # "quoteTxId": "1010020692439481682687668224",
8543
+ # "exchangeRate": "0.000015330836780000",
8544
+ # "fromCoin": "USDT",
8545
+ # "fromCoinType": "crypto",
8546
+ # "toCoin": "BTC",
8547
+ # "toCoinType": "crypto",
8548
+ # "fromAmount": "10",
8549
+ # "toAmount": "0.000153308367800000",
8550
+ # "expiredTime": "1727257413353",
8551
+ # "requestId": ""
8552
+ # }
8553
+ #
8554
+ # createConvertTrade
8555
+ #
8556
+ # {
8557
+ # "exchangeStatus": "processing",
8558
+ # "quoteTxId": "1010020692439483803499737088"
8559
+ # }
8560
+ #
8561
+ # fetchConvertTrade, fetchConvertTradeHistory
8562
+ #
8563
+ # {
8564
+ # "accountType": "eb_convert_uta",
8565
+ # "exchangeTxId": "1010020692439483803499737088",
8566
+ # "userId": "100406395",
8567
+ # "fromCoin": "USDT",
8568
+ # "fromCoinType": "crypto",
8569
+ # "fromAmount": "10",
8570
+ # "toCoin": "BTC",
8571
+ # "toCoinType": "crypto",
8572
+ # "toAmount": "0.00015344889",
8573
+ # "exchangeStatus": "success",
8574
+ # "extInfo": {},
8575
+ # "convertRate": "0.000015344889",
8576
+ # "createdAt": "1727257904726"
8577
+ # }
8578
+ #
8579
+ timestamp = self.safe_integer_2(conversion, 'expiredTime', 'createdAt')
8580
+ fromCoin = self.safe_string(conversion, 'fromCoin')
8581
+ fromCode = self.safe_currency_code(fromCoin, fromCurrency)
8582
+ to = self.safe_string(conversion, 'toCoin')
8583
+ toCode = self.safe_currency_code(to, toCurrency)
8584
+ return {
8585
+ 'info': conversion,
8586
+ 'timestamp': timestamp,
8587
+ 'datetime': self.iso8601(timestamp),
8588
+ 'id': self.safe_string_2(conversion, 'quoteTxId', 'exchangeTxId'),
8589
+ 'fromCurrency': fromCode,
8590
+ 'fromAmount': self.safe_number(conversion, 'fromAmount'),
8591
+ 'toCurrency': toCode,
8592
+ 'toAmount': self.safe_number(conversion, 'toAmount'),
8593
+ 'price': None,
8594
+ 'fee': None,
8595
+ }
8596
+
8248
8597
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
8249
8598
  url = self.implode_hostname(self.urls['api'][api]) + '/' + path
8250
8599
  if api == 'public':
ccxt/htx.py CHANGED
@@ -2030,6 +2030,10 @@ class htx(Exchange, ImplicitAPI):
2030
2030
  def fetch_ticker(self, symbol: str, params={}) -> Ticker:
2031
2031
  """
2032
2032
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
2033
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#get-latest-aggregated-ticker
2034
+ :see: https://huobiapi.github.io/docs/dm/v1/en/#get-market-data-overview
2035
+ :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-market-data-overview
2036
+ :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-market-data-overview
2033
2037
  :param str symbol: unified symbol of the market to fetch the ticker for
2034
2038
  :param dict [params]: extra parameters specific to the exchange API endpoint
2035
2039
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -2323,6 +2327,10 @@ class htx(Exchange, ImplicitAPI):
2323
2327
  def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
2324
2328
  """
2325
2329
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
2330
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#get-market-depth
2331
+ :see: https://huobiapi.github.io/docs/dm/v1/en/#get-market-depth
2332
+ :see: https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-market-depth
2333
+ :see: https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-market-depth
2326
2334
  :param str symbol: unified symbol of the market to fetch the order book for
2327
2335
  :param int [limit]: the maximum amount of order book entries to return
2328
2336
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2534,6 +2542,7 @@ class htx(Exchange, ImplicitAPI):
2534
2542
  def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2535
2543
  """
2536
2544
  fetch all the trades made from a single order
2545
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#get-the-match-result-of-an-order
2537
2546
  :param str id: order id
2538
2547
  :param str symbol: unified market symbol
2539
2548
  :param int [since]: the earliest time in ms to fetch trades for
@@ -2551,6 +2560,17 @@ class htx(Exchange, ImplicitAPI):
2551
2560
  return self.fetch_spot_order_trades(id, symbol, since, limit, params)
2552
2561
 
2553
2562
  def fetch_spot_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2563
+ """
2564
+ * @ignore
2565
+ fetch all the trades made from a single order
2566
+ :see: https://huobiapi.github.io/docs/spot/v1/en/#get-the-match-result-of-an-order
2567
+ :param str id: order id
2568
+ :param str symbol: unified market symbol
2569
+ :param int [since]: the earliest time in ms to fetch trades for
2570
+ :param int [limit]: the maximum number of trades to retrieve
2571
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2572
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
2573
+ """
2554
2574
  self.load_markets()
2555
2575
  request: dict = {
2556
2576
  'order-id': id,