ccxt 4.2.77__py2.py3-none-any.whl → 4.2.79__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 (51) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/bingx.py +1 -0
  3. ccxt/abstract/gate.py +1 -0
  4. ccxt/abstract/gateio.py +1 -0
  5. ccxt/async_support/__init__.py +1 -1
  6. ccxt/async_support/base/exchange.py +1 -1
  7. ccxt/async_support/base/ws/functions.py +1 -1
  8. ccxt/async_support/bingx.py +37 -5
  9. ccxt/async_support/bitstamp.py +20 -26
  10. ccxt/async_support/bybit.py +97 -2
  11. ccxt/async_support/coinbase.py +20 -9
  12. ccxt/async_support/coinbaseinternational.py +2 -2
  13. ccxt/async_support/gate.py +4 -1
  14. ccxt/async_support/htx.py +34 -27
  15. ccxt/async_support/hyperliquid.py +6 -4
  16. ccxt/async_support/kucoin.py +52 -0
  17. ccxt/async_support/okcoin.py +27 -1
  18. ccxt/async_support/okx.py +18 -0
  19. ccxt/async_support/woo.py +43 -3
  20. ccxt/base/exchange.py +5 -5
  21. ccxt/bingx.py +37 -5
  22. ccxt/bitstamp.py +20 -26
  23. ccxt/bybit.py +97 -2
  24. ccxt/coinbase.py +20 -9
  25. ccxt/coinbaseinternational.py +2 -2
  26. ccxt/gate.py +4 -1
  27. ccxt/htx.py +34 -27
  28. ccxt/hyperliquid.py +6 -4
  29. ccxt/kucoin.py +52 -0
  30. ccxt/okcoin.py +27 -1
  31. ccxt/okx.py +18 -0
  32. ccxt/pro/__init__.py +1 -1
  33. ccxt/pro/alpaca.py +1 -1
  34. ccxt/pro/bitfinex2.py +1 -1
  35. ccxt/pro/bitget.py +1 -1
  36. ccxt/pro/bitmart.py +1 -1
  37. ccxt/pro/bitmex.py +1 -1
  38. ccxt/pro/blockchaincom.py +1 -1
  39. ccxt/pro/bybit.py +14 -1
  40. ccxt/pro/cex.py +9 -5
  41. ccxt/pro/cryptocom.py +1 -1
  42. ccxt/pro/hitbtc.py +1 -1
  43. ccxt/pro/htx.py +1 -1
  44. ccxt/pro/okcoin.py +1 -1
  45. ccxt/pro/onetrading.py +1 -1
  46. ccxt/pro/woo.py +30 -0
  47. ccxt/woo.py +43 -3
  48. {ccxt-4.2.77.dist-info → ccxt-4.2.79.dist-info}/METADATA +6 -6
  49. {ccxt-4.2.77.dist-info → ccxt-4.2.79.dist-info}/RECORD +51 -51
  50. {ccxt-4.2.77.dist-info → ccxt-4.2.79.dist-info}/WHEEL +0 -0
  51. {ccxt-4.2.77.dist-info → ccxt-4.2.79.dist-info}/top_level.txt +0 -0
ccxt/__init__.py CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.2.77'
25
+ __version__ = '4.2.79'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
ccxt/abstract/bingx.py CHANGED
@@ -32,6 +32,7 @@ class ImplicitAPI:
32
32
  swap_v1_private_get_trade_batchcancelreplace = swapV1PrivateGetTradeBatchCancelReplace = Entry('trade/batchCancelReplace', ['swap', 'v1', 'private'], 'GET', {'cost': 1})
33
33
  swap_v1_private_post_trade_cancelreplace = swapV1PrivatePostTradeCancelReplace = Entry('trade/cancelReplace', ['swap', 'v1', 'private'], 'POST', {'cost': 1})
34
34
  swap_v1_private_post_positionside_dual = swapV1PrivatePostPositionSideDual = Entry('positionSide/dual', ['swap', 'v1', 'private'], 'POST', {'cost': 1})
35
+ swap_v1_private_post_trade_closeposition = swapV1PrivatePostTradeClosePosition = Entry('trade/closePosition', ['swap', 'v1', 'private'], 'POST', {'cost': 1})
35
36
  swap_v2_public_get_server_time = swapV2PublicGetServerTime = Entry('server/time', ['swap', 'v2', 'public'], 'GET', {'cost': 3})
36
37
  swap_v2_public_get_quote_contracts = swapV2PublicGetQuoteContracts = Entry('quote/contracts', ['swap', 'v2', 'public'], 'GET', {'cost': 1})
37
38
  swap_v2_public_get_quote_price = swapV2PublicGetQuotePrice = Entry('quote/price', ['swap', 'v2', 'public'], 'GET', {'cost': 1})
ccxt/abstract/gate.py CHANGED
@@ -91,6 +91,7 @@ class ImplicitAPI:
91
91
  private_unified_get_loan_records = privateUnifiedGetLoanRecords = Entry('loan_records', ['private', 'unified'], 'GET', {'cost': 1.3333333333333333})
92
92
  private_unified_get_interest_records = privateUnifiedGetInterestRecords = Entry('interest_records', ['private', 'unified'], 'GET', {'cost': 1.3333333333333333})
93
93
  private_unified_get_estimate_rate = privateUnifiedGetEstimateRate = Entry('estimate_rate', ['private', 'unified'], 'GET', {'cost': 1.3333333333333333})
94
+ private_unified_get_currency_discount_tiers = privateUnifiedGetCurrencyDiscountTiers = Entry('currency_discount_tiers', ['private', 'unified'], 'GET', {'cost': 1.3333333333333333})
94
95
  private_unified_post_account_mode = privateUnifiedPostAccountMode = Entry('account_mode', ['private', 'unified'], 'POST', {'cost': 1.3333333333333333})
95
96
  private_unified_post_loans = privateUnifiedPostLoans = Entry('loans', ['private', 'unified'], 'POST', {'cost': 13.333333333333334})
96
97
  private_spot_get_fee = privateSpotGetFee = Entry('fee', ['private', 'spot'], 'GET', {'cost': 1})
ccxt/abstract/gateio.py CHANGED
@@ -91,6 +91,7 @@ class ImplicitAPI:
91
91
  private_unified_get_loan_records = privateUnifiedGetLoanRecords = Entry('loan_records', ['private', 'unified'], 'GET', {'cost': 1.3333333333333333})
92
92
  private_unified_get_interest_records = privateUnifiedGetInterestRecords = Entry('interest_records', ['private', 'unified'], 'GET', {'cost': 1.3333333333333333})
93
93
  private_unified_get_estimate_rate = privateUnifiedGetEstimateRate = Entry('estimate_rate', ['private', 'unified'], 'GET', {'cost': 1.3333333333333333})
94
+ private_unified_get_currency_discount_tiers = privateUnifiedGetCurrencyDiscountTiers = Entry('currency_discount_tiers', ['private', 'unified'], 'GET', {'cost': 1.3333333333333333})
94
95
  private_unified_post_account_mode = privateUnifiedPostAccountMode = Entry('account_mode', ['private', 'unified'], 'POST', {'cost': 1.3333333333333333})
95
96
  private_unified_post_loans = privateUnifiedPostLoans = Entry('loans', ['private', 'unified'], 'POST', {'cost': 13.333333333333334})
96
97
  private_spot_get_fee = privateSpotGetFee = Entry('fee', ['private', 'spot'], 'GET', {'cost': 1})
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.2.77'
7
+ __version__ = '4.2.79'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.2.77'
5
+ __version__ = '4.2.79'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -34,7 +34,7 @@ def iso8601(timestamp=None):
34
34
  if int(timestamp) < 0:
35
35
  return None
36
36
  try:
37
- utc = datetime.datetime.utcfromtimestamp(timestamp // 1000)
37
+ utc = datetime.datetime.fromtimestamp(timestamp // 1000, datetime.timezone.utc)
38
38
  return utc.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-6] + "{:03d}".format(int(timestamp) % 1000) + 'Z'
39
39
  except (TypeError, OverflowError, OSError):
40
40
  return None
@@ -196,6 +196,7 @@ class bingx(Exchange, ImplicitAPI):
196
196
  'post': {
197
197
  'trade/cancelReplace': 1,
198
198
  'positionSide/dual': 1,
199
+ 'trade/closePosition': 1,
199
200
  },
200
201
  },
201
202
  },
@@ -2032,6 +2033,8 @@ class bingx(Exchange, ImplicitAPI):
2032
2033
  'SELL': 'sell',
2033
2034
  'SHORT': 'sell',
2034
2035
  'LONG': 'buy',
2036
+ 'ask': 'sell',
2037
+ 'bid': 'buy',
2035
2038
  }
2036
2039
  return self.safe_string(sides, side, side)
2037
2040
 
@@ -3656,14 +3659,43 @@ class bingx(Exchange, ImplicitAPI):
3656
3659
  :param str symbol: Unified CCXT market symbol
3657
3660
  :param str [side]: not used by bingx
3658
3661
  :param dict [params]: extra parameters specific to the bingx api endpoint
3662
+ :param str|None [params.positionId]: it is recommended to hasattr(self, fill) parameter when closing a position
3659
3663
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3660
3664
  """
3661
3665
  await self.load_markets()
3662
- market = self.market(symbol)
3663
- request: dict = {
3664
- 'symbol': market['id'],
3665
- }
3666
- response = await self.swapV2PrivatePostTradeCloseAllPositions(self.extend(request, params))
3666
+ positionId = self.safe_string(params, 'positionId')
3667
+ params = self.omit(params, 'positionId')
3668
+ response = None
3669
+ if positionId is not None:
3670
+ request: dict = {
3671
+ 'positionId': positionId,
3672
+ }
3673
+ response = await self.swapV1PrivatePostTradeClosePosition(self.extend(request, params))
3674
+ else:
3675
+ market = self.market(symbol)
3676
+ request: dict = {
3677
+ 'symbol': market['id'],
3678
+ }
3679
+ response = await self.swapV2PrivatePostTradeCloseAllPositions(self.extend(request, params))
3680
+ #
3681
+ # swapV1PrivatePostTradeClosePosition
3682
+ #
3683
+ # {
3684
+ # "code": 0,
3685
+ # "msg": "",
3686
+ # "timestamp": 1710992264190,
3687
+ # "data": {
3688
+ # "orderId": 1770656007907930112,
3689
+ # "positionId": "1751667128353910784",
3690
+ # "symbol": "LTC-USDT",
3691
+ # "side": "Ask",
3692
+ # "type": "MARKET",
3693
+ # "positionSide": "Long",
3694
+ # "origQty": "0.2"
3695
+ # }
3696
+ # }
3697
+ #
3698
+ # swapV2PrivatePostTradeCloseAllPositions
3667
3699
  #
3668
3700
  # {
3669
3701
  # "code": 0,
@@ -1082,16 +1082,17 @@ class bitstamp(Exchange, ImplicitAPI):
1082
1082
  'timestamp': None,
1083
1083
  'datetime': None,
1084
1084
  }
1085
- codes = list(self.currencies.keys())
1086
- for i in range(0, len(codes)):
1087
- code = codes[i]
1088
- currency = self.currency(code)
1089
- currencyId = currency['id']
1085
+ if response is None:
1086
+ response = []
1087
+ for i in range(0, len(response)):
1088
+ currencyBalance = response[i]
1089
+ currencyId = self.safe_string(currencyBalance, 'currency')
1090
+ currencyCode = self.safe_currency_code(currencyId)
1090
1091
  account = self.account()
1091
- account['free'] = self.safe_string(response, currencyId + '_available')
1092
- account['used'] = self.safe_string(response, currencyId + '_reserved')
1093
- account['total'] = self.safe_string(response, currencyId + '_balance')
1094
- result[code] = account
1092
+ account['free'] = self.safe_string(currencyBalance, 'available')
1093
+ account['used'] = self.safe_string(currencyBalance, 'reserved')
1094
+ account['total'] = self.safe_string(currencyBalance, 'total')
1095
+ result[currencyCode] = account
1095
1096
  return self.safe_balance(result)
1096
1097
 
1097
1098
  async def fetch_balance(self, params={}) -> Balances:
@@ -1102,24 +1103,17 @@ class bitstamp(Exchange, ImplicitAPI):
1102
1103
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
1103
1104
  """
1104
1105
  await self.load_markets()
1105
- response = await self.privatePostBalance(params)
1106
+ response = await self.privatePostAccountBalances(params)
1106
1107
  #
1107
- # {
1108
- # "aave_available": "0.00000000",
1109
- # "aave_balance": "0.00000000",
1110
- # "aave_reserved": "0.00000000",
1111
- # "aave_withdrawal_fee": "0.07000000",
1112
- # "aavebtc_fee": "0.000",
1113
- # "aaveeur_fee": "0.000",
1114
- # "aaveusd_fee": "0.000",
1115
- # "bat_available": "0.00000000",
1116
- # "bat_balance": "0.00000000",
1117
- # "bat_reserved": "0.00000000",
1118
- # "bat_withdrawal_fee": "5.00000000",
1119
- # "batbtc_fee": "0.000",
1120
- # "bateur_fee": "0.000",
1121
- # "batusd_fee": "0.000",
1122
- # }
1108
+ # [
1109
+ # {
1110
+ # "currency": "usdt",
1111
+ # "total": "7.00000",
1112
+ # "available": "7.00000",
1113
+ # "reserved": "0.00000"
1114
+ # },
1115
+ # ...
1116
+ # ]
1123
1117
  #
1124
1118
  return self.parse_balance(response)
1125
1119
 
@@ -85,6 +85,7 @@ class bybit(Exchange, ImplicitAPI):
85
85
  'fetchDeposits': True,
86
86
  'fetchDepositWithdrawFee': 'emulated',
87
87
  'fetchDepositWithdrawFees': True,
88
+ 'fetchFundingHistory': True,
88
89
  'fetchFundingRate': True, # emulated in exchange
89
90
  'fetchFundingRateHistory': True,
90
91
  'fetchFundingRates': True,
@@ -7526,17 +7527,111 @@ class bybit(Exchange, ImplicitAPI):
7526
7527
  tier = info[i]
7527
7528
  marketId = self.safe_string(info, 'symbol')
7528
7529
  market = self.safe_market(marketId)
7530
+ minNotional = self.parse_number('0')
7531
+ if i != 0:
7532
+ minNotional = self.safe_number(info[i - 1], 'riskLimitValue')
7529
7533
  tiers.append({
7530
7534
  'tier': self.safe_integer(tier, 'id'),
7531
7535
  'currency': market['settle'],
7532
- 'minNotional': None,
7533
- 'maxNotional': None,
7536
+ 'minNotional': minNotional,
7537
+ 'maxNotional': self.safe_number(tier, 'riskLimitValue'),
7534
7538
  'maintenanceMarginRate': self.safe_number(tier, 'maintenanceMargin'),
7535
7539
  'maxLeverage': self.safe_number(tier, 'maxLeverage'),
7536
7540
  'info': tier,
7537
7541
  })
7538
7542
  return tiers
7539
7543
 
7544
+ async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
7545
+ """
7546
+ fetch the history of funding payments paid and received on self account
7547
+ :see: https://bybit-exchange.github.io/docs/api-explorer/v5/position/execution
7548
+ :param str [symbol]: unified market symbol
7549
+ :param int [since]: the earliest time in ms to fetch funding history for
7550
+ :param int [limit]: the maximum number of funding history structures to retrieve
7551
+ :param dict [params]: extra parameters specific to the exchange API endpoint
7552
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
7553
+ :returns dict: a `funding history structure <https://docs.ccxt.com/#/?id=funding-history-structure>`
7554
+ """
7555
+ await self.load_markets()
7556
+ paginate = False
7557
+ paginate, params = self.handle_option_and_params(params, 'fetchFundingHistory', 'paginate')
7558
+ if paginate:
7559
+ return await self.fetch_paginated_call_cursor('fetchFundingHistory', symbol, since, limit, params, 'nextPageCursor', 'cursor', None, 100)
7560
+ request = {
7561
+ 'execType': 'Funding',
7562
+ }
7563
+ market: Market = None
7564
+ if symbol is not None:
7565
+ market = self.market(symbol)
7566
+ request['symbol'] = market['id']
7567
+ type = None
7568
+ type, params = self.get_bybit_type('fetchFundingHistory', market, params)
7569
+ request['category'] = type
7570
+ if symbol is not None:
7571
+ request['symbol'] = market['id']
7572
+ if since is not None:
7573
+ request['startTime'] = since
7574
+ if limit is not None:
7575
+ request['size'] = limit
7576
+ else:
7577
+ request['size'] = 100
7578
+ request, params = self.handle_until_option('endTime', request, params)
7579
+ response = await self.privateGetV5ExecutionList(self.extend(request, params))
7580
+ fundings = self.add_pagination_cursor_to_result(response)
7581
+ return self.parse_incomes(fundings, market, since, limit)
7582
+
7583
+ def parse_income(self, income, market: Market = None):
7584
+ #
7585
+ # {
7586
+ # "symbol": "XMRUSDT",
7587
+ # "orderType": "UNKNOWN",
7588
+ # "underlyingPrice": "",
7589
+ # "orderLinkId": "",
7590
+ # "orderId": "a11e5fe2-1dbf-4bab-a9b2-af80a14efc5d",
7591
+ # "stopOrderType": "UNKNOWN",
7592
+ # "execTime": "1710950400000",
7593
+ # "feeCurrency": "",
7594
+ # "createType": "",
7595
+ # "feeRate": "-0.000761",
7596
+ # "tradeIv": "",
7597
+ # "blockTradeId": "",
7598
+ # "markPrice": "136.79",
7599
+ # "execPrice": "137.11",
7600
+ # "markIv": "",
7601
+ # "orderQty": "0",
7602
+ # "orderPrice": "0",
7603
+ # "execValue": "134.3678",
7604
+ # "closedSize": "0",
7605
+ # "execType": "Funding",
7606
+ # "seq": "28097658790",
7607
+ # "side": "Sell",
7608
+ # "indexPrice": "",
7609
+ # "leavesQty": "0",
7610
+ # "isMaker": False,
7611
+ # "execFee": "-0.10232512",
7612
+ # "execId": "8d1ef156-4ec6-4445-9a6c-1c0c24dbd046",
7613
+ # "marketUnit": "",
7614
+ # "execQty": "0.98",
7615
+ # "nextPageCursor": "5774437%3A0%2C5771289%3A0"
7616
+ # }
7617
+ #
7618
+ marketId = self.safe_string(income, 'symbol')
7619
+ market = self.safe_market(marketId, market, None, 'contract')
7620
+ code = 'USDT'
7621
+ if market['inverse']:
7622
+ code = market['quote']
7623
+ timestamp = self.safe_integer(income, 'execTime')
7624
+ return {
7625
+ 'info': income,
7626
+ 'symbol': self.safe_symbol(marketId, market, '-', 'swap'),
7627
+ 'code': code,
7628
+ 'timestamp': timestamp,
7629
+ 'datetime': self.iso8601(timestamp),
7630
+ 'id': self.safe_string(income, 'execId'),
7631
+ 'amount': self.safe_number(income, 'execQty'),
7632
+ 'rate': self.safe_number(income, 'feeRate'),
7633
+ }
7634
+
7540
7635
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
7541
7636
  url = self.implode_hostname(self.urls['api'][api]) + '/' + path
7542
7637
  if api == 'public':
@@ -1041,7 +1041,9 @@ class coinbase(Exchange, ImplicitAPI):
1041
1041
  :returns dict[]: an array of objects representing market data
1042
1042
  """
1043
1043
  method = self.safe_string(self.options, 'fetchMarkets', 'fetchMarketsV3')
1044
- return await getattr(self, method)(params)
1044
+ if method == 'fetchMarketsV3':
1045
+ return await self.fetch_markets_v3(params)
1046
+ return await self.fetch_markets_v2(params)
1045
1047
 
1046
1048
  async def fetch_markets_v2(self, params={}):
1047
1049
  response = await self.fetch_currencies_from_cache(params)
@@ -1113,7 +1115,13 @@ class coinbase(Exchange, ImplicitAPI):
1113
1115
  return result
1114
1116
 
1115
1117
  async def fetch_markets_v3(self, params={}):
1116
- response = await self.v3PrivateGetBrokerageProducts(params)
1118
+ promisesUnresolved = [
1119
+ self.v3PrivateGetBrokerageProducts(params),
1120
+ self.v3PrivateGetBrokerageTransactionSummary(params),
1121
+ ]
1122
+ # response = await self.v3PrivateGetBrokerageProducts(params)
1123
+ promises = await asyncio.gather(*promisesUnresolved)
1124
+ response = self.safe_dict(promises, 0, {})
1117
1125
  #
1118
1126
  # [
1119
1127
  # {
@@ -1148,7 +1156,8 @@ class coinbase(Exchange, ImplicitAPI):
1148
1156
  # ...
1149
1157
  # ]
1150
1158
  #
1151
- fees = await self.v3PrivateGetBrokerageTransactionSummary(params)
1159
+ # fees = await self.v3PrivateGetBrokerageTransactionSummary(params)
1160
+ fees = self.safe_dict(promises, 1, {})
1152
1161
  #
1153
1162
  # {
1154
1163
  # "total_volume": 0,
@@ -1832,6 +1841,8 @@ class coinbase(Exchange, ImplicitAPI):
1832
1841
  response = await self.v2PrivateGetAccountsAccountIdTransactions(self.extend(request, params))
1833
1842
  ledger = self.parse_ledger(response['data'], currency, since, limit)
1834
1843
  length = len(ledger)
1844
+ if length == 0:
1845
+ return ledger
1835
1846
  lastIndex = length - 1
1836
1847
  last = self.safe_dict(ledger, lastIndex)
1837
1848
  pagination = self.safe_dict(response, 'pagination', {})
@@ -2165,9 +2176,9 @@ class coinbase(Exchange, ImplicitAPI):
2165
2176
  'fee': fee,
2166
2177
  }
2167
2178
 
2168
- async def find_account_id(self, code):
2179
+ async def find_account_id(self, code, params={}):
2169
2180
  await self.load_markets()
2170
- await self.load_accounts()
2181
+ await self.load_accounts(False, params)
2171
2182
  for i in range(0, len(self.accounts)):
2172
2183
  account = self.accounts[i]
2173
2184
  if account['code'] == code:
@@ -2191,7 +2202,7 @@ class coinbase(Exchange, ImplicitAPI):
2191
2202
  if accountId is None:
2192
2203
  if code is None:
2193
2204
  raise ArgumentsRequired(self.id + ' prepareAccountRequestWithCurrencyCode() method requires an account_id(or accountId) parameter OR a currency code argument')
2194
- accountId = await self.find_account_id(code)
2205
+ accountId = await self.find_account_id(code, params)
2195
2206
  if accountId is None:
2196
2207
  raise ExchangeError(self.id + ' prepareAccountRequestWithCurrencyCode() could not find account id for ' + code)
2197
2208
  request = {
@@ -3220,7 +3231,7 @@ class coinbase(Exchange, ImplicitAPI):
3220
3231
  if accountId is None:
3221
3232
  if code is None:
3222
3233
  raise ArgumentsRequired(self.id + ' withdraw() requires an account_id(or accountId) parameter OR a currency code argument')
3223
- accountId = await self.find_account_id(code)
3234
+ accountId = await self.find_account_id(code, params)
3224
3235
  if accountId is None:
3225
3236
  raise ExchangeError(self.id + ' withdraw() could not find account id for ' + code)
3226
3237
  request = {
@@ -3437,7 +3448,7 @@ class coinbase(Exchange, ImplicitAPI):
3437
3448
  if accountId is None:
3438
3449
  if code is None:
3439
3450
  raise ArgumentsRequired(self.id + ' deposit() requires an account_id(or accountId) parameter OR a currency code argument')
3440
- accountId = await self.find_account_id(code)
3451
+ accountId = await self.find_account_id(code, params)
3441
3452
  if accountId is None:
3442
3453
  raise ExchangeError(self.id + ' deposit() could not find account id for ' + code)
3443
3454
  request = {
@@ -3502,7 +3513,7 @@ class coinbase(Exchange, ImplicitAPI):
3502
3513
  if accountId is None:
3503
3514
  if code is None:
3504
3515
  raise ArgumentsRequired(self.id + ' fetchDeposit() requires an account_id(or accountId) parameter OR a currency code argument')
3505
- accountId = await self.find_account_id(code)
3516
+ accountId = await self.find_account_id(code, params)
3506
3517
  if accountId is None:
3507
3518
  raise ExchangeError(self.id + ' fetchDeposit() could not find account id for ' + code)
3508
3519
  request = {
@@ -126,10 +126,10 @@ class coinbaseinternational(Exchange, ImplicitAPI):
126
126
  },
127
127
  'www': 'https://international.coinbase.com',
128
128
  'doc': [
129
- 'https://docs.cloud.coinbaseinternational.com/intx/docs',
129
+ 'https://docs.cloud.coinbase.com/intx/docs',
130
130
  ],
131
131
  'fees': [
132
- 'https://help.coinbaseinternational.com/en/international-exchange/trading-deposits-withdrawals/international-exchange-fees',
132
+ 'https://help.coinbase.com/en/international-exchange/trading-deposits-withdrawals/international-exchange-fees',
133
133
  ],
134
134
  'referral': '',
135
135
  },
@@ -68,6 +68,7 @@ class gate(Exchange, ImplicitAPI):
68
68
  'rebate': 'https://api.gateio.ws/api/v4',
69
69
  'earn': 'https://api.gateio.ws/api/v4',
70
70
  'account': 'https://api.gateio.ws/api/v4',
71
+ 'loan': 'https://api.gateio.ws/api/v4',
71
72
  },
72
73
  },
73
74
  'test': {
@@ -328,6 +329,7 @@ class gate(Exchange, ImplicitAPI):
328
329
  'loan_records': 20 / 15,
329
330
  'interest_records': 20 / 15,
330
331
  'estimate_rate': 20 / 15,
332
+ 'currency_discount_tiers': 20 / 15,
331
333
  },
332
334
  'post': {
333
335
  'account_mode': 20 / 15,
@@ -3958,7 +3960,8 @@ class gate(Exchange, ImplicitAPI):
3958
3960
  'account': account,
3959
3961
  }
3960
3962
  if amount is not None:
3961
- request['amount'] = self.amount_to_precision(symbol, amount)
3963
+ amountKey = 'amount' if (market['spot']) else 'size'
3964
+ request[amountKey] = self.amount_to_precision(symbol, amount)
3962
3965
  if price is not None:
3963
3966
  request['price'] = self.price_to_precision(symbol, price)
3964
3967
  response = None
ccxt/async_support/htx.py CHANGED
@@ -2849,63 +2849,68 @@ class htx(Exchange, ImplicitAPI):
2849
2849
  # 'from': int((since / str(1000))), spot only
2850
2850
  # 'to': self.seconds(), spot only
2851
2851
  }
2852
- price = self.safe_string(params, 'price')
2853
- params = self.omit(params, 'price')
2852
+ priceType = self.safe_string_n(params, ['priceType', 'price'])
2853
+ params = self.omit(params, ['priceType', 'price'])
2854
+ until = None
2855
+ until, params = self.handle_param_integer(params, 'until')
2856
+ untilSeconds = self.parse_to_int(until / 1000) if (until is not None) else None
2854
2857
  if market['contract']:
2855
2858
  if limit is not None:
2856
- request['size'] = limit # when using limit from and to are ignored
2859
+ request['size'] = limit # when using limit: from & to are ignored
2857
2860
  # https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-kline-data
2858
2861
  else:
2859
2862
  limit = 2000 # only used for from/to calculation
2860
- if price is None:
2863
+ if priceType is None:
2861
2864
  duration = self.parse_timeframe(timeframe)
2865
+ calcualtedEnd = None
2862
2866
  if since is None:
2863
2867
  now = self.seconds()
2864
2868
  request['from'] = now - duration * (limit - 1)
2865
- request['to'] = now
2869
+ calcualtedEnd = now
2866
2870
  else:
2867
2871
  start = self.parse_to_int(since / 1000)
2868
2872
  request['from'] = start
2869
- request['to'] = self.sum(start, duration * (limit - 1))
2873
+ calcualtedEnd = self.sum(start, duration * (limit - 1))
2874
+ request['to'] = untilSeconds if (untilSeconds is not None) else calcualtedEnd
2870
2875
  response = None
2871
2876
  if market['future']:
2872
2877
  if market['inverse']:
2873
2878
  request['symbol'] = market['id']
2874
- if price == 'mark':
2879
+ if priceType == 'mark':
2875
2880
  response = await self.contractPublicGetIndexMarketHistoryMarkPriceKline(self.extend(request, params))
2876
- elif price == 'index':
2881
+ elif priceType == 'index':
2877
2882
  response = await self.contractPublicGetIndexMarketHistoryIndex(self.extend(request, params))
2878
- elif price == 'premiumIndex':
2879
- raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + price + ' kline data')
2883
+ elif priceType == 'premiumIndex':
2884
+ raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + priceType + ' kline data')
2880
2885
  else:
2881
2886
  response = await self.contractPublicGetMarketHistoryKline(self.extend(request, params))
2882
2887
  elif market['linear']:
2883
2888
  request['contract_code'] = market['id']
2884
- if price == 'mark':
2889
+ if priceType == 'mark':
2885
2890
  response = await self.contractPublicGetIndexMarketHistoryLinearSwapMarkPriceKline(self.extend(request, params))
2886
- elif price == 'index':
2887
- raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + price + ' kline data')
2888
- elif price == 'premiumIndex':
2891
+ elif priceType == 'index':
2892
+ raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + priceType + ' kline data')
2893
+ elif priceType == 'premiumIndex':
2889
2894
  response = await self.contractPublicGetIndexMarketHistoryLinearSwapPremiumIndexKline(self.extend(request, params))
2890
2895
  else:
2891
2896
  response = await self.contractPublicGetLinearSwapExMarketHistoryKline(self.extend(request, params))
2892
2897
  elif market['swap']:
2893
2898
  request['contract_code'] = market['id']
2894
2899
  if market['inverse']:
2895
- if price == 'mark':
2900
+ if priceType == 'mark':
2896
2901
  response = await self.contractPublicGetIndexMarketHistorySwapMarkPriceKline(self.extend(request, params))
2897
- elif price == 'index':
2898
- raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + price + ' kline data')
2899
- elif price == 'premiumIndex':
2902
+ elif priceType == 'index':
2903
+ raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + priceType + ' kline data')
2904
+ elif priceType == 'premiumIndex':
2900
2905
  response = await self.contractPublicGetIndexMarketHistorySwapPremiumIndexKline(self.extend(request, params))
2901
2906
  else:
2902
2907
  response = await self.contractPublicGetSwapExMarketHistoryKline(self.extend(request, params))
2903
2908
  elif market['linear']:
2904
- if price == 'mark':
2909
+ if priceType == 'mark':
2905
2910
  response = await self.contractPublicGetIndexMarketHistoryLinearSwapMarkPriceKline(self.extend(request, params))
2906
- elif price == 'index':
2907
- raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + price + ' kline data')
2908
- elif price == 'premiumIndex':
2911
+ elif priceType == 'index':
2912
+ raise BadRequest(self.id + ' ' + market['type'] + ' has no api endpoint for ' + priceType + ' kline data')
2913
+ elif priceType == 'premiumIndex':
2909
2914
  response = await self.contractPublicGetIndexMarketHistoryLinearSwapPremiumIndexKline(self.extend(request, params))
2910
2915
  else:
2911
2916
  response = await self.contractPublicGetLinearSwapExMarketHistoryKline(self.extend(request, params))
@@ -2914,15 +2919,17 @@ class htx(Exchange, ImplicitAPI):
2914
2919
  useHistorical = None
2915
2920
  useHistorical, params = self.handle_option_and_params(params, 'fetchOHLCV', 'useHistoricalEndpointForSpot', True)
2916
2921
  if not useHistorical:
2917
- # `limit` only available for the self endpoint
2918
2922
  if limit is not None:
2919
- request['size'] = limit # max 2000
2923
+ request['size'] = min(2000, limit) # max 2000
2920
2924
  response = await self.spotPublicGetMarketHistoryKline(self.extend(request, params))
2921
2925
  else:
2922
- # `since` only available for the self endpoint
2926
+ # "from & to" only available for the self endpoint
2923
2927
  if since is not None:
2924
- # default 150 bars
2925
2928
  request['from'] = self.parse_to_int(since / 1000)
2929
+ if untilSeconds is not None:
2930
+ request['to'] = untilSeconds
2931
+ if limit is not None:
2932
+ request['size'] = min(1000, limit) # max 1000, otherwise default returns 150
2926
2933
  response = await self.spotPublicGetMarketHistoryCandles(self.extend(request, params))
2927
2934
  #
2928
2935
  # {
@@ -2936,7 +2943,7 @@ class htx(Exchange, ImplicitAPI):
2936
2943
  # ]
2937
2944
  # }
2938
2945
  #
2939
- data = self.safe_value(response, 'data', [])
2946
+ data = self.safe_list(response, 'data', [])
2940
2947
  return self.parse_ohlcvs(data, market, timeframe, since, limit)
2941
2948
 
2942
2949
  async def fetch_accounts(self, params={}) -> List[Account]:
@@ -747,8 +747,9 @@ class hyperliquid(Exchange, ImplicitAPI):
747
747
  :param bool [params.postOnly]: True or False whether the order is post-only
748
748
  :param bool [params.reduceOnly]: True or False whether the order is reduce-only
749
749
  :param float [params.triggerPrice]: The price at which a trigger order is triggered at
750
- :param str [params.clientOrderId]: client order id, optional 128 bit hex string
750
+ :param str [params.clientOrderId]: client order id,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
751
751
  :param str [params.slippage]: the slippage for market order
752
+ :param str [params.vaultAddress]: the vault address for order
752
753
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
753
754
  """
754
755
  await self.load_markets()
@@ -791,7 +792,7 @@ class hyperliquid(Exchange, ImplicitAPI):
791
792
  clientOrderId = self.safe_string_2(orderParams, 'clientOrderId', 'client_id')
792
793
  if clientOrderId is None:
793
794
  raise ArgumentsRequired(self.id + ' createOrders() all orders must have clientOrderId if at least one has a clientOrderId')
794
- params = self.omit(params, ['slippage', 'clientOrderId', 'client_id', 'slippage', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice'])
795
+ params = self.omit(params, ['slippage', 'clientOrderId', 'client_id', 'slippage', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'timeInForce'])
795
796
  nonce = self.milliseconds()
796
797
  orderReq = []
797
798
  for i in range(0, len(orders)):
@@ -905,7 +906,7 @@ class hyperliquid(Exchange, ImplicitAPI):
905
906
  :param str id: order id
906
907
  :param str symbol: unified symbol of the market the order was made in
907
908
  :param dict [params]: extra parameters specific to the exchange API endpoint
908
- :param str [params.clientOrderId]: client order id(default None)
909
+ :param str [params.clientOrderId]: client order id,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
909
910
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
910
911
  """
911
912
  return await self.cancel_orders([id], symbol, params)
@@ -918,7 +919,7 @@ class hyperliquid(Exchange, ImplicitAPI):
918
919
  :param str[] ids: order ids
919
920
  :param str [symbol]: unified market symbol
920
921
  :param dict [params]: extra parameters specific to the exchange API endpoint
921
- :param string|str[] [params.clientOrderId]: client order ids(default None)
922
+ :param string|str[] [params.clientOrderId]: client order ids,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
922
923
  :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
923
924
  """
924
925
  self.check_required_credentials()
@@ -993,6 +994,7 @@ class hyperliquid(Exchange, ImplicitAPI):
993
994
  :param bool [params.reduceOnly]: True or False whether the order is reduce-only
994
995
  :param float [params.triggerPrice]: The price at which a trigger order is triggered at
995
996
  :param str [params.clientOrderId]: client order id,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
997
+ :param str [params.vaultAddress]: the vault address for order
996
998
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
997
999
  """
998
1000
  self.check_required_credentials()