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
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 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
9
+ 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
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -1018,7 +1018,6 @@ class bybit(Exchange, ImplicitAPI):
1018
1018
  'precisionMode': TICK_SIZE,
1019
1019
  'options': {
1020
1020
  'usePrivateInstrumentsInfo': False,
1021
- 'sandboxMode': False,
1022
1021
  'enableDemoTrading': False,
1023
1022
  'fetchMarkets': ['spot', 'linear', 'inverse', 'option'],
1024
1023
  'createOrder': {
@@ -1104,21 +1103,13 @@ class bybit(Exchange, ImplicitAPI):
1104
1103
  },
1105
1104
  })
1106
1105
 
1107
- def set_sandbox_mode(self, enable: bool):
1108
- """
1109
- enables or disables sandbox mode
1110
- :param boolean [enable]: True if demo trading should be enabled, False otherwise
1111
- """
1112
- super(bybit, self).set_sandbox_mode(enable)
1113
- self.options['sandboxMode'] = enable
1114
-
1115
1106
  def enable_demo_trading(self, enable: bool):
1116
1107
  """
1117
1108
  enables or disables demo trading mode
1118
1109
  :see: https://bybit-exchange.github.io/docs/v5/demo
1119
1110
  :param boolean [enable]: True if demo trading should be enabled, False otherwise
1120
1111
  """
1121
- if self.options['sandboxMode']:
1112
+ if self.isSandboxModeEnabled:
1122
1113
  raise NotSupported(self.id + ' demo trading does not support in sandbox environment')
1123
1114
  # enable demo trading in bybit, see: https://bybit-exchange.github.io/docs/v5/demo
1124
1115
  if enable:
@@ -6832,7 +6823,7 @@ class bybit(Exchange, ImplicitAPI):
6832
6823
  'info': info,
6833
6824
  }
6834
6825
 
6835
- def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6826
+ def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
6836
6827
  """
6837
6828
  fetch the interest owed by the user for borrowing currency for margin trading
6838
6829
  :see: https://bybit-exchange.github.io/docs/zh-TW/v5/spot-margin-normal/account-info
@@ -6923,7 +6914,7 @@ class bybit(Exchange, ImplicitAPI):
6923
6914
  rows = self.safe_list(data, 'list', [])
6924
6915
  return self.parse_borrow_rate_history(rows, code, since, limit)
6925
6916
 
6926
- def parse_borrow_interest(self, info: dict, market: Market = None):
6917
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
6927
6918
  #
6928
6919
  # {
6929
6920
  # "tokenId": "BTC",
@@ -6935,15 +6926,15 @@ class bybit(Exchange, ImplicitAPI):
6935
6926
  # },
6936
6927
  #
6937
6928
  return {
6929
+ 'info': info,
6938
6930
  'symbol': None,
6939
- 'marginMode': 'cross',
6940
6931
  'currency': self.safe_currency_code(self.safe_string(info, 'tokenId')),
6941
6932
  'interest': self.safe_number(info, 'interest'),
6942
6933
  'interestRate': None,
6943
6934
  'amountBorrowed': self.safe_number(info, 'loan'),
6935
+ 'marginMode': 'cross',
6944
6936
  'timestamp': None,
6945
6937
  'datetime': None,
6946
- 'info': info,
6947
6938
  }
6948
6939
 
6949
6940
  def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
ccxt/cex.py CHANGED
@@ -39,6 +39,7 @@ class cex(Exchange, ImplicitAPI):
39
39
  'createOrder': True,
40
40
  'fetchAccounts': True,
41
41
  'fetchBalance': True,
42
+ 'fetchClosedOrder': True,
42
43
  'fetchClosedOrders': True,
43
44
  'fetchCurrencies': True,
44
45
  'fetchDepositAddress': True,
@@ -50,6 +51,7 @@ class cex(Exchange, ImplicitAPI):
50
51
  'fetchLedger': True,
51
52
  'fetchMarkets': True,
52
53
  'fetchOHLCV': True,
54
+ 'fetchOpenOrder': True,
53
55
  'fetchOpenOrders': True,
54
56
  'fetchOrderBook': True,
55
57
  'fetchTicker': True,
@@ -898,6 +900,7 @@ class cex(Exchange, ImplicitAPI):
898
900
 
899
901
  def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
900
902
  """
903
+ :see: https://trade.cex.io/docs/#rest-private-api-calls-orders
901
904
  fetches information on multiple canceled orders made by the user
902
905
  :param str symbol: unified market symbol of the market orders were made in
903
906
  :param int [since]: timestamp in ms of the earliest order, default is None
@@ -909,6 +912,7 @@ class cex(Exchange, ImplicitAPI):
909
912
 
910
913
  def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
911
914
  """
915
+ :see: https://trade.cex.io/docs/#rest-private-api-calls-orders
912
916
  fetches information on multiple canceled orders made by the user
913
917
  :param str symbol: unified market symbol of the market orders were made in
914
918
  :param int [since]: timestamp in ms of the earliest order, default is None
@@ -918,6 +922,38 @@ class cex(Exchange, ImplicitAPI):
918
922
  """
919
923
  return self.fetch_orders_by_status('open', symbol, since, limit, params)
920
924
 
925
+ def fetch_open_order(self, id: str, symbol: Str = None, params={}):
926
+ """
927
+ fetches information on an open order made by the user
928
+ :see: https://trade.cex.io/docs/#rest-private-api-calls-orders
929
+ :param str id: order id
930
+ :param str [symbol]: unified symbol of the market the order was made in
931
+ :param dict [params]: extra parameters specific to the exchange API endpoint
932
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
933
+ """
934
+ self.load_markets()
935
+ request: dict = {
936
+ 'orderId': int(id),
937
+ }
938
+ result = self.fetch_open_orders(symbol, None, None, self.extend(request, params))
939
+ return result[0]
940
+
941
+ def fetch_closed_order(self, id: str, symbol: Str = None, params={}):
942
+ """
943
+ fetches information on an closed order made by the user
944
+ :see: https://trade.cex.io/docs/#rest-private-api-calls-orders
945
+ :param str id: order id
946
+ :param str [symbol]: unified symbol of the market the order was made in
947
+ :param dict [params]: extra parameters specific to the exchange API endpoint
948
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
949
+ """
950
+ self.load_markets()
951
+ request: dict = {
952
+ 'orderId': int(id),
953
+ }
954
+ result = self.fetch_closed_orders(symbol, None, None, self.extend(request, params))
955
+ return result[0]
956
+
921
957
  def parse_order_status(self, status: Str):
922
958
  statuses: dict = {
923
959
  'FILLED': 'closed',
ccxt/coinex.py CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.coinex import ImplicitAPI
8
- 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
8
+ 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
9
9
  from typing import List
10
10
  from ccxt.base.errors import ExchangeError
11
11
  from ccxt.base.errors import AuthenticationError
@@ -473,9 +473,43 @@ class coinex(Exchange, ImplicitAPI):
473
473
  'FUTURES': 'swap',
474
474
  },
475
475
  'networks': {
476
+ 'BTC': 'BTC',
476
477
  'BEP20': 'BSC',
477
- 'TRX': 'TRC20',
478
- 'ETH': 'ERC20',
478
+ 'TRC20': 'TRC20',
479
+ 'ERC20': 'ERC20',
480
+ 'BRC20': 'BRC20',
481
+ 'SOL': 'SOL',
482
+ 'TON': 'SOL',
483
+ 'BSV': 'BSV',
484
+ 'AVAXC': 'AVA_C',
485
+ 'AVAXX': 'AVA',
486
+ 'SUI': 'SUI',
487
+ 'ACA': 'ACA',
488
+ 'CHZ': 'CHILIZ',
489
+ 'ADA': 'ADA',
490
+ 'ARB': 'ARBITRUM',
491
+ 'ARBNOVA': 'ARBITRUM_NOVA',
492
+ 'OP': 'OPTIMISM',
493
+ 'APT': 'APTOS',
494
+ 'ATOM': 'ATOM',
495
+ 'FTM': 'FTM',
496
+ 'BCH': 'BCH',
497
+ 'ASTR': 'ASTR',
498
+ 'LTC': 'LTC',
499
+ 'MATIC': 'MATIC',
500
+ 'CRONOS': 'CRONOS',
501
+ 'DASH': 'DASH',
502
+ 'DOT': 'DOT',
503
+ 'ETC': 'ETC',
504
+ 'ETHW': 'ETHPOW',
505
+ 'FIL': 'FIL',
506
+ 'ZIL': 'ZIL',
507
+ 'DOGE': 'DOGE',
508
+ 'TIA': 'CELESTIA',
509
+ 'SEI': 'SEI',
510
+ 'XRP': 'XRP',
511
+ 'XMR': 'XMR',
512
+ # CSC, AE, BASE, AIPG, AKASH, POLKADOTASSETHUB ?, ALEO, STX, ALGO, ALPH, BLAST, AR, ARCH, ARDR, ARK, ARRR, MANTA, NTRN, LUNA, AURORA, AVAIL, ASC20, AVA, AYA, AZERO, BAN, BAND, BB, RUNES, BEAM, BELLSCOIN, BITCI, NEAR, AGORIC, BLOCX, BNC, BOBA, BRISE, KRC20, CANTO, CAPS, CCD, CELO, CFX, CHI, CKB, CLORE, CLV, CORE, CSPR, CTXC, DAG, DCR, DERO, DESO, DEFI, DGB, DNX, DOCK, DOGECHAIN, DYDX, DYMENSION, EGLD, ELA, ELF, ENJIN, EOSIO, ERG, ETN_SC, EVMOS, EWC, SGB, FACT, FB, FET, FIO, FIRO, NEO3, FLOW, FLARE, FLUX, LINEA, FREN, FSN, FB_BRC20, GLMR, GRIN, GRS, HACASH, HBAR, HERB, HIVE, MAPO, HMND, HNS, ZKSYNC, HTR, HUAHUA, MERLIN, ICP, ICX, INJ, IOST, IOTA, IOTX, IRIS, IRON, ONE, JOYSTREAM, KAI, KAR, KAS, KAVA, KCN, KDA, KLAY, KLY, KMD, KSM, KUB, KUJIRA, LAT, LBC, LUNC, LUKSO, MARS, METIS, MINA, MANTLE, MOB, MODE, MONA, MOVR, MTL, NEOX, NEXA, NIBI, NIMIQ, NMC, ONOMY, NRG, WAVES, NULS, OAS, OCTA, OLT, ONT, OORT, ORAI, OSMO, P3D, COMPOSABLE, PIVX, RON, POKT, POLYMESH, PRE_MARKET, PYI, QKC, QTUM, QUBIC, RSK, ROSE, ROUTE, RTM, THORCHAIN, RVN, RADIANT, SAGA, SALVIUM, SATOX, SC, SCP, _NULL, SCRT, SDN, RGBPP, SELF, SMH, SPACE, STARGAZE, STC, STEEM, STRATISEVM, STRD, STARKNET, SXP, SYS, TAIKO, TAO, TARA, TENET, THETA, TT, VENOM, VECHAIN, TOMO, VITE, VLX, VSYS, VTC, WAN, WAXP, WEMIX, XCH, XDC, XEC, XELIS, NEM, XHV, XLM, XNA, NANO, XPLA, XPR, XPRT, XRD, XTZ, XVG, XYM, ZANO, ZEC, ZEN, ZEPH, ZETA
479
513
  },
480
514
  },
481
515
  'commonCurrencies': {
@@ -3546,20 +3580,14 @@ class coinex(Exchange, ImplicitAPI):
3546
3580
  """
3547
3581
  self.load_markets()
3548
3582
  currency = self.currency(code)
3549
- networks = self.safe_dict(currency, 'networks', {})
3550
- network = self.safe_string_2(params, 'network', 'chain')
3551
- params = self.omit(params, 'network')
3552
- networksKeys = list(networks.keys())
3553
- numOfNetworks = len(networksKeys)
3554
- if networks is not None and numOfNetworks > 1:
3555
- if network is None:
3556
- raise ArgumentsRequired(self.id + ' fetchDepositAddress() ' + code + ' requires a network parameter')
3557
- if not (network in networks):
3558
- raise ExchangeError(self.id + ' fetchDepositAddress() ' + network + ' network not supported for ' + code)
3559
3583
  request: dict = {
3560
3584
  'ccy': currency['id'],
3561
- 'chain': network,
3562
3585
  }
3586
+ networkCode = None
3587
+ networkCode, params = self.handle_network_code_and_params(params)
3588
+ if networkCode is None:
3589
+ raise ArgumentsRequired(self.id + ' fetchDepositAddress() requires a "network" parameter')
3590
+ request['chain'] = self.network_code_to_id(networkCode) # required for on-chain, not required for inter-user transfer
3563
3591
  response = self.v2PrivateGetAssetsDepositAddress(self.extend(request, params))
3564
3592
  #
3565
3593
  # {
@@ -3572,12 +3600,7 @@ class coinex(Exchange, ImplicitAPI):
3572
3600
  # }
3573
3601
  #
3574
3602
  data = self.safe_dict(response, 'data', {})
3575
- depositAddress = self.parse_deposit_address(data, currency)
3576
- options = self.safe_dict(self.options, 'fetchDepositAddress', {})
3577
- fillResponseFromRequest = self.safe_bool(options, 'fillResponseFromRequest', True)
3578
- if fillResponseFromRequest:
3579
- depositAddress['network'] = self.network_id_to_code(network, currency).upper()
3580
- return depositAddress
3603
+ return self.parse_deposit_address(data, currency)
3581
3604
 
3582
3605
  def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
3583
3606
  #
@@ -4417,8 +4440,6 @@ class coinex(Exchange, ImplicitAPI):
4417
4440
  self.check_address(address)
4418
4441
  self.load_markets()
4419
4442
  currency = self.currency(code)
4420
- networkCode = self.safe_string_upper_2(params, 'network', 'chain')
4421
- params = self.omit(params, 'network')
4422
4443
  if tag:
4423
4444
  address = address + ':' + tag
4424
4445
  request: dict = {
@@ -4426,6 +4447,8 @@ class coinex(Exchange, ImplicitAPI):
4426
4447
  'to_address': address, # must be authorized, inter-user transfer by a registered mobile phone number or an email address is supported
4427
4448
  'amount': self.number_to_string(amount), # the actual amount without fees, https://www.coinex.com/fees
4428
4449
  }
4450
+ networkCode = None
4451
+ networkCode, params = self.handle_network_code_and_params(params)
4429
4452
  if networkCode is not None:
4430
4453
  request['chain'] = self.network_code_to_id(networkCode) # required for on-chain, not required for inter-user transfer
4431
4454
  response = self.v2PrivatePostAssetsWithdraw(self.extend(request, params))
@@ -4462,6 +4485,7 @@ class coinex(Exchange, ImplicitAPI):
4462
4485
  statuses: dict = {
4463
4486
  'audit': 'pending',
4464
4487
  'pass': 'pending',
4488
+ 'audit_required': 'pending',
4465
4489
  'processing': 'pending',
4466
4490
  'confirming': 'pending',
4467
4491
  'not_pass': 'failed',
@@ -4935,7 +4959,7 @@ class coinex(Exchange, ImplicitAPI):
4935
4959
  data = self.safe_dict(response, 'data', {})
4936
4960
  return self.parse_isolated_borrow_rate(data, market)
4937
4961
 
4938
- def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4962
+ def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
4939
4963
  """
4940
4964
  fetch the interest owed by the user for borrowing currency for margin trading
4941
4965
  :see: https://docs.coinex.com/api/v2/assets/loan-flat/http/list-margin-borrow-history
@@ -4983,7 +5007,7 @@ class coinex(Exchange, ImplicitAPI):
4983
5007
  interest = self.parse_borrow_interests(rows, market)
4984
5008
  return self.filter_by_currency_since_limit(interest, code, since, limit)
4985
5009
 
4986
- def parse_borrow_interest(self, info: dict, market: Market = None):
5010
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
4987
5011
  #
4988
5012
  # {
4989
5013
  # "borrow_id": 2642934,
@@ -5002,17 +5026,15 @@ class coinex(Exchange, ImplicitAPI):
5002
5026
  market = self.safe_market(marketId, market, None, 'spot')
5003
5027
  timestamp = self.safe_integer(info, 'expired_at')
5004
5028
  return {
5005
- 'account': None, # deprecated
5029
+ 'info': info,
5006
5030
  'symbol': market['symbol'],
5007
- 'marginMode': 'isolated',
5008
- 'marginType': None, # deprecated
5009
5031
  'currency': self.safe_currency_code(self.safe_string(info, 'ccy')),
5010
5032
  'interest': self.safe_number(info, 'to_repaied_amount'),
5011
5033
  'interestRate': self.safe_number(info, 'daily_interest_rate'),
5012
5034
  'amountBorrowed': self.safe_number(info, 'borrow_amount'),
5035
+ 'marginMode': 'isolated',
5013
5036
  'timestamp': timestamp, # expiry time
5014
5037
  'datetime': self.iso8601(timestamp),
5015
- 'info': info,
5016
5038
  }
5017
5039
 
5018
5040
  def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
ccxt/digifinex.py CHANGED
@@ -7,7 +7,7 @@ from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.digifinex import ImplicitAPI
8
8
  import hashlib
9
9
  import json
10
- 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
10
+ 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
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import AuthenticationError
@@ -2816,7 +2816,7 @@ class digifinex(Exchange, ImplicitAPI):
2816
2816
  #
2817
2817
  return self.parse_transaction(response, currency)
2818
2818
 
2819
- def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2819
+ def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
2820
2820
  self.load_markets()
2821
2821
  request: dict = {}
2822
2822
  market = None
@@ -2849,7 +2849,7 @@ class digifinex(Exchange, ImplicitAPI):
2849
2849
  interest = self.parse_borrow_interests(rows, market)
2850
2850
  return self.filter_by_currency_since_limit(interest, code, since, limit)
2851
2851
 
2852
- def parse_borrow_interest(self, info: dict, market: Market = None):
2852
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
2853
2853
  #
2854
2854
  # {
2855
2855
  # "amount": 0.0006103,
@@ -2871,15 +2871,15 @@ class digifinex(Exchange, ImplicitAPI):
2871
2871
  currency = None if (market is None) else market['base']
2872
2872
  symbol = self.safe_symbol(marketId, market)
2873
2873
  return {
2874
- 'account': symbol,
2874
+ 'info': info,
2875
2875
  'symbol': symbol,
2876
2876
  'currency': currency,
2877
2877
  'interest': None,
2878
2878
  'interestRate': 0.001, # all interest rates on digifinex are 0.1%
2879
2879
  'amountBorrowed': self.parse_number(amountBorrowed),
2880
+ 'marginMode': None,
2880
2881
  'timestamp': None,
2881
2882
  'datetime': None,
2882
- 'info': info,
2883
2883
  }
2884
2884
 
2885
2885
  def fetch_cross_borrow_rate(self, code: str, params={}) -> CrossBorrowRate:
ccxt/exmo.py CHANGED
@@ -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, #
ccxt/gate.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.gate import ImplicitAPI
8
8
  import hashlib
9
- 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
9
+ 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
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -5968,7 +5968,7 @@ class gate(Exchange, ImplicitAPI):
5968
5968
  'info': info,
5969
5969
  }
5970
5970
 
5971
- def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5971
+ def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
5972
5972
  """
5973
5973
  fetch the interest owed by the user for borrowing currency for margin trading
5974
5974
  :see: https://www.gate.io/docs/developers/apiv4/en/#list-interest-records
@@ -6013,21 +6013,21 @@ class gate(Exchange, ImplicitAPI):
6013
6013
  interest = self.parse_borrow_interests(response, market)
6014
6014
  return self.filter_by_currency_since_limit(interest, code, since, limit)
6015
6015
 
6016
- def parse_borrow_interest(self, info: dict, market: Market = None):
6016
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
6017
6017
  marketId = self.safe_string(info, 'currency_pair')
6018
6018
  market = self.safe_market(marketId, market)
6019
6019
  marginMode = 'isolated' if (marketId is not None) else 'cross'
6020
6020
  timestamp = self.safe_integer(info, 'create_time')
6021
6021
  return {
6022
6022
  'info': info,
6023
- 'timestamp': timestamp,
6024
- 'datetime': self.iso8601(timestamp),
6025
6023
  'symbol': self.safe_string(market, 'symbol'),
6026
6024
  'currency': self.safe_currency_code(self.safe_string(info, 'currency')),
6027
- 'marginMode': marginMode,
6028
6025
  'interest': self.safe_number(info, 'interest'),
6029
6026
  'interestRate': self.safe_number(info, 'actual_rate'),
6030
6027
  'amountBorrowed': None,
6028
+ 'marginMode': marginMode,
6029
+ 'timestamp': timestamp,
6030
+ 'datetime': self.iso8601(timestamp),
6031
6031
  }
6032
6032
 
6033
6033
  def sign(self, path, api=[], method='GET', params={}, headers=None, body=None):
ccxt/hitbtc.py CHANGED
@@ -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
  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/htx.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.htx import ImplicitAPI
8
8
  import hashlib
9
- 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
9
+ 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
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -4904,15 +4904,15 @@ class htx(Exchange, ImplicitAPI):
4904
4904
  orderType = type.replace('buy-', '')
4905
4905
  orderType = orderType.replace('sell-', '')
4906
4906
  options = self.safe_value(self.options, market['type'], {})
4907
- stopPrice = self.safe_string_2(params, 'stopPrice', 'stop-price')
4908
- if stopPrice is None:
4907
+ triggerPrice = self.safe_string_n(params, ['triggerPrice', 'stopPrice', 'stop-price'])
4908
+ if triggerPrice is None:
4909
4909
  stopOrderTypes = self.safe_value(options, 'stopOrderTypes', {})
4910
4910
  if orderType in stopOrderTypes:
4911
- raise ArgumentsRequired(self.id + ' createOrder() requires a stopPrice or a stop-price parameter for a stop order')
4911
+ raise ArgumentsRequired(self.id + ' createOrder() requires a triggerPrice for a stop order')
4912
4912
  else:
4913
4913
  defaultOperator = 'lte' if (side == 'sell') else 'gte'
4914
4914
  stopOperator = self.safe_string(params, 'operator', defaultOperator)
4915
- request['stop-price'] = self.price_to_precision(symbol, stopPrice)
4915
+ request['stop-price'] = self.price_to_precision(symbol, triggerPrice)
4916
4916
  request['operator'] = stopOperator
4917
4917
  if (orderType == 'limit') or (orderType == 'limit-fok'):
4918
4918
  orderType = 'stop-' + orderType
@@ -4970,7 +4970,7 @@ class htx(Exchange, ImplicitAPI):
4970
4970
  limitOrderTypes = self.safe_value(options, 'limitOrderTypes', {})
4971
4971
  if orderType in limitOrderTypes:
4972
4972
  request['price'] = self.price_to_precision(symbol, price)
4973
- params = self.omit(params, ['stopPrice', 'stop-price', 'clientOrderId', 'client-order-id', 'operator', 'timeInForce'])
4973
+ params = self.omit(params, ['triggerPrice', 'stopPrice', 'stop-price', 'clientOrderId', 'client-order-id', 'operator', 'timeInForce'])
4974
4974
  return self.extend(request, params)
4975
4975
 
4976
4976
  def create_contract_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
@@ -5003,16 +5003,16 @@ class htx(Exchange, ImplicitAPI):
5003
5003
  type = 'fok'
5004
5004
  elif timeInForce == 'IOC':
5005
5005
  type = 'ioc'
5006
- triggerPrice = self.safe_number_2(params, 'stopPrice', 'trigger_price')
5006
+ triggerPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'trigger_price'])
5007
5007
  stopLossTriggerPrice = self.safe_number_2(params, 'stopLossPrice', 'sl_trigger_price')
5008
5008
  takeProfitTriggerPrice = self.safe_number_2(params, 'takeProfitPrice', 'tp_trigger_price')
5009
5009
  trailingPercent = self.safe_string_2(params, 'trailingPercent', 'callback_rate')
5010
5010
  trailingTriggerPrice = self.safe_number(params, 'trailingTriggerPrice', price)
5011
5011
  isTrailingPercentOrder = trailingPercent is not None
5012
- isStop = triggerPrice is not None
5012
+ isTrigger = triggerPrice is not None
5013
5013
  isStopLossTriggerOrder = stopLossTriggerPrice is not None
5014
5014
  isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
5015
- if isStop:
5015
+ if isTrigger:
5016
5016
  triggerType = self.safe_string_2(params, 'triggerType', 'trigger_type', 'le')
5017
5017
  request['trigger_type'] = triggerType
5018
5018
  request['trigger_price'] = self.price_to_precision(symbol, triggerPrice)
@@ -5051,7 +5051,7 @@ class htx(Exchange, ImplicitAPI):
5051
5051
  broker = self.safe_value(self.options, 'broker', {})
5052
5052
  brokerId = self.safe_string(broker, 'id')
5053
5053
  request['channel_code'] = brokerId
5054
- params = self.omit(params, ['reduceOnly', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerType', 'leverRate', 'timeInForce', 'leverage', 'trailingPercent', 'trailingTriggerPrice'])
5054
+ params = self.omit(params, ['reduceOnly', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerType', 'leverRate', 'timeInForce', 'leverage', 'trailingPercent', 'trailingTriggerPrice'])
5055
5055
  return self.extend(request, params)
5056
5056
 
5057
5057
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
@@ -5072,7 +5072,7 @@ class htx(Exchange, ImplicitAPI):
5072
5072
  :param float amount: how much you want to trade in units of the base currency
5073
5073
  :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
5074
5074
  :param dict [params]: extra parameters specific to the exchange API endpoint
5075
- :param float [params.stopPrice]: the price a trigger order is triggered at
5075
+ :param float [params.triggerPrice]: the price a trigger order is triggered at
5076
5076
  :param str [params.triggerType]: *contract trigger orders only* ge: greater than or equal to, le: less than or equal to
5077
5077
  :param float [params.stopLossPrice]: *contract only* the price a stop-loss order is triggered at
5078
5078
  :param float [params.takeProfitPrice]: *contract only* the price a take-profit order is triggered at
@@ -5088,12 +5088,12 @@ class htx(Exchange, ImplicitAPI):
5088
5088
  """
5089
5089
  self.load_markets()
5090
5090
  market = self.market(symbol)
5091
- triggerPrice = self.safe_number_2(params, 'stopPrice', 'trigger_price')
5091
+ triggerPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'trigger_price'])
5092
5092
  stopLossTriggerPrice = self.safe_number_2(params, 'stopLossPrice', 'sl_trigger_price')
5093
5093
  takeProfitTriggerPrice = self.safe_number_2(params, 'takeProfitPrice', 'tp_trigger_price')
5094
5094
  trailingPercent = self.safe_number(params, 'trailingPercent')
5095
5095
  isTrailingPercentOrder = trailingPercent is not None
5096
- isStop = triggerPrice is not None
5096
+ isTrigger = triggerPrice is not None
5097
5097
  isStopLossTriggerOrder = stopLossTriggerPrice is not None
5098
5098
  isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
5099
5099
  response = None
@@ -5109,7 +5109,7 @@ class htx(Exchange, ImplicitAPI):
5109
5109
  marginMode, contractRequest = self.handle_margin_mode_and_params('createOrder', contractRequest)
5110
5110
  marginMode = 'cross' if (marginMode is None) else marginMode
5111
5111
  if marginMode == 'isolated':
5112
- if isStop:
5112
+ if isTrigger:
5113
5113
  response = self.contractPrivatePostLinearSwapApiV1SwapTriggerOrder(contractRequest)
5114
5114
  elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
5115
5115
  response = self.contractPrivatePostLinearSwapApiV1SwapTpslOrder(contractRequest)
@@ -5118,7 +5118,7 @@ class htx(Exchange, ImplicitAPI):
5118
5118
  else:
5119
5119
  response = self.contractPrivatePostLinearSwapApiV1SwapOrder(contractRequest)
5120
5120
  elif marginMode == 'cross':
5121
- if isStop:
5121
+ if isTrigger:
5122
5122
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerOrder(contractRequest)
5123
5123
  elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
5124
5124
  response = self.contractPrivatePostLinearSwapApiV1SwapCrossTpslOrder(contractRequest)
@@ -5131,7 +5131,7 @@ class htx(Exchange, ImplicitAPI):
5131
5131
  if offset is None:
5132
5132
  raise ArgumentsRequired(self.id + ' createOrder() requires an extra parameter params["offset"] to be set to "open" or "close" when placing orders in inverse markets')
5133
5133
  if market['swap']:
5134
- if isStop:
5134
+ if isTrigger:
5135
5135
  response = self.contractPrivatePostSwapApiV1SwapTriggerOrder(contractRequest)
5136
5136
  elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
5137
5137
  response = self.contractPrivatePostSwapApiV1SwapTpslOrder(contractRequest)
@@ -5140,7 +5140,7 @@ class htx(Exchange, ImplicitAPI):
5140
5140
  else:
5141
5141
  response = self.contractPrivatePostSwapApiV1SwapOrder(contractRequest)
5142
5142
  elif market['future']:
5143
- if isStop:
5143
+ if isTrigger:
5144
5144
  response = self.contractPrivatePostApiV1ContractTriggerOrder(contractRequest)
5145
5145
  elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
5146
5146
  response = self.contractPrivatePostApiV1ContractTpslOrder(contractRequest)
@@ -6574,7 +6574,7 @@ class htx(Exchange, ImplicitAPI):
6574
6574
  result = self.parse_funding_rates(data)
6575
6575
  return self.filter_by_array(result, 'symbol', symbols)
6576
6576
 
6577
- def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6577
+ def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
6578
6578
  """
6579
6579
  fetch the interest owed by the user for borrowing currency for margin trading
6580
6580
  :see: https://huobiapi.github.io/docs/spot/v1/en/#search-past-margin-orders-cross
@@ -6633,7 +6633,7 @@ class htx(Exchange, ImplicitAPI):
6633
6633
  interest = self.parse_borrow_interests(data, market)
6634
6634
  return self.filter_by_currency_since_limit(interest, code, since, limit)
6635
6635
 
6636
- def parse_borrow_interest(self, info: dict, market: Market = None):
6636
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
6637
6637
  # isolated
6638
6638
  # {
6639
6639
  # "interest-rate":"0.000040830000000000",
@@ -6681,16 +6681,15 @@ class htx(Exchange, ImplicitAPI):
6681
6681
  symbol = self.safe_string(market, 'symbol')
6682
6682
  timestamp = self.safe_integer(info, 'accrued-at')
6683
6683
  return {
6684
- 'account': symbol if (marginMode == 'isolated') else 'cross', # deprecated
6684
+ 'info': info,
6685
6685
  'symbol': symbol,
6686
- 'marginMode': marginMode,
6687
6686
  'currency': self.safe_currency_code(self.safe_string(info, 'currency')),
6688
6687
  'interest': self.safe_number(info, 'interest-amount'),
6689
6688
  'interestRate': self.safe_number(info, 'interest-rate'),
6690
6689
  'amountBorrowed': self.safe_number(info, 'loan-amount'),
6690
+ 'marginMode': marginMode,
6691
6691
  'timestamp': timestamp, # Interest accrued time
6692
6692
  'datetime': self.iso8601(timestamp),
6693
- 'info': info,
6694
6693
  }
6695
6694
 
6696
6695
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
ccxt/hyperliquid.py CHANGED
@@ -769,9 +769,16 @@ class hyperliquid(Exchange, ImplicitAPI):
769
769
  self.load_markets()
770
770
  market = self.market(symbol)
771
771
  until = self.safe_integer(params, 'until', self.milliseconds())
772
- useTail = (since is None)
772
+ useTail = since is None
773
+ originalSince = since
773
774
  if since is None:
774
- since = 0
775
+ if limit is not None:
776
+ # optimization if limit is provided
777
+ timeframeInMilliseconds = self.parse_timeframe(timeframe) * 1000
778
+ since = self.sum(until, timeframeInMilliseconds * limit * -1)
779
+ useTail = False
780
+ else:
781
+ since = 0
775
782
  params = self.omit(params, ['until'])
776
783
  request: dict = {
777
784
  'type': 'candleSnapshot',
@@ -799,7 +806,7 @@ class hyperliquid(Exchange, ImplicitAPI):
799
806
  # }
800
807
  # ]
801
808
  #
802
- return self.parse_ohlcvs(response, market, timeframe, since, limit, useTail)
809
+ return self.parse_ohlcvs(response, market, timeframe, originalSince, limit, useTail)
803
810
 
804
811
  def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
805
812
  #
@@ -1533,7 +1540,8 @@ class hyperliquid(Exchange, ImplicitAPI):
1533
1540
  if since is not None:
1534
1541
  request['startTime'] = since
1535
1542
  else:
1536
- request['startTime'] = self.milliseconds() - 100 * 60 * 60 * 1000
1543
+ maxLimit = 500 if (limit is None) else limit
1544
+ request['startTime'] = self.milliseconds() - maxLimit * 60 * 60 * 1000
1537
1545
  until = self.safe_integer(params, 'until')
1538
1546
  params = self.omit(params, 'until')
1539
1547
  if until is not None: