ccxt 4.4.5__py2.py3-none-any.whl → 4.4.7__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ccxt/coinbase.py CHANGED
@@ -751,28 +751,26 @@ class coinbase(Exchange, ImplicitAPI):
751
751
 
752
752
  def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
753
753
  """
754
- fetch all withdrawals made from an account
755
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-withdrawals#list-withdrawals
754
+ Fetch all withdrawals made from an account. Won't return crypto withdrawals. Use fetchLedger for those.
755
+ :see: https://docs.cdp.coinbase.com/coinbase-app/docs/api-withdrawals#list-withdrawals
756
756
  :param str code: unified currency code
757
757
  :param int [since]: the earliest time in ms to fetch withdrawals for
758
758
  :param int [limit]: the maximum number of withdrawals structures to retrieve
759
759
  :param dict [params]: extra parameters specific to the exchange API endpoint
760
760
  :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
761
761
  """
762
- # fiat only, for crypto transactions use fetchLedger
763
762
  return self.fetch_transactions_with_method('v2PrivateGetAccountsAccountIdWithdrawals', code, since, limit, params)
764
763
 
765
764
  def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
766
765
  """
767
- fetch all deposits made to an account
768
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-deposits#list-deposits
766
+ Fetch all fiat deposits made to an account. Won't return crypto deposits or staking rewards. Use fetchLedger for those.
767
+ :see: https://docs.cdp.coinbase.com/coinbase-app/docs/api-deposits#list-deposits
769
768
  :param str code: unified currency code
770
769
  :param int [since]: the earliest time in ms to fetch deposits for
771
770
  :param int [limit]: the maximum number of deposits structures to retrieve
772
771
  :param dict [params]: extra parameters specific to the exchange API endpoint
773
772
  :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
774
773
  """
775
- # fiat only, for crypto transactions use fetchLedger
776
774
  return self.fetch_transactions_with_method('v2PrivateGetAccountsAccountIdDeposits', code, since, limit, params)
777
775
 
778
776
  def parse_transaction_status(self, status: Str):
@@ -2172,8 +2170,8 @@ class coinbase(Exchange, ImplicitAPI):
2172
2170
 
2173
2171
  def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
2174
2172
  """
2175
- fetch the history of changes, actions done by the user or operations that altered the balance of the user
2176
- :see: https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-transactions#list-transactions
2173
+ Fetch the history of changes, i.e. actions done by the user or operations that altered the balance. Will return staking rewards, and crypto deposits or withdrawals.
2174
+ :see: https://docs.cdp.coinbase.com/coinbase-app/docs/api-transactions#list-transactions
2177
2175
  :param str [code]: unified currency code, default is None
2178
2176
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
2179
2177
  :param int [limit]: max number of ledger entries to return, default is None
ccxt/gate.py CHANGED
@@ -657,6 +657,9 @@ class gate(Exchange, ImplicitAPI):
657
657
  'OPTIMISM': 'OPETH',
658
658
  'POLKADOT': 'DOTSM',
659
659
  'TRC20': 'TRX',
660
+ 'LUNA': 'LUNC',
661
+ 'BASE': 'BASEEVM',
662
+ 'BRC20': 'BTCBRC',
660
663
  },
661
664
  'timeInForce': {
662
665
  'GTC': 'gtc',
ccxt/kraken.py CHANGED
@@ -249,6 +249,8 @@ class kraken(Exchange, ImplicitAPI):
249
249
  'XDG': 'DOGE',
250
250
  },
251
251
  'options': {
252
+ 'timeDifference': 0, # the difference between system clock and Binance clock
253
+ 'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
252
254
  'marketsByAltname': {},
253
255
  'delistedMarketsById': {},
254
256
  # cannot withdraw/deposit these
@@ -477,6 +479,8 @@ class kraken(Exchange, ImplicitAPI):
477
479
  :param dict [params]: extra parameters specific to the exchange API endpoint
478
480
  :returns dict[]: an array of objects representing market data
479
481
  """
482
+ if self.options['adjustForTimeDifference']:
483
+ self.load_time_difference()
480
484
  response = self.publicGetAssetPairs(params)
481
485
  #
482
486
  # {
@@ -2941,7 +2945,7 @@ class kraken(Exchange, ImplicitAPI):
2941
2945
  return {'url': url, 'method': method, 'body': body, 'headers': headers}
2942
2946
 
2943
2947
  def nonce(self):
2944
- return self.milliseconds()
2948
+ return self.milliseconds() - self.options['timeDifference']
2945
2949
 
2946
2950
  def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
2947
2951
  if code == 520:
ccxt/kucoin.py CHANGED
@@ -777,7 +777,7 @@ class kucoin(Exchange, ImplicitAPI):
777
777
  'hf': 'trade_hf',
778
778
  },
779
779
  'networks': {
780
- 'BTC': 'btc',
780
+ 'BRC20': 'btc',
781
781
  'BTCNATIVESEGWIT': 'bech32',
782
782
  'ERC20': 'eth',
783
783
  'TRC20': 'trx',
@@ -1343,7 +1343,7 @@ class kucoin(Exchange, ImplicitAPI):
1343
1343
  for j in range(0, chainsLength):
1344
1344
  chain = chains[j]
1345
1345
  chainId = self.safe_string(chain, 'chainId')
1346
- networkCode = self.network_id_to_code(chainId)
1346
+ networkCode = self.network_id_to_code(chainId, code)
1347
1347
  chainWithdrawEnabled = self.safe_bool(chain, 'isWithdrawEnabled', False)
1348
1348
  if isWithdrawEnabled is None:
1349
1349
  isWithdrawEnabled = chainWithdrawEnabled
ccxt/mexc.py CHANGED
@@ -44,6 +44,9 @@ class mexc(Exchange, ImplicitAPI):
44
44
  'future': False,
45
45
  'option': False,
46
46
  'addMargin': True,
47
+ 'borrowCrossMargin': False,
48
+ 'borrowIsolatedMargin': False,
49
+ 'borrowMargin': False,
47
50
  'cancelAllOrders': True,
48
51
  'cancelOrder': True,
49
52
  'cancelOrders': None,
@@ -51,18 +54,27 @@ class mexc(Exchange, ImplicitAPI):
51
54
  'closePosition': False,
52
55
  'createDepositAddress': True,
53
56
  'createMarketBuyOrderWithCost': True,
54
- 'createMarketOrderWithCost': False,
55
- 'createMarketSellOrderWithCost': False,
57
+ 'createMarketOrderWithCost': True,
58
+ 'createMarketSellOrderWithCost': True,
56
59
  'createOrder': True,
57
60
  'createOrders': True,
58
61
  'createPostOnlyOrder': True,
59
62
  'createReduceOnlyOrder': True,
63
+ 'createStopLimitOrder': True,
64
+ 'createStopMarketOrder': True,
65
+ 'createStopOrder': True,
66
+ 'createTriggerOrder': True,
60
67
  'deposit': None,
61
68
  'editOrder': None,
62
69
  'fetchAccounts': True,
63
70
  'fetchBalance': True,
64
71
  'fetchBidsAsks': True,
65
- 'fetchBorrowRateHistory': None,
72
+ 'fetchBorrowInterest': False,
73
+ 'fetchBorrowRate': False,
74
+ 'fetchBorrowRateHistories': False,
75
+ 'fetchBorrowRateHistory': False,
76
+ 'fetchBorrowRates': False,
77
+ 'fetchBorrowRatesPerSymbol': False,
66
78
  'fetchCanceledOrders': True,
67
79
  'fetchClosedOrder': None,
68
80
  'fetchClosedOrders': True,
@@ -83,6 +95,7 @@ class mexc(Exchange, ImplicitAPI):
83
95
  'fetchIndexOHLCV': True,
84
96
  'fetchIsolatedBorrowRate': False,
85
97
  'fetchIsolatedBorrowRates': False,
98
+ 'fetchIsolatedPositions': False,
86
99
  'fetchL2OrderBook': True,
87
100
  'fetchLedger': None,
88
101
  'fetchLedgerEntry': None,
@@ -91,11 +104,13 @@ class mexc(Exchange, ImplicitAPI):
91
104
  'fetchLeverageTiers': True,
92
105
  'fetchMarginAdjustmentHistory': False,
93
106
  'fetchMarginMode': False,
94
- 'fetchMarketLeverageTiers': None,
107
+ 'fetchMarketLeverageTiers': 'emulated',
95
108
  'fetchMarkets': True,
96
109
  'fetchMarkOHLCV': True,
97
110
  'fetchMyTrades': True,
98
111
  'fetchOHLCV': True,
112
+ 'fetchOpenInterest': False,
113
+ 'fetchOpenInterestHistory': False,
99
114
  'fetchOpenOrder': None,
100
115
  'fetchOpenOrders': True,
101
116
  'fetchOrder': True,
@@ -129,7 +144,7 @@ class mexc(Exchange, ImplicitAPI):
129
144
  'repayCrossMargin': False,
130
145
  'repayIsolatedMargin': False,
131
146
  'setLeverage': True,
132
- 'setMarginMode': None,
147
+ 'setMarginMode': True,
133
148
  'setPositionMode': True,
134
149
  'signIn': None,
135
150
  'transfer': None,
@@ -413,7 +428,8 @@ class mexc(Exchange, ImplicitAPI):
413
428
  },
414
429
  },
415
430
  'options': {
416
- 'createMarketBuyOrderRequiresPrice': True,
431
+ 'adjustForTimeDifference': False,
432
+ 'timeDifference': 0,
417
433
  'unavailableContracts': {
418
434
  'BTC/USDT:USDT': True,
419
435
  'LTC/USDT:USDT': True,
@@ -462,11 +478,14 @@ class mexc(Exchange, ImplicitAPI):
462
478
  'LTC': 'LTC',
463
479
  },
464
480
  'networks': {
481
+ 'ZKSYNC': 'ZKSYNCERA',
465
482
  'TRC20': 'TRX',
466
483
  'TON': 'TONCOIN',
467
484
  'AVAXC': 'AVAX_CCHAIN',
468
485
  'ERC20': 'ETH',
469
486
  'ACA': 'ACALA',
487
+ 'BEP20': 'BSC',
488
+ 'OPTIMISM': 'OP',
470
489
  # 'ADA': 'Cardano(ADA)',
471
490
  # 'AE': 'AE',
472
491
  # 'ALGO': 'Algorand(ALGO)',
@@ -1007,6 +1026,8 @@ class mexc(Exchange, ImplicitAPI):
1007
1026
  :param dict [params]: extra parameters specific to the exchange API endpoint
1008
1027
  :returns dict[]: an array of objects representing market data
1009
1028
  """
1029
+ if self.options['adjustForTimeDifference']:
1030
+ self.load_time_difference()
1010
1031
  spotMarketPromise = self.fetch_spot_markets(params)
1011
1032
  swapMarketPromise = self.fetch_swap_markets(params)
1012
1033
  spotMarket, swapMarket = [spotMarketPromise, swapMarketPromise]
@@ -1998,8 +2019,24 @@ class mexc(Exchange, ImplicitAPI):
1998
2019
  market = self.market(symbol)
1999
2020
  if not market['spot']:
2000
2021
  raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
2001
- params['createMarketBuyOrderRequiresPrice'] = False
2002
- return self.create_order(symbol, 'market', 'buy', cost, None, params)
2022
+ params['cost'] = cost
2023
+ return self.create_order(symbol, 'market', 'buy', 0, None, params)
2024
+
2025
+ def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}):
2026
+ """
2027
+ create a market sell order by providing the symbol and cost
2028
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#new-order
2029
+ :param str symbol: unified symbol of the market to create an order in
2030
+ :param float cost: how much you want to trade in units of the quote currency
2031
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2032
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2033
+ """
2034
+ self.load_markets()
2035
+ market = self.market(symbol)
2036
+ if not market['spot']:
2037
+ raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
2038
+ params['cost'] = cost
2039
+ return self.create_order(symbol, 'market', 'sell', 0, None, params)
2003
2040
 
2004
2041
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
2005
2042
  """
@@ -2023,6 +2060,7 @@ class mexc(Exchange, ImplicitAPI):
2023
2060
  :param long [params.positionId]: *contract only* it is recommended to hasattr(self, fill) parameter when closing a position
2024
2061
  :param str [params.externalOid]: *contract only* external order ID
2025
2062
  :param int [params.positionMode]: *contract only* 1:hedge, 2:one-way, default: the user's current config
2063
+ :param boolean [params.test]: *spot only* whether to use the test endpoint or not, default is False
2026
2064
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2027
2065
  """
2028
2066
  self.load_markets()
@@ -2041,22 +2079,21 @@ class mexc(Exchange, ImplicitAPI):
2041
2079
  'side': orderSide,
2042
2080
  'type': type.upper(),
2043
2081
  }
2044
- if orderSide == 'BUY' and type == 'market':
2045
- createMarketBuyOrderRequiresPrice = True
2046
- createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
2082
+ if type == 'market':
2047
2083
  cost = self.safe_number_2(params, 'cost', 'quoteOrderQty')
2048
2084
  params = self.omit(params, 'cost')
2049
2085
  if cost is not None:
2050
2086
  amount = cost
2051
- elif createMarketBuyOrderRequiresPrice:
2087
+ request['quoteOrderQty'] = self.cost_to_precision(symbol, amount)
2088
+ else:
2052
2089
  if price is None:
2053
- raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend in the amount argument')
2090
+ request['quantity'] = self.amount_to_precision(symbol, amount)
2054
2091
  else:
2055
2092
  amountString = self.number_to_string(amount)
2056
2093
  priceString = self.number_to_string(price)
2057
2094
  quoteAmount = Precise.string_mul(amountString, priceString)
2058
2095
  amount = quoteAmount
2059
- request['quoteOrderQty'] = self.cost_to_precision(symbol, amount)
2096
+ request['quoteOrderQty'] = self.cost_to_precision(symbol, amount)
2060
2097
  else:
2061
2098
  request['quantity'] = self.amount_to_precision(symbol, amount)
2062
2099
  if price is not None:
@@ -2091,8 +2128,14 @@ class mexc(Exchange, ImplicitAPI):
2091
2128
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2092
2129
  """
2093
2130
  self.load_markets()
2131
+ test = self.safe_bool(params, 'test', False)
2132
+ params = self.omit(params, 'test')
2094
2133
  request = self.create_spot_order_request(market, type, side, amount, price, marginMode, params)
2095
- response = self.spotPrivatePostOrder(self.extend(request, params))
2134
+ response = None
2135
+ if test:
2136
+ response = self.spotPrivatePostOrderTest(request)
2137
+ else:
2138
+ response = self.spotPrivatePostOrder(request)
2096
2139
  #
2097
2140
  # spot
2098
2141
  #
@@ -2406,6 +2449,9 @@ class mexc(Exchange, ImplicitAPI):
2406
2449
  def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
2407
2450
  """
2408
2451
  fetches information on multiple orders made by the user
2452
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#all-orders
2453
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-all-of-the-user-39-s-historical-orders
2454
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#gets-the-trigger-order-list
2409
2455
  :param str symbol: unified market symbol of the market orders were made in
2410
2456
  :param int [since]: the earliest time in ms to fetch orders for
2411
2457
  :param int [limit]: the maximum number of order structures to retrieve
@@ -2619,6 +2665,9 @@ class mexc(Exchange, ImplicitAPI):
2619
2665
  def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
2620
2666
  """
2621
2667
  fetch all unfilled currently open orders
2668
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#current-open-orders
2669
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-all-of-the-user-39-s-historical-orders
2670
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#gets-the-trigger-order-list
2622
2671
  :param str symbol: unified market symbol
2623
2672
  :param int [since]: the earliest time in ms to fetch open orders for
2624
2673
  :param int [limit]: the maximum number of open orders structures to retrieve
@@ -2701,6 +2750,9 @@ class mexc(Exchange, ImplicitAPI):
2701
2750
  def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
2702
2751
  """
2703
2752
  fetches information on multiple closed orders made by the user
2753
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#all-orders
2754
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-all-of-the-user-39-s-historical-orders
2755
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#gets-the-trigger-order-list
2704
2756
  :param str symbol: unified market symbol of the market orders were made in
2705
2757
  :param int [since]: the earliest time in ms to fetch orders for
2706
2758
  :param int [limit]: the maximum number of order structures to retrieve
@@ -2712,6 +2764,9 @@ class mexc(Exchange, ImplicitAPI):
2712
2764
  def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2713
2765
  """
2714
2766
  fetches information on multiple canceled orders made by the user
2767
+ :see: https://mexcdevelop.github.io/apidocs/spot_v3_en/#all-orders
2768
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#get-all-of-the-user-39-s-historical-orders
2769
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#gets-the-trigger-order-list
2715
2770
  :param str symbol: unified market symbol of the market orders were made in
2716
2771
  :param int [since]: timestamp in ms of the earliest order, default is None
2717
2772
  :param int [limit]: max number of orders to return, default is None
@@ -4247,7 +4302,7 @@ class mexc(Exchange, ImplicitAPI):
4247
4302
  # 'coin': currency['id'] + network example: USDT-TRX,
4248
4303
  # 'status': 'status',
4249
4304
  # 'startTime': since, # default 90 days
4250
- # 'endTime': self.milliseconds(),
4305
+ # 'endTime': self.nonce(),
4251
4306
  # 'limit': limit, # default 1000, maximum 1000
4252
4307
  }
4253
4308
  currency = None
@@ -4300,7 +4355,7 @@ class mexc(Exchange, ImplicitAPI):
4300
4355
  # 'coin': currency['id'],
4301
4356
  # 'status': 'status',
4302
4357
  # 'startTime': since, # default 90 days
4303
- # 'endTime': self.milliseconds(),
4358
+ # 'endTime': self.nonce(),
4304
4359
  # 'limit': limit, # default 1000, maximum 1000
4305
4360
  }
4306
4361
  currency = None
@@ -5265,6 +5320,46 @@ class mexc(Exchange, ImplicitAPI):
5265
5320
  positions = self.parse_positions(data, symbols, params)
5266
5321
  return self.filter_by_since_limit(positions, since, limit)
5267
5322
 
5323
+ def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
5324
+ """
5325
+ set margin mode to 'cross' or 'isolated'
5326
+ :see: https://mexcdevelop.github.io/apidocs/contract_v1_en/#switch-leverage
5327
+ :param str marginMode: 'cross' or 'isolated'
5328
+ :param str [symbol]: required when there is no position, else provide params["positionId"]
5329
+ :param dict [params]: extra parameters specific to the exchange API endpoint
5330
+ :param str [params.positionId]: required when a position is set
5331
+ :param str [params.direction]: "long" or "short" required when there is no position
5332
+ :returns dict: response from the exchange
5333
+ """
5334
+ self.load_markets()
5335
+ market = self.market(symbol)
5336
+ if market['spot']:
5337
+ raise BadSymbol(self.id + ' setMarginMode() supports contract markets only')
5338
+ marginMode = marginMode.lower()
5339
+ if marginMode != 'isolated' and marginMode != 'cross':
5340
+ raise BadRequest(self.id + ' setMarginMode() marginMode argument should be isolated or cross')
5341
+ leverage = self.safe_integer(params, 'leverage')
5342
+ if leverage is None:
5343
+ raise ArgumentsRequired(self.id + ' setMarginMode() requires a leverage parameter')
5344
+ direction = self.safe_string_lower_2(params, 'direction', 'positionId')
5345
+ request: dict = {
5346
+ 'leverage': leverage,
5347
+ 'openType': 1 if (marginMode == 'isolated') else 2,
5348
+ }
5349
+ if symbol is not None:
5350
+ request['symbol'] = market['id']
5351
+ if direction is not None:
5352
+ request['positionType'] = 2 if (direction == 'short') else 1
5353
+ params = self.omit(params, 'direction')
5354
+ response = self.contractPrivatePostPositionChangeLeverage(self.extend(request, params))
5355
+ #
5356
+ # {success: True, code: '0'}
5357
+ #
5358
+ return self.parse_leverage(response, market)
5359
+
5360
+ def nonce(self):
5361
+ return self.milliseconds() - self.safe_integer(self.options, 'timeDifference', 0)
5362
+
5268
5363
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
5269
5364
  section = self.safe_string(api, 0)
5270
5365
  access = self.safe_string(api, 1)
@@ -5277,7 +5372,7 @@ class mexc(Exchange, ImplicitAPI):
5277
5372
  url = self.urls['api'][section][access] + '/api/' + self.version + '/' + path
5278
5373
  paramsEncoded = ''
5279
5374
  if access == 'private':
5280
- params['timestamp'] = self.milliseconds()
5375
+ params['timestamp'] = self.nonce()
5281
5376
  params['recvWindow'] = self.safe_integer(self.options, 'recvWindow', 5000)
5282
5377
  if params:
5283
5378
  paramsEncoded = self.urlencode(params)
@@ -5300,7 +5395,7 @@ class mexc(Exchange, ImplicitAPI):
5300
5395
  url += '?' + self.urlencode(params)
5301
5396
  else:
5302
5397
  self.check_required_credentials()
5303
- timestamp = str(self.milliseconds())
5398
+ timestamp = str(self.nonce())
5304
5399
  auth = ''
5305
5400
  headers = {
5306
5401
  'ApiKey': self.apiKey,
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.5'
7
+ __version__ = '4.4.7'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/bitget.py CHANGED
@@ -42,6 +42,7 @@ class bitget(ccxt.async_support.bitget):
42
42
  'watchOrders': True,
43
43
  'watchTicker': True,
44
44
  'watchTickers': True,
45
+ 'watchBidsAsks': True,
45
46
  'watchTrades': True,
46
47
  'watchTradesForSymbols': True,
47
48
  'watchPositions': True,
@@ -209,6 +210,7 @@ class bitget(ccxt.async_support.bitget):
209
210
  # "ts": 1701842994341
210
211
  # }
211
212
  #
213
+ self.handle_bid_ask(client, message)
212
214
  ticker = self.parse_ws_ticker(message)
213
215
  symbol = ticker['symbol']
214
216
  self.tickers[symbol] = ticker
@@ -320,6 +322,66 @@ class bitget(ccxt.async_support.bitget):
320
322
  'info': ticker,
321
323
  }, market)
322
324
 
325
+ async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
326
+ """
327
+ :see: https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
328
+ :see: https://www.bitget.com/api-doc/contract/websocket/public/Tickers-Channel
329
+ watches best bid & ask for symbols
330
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
331
+ :param dict [params]: extra parameters specific to the exchange API endpoint
332
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
333
+ """
334
+ await self.load_markets()
335
+ symbols = self.market_symbols(symbols, None, False)
336
+ market = self.market(symbols[0])
337
+ instType = None
338
+ instType, params = self.get_inst_type(market, params)
339
+ topics = []
340
+ messageHashes = []
341
+ for i in range(0, len(symbols)):
342
+ symbol = symbols[i]
343
+ marketInner = self.market(symbol)
344
+ args: dict = {
345
+ 'instType': instType,
346
+ 'channel': 'ticker',
347
+ 'instId': marketInner['id'],
348
+ }
349
+ topics.append(args)
350
+ messageHashes.append('bidask:' + symbol)
351
+ tickers = await self.watch_public_multiple(messageHashes, topics, params)
352
+ if self.newUpdates:
353
+ result: dict = {}
354
+ result[tickers['symbol']] = tickers
355
+ return result
356
+ return self.filter_by_array(self.bidsasks, 'symbol', symbols)
357
+
358
+ def handle_bid_ask(self, client: Client, message):
359
+ ticker = self.parse_ws_bid_ask(message)
360
+ symbol = ticker['symbol']
361
+ self.bidsasks[symbol] = ticker
362
+ messageHash = 'bidask:' + symbol
363
+ client.resolve(ticker, messageHash)
364
+
365
+ def parse_ws_bid_ask(self, message, market=None):
366
+ arg = self.safe_value(message, 'arg', {})
367
+ data = self.safe_value(message, 'data', [])
368
+ ticker = self.safe_value(data, 0, {})
369
+ timestamp = self.safe_integer(ticker, 'ts')
370
+ instType = self.safe_string(arg, 'instType')
371
+ marketType = 'spot' if (instType == 'SPOT') else 'contract'
372
+ marketId = self.safe_string(ticker, 'instId')
373
+ market = self.safe_market(marketId, market, None, marketType)
374
+ return self.safe_ticker({
375
+ 'symbol': market['symbol'],
376
+ 'timestamp': timestamp,
377
+ 'datetime': self.iso8601(timestamp),
378
+ 'ask': self.safe_string(ticker, 'askPr'),
379
+ 'askVolume': self.safe_string(ticker, 'askSz'),
380
+ 'bid': self.safe_string(ticker, 'bidPr'),
381
+ 'bidVolume': self.safe_string(ticker, 'bidSz'),
382
+ 'info': ticker,
383
+ }, market)
384
+
323
385
  async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
324
386
  """
325
387
  watches historical candlestick data containing the open, high, low, close price, and the volume of a market
ccxt/pro/htx.py CHANGED
@@ -143,6 +143,8 @@ class htx(ccxt.async_support.htx):
143
143
  async def watch_ticker(self, symbol: str, params={}) -> Ticker:
144
144
  """
145
145
  watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
146
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=7ec53561-7773-11ed-9966-0242ac110003
147
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=28c33ab2-77ae-11ed-9966-0242ac110003
146
148
  :param str symbol: unified symbol of the market to fetch the ticker for
147
149
  :param dict [params]: extra parameters specific to the exchange API endpoint
148
150
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -208,6 +210,9 @@ class htx(ccxt.async_support.htx):
208
210
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
209
211
  """
210
212
  get the list of most recent trades for a particular symbol
213
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=7ec53b69-7773-11ed-9966-0242ac110003
214
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=28c33c21-77ae-11ed-9966-0242ac110003
215
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=28c33cfe-77ae-11ed-9966-0242ac110003
211
216
  :param str symbol: unified symbol of the market to fetch trades for
212
217
  :param int [since]: timestamp in ms of the earliest trade to fetch
213
218
  :param int [limit]: the maximum amount of trades to fetch
@@ -266,6 +271,9 @@ class htx(ccxt.async_support.htx):
266
271
  async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
267
272
  """
268
273
  watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
274
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=7ec53241-7773-11ed-9966-0242ac110003
275
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=28c3346a-77ae-11ed-9966-0242ac110003
276
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=28c33563-77ae-11ed-9966-0242ac110003
269
277
  :param str symbol: unified symbol of the market to fetch OHLCV data for
270
278
  :param str timeframe: the length of time each candle represents
271
279
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -642,6 +650,7 @@ class htx(ccxt.async_support.htx):
642
650
  async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
643
651
  """
644
652
  watches information on multiple trades made by the user
653
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=7ec53dd5-7773-11ed-9966-0242ac110003
645
654
  :param str symbol: unified market symbol of the market trades were made in
646
655
  :param int [since]: the earliest time in ms to fetch trades for
647
656
  :param int [limit]: the maximum number of trade structures to retrieve
@@ -728,6 +737,7 @@ class htx(ccxt.async_support.htx):
728
737
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
729
738
  """
730
739
  watches information on multiple orders made by the user
740
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=7ec53c8f-7773-11ed-9966-0242ac110003
731
741
  :param str symbol: unified market symbol of the market orders were made in
732
742
  :param int [since]: the earliest time in ms to fetch orders for
733
743
  :param int [limit]: the maximum number of order structures to retrieve
@@ -1269,6 +1279,10 @@ class htx(ccxt.async_support.htx):
1269
1279
  async def watch_balance(self, params={}) -> Balances:
1270
1280
  """
1271
1281
  watch balance and get the amount of funds available for trading or funds locked in orders
1282
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=7ec52e28-7773-11ed-9966-0242ac110003
1283
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=10000084-77b7-11ed-9966-0242ac110003
1284
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=8cb7dcca-77b5-11ed-9966-0242ac110003
1285
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=28c34995-77ae-11ed-9966-0242ac110003
1272
1286
  :param dict [params]: extra parameters specific to the exchange API endpoint
1273
1287
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
1274
1288
  """
ccxt/pro/kraken.py CHANGED
@@ -38,6 +38,7 @@ class kraken(ccxt.async_support.kraken):
38
38
  'watchOrders': True,
39
39
  'watchTicker': True,
40
40
  'watchTickers': True,
41
+ 'watchBidsAsks': True,
41
42
  'watchTrades': True,
42
43
  'watchTradesForSymbols': True,
43
44
  'createOrderWs': True,
@@ -492,6 +493,61 @@ class kraken(ccxt.async_support.kraken):
492
493
  return result
493
494
  return self.filter_by_array(self.tickers, 'symbol', symbols)
494
495
 
496
+ async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
497
+ """
498
+ :see: https://docs.kraken.com/api/docs/websocket-v1/spread
499
+ watches best bid & ask for symbols
500
+ :param str[] symbols: unified symbol of the market to fetch the ticker for
501
+ :param dict [params]: extra parameters specific to the exchange API endpoint
502
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
503
+ """
504
+ await self.load_markets()
505
+ symbols = self.market_symbols(symbols, None, False)
506
+ ticker = await self.watch_multi_helper('bidask', 'spread', symbols, None, params)
507
+ if self.newUpdates:
508
+ result: dict = {}
509
+ result[ticker['symbol']] = ticker
510
+ return result
511
+ return self.filter_by_array(self.bidsasks, 'symbol', symbols)
512
+
513
+ def handle_bid_ask(self, client: Client, message, subscription):
514
+ #
515
+ # [
516
+ # 7208974, # channelID
517
+ # [
518
+ # "63758.60000", # bid
519
+ # "63759.10000", # ask
520
+ # "1726814731.089778", # timestamp
521
+ # "0.00057917", # bid_volume
522
+ # "0.15681688" # ask_volume
523
+ # ],
524
+ # "spread",
525
+ # "XBT/USDT"
526
+ # ]
527
+ #
528
+ parsedTicker = self.parse_ws_bid_ask(message)
529
+ symbol = parsedTicker['symbol']
530
+ self.bidsasks[symbol] = parsedTicker
531
+ messageHash = self.get_message_hash('bidask', None, symbol)
532
+ client.resolve(parsedTicker, messageHash)
533
+
534
+ def parse_ws_bid_ask(self, ticker, market=None):
535
+ data = self.safe_list(ticker, 1, [])
536
+ marketId = self.safe_string(ticker, 3)
537
+ market = self.safe_value(self.options['marketsByWsName'], marketId)
538
+ symbol = self.safe_string(market, 'symbol')
539
+ timestamp = self.parse_to_int(self.safe_integer(data, 2)) * 1000
540
+ return self.safe_ticker({
541
+ 'symbol': symbol,
542
+ 'timestamp': timestamp,
543
+ 'datetime': self.iso8601(timestamp),
544
+ 'ask': self.safe_string(data, 1),
545
+ 'askVolume': self.safe_string(data, 4),
546
+ 'bid': self.safe_string(data, 0),
547
+ 'bidVolume': self.safe_string(data, 3),
548
+ 'info': ticker,
549
+ }, market)
550
+
495
551
  async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
496
552
  """
497
553
  get the list of most recent trades for a particular symbol
@@ -1400,6 +1456,7 @@ class kraken(ccxt.async_support.kraken):
1400
1456
  'book': self.handle_order_book,
1401
1457
  'ohlc': self.handle_ohlcv,
1402
1458
  'ticker': self.handle_ticker,
1459
+ 'spread': self.handle_bid_ask,
1403
1460
  'trade': self.handle_trades,
1404
1461
  # private
1405
1462
  'openOrders': self.handle_orders,