ccxt 4.4.24__py2.py3-none-any.whl → 4.4.26__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.
Files changed (61) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/alpaca.py +1 -0
  3. ccxt/abstract/bingx.py +1 -0
  4. ccxt/abstract/okx.py +1 -0
  5. ccxt/abstract/phemex.py +1 -0
  6. ccxt/alpaca.py +245 -12
  7. ccxt/async_support/__init__.py +1 -1
  8. ccxt/async_support/alpaca.py +245 -12
  9. ccxt/async_support/base/exchange.py +6 -6
  10. ccxt/async_support/binance.py +5 -6
  11. ccxt/async_support/bingx.py +6 -1
  12. ccxt/async_support/bitget.py +5 -5
  13. ccxt/async_support/bitmart.py +6 -6
  14. ccxt/async_support/bitmex.py +8 -7
  15. ccxt/async_support/bybit.py +6 -15
  16. ccxt/async_support/cex.py +36 -0
  17. ccxt/async_support/coinex.py +50 -28
  18. ccxt/async_support/digifinex.py +5 -5
  19. ccxt/async_support/exmo.py +1 -0
  20. ccxt/async_support/gate.py +6 -6
  21. ccxt/async_support/hitbtc.py +5 -9
  22. ccxt/async_support/htx.py +21 -22
  23. ccxt/async_support/hyperliquid.py +12 -4
  24. ccxt/async_support/kucoin.py +5 -5
  25. ccxt/async_support/okx.py +6 -5
  26. ccxt/async_support/phemex.py +4 -2
  27. ccxt/async_support/whitebit.py +5 -5
  28. ccxt/async_support/woo.py +1 -1
  29. ccxt/async_support/woofipro.py +1 -1
  30. ccxt/async_support/xt.py +36 -25
  31. ccxt/base/exchange.py +11 -6
  32. ccxt/base/types.py +12 -0
  33. ccxt/binance.py +5 -6
  34. ccxt/bingx.py +6 -1
  35. ccxt/bitget.py +5 -5
  36. ccxt/bitmart.py +6 -6
  37. ccxt/bitmex.py +8 -7
  38. ccxt/bybit.py +6 -15
  39. ccxt/cex.py +36 -0
  40. ccxt/coinex.py +50 -28
  41. ccxt/digifinex.py +5 -5
  42. ccxt/exmo.py +1 -0
  43. ccxt/gate.py +6 -6
  44. ccxt/hitbtc.py +5 -9
  45. ccxt/htx.py +21 -22
  46. ccxt/hyperliquid.py +12 -4
  47. ccxt/kucoin.py +5 -5
  48. ccxt/okx.py +6 -5
  49. ccxt/phemex.py +4 -2
  50. ccxt/pro/__init__.py +1 -1
  51. ccxt/pro/exmo.py +204 -4
  52. ccxt/test/tests_helpers.py +3 -1
  53. ccxt/whitebit.py +5 -5
  54. ccxt/woo.py +1 -1
  55. ccxt/woofipro.py +1 -1
  56. ccxt/xt.py +36 -25
  57. {ccxt-4.4.24.dist-info → ccxt-4.4.26.dist-info}/METADATA +7 -7
  58. {ccxt-4.4.24.dist-info → ccxt-4.4.26.dist-info}/RECORD +61 -61
  59. {ccxt-4.4.24.dist-info → ccxt-4.4.26.dist-info}/LICENSE.txt +0 -0
  60. {ccxt-4.4.24.dist-info → ccxt-4.4.26.dist-info}/WHEEL +0 -0
  61. {ccxt-4.4.24.dist-info → ccxt-4.4.26.dist-info}/top_level.txt +0 -0
@@ -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 LongShortRatio, Balances, Conversion, CrossBorrowRate, Currencies, Currency, DepositAddress, Greeks, Int, LedgerEntry, Leverage, LeverageTier, LeverageTiers, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
10
+ from ccxt.base.types import Balances, BorrowInterest, Conversion, CrossBorrowRate, Currencies, Currency, DepositAddress, Greeks, Int, LedgerEntry, Leverage, LeverageTier, LeverageTiers, LongShortRatio, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, 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
@@ -1019,7 +1019,6 @@ class bybit(Exchange, ImplicitAPI):
1019
1019
  'precisionMode': TICK_SIZE,
1020
1020
  'options': {
1021
1021
  'usePrivateInstrumentsInfo': False,
1022
- 'sandboxMode': False,
1023
1022
  'enableDemoTrading': False,
1024
1023
  'fetchMarkets': ['spot', 'linear', 'inverse', 'option'],
1025
1024
  'createOrder': {
@@ -1105,21 +1104,13 @@ class bybit(Exchange, ImplicitAPI):
1105
1104
  },
1106
1105
  })
1107
1106
 
1108
- def set_sandbox_mode(self, enable: bool):
1109
- """
1110
- enables or disables sandbox mode
1111
- :param boolean [enable]: True if demo trading should be enabled, False otherwise
1112
- """
1113
- super(bybit, self).set_sandbox_mode(enable)
1114
- self.options['sandboxMode'] = enable
1115
-
1116
1107
  def enable_demo_trading(self, enable: bool):
1117
1108
  """
1118
1109
  enables or disables demo trading mode
1119
1110
  :see: https://bybit-exchange.github.io/docs/v5/demo
1120
1111
  :param boolean [enable]: True if demo trading should be enabled, False otherwise
1121
1112
  """
1122
- if self.options['sandboxMode']:
1113
+ if self.isSandboxModeEnabled:
1123
1114
  raise NotSupported(self.id + ' demo trading does not support in sandbox environment')
1124
1115
  # enable demo trading in bybit, see: https://bybit-exchange.github.io/docs/v5/demo
1125
1116
  if enable:
@@ -6833,7 +6824,7 @@ class bybit(Exchange, ImplicitAPI):
6833
6824
  'info': info,
6834
6825
  }
6835
6826
 
6836
- async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6827
+ async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
6837
6828
  """
6838
6829
  fetch the interest owed by the user for borrowing currency for margin trading
6839
6830
  :see: https://bybit-exchange.github.io/docs/zh-TW/v5/spot-margin-normal/account-info
@@ -6924,7 +6915,7 @@ class bybit(Exchange, ImplicitAPI):
6924
6915
  rows = self.safe_list(data, 'list', [])
6925
6916
  return self.parse_borrow_rate_history(rows, code, since, limit)
6926
6917
 
6927
- def parse_borrow_interest(self, info: dict, market: Market = None):
6918
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
6928
6919
  #
6929
6920
  # {
6930
6921
  # "tokenId": "BTC",
@@ -6936,15 +6927,15 @@ class bybit(Exchange, ImplicitAPI):
6936
6927
  # },
6937
6928
  #
6938
6929
  return {
6930
+ 'info': info,
6939
6931
  'symbol': None,
6940
- 'marginMode': 'cross',
6941
6932
  'currency': self.safe_currency_code(self.safe_string(info, 'tokenId')),
6942
6933
  'interest': self.safe_number(info, 'interest'),
6943
6934
  'interestRate': None,
6944
6935
  'amountBorrowed': self.safe_number(info, 'loan'),
6936
+ 'marginMode': 'cross',
6945
6937
  'timestamp': None,
6946
6938
  'datetime': None,
6947
- 'info': info,
6948
6939
  }
6949
6940
 
6950
6941
  async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
ccxt/async_support/cex.py CHANGED
@@ -40,6 +40,7 @@ class cex(Exchange, ImplicitAPI):
40
40
  'createOrder': True,
41
41
  'fetchAccounts': True,
42
42
  'fetchBalance': True,
43
+ 'fetchClosedOrder': True,
43
44
  'fetchClosedOrders': True,
44
45
  'fetchCurrencies': True,
45
46
  'fetchDepositAddress': True,
@@ -51,6 +52,7 @@ class cex(Exchange, ImplicitAPI):
51
52
  'fetchLedger': True,
52
53
  'fetchMarkets': True,
53
54
  'fetchOHLCV': True,
55
+ 'fetchOpenOrder': True,
54
56
  'fetchOpenOrders': True,
55
57
  'fetchOrderBook': True,
56
58
  'fetchTicker': True,
@@ -899,6 +901,7 @@ class cex(Exchange, ImplicitAPI):
899
901
 
900
902
  async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
901
903
  """
904
+ :see: https://trade.cex.io/docs/#rest-private-api-calls-orders
902
905
  fetches information on multiple canceled orders made by the user
903
906
  :param str symbol: unified market symbol of the market orders were made in
904
907
  :param int [since]: timestamp in ms of the earliest order, default is None
@@ -910,6 +913,7 @@ class cex(Exchange, ImplicitAPI):
910
913
 
911
914
  async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
912
915
  """
916
+ :see: https://trade.cex.io/docs/#rest-private-api-calls-orders
913
917
  fetches information on multiple canceled orders made by the user
914
918
  :param str symbol: unified market symbol of the market orders were made in
915
919
  :param int [since]: timestamp in ms of the earliest order, default is None
@@ -919,6 +923,38 @@ class cex(Exchange, ImplicitAPI):
919
923
  """
920
924
  return await self.fetch_orders_by_status('open', symbol, since, limit, params)
921
925
 
926
+ async def fetch_open_order(self, id: str, symbol: Str = None, params={}):
927
+ """
928
+ fetches information on an open order made by the user
929
+ :see: https://trade.cex.io/docs/#rest-private-api-calls-orders
930
+ :param str id: order id
931
+ :param str [symbol]: unified symbol of the market the order was made in
932
+ :param dict [params]: extra parameters specific to the exchange API endpoint
933
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
934
+ """
935
+ await self.load_markets()
936
+ request: dict = {
937
+ 'orderId': int(id),
938
+ }
939
+ result = await self.fetch_open_orders(symbol, None, None, self.extend(request, params))
940
+ return result[0]
941
+
942
+ async def fetch_closed_order(self, id: str, symbol: Str = None, params={}):
943
+ """
944
+ fetches information on an closed order made by the user
945
+ :see: https://trade.cex.io/docs/#rest-private-api-calls-orders
946
+ :param str id: order id
947
+ :param str [symbol]: unified symbol of the market the order was made in
948
+ :param dict [params]: extra parameters specific to the exchange API endpoint
949
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
950
+ """
951
+ await self.load_markets()
952
+ request: dict = {
953
+ 'orderId': int(id),
954
+ }
955
+ result = await self.fetch_closed_orders(symbol, None, None, self.extend(request, params))
956
+ return result[0]
957
+
922
958
  def parse_order_status(self, status: Str):
923
959
  statuses: dict = {
924
960
  'FILLED': 'closed',
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.coinex import ImplicitAPI
8
8
  import asyncio
9
- from ccxt.base.types import Balances, Currencies, Currency, DepositAddress, Int, IsolatedBorrowRate, Leverage, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
9
+ from ccxt.base.types import Balances, BorrowInterest, Currencies, Currency, DepositAddress, Int, IsolatedBorrowRate, Leverage, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, 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
@@ -474,9 +474,43 @@ class coinex(Exchange, ImplicitAPI):
474
474
  'FUTURES': 'swap',
475
475
  },
476
476
  'networks': {
477
+ 'BTC': 'BTC',
477
478
  'BEP20': 'BSC',
478
- 'TRX': 'TRC20',
479
- 'ETH': 'ERC20',
479
+ 'TRC20': 'TRC20',
480
+ 'ERC20': 'ERC20',
481
+ 'BRC20': 'BRC20',
482
+ 'SOL': 'SOL',
483
+ 'TON': 'SOL',
484
+ 'BSV': 'BSV',
485
+ 'AVAXC': 'AVA_C',
486
+ 'AVAXX': 'AVA',
487
+ 'SUI': 'SUI',
488
+ 'ACA': 'ACA',
489
+ 'CHZ': 'CHILIZ',
490
+ 'ADA': 'ADA',
491
+ 'ARB': 'ARBITRUM',
492
+ 'ARBNOVA': 'ARBITRUM_NOVA',
493
+ 'OP': 'OPTIMISM',
494
+ 'APT': 'APTOS',
495
+ 'ATOM': 'ATOM',
496
+ 'FTM': 'FTM',
497
+ 'BCH': 'BCH',
498
+ 'ASTR': 'ASTR',
499
+ 'LTC': 'LTC',
500
+ 'MATIC': 'MATIC',
501
+ 'CRONOS': 'CRONOS',
502
+ 'DASH': 'DASH',
503
+ 'DOT': 'DOT',
504
+ 'ETC': 'ETC',
505
+ 'ETHW': 'ETHPOW',
506
+ 'FIL': 'FIL',
507
+ 'ZIL': 'ZIL',
508
+ 'DOGE': 'DOGE',
509
+ 'TIA': 'CELESTIA',
510
+ 'SEI': 'SEI',
511
+ 'XRP': 'XRP',
512
+ 'XMR': 'XMR',
513
+ # 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
480
514
  },
481
515
  },
482
516
  'commonCurrencies': {
@@ -3547,20 +3581,14 @@ class coinex(Exchange, ImplicitAPI):
3547
3581
  """
3548
3582
  await self.load_markets()
3549
3583
  currency = self.currency(code)
3550
- networks = self.safe_dict(currency, 'networks', {})
3551
- network = self.safe_string_2(params, 'network', 'chain')
3552
- params = self.omit(params, 'network')
3553
- networksKeys = list(networks.keys())
3554
- numOfNetworks = len(networksKeys)
3555
- if networks is not None and numOfNetworks > 1:
3556
- if network is None:
3557
- raise ArgumentsRequired(self.id + ' fetchDepositAddress() ' + code + ' requires a network parameter')
3558
- if not (network in networks):
3559
- raise ExchangeError(self.id + ' fetchDepositAddress() ' + network + ' network not supported for ' + code)
3560
3584
  request: dict = {
3561
3585
  'ccy': currency['id'],
3562
- 'chain': network,
3563
3586
  }
3587
+ networkCode = None
3588
+ networkCode, params = self.handle_network_code_and_params(params)
3589
+ if networkCode is None:
3590
+ raise ArgumentsRequired(self.id + ' fetchDepositAddress() requires a "network" parameter')
3591
+ request['chain'] = self.network_code_to_id(networkCode) # required for on-chain, not required for inter-user transfer
3564
3592
  response = await self.v2PrivateGetAssetsDepositAddress(self.extend(request, params))
3565
3593
  #
3566
3594
  # {
@@ -3573,12 +3601,7 @@ class coinex(Exchange, ImplicitAPI):
3573
3601
  # }
3574
3602
  #
3575
3603
  data = self.safe_dict(response, 'data', {})
3576
- depositAddress = self.parse_deposit_address(data, currency)
3577
- options = self.safe_dict(self.options, 'fetchDepositAddress', {})
3578
- fillResponseFromRequest = self.safe_bool(options, 'fillResponseFromRequest', True)
3579
- if fillResponseFromRequest:
3580
- depositAddress['network'] = self.network_id_to_code(network, currency).upper()
3581
- return depositAddress
3604
+ return self.parse_deposit_address(data, currency)
3582
3605
 
3583
3606
  def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
3584
3607
  #
@@ -4418,8 +4441,6 @@ class coinex(Exchange, ImplicitAPI):
4418
4441
  self.check_address(address)
4419
4442
  await self.load_markets()
4420
4443
  currency = self.currency(code)
4421
- networkCode = self.safe_string_upper_2(params, 'network', 'chain')
4422
- params = self.omit(params, 'network')
4423
4444
  if tag:
4424
4445
  address = address + ':' + tag
4425
4446
  request: dict = {
@@ -4427,6 +4448,8 @@ class coinex(Exchange, ImplicitAPI):
4427
4448
  'to_address': address, # must be authorized, inter-user transfer by a registered mobile phone number or an email address is supported
4428
4449
  'amount': self.number_to_string(amount), # the actual amount without fees, https://www.coinex.com/fees
4429
4450
  }
4451
+ networkCode = None
4452
+ networkCode, params = self.handle_network_code_and_params(params)
4430
4453
  if networkCode is not None:
4431
4454
  request['chain'] = self.network_code_to_id(networkCode) # required for on-chain, not required for inter-user transfer
4432
4455
  response = await self.v2PrivatePostAssetsWithdraw(self.extend(request, params))
@@ -4463,6 +4486,7 @@ class coinex(Exchange, ImplicitAPI):
4463
4486
  statuses: dict = {
4464
4487
  'audit': 'pending',
4465
4488
  'pass': 'pending',
4489
+ 'audit_required': 'pending',
4466
4490
  'processing': 'pending',
4467
4491
  'confirming': 'pending',
4468
4492
  'not_pass': 'failed',
@@ -4936,7 +4960,7 @@ class coinex(Exchange, ImplicitAPI):
4936
4960
  data = self.safe_dict(response, 'data', {})
4937
4961
  return self.parse_isolated_borrow_rate(data, market)
4938
4962
 
4939
- async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4963
+ async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
4940
4964
  """
4941
4965
  fetch the interest owed by the user for borrowing currency for margin trading
4942
4966
  :see: https://docs.coinex.com/api/v2/assets/loan-flat/http/list-margin-borrow-history
@@ -4984,7 +5008,7 @@ class coinex(Exchange, ImplicitAPI):
4984
5008
  interest = self.parse_borrow_interests(rows, market)
4985
5009
  return self.filter_by_currency_since_limit(interest, code, since, limit)
4986
5010
 
4987
- def parse_borrow_interest(self, info: dict, market: Market = None):
5011
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
4988
5012
  #
4989
5013
  # {
4990
5014
  # "borrow_id": 2642934,
@@ -5003,17 +5027,15 @@ class coinex(Exchange, ImplicitAPI):
5003
5027
  market = self.safe_market(marketId, market, None, 'spot')
5004
5028
  timestamp = self.safe_integer(info, 'expired_at')
5005
5029
  return {
5006
- 'account': None, # deprecated
5030
+ 'info': info,
5007
5031
  'symbol': market['symbol'],
5008
- 'marginMode': 'isolated',
5009
- 'marginType': None, # deprecated
5010
5032
  'currency': self.safe_currency_code(self.safe_string(info, 'ccy')),
5011
5033
  'interest': self.safe_number(info, 'to_repaied_amount'),
5012
5034
  'interestRate': self.safe_number(info, 'daily_interest_rate'),
5013
5035
  'amountBorrowed': self.safe_number(info, 'borrow_amount'),
5036
+ 'marginMode': 'isolated',
5014
5037
  'timestamp': timestamp, # expiry time
5015
5038
  'datetime': self.iso8601(timestamp),
5016
- 'info': info,
5017
5039
  }
5018
5040
 
5019
5041
  async def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
@@ -8,7 +8,7 @@ from ccxt.abstract.digifinex import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
10
  import json
11
- from ccxt.base.types import Balances, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, DepositAddress, Int, LedgerEntry, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
11
+ from ccxt.base.types import Balances, BorrowInterest, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, DepositAddress, Int, LedgerEntry, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
12
12
  from typing import List
13
13
  from ccxt.base.errors import ExchangeError
14
14
  from ccxt.base.errors import AuthenticationError
@@ -2817,7 +2817,7 @@ class digifinex(Exchange, ImplicitAPI):
2817
2817
  #
2818
2818
  return self.parse_transaction(response, currency)
2819
2819
 
2820
- async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2820
+ async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
2821
2821
  await self.load_markets()
2822
2822
  request: dict = {}
2823
2823
  market = None
@@ -2850,7 +2850,7 @@ class digifinex(Exchange, ImplicitAPI):
2850
2850
  interest = self.parse_borrow_interests(rows, market)
2851
2851
  return self.filter_by_currency_since_limit(interest, code, since, limit)
2852
2852
 
2853
- def parse_borrow_interest(self, info: dict, market: Market = None):
2853
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
2854
2854
  #
2855
2855
  # {
2856
2856
  # "amount": 0.0006103,
@@ -2872,15 +2872,15 @@ class digifinex(Exchange, ImplicitAPI):
2872
2872
  currency = None if (market is None) else market['base']
2873
2873
  symbol = self.safe_symbol(marketId, market)
2874
2874
  return {
2875
- 'account': symbol,
2875
+ 'info': info,
2876
2876
  'symbol': symbol,
2877
2877
  'currency': currency,
2878
2878
  'interest': None,
2879
2879
  'interestRate': 0.001, # all interest rates on digifinex are 0.1%
2880
2880
  'amountBorrowed': self.parse_number(amountBorrowed),
2881
+ 'marginMode': None,
2881
2882
  'timestamp': None,
2882
2883
  'datetime': None,
2883
- 'info': info,
2884
2884
  }
2885
2885
 
2886
2886
  async def fetch_cross_borrow_rate(self, code: str, params={}) -> CrossBorrowRate:
@@ -223,6 +223,7 @@ class exmo(Exchange, ImplicitAPI):
223
223
  'precisionMode': TICK_SIZE,
224
224
  'exceptions': {
225
225
  'exact': {
226
+ '140333': InvalidOrder, # {"error":{"code":140333,"msg":"The number of characters after the point in the price exceeds the maximum number '8\u003e6'"}}
226
227
  '140434': BadRequest,
227
228
  '40005': AuthenticationError, # Authorization error, incorrect signature
228
229
  '40009': InvalidNonce, #
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.gate import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Balances, Bool, Currencies, Currency, DepositAddress, FundingHistory, Greeks, Int, LedgerEntry, Leverage, Leverages, LeverageTier, LeverageTiers, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
10
+ from ccxt.base.types import Balances, BorrowInterest, Bool, Currencies, Currency, DepositAddress, FundingHistory, Greeks, Int, LedgerEntry, Leverage, Leverages, LeverageTier, LeverageTiers, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, 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
@@ -5969,7 +5969,7 @@ class gate(Exchange, ImplicitAPI):
5969
5969
  'info': info,
5970
5970
  }
5971
5971
 
5972
- async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5972
+ async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
5973
5973
  """
5974
5974
  fetch the interest owed by the user for borrowing currency for margin trading
5975
5975
  :see: https://www.gate.io/docs/developers/apiv4/en/#list-interest-records
@@ -6014,21 +6014,21 @@ class gate(Exchange, ImplicitAPI):
6014
6014
  interest = self.parse_borrow_interests(response, market)
6015
6015
  return self.filter_by_currency_since_limit(interest, code, since, limit)
6016
6016
 
6017
- def parse_borrow_interest(self, info: dict, market: Market = None):
6017
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
6018
6018
  marketId = self.safe_string(info, 'currency_pair')
6019
6019
  market = self.safe_market(marketId, market)
6020
6020
  marginMode = 'isolated' if (marketId is not None) else 'cross'
6021
6021
  timestamp = self.safe_integer(info, 'create_time')
6022
6022
  return {
6023
6023
  'info': info,
6024
- 'timestamp': timestamp,
6025
- 'datetime': self.iso8601(timestamp),
6026
6024
  'symbol': self.safe_string(market, 'symbol'),
6027
6025
  'currency': self.safe_currency_code(self.safe_string(info, 'currency')),
6028
- 'marginMode': marginMode,
6029
6026
  'interest': self.safe_number(info, 'interest'),
6030
6027
  'interestRate': self.safe_number(info, 'actual_rate'),
6031
6028
  'amountBorrowed': None,
6029
+ 'marginMode': marginMode,
6030
+ 'timestamp': timestamp,
6031
+ 'datetime': self.iso8601(timestamp),
6032
6032
  }
6033
6033
 
6034
6034
  def sign(self, path, api=[], method='GET', params={}, headers=None, body=None):
@@ -859,7 +859,8 @@ class hitbtc(Exchange, ImplicitAPI):
859
859
  for j in range(0, len(rawNetworks)):
860
860
  rawNetwork = rawNetworks[j]
861
861
  networkId = self.safe_string_2(rawNetwork, 'protocol', 'network')
862
- network = self.safe_network(networkId)
862
+ networkCode = self.network_id_to_code(networkId)
863
+ networkCode = networkCode.upper() if (networkCode is not None) else None
863
864
  fee = self.safe_number(rawNetwork, 'payout_fee')
864
865
  networkPrecision = self.safe_number(rawNetwork, 'precision_payout')
865
866
  payinEnabledNetwork = self.safe_bool(rawNetwork, 'payin_enabled', False)
@@ -873,10 +874,10 @@ class hitbtc(Exchange, ImplicitAPI):
873
874
  withdrawEnabled = True
874
875
  elif not payoutEnabledNetwork:
875
876
  withdrawEnabled = False
876
- networks[network] = {
877
+ networks[networkCode] = {
877
878
  'info': rawNetwork,
878
879
  'id': networkId,
879
- 'network': network,
880
+ 'network': networkCode,
880
881
  'fee': fee,
881
882
  'active': activeNetwork,
882
883
  'deposit': payinEnabledNetwork,
@@ -911,12 +912,6 @@ class hitbtc(Exchange, ImplicitAPI):
911
912
  }
912
913
  return result
913
914
 
914
- def safe_network(self, networkId):
915
- if networkId is None:
916
- return None
917
- else:
918
- return networkId.upper()
919
-
920
915
  async def create_deposit_address(self, code: str, params={}):
921
916
  """
922
917
  create a currency deposit address
@@ -3298,6 +3293,7 @@ class hitbtc(Exchange, ImplicitAPI):
3298
3293
  networkEntry = networks[j]
3299
3294
  networkId = self.safe_string(networkEntry, 'network')
3300
3295
  networkCode = self.network_id_to_code(networkId)
3296
+ networkCode = networkCode.upper() if (networkCode is not None) else None
3301
3297
  withdrawFee = self.safe_number(networkEntry, 'payout_fee')
3302
3298
  isDefault = self.safe_value(networkEntry, 'default')
3303
3299
  withdrawResult: dict = {
ccxt/async_support/htx.py CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.htx import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Account, Balances, Currencies, Currency, DepositAddress, Int, IsolatedBorrowRate, IsolatedBorrowRates, LedgerEntry, LeverageTier, LeverageTiers, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, Transaction, TransferEntry
10
+ from ccxt.base.types import Account, Balances, BorrowInterest, Currencies, Currency, DepositAddress, Int, IsolatedBorrowRate, IsolatedBorrowRates, LedgerEntry, LeverageTier, LeverageTiers, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import AuthenticationError
@@ -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
- stopPrice = self.safe_string_2(params, 'stopPrice', 'stop-price')
4909
- if stopPrice is None:
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 stopPrice or a stop-price parameter for a stop order')
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, stopPrice)
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.safe_number_2(params, 'stopPrice', 'trigger_price')
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
- isStop = triggerPrice is not None
5013
+ isTrigger = triggerPrice is not None
5014
5014
  isStopLossTriggerOrder = stopLossTriggerPrice is not None
5015
5015
  isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
5016
- if isStop:
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.stopPrice]: the price a trigger order is triggered at
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.safe_number_2(params, 'stopPrice', 'trigger_price')
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
- isStop = triggerPrice is not None
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 isStop:
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 isStop:
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 isStop:
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 isStop:
5144
+ if isTrigger:
5145
5145
  response = await self.contractPrivatePostApiV1ContractTriggerOrder(contractRequest)
5146
5146
  elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
5147
5147
  response = await self.contractPrivatePostApiV1ContractTpslOrder(contractRequest)
@@ -6575,7 +6575,7 @@ class htx(Exchange, ImplicitAPI):
6575
6575
  result = self.parse_funding_rates(data)
6576
6576
  return self.filter_by_array(result, 'symbol', symbols)
6577
6577
 
6578
- async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6578
+ async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
6579
6579
  """
6580
6580
  fetch the interest owed by the user for borrowing currency for margin trading
6581
6581
  :see: https://huobiapi.github.io/docs/spot/v1/en/#search-past-margin-orders-cross
@@ -6634,7 +6634,7 @@ class htx(Exchange, ImplicitAPI):
6634
6634
  interest = self.parse_borrow_interests(data, market)
6635
6635
  return self.filter_by_currency_since_limit(interest, code, since, limit)
6636
6636
 
6637
- def parse_borrow_interest(self, info: dict, market: Market = None):
6637
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
6638
6638
  # isolated
6639
6639
  # {
6640
6640
  # "interest-rate":"0.000040830000000000",
@@ -6682,16 +6682,15 @@ class htx(Exchange, ImplicitAPI):
6682
6682
  symbol = self.safe_string(market, 'symbol')
6683
6683
  timestamp = self.safe_integer(info, 'accrued-at')
6684
6684
  return {
6685
- 'account': symbol if (marginMode == 'isolated') else 'cross', # deprecated
6685
+ 'info': info,
6686
6686
  'symbol': symbol,
6687
- 'marginMode': marginMode,
6688
6687
  'currency': self.safe_currency_code(self.safe_string(info, 'currency')),
6689
6688
  'interest': self.safe_number(info, 'interest-amount'),
6690
6689
  'interestRate': self.safe_number(info, 'interest-rate'),
6691
6690
  'amountBorrowed': self.safe_number(info, 'loan-amount'),
6691
+ 'marginMode': marginMode,
6692
6692
  'timestamp': timestamp, # Interest accrued time
6693
6693
  'datetime': self.iso8601(timestamp),
6694
- 'info': info,
6695
6694
  }
6696
6695
 
6697
6696
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
@@ -770,9 +770,16 @@ class hyperliquid(Exchange, ImplicitAPI):
770
770
  await self.load_markets()
771
771
  market = self.market(symbol)
772
772
  until = self.safe_integer(params, 'until', self.milliseconds())
773
- useTail = (since is None)
773
+ useTail = since is None
774
+ originalSince = since
774
775
  if since is None:
775
- since = 0
776
+ if limit is not None:
777
+ # optimization if limit is provided
778
+ timeframeInMilliseconds = self.parse_timeframe(timeframe) * 1000
779
+ since = self.sum(until, timeframeInMilliseconds * limit * -1)
780
+ useTail = False
781
+ else:
782
+ since = 0
776
783
  params = self.omit(params, ['until'])
777
784
  request: dict = {
778
785
  'type': 'candleSnapshot',
@@ -800,7 +807,7 @@ class hyperliquid(Exchange, ImplicitAPI):
800
807
  # }
801
808
  # ]
802
809
  #
803
- return self.parse_ohlcvs(response, market, timeframe, since, limit, useTail)
810
+ return self.parse_ohlcvs(response, market, timeframe, originalSince, limit, useTail)
804
811
 
805
812
  def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
806
813
  #
@@ -1534,7 +1541,8 @@ class hyperliquid(Exchange, ImplicitAPI):
1534
1541
  if since is not None:
1535
1542
  request['startTime'] = since
1536
1543
  else:
1537
- request['startTime'] = self.milliseconds() - 100 * 60 * 60 * 1000
1544
+ maxLimit = 500 if (limit is None) else limit
1545
+ request['startTime'] = self.milliseconds() - maxLimit * 60 * 60 * 1000
1538
1546
  until = self.safe_integer(params, 'until')
1539
1547
  params = self.omit(params, 'until')
1540
1548
  if until is not None: