ccxt 4.4.25__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 (55) 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/bybit.py +6 -15
  15. ccxt/async_support/cex.py +36 -0
  16. ccxt/async_support/coinex.py +5 -7
  17. ccxt/async_support/digifinex.py +5 -5
  18. ccxt/async_support/exmo.py +1 -0
  19. ccxt/async_support/gate.py +6 -6
  20. ccxt/async_support/htx.py +5 -6
  21. ccxt/async_support/hyperliquid.py +12 -4
  22. ccxt/async_support/kucoin.py +5 -5
  23. ccxt/async_support/okx.py +6 -5
  24. ccxt/async_support/phemex.py +4 -2
  25. ccxt/async_support/whitebit.py +5 -5
  26. ccxt/async_support/woo.py +1 -1
  27. ccxt/async_support/xt.py +32 -24
  28. ccxt/base/exchange.py +11 -6
  29. ccxt/base/types.py +12 -0
  30. ccxt/binance.py +5 -6
  31. ccxt/bingx.py +6 -1
  32. ccxt/bitget.py +5 -5
  33. ccxt/bitmart.py +6 -6
  34. ccxt/bybit.py +6 -15
  35. ccxt/cex.py +36 -0
  36. ccxt/coinex.py +5 -7
  37. ccxt/digifinex.py +5 -5
  38. ccxt/exmo.py +1 -0
  39. ccxt/gate.py +6 -6
  40. ccxt/htx.py +5 -6
  41. ccxt/hyperliquid.py +12 -4
  42. ccxt/kucoin.py +5 -5
  43. ccxt/okx.py +6 -5
  44. ccxt/phemex.py +4 -2
  45. ccxt/pro/__init__.py +1 -1
  46. ccxt/pro/exmo.py +204 -4
  47. ccxt/test/tests_helpers.py +3 -1
  48. ccxt/whitebit.py +5 -5
  49. ccxt/woo.py +1 -1
  50. ccxt/xt.py +32 -24
  51. {ccxt-4.4.25.dist-info → ccxt-4.4.26.dist-info}/METADATA +5 -5
  52. {ccxt-4.4.25.dist-info → ccxt-4.4.26.dist-info}/RECORD +55 -55
  53. {ccxt-4.4.25.dist-info → ccxt-4.4.26.dist-info}/LICENSE.txt +0 -0
  54. {ccxt-4.4.25.dist-info → ccxt-4.4.26.dist-info}/WHEEL +0 -0
  55. {ccxt-4.4.25.dist-info → ccxt-4.4.26.dist-info}/top_level.txt +0 -0
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
@@ -4960,7 +4960,7 @@ class coinex(Exchange, ImplicitAPI):
4960
4960
  data = self.safe_dict(response, 'data', {})
4961
4961
  return self.parse_isolated_borrow_rate(data, market)
4962
4962
 
4963
- 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]:
4964
4964
  """
4965
4965
  fetch the interest owed by the user for borrowing currency for margin trading
4966
4966
  :see: https://docs.coinex.com/api/v2/assets/loan-flat/http/list-margin-borrow-history
@@ -5008,7 +5008,7 @@ class coinex(Exchange, ImplicitAPI):
5008
5008
  interest = self.parse_borrow_interests(rows, market)
5009
5009
  return self.filter_by_currency_since_limit(interest, code, since, limit)
5010
5010
 
5011
- def parse_borrow_interest(self, info: dict, market: Market = None):
5011
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
5012
5012
  #
5013
5013
  # {
5014
5014
  # "borrow_id": 2642934,
@@ -5027,17 +5027,15 @@ class coinex(Exchange, ImplicitAPI):
5027
5027
  market = self.safe_market(marketId, market, None, 'spot')
5028
5028
  timestamp = self.safe_integer(info, 'expired_at')
5029
5029
  return {
5030
- 'account': None, # deprecated
5030
+ 'info': info,
5031
5031
  'symbol': market['symbol'],
5032
- 'marginMode': 'isolated',
5033
- 'marginType': None, # deprecated
5034
5032
  'currency': self.safe_currency_code(self.safe_string(info, 'ccy')),
5035
5033
  'interest': self.safe_number(info, 'to_repaied_amount'),
5036
5034
  'interestRate': self.safe_number(info, 'daily_interest_rate'),
5037
5035
  'amountBorrowed': self.safe_number(info, 'borrow_amount'),
5036
+ 'marginMode': 'isolated',
5038
5037
  'timestamp': timestamp, # expiry time
5039
5038
  'datetime': self.iso8601(timestamp),
5040
- 'info': info,
5041
5039
  }
5042
5040
 
5043
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):
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
@@ -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:
@@ -9,7 +9,7 @@ import asyncio
9
9
  import hashlib
10
10
  import math
11
11
  import json
12
- from ccxt.base.types import Account, Balances, Bool, Currencies, Currency, DepositAddress, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
12
+ from ccxt.base.types import Account, Balances, BorrowInterest, Bool, Currencies, Currency, DepositAddress, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
13
13
  from typing import List
14
14
  from ccxt.base.errors import ExchangeError
15
15
  from ccxt.base.errors import AuthenticationError
@@ -4154,7 +4154,7 @@ class kucoin(Exchange, ImplicitAPI):
4154
4154
  'info': info,
4155
4155
  }
4156
4156
 
4157
- async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4157
+ async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
4158
4158
  """
4159
4159
  fetch the interest owed by the user for borrowing currency for margin trading
4160
4160
  :see: https://docs.kucoin.com/#get-repay-record
@@ -4249,7 +4249,7 @@ class kucoin(Exchange, ImplicitAPI):
4249
4249
  assets = self.safe_list(data, 'assets', []) if (marginMode == 'isolated') else self.safe_list(data, 'accounts', [])
4250
4250
  return self.parse_borrow_interests(assets, None)
4251
4251
 
4252
- def parse_borrow_interest(self, info: dict, market: Market = None):
4252
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
4253
4253
  #
4254
4254
  # Cross
4255
4255
  #
@@ -4312,15 +4312,15 @@ class kucoin(Exchange, ImplicitAPI):
4312
4312
  interest = self.safe_number(info, 'accruedInterest')
4313
4313
  currencyId = self.safe_string(info, 'currency')
4314
4314
  return {
4315
+ 'info': info,
4315
4316
  'symbol': symbol,
4316
- 'marginMode': marginMode,
4317
4317
  'currency': self.safe_currency_code(currencyId),
4318
4318
  'interest': interest,
4319
4319
  'interestRate': self.safe_number(info, 'dailyIntRate'),
4320
4320
  'amountBorrowed': amountBorrowed,
4321
+ 'marginMode': marginMode,
4321
4322
  'timestamp': timestamp, # create time
4322
4323
  'datetime': self.iso8601(timestamp),
4323
- 'info': info,
4324
4324
  }
4325
4325
 
4326
4326
  async def fetch_borrow_rate_histories(self, codes=None, since: Int = None, limit: Int = None, params={}):
ccxt/async_support/okx.py CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.okx import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Account, LongShortRatio, Balances, Conversion, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, DepositAddress, Greeks, Int, LedgerEntry, Leverage, LeverageTier, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
10
+ from ccxt.base.types import Account, Balances, BorrowInterest, Conversion, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, DepositAddress, Greeks, Int, LedgerEntry, Leverage, LeverageTier, LongShortRatio, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
11
11
  from typing import List
12
12
  from typing import Any
13
13
  from ccxt.base.errors import ExchangeError
@@ -422,6 +422,7 @@ class okx(Exchange, ImplicitAPI):
422
422
  # eth staking
423
423
  'finance/staking-defi/eth/balance': 5 / 3,
424
424
  'finance/staking-defi/eth/purchase-redeem-history': 5 / 3,
425
+ 'finance/staking-defi/eth/product-info': 3,
425
426
  # copytrading
426
427
  'copytrading/current-subpositions': 1,
427
428
  'copytrading/subpositions-history': 1,
@@ -6540,7 +6541,7 @@ class okx(Exchange, ImplicitAPI):
6540
6541
  })
6541
6542
  return tiers
6542
6543
 
6543
- async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6544
+ async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
6544
6545
  """
6545
6546
  fetch the interest owed by the user for borrowing currency for margin trading
6546
6547
  :see: https://www.okx.com/docs-v5/en/#rest-api-account-get-interest-accrued-data
@@ -6596,21 +6597,21 @@ class okx(Exchange, ImplicitAPI):
6596
6597
  interest = self.parse_borrow_interests(data)
6597
6598
  return self.filter_by_currency_since_limit(interest, code, since, limit)
6598
6599
 
6599
- def parse_borrow_interest(self, info: dict, market: Market = None):
6600
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
6600
6601
  instId = self.safe_string(info, 'instId')
6601
6602
  if instId is not None:
6602
6603
  market = self.safe_market(instId, market)
6603
6604
  timestamp = self.safe_integer(info, 'ts')
6604
6605
  return {
6606
+ 'info': info,
6605
6607
  'symbol': self.safe_string(market, 'symbol'),
6606
- 'marginMode': self.safe_string(info, 'mgnMode'),
6607
6608
  'currency': self.safe_currency_code(self.safe_string(info, 'ccy')),
6608
6609
  'interest': self.safe_number(info, 'interest'),
6609
6610
  'interestRate': self.safe_number(info, 'interestRate'),
6610
6611
  'amountBorrowed': self.safe_number(info, 'liab'),
6612
+ 'marginMode': self.safe_string(info, 'mgnMode'),
6611
6613
  'timestamp': timestamp, # Interest accrued time
6612
6614
  'datetime': self.iso8601(timestamp),
6613
- 'info': info,
6614
6615
  }
6615
6616
 
6616
6617
  async def borrow_cross_margin(self, code: str, amount: float, params={}):
@@ -121,7 +121,7 @@ class phemex(Exchange, ImplicitAPI):
121
121
  'private': 'https://{hostname}',
122
122
  },
123
123
  'www': 'https://phemex.com',
124
- 'doc': 'https://github.com/phemex/phemex-api-docs',
124
+ 'doc': 'https://phemex-docs.github.io/#overview',
125
125
  'fees': 'https://phemex.com/fees-conditions',
126
126
  'referral': {
127
127
  'url': 'https://phemex.com/register?referralCode=EDNVJ',
@@ -179,6 +179,7 @@ class phemex(Exchange, ImplicitAPI):
179
179
  'v2': {
180
180
  'get': {
181
181
  'public/products': 5,
182
+ 'public/products-plus': 5,
182
183
  'md/v2/orderbook': 5, # ?symbol=<symbol>&id=<id>
183
184
  'md/v2/trade': 5, # ?symbol=<symbol>&id=<id>
184
185
  'md/v2/ticker/24hr': 5, # ?symbol=<symbol>&id=<id>
@@ -746,13 +747,14 @@ class phemex(Exchange, ImplicitAPI):
746
747
  'max': self.parse_safe_number(self.safe_string(market, 'maxOrderValue')),
747
748
  },
748
749
  },
749
- 'created': None,
750
+ 'created': self.safe_integer(market, 'listTime'),
750
751
  'info': market,
751
752
  })
752
753
 
753
754
  async def fetch_markets(self, params={}) -> List[Market]:
754
755
  """
755
756
  retrieves data on all markets for phemex
757
+ :see: https://phemex-docs.github.io/#query-product-information-3
756
758
  :param dict [params]: extra parameters specific to the exchange API endpoint
757
759
  :returns dict[]: an array of objects representing market data
758
760
  """
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.whitebit import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Bool, Currencies, Currency, DepositAddress, Int, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFees, Transaction, TransferEntry
9
+ from ccxt.base.types import Balances, BorrowInterest, Bool, Currencies, Currency, DepositAddress, Int, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, 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
@@ -2144,7 +2144,7 @@ class whitebit(Exchange, ImplicitAPI):
2144
2144
  records = self.safe_list(response, 'records', [])
2145
2145
  return self.parse_transactions(records, currency, since, limit)
2146
2146
 
2147
- async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2147
+ async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
2148
2148
  """
2149
2149
  fetch the interest owed by the user for borrowing currency for margin trading
2150
2150
  :see: https://docs.whitebit.com/private/http-trade-v4/#open-positions
@@ -2186,7 +2186,7 @@ class whitebit(Exchange, ImplicitAPI):
2186
2186
  interest = self.parse_borrow_interests(response, market)
2187
2187
  return self.filter_by_currency_since_limit(interest, code, since, limit)
2188
2188
 
2189
- def parse_borrow_interest(self, info: dict, market: Market = None):
2189
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
2190
2190
  #
2191
2191
  # {
2192
2192
  # "positionId": 191823,
@@ -2210,15 +2210,15 @@ class whitebit(Exchange, ImplicitAPI):
2210
2210
  symbol = self.safe_symbol(marketId, market, '_')
2211
2211
  timestamp = self.safe_timestamp(info, 'modifyDate')
2212
2212
  return {
2213
+ 'info': info,
2213
2214
  'symbol': symbol,
2214
- 'marginMode': 'cross',
2215
2215
  'currency': 'USDT',
2216
2216
  'interest': self.safe_number(info, 'unrealizedFunding'),
2217
2217
  'interestRate': 0.00098, # https://whitebit.com/fees
2218
2218
  'amountBorrowed': self.safe_number(info, 'amount'),
2219
+ 'marginMode': 'cross',
2219
2220
  'timestamp': timestamp,
2220
2221
  'datetime': self.iso8601(timestamp),
2221
- 'info': info,
2222
2222
  }
2223
2223
 
2224
2224
  async def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
ccxt/async_support/woo.py CHANGED
@@ -2332,7 +2332,7 @@ class woo(Exchange, ImplicitAPI):
2332
2332
  #
2333
2333
  return self.parse_transaction(response, currency)
2334
2334
 
2335
- async def repay_margin(self, code: str, amount, symbol: Str = None, params={}):
2335
+ async def repay_margin(self, code: str, amount: float, symbol: Str = None, params={}):
2336
2336
  """
2337
2337
  repay borrowed margin and interest
2338
2338
  :see: https://docs.woo.org/#repay-interest
ccxt/async_support/xt.py CHANGED
@@ -1906,6 +1906,17 @@ class xt(Exchange, ImplicitAPI):
1906
1906
  # "b": True
1907
1907
  # }
1908
1908
  #
1909
+ # spot: watchTrades
1910
+ #
1911
+ # {
1912
+ # s: 'btc_usdt',
1913
+ # i: '228825383103928709',
1914
+ # t: 1684258222702,
1915
+ # p: '27003.65',
1916
+ # q: '0.000796',
1917
+ # b: True
1918
+ # }
1919
+ #
1909
1920
  # spot: watchMyTrades
1910
1921
  #
1911
1922
  # {
@@ -1918,17 +1929,6 @@ class xt(Exchange, ImplicitAPI):
1918
1929
  # "v": "90000" # volume trade amount
1919
1930
  # }
1920
1931
  #
1921
- # spot: watchTrades
1922
- #
1923
- # {
1924
- # s: 'btc_usdt',
1925
- # i: '228825383103928709',
1926
- # t: 1684258222702,
1927
- # p: '27003.65',
1928
- # q: '0.000796',
1929
- # b: True
1930
- # }
1931
- #
1932
1932
  # swap and future: fetchTrades
1933
1933
  #
1934
1934
  # {
@@ -2007,19 +2007,27 @@ class xt(Exchange, ImplicitAPI):
2007
2007
  if marketType is None:
2008
2008
  marketType = 'spot' if hasSpotKeys else 'contract'
2009
2009
  market = self.safe_market(marketId, market, '_', marketType)
2010
- bidOrAsk = self.safe_string(trade, 'm')
2011
- side = self.safe_string_lower(trade, 'orderSide')
2012
- if bidOrAsk is not None:
2013
- side = 'buy' if (bidOrAsk == 'BID') else 'sell'
2014
- buyerMaker = self.safe_value(trade, 'b')
2015
- if buyerMaker is not None:
2016
- side = 'buy'
2017
- takerOrMaker = self.safe_string_lower(trade, 'takerMaker')
2018
- if buyerMaker is not None:
2019
- takerOrMaker = 'maker' if buyerMaker else 'taker'
2020
- isMaker = self.safe_bool(trade, 'isMaker')
2021
- if isMaker is not None:
2022
- takerOrMaker = 'maker' if isMaker else 'taker'
2010
+ side = None
2011
+ takerOrMaker = None
2012
+ isBuyerMaker = self.safe_bool(trade, 'b')
2013
+ if isBuyerMaker is not None:
2014
+ side = 'sell' if isBuyerMaker else 'buy'
2015
+ takerOrMaker = 'taker' # public trades always taker
2016
+ else:
2017
+ takerMaker = self.safe_string_lower(trade, 'takerMaker')
2018
+ if takerMaker is not None:
2019
+ takerOrMaker = takerMaker
2020
+ else:
2021
+ isMaker = self.safe_bool(trade, 'isMaker')
2022
+ if isMaker is not None:
2023
+ takerOrMaker = 'maker' if isMaker else 'taker'
2024
+ orderSide = self.safe_string_lower(trade, 'orderSide')
2025
+ if orderSide is not None:
2026
+ side = orderSide
2027
+ else:
2028
+ bidOrAsk = self.safe_string(trade, 'm')
2029
+ if bidOrAsk is not None:
2030
+ side = 'buy' if (bidOrAsk == 'BID') else 'sell'
2023
2031
  timestamp = self.safe_integer_n(trade, ['t', 'time', 'timestamp'])
2024
2032
  quantity = self.safe_string_2(trade, 'q', 'quantity')
2025
2033
  amount = None
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.25'
7
+ __version__ = '4.4.26'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -296,6 +296,7 @@ class Exchange(object):
296
296
  quote_currencies = None
297
297
  currencies = None
298
298
  options = None # Python does not allow to define properties in run-time with setattr
299
+ isSandboxModeEnabled = False
299
300
  accounts = None
300
301
  positions = None
301
302
 
@@ -2403,6 +2404,8 @@ class Exchange(object):
2403
2404
  self.urls['api'] = self.clone(self.urls['test'])
2404
2405
  else:
2405
2406
  raise NotSupported(self.id + ' does not have a sandbox URL')
2407
+ # set flag
2408
+ self.isSandboxModeEnabled = True
2406
2409
  elif 'apiBackup' in self.urls:
2407
2410
  if isinstance(self.urls['api'], str):
2408
2411
  self.urls['api'] = self.urls['apiBackup']
@@ -2410,6 +2413,8 @@ class Exchange(object):
2410
2413
  self.urls['api'] = self.clone(self.urls['apiBackup'])
2411
2414
  newUrls = self.omit(self.urls, 'apiBackup')
2412
2415
  self.urls = newUrls
2416
+ # set flag
2417
+ self.isSandboxModeEnabled = False
2413
2418
 
2414
2419
  def sign(self, path, api: Any = 'public', method='GET', params={}, headers: Any = None, body: Any = None):
2415
2420
  return {}
@@ -3509,13 +3514,13 @@ class Exchange(object):
3509
3514
  'markPrice': self.safe_number(ticker, 'markPrice'),
3510
3515
  })
3511
3516
 
3512
- def fetch_borrow_rate(self, code: str, amount, params={}):
3517
+ def fetch_borrow_rate(self, code: str, amount: float, params={}):
3513
3518
  raise NotSupported(self.id + ' fetchBorrowRate is deprecated, please use fetchCrossBorrowRate or fetchIsolatedBorrowRate instead')
3514
3519
 
3515
- def repay_cross_margin(self, code: str, amount, params={}):
3520
+ def repay_cross_margin(self, code: str, amount: float, params={}):
3516
3521
  raise NotSupported(self.id + ' repayCrossMargin is not support yet')
3517
3522
 
3518
- def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
3523
+ def repay_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
3519
3524
  raise NotSupported(self.id + ' repayIsolatedMargin is not support yet')
3520
3525
 
3521
3526
  def borrow_cross_margin(self, code: str, amount: float, params={}):
@@ -3524,10 +3529,10 @@ class Exchange(object):
3524
3529
  def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
3525
3530
  raise NotSupported(self.id + ' borrowIsolatedMargin is not support yet')
3526
3531
 
3527
- def borrow_margin(self, code: str, amount, symbol: Str = None, params={}):
3532
+ def borrow_margin(self, code: str, amount: float, symbol: Str = None, params={}):
3528
3533
  raise NotSupported(self.id + ' borrowMargin is deprecated, please use borrowCrossMargin or borrowIsolatedMargin instead')
3529
3534
 
3530
- def repay_margin(self, code: str, amount, symbol: Str = None, params={}):
3535
+ def repay_margin(self, code: str, amount: float, symbol: Str = None, params={}):
3531
3536
  raise NotSupported(self.id + ' repayMargin is deprecated, please use repayCrossMargin or repayIsolatedMargin instead')
3532
3537
 
3533
3538
  def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}):
ccxt/base/types.py CHANGED
@@ -542,6 +542,18 @@ class LongShortRatio:
542
542
  longShortRatio: float
543
543
 
544
544
 
545
+ class BorrowInterest:
546
+ info: Any
547
+ symbol: Optional[Str]
548
+ currency: Optional[Str]
549
+ interest: Optional[Num]
550
+ interestRate: Optional[Num]
551
+ amountBorrowed: Optional[Num]
552
+ marginMode: Optional[Str]
553
+ timestamp: Optional[Int]
554
+ datetime: Optional[Str]
555
+
556
+
545
557
  FundingRates = Dict[Str, FundingRate]
546
558
  LastPrices = Dict[Str, LastPrice]
547
559
  Currencies = Dict[Str, CurrencyInterface]