ccxt 4.3.24__py2.py3-none-any.whl → 4.3.27__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/__init__.py CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.3.24'
25
+ __version__ = '4.3.27'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.24'
7
+ __version__ = '4.3.27'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.3.24'
5
+ __version__ = '4.3.27'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -839,7 +839,7 @@ class Exchange(BaseExchange):
839
839
  await self.cancelOrder(id, symbol)
840
840
  return await self.create_order(symbol, type, side, amount, price, params)
841
841
 
842
- async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
842
+ async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
843
843
  await self.cancelOrderWs(id, symbol)
844
844
  return await self.createOrderWs(symbol, type, side, amount, price, params)
845
845
 
@@ -458,11 +458,16 @@ class coinex(Exchange, ImplicitAPI):
458
458
  'fetchDepositAddress': {
459
459
  'fillResponseFromRequest': True,
460
460
  },
461
- 'accountsById': {
461
+ 'accountsByType': {
462
462
  'spot': 'SPOT',
463
463
  'margin': 'MARGIN',
464
464
  'swap': 'FUTURES',
465
465
  },
466
+ 'accountsById': {
467
+ 'SPOT': 'spot',
468
+ 'MARGIN': 'margin',
469
+ 'FUTURES': 'swap',
470
+ },
466
471
  'networks': {
467
472
  'BEP20': 'BSC',
468
473
  'TRX': 'TRC20',
@@ -4616,9 +4621,9 @@ class coinex(Exchange, ImplicitAPI):
4616
4621
  await self.load_markets()
4617
4622
  currency = self.currency(code)
4618
4623
  amountToPrecision = self.currency_to_precision(code, amount)
4619
- accountsById = self.safe_dict(self.options, 'accountsById', {})
4620
- fromId = self.safe_string(accountsById, fromAccount, fromAccount)
4621
- toId = self.safe_string(accountsById, toAccount, toAccount)
4624
+ accountsByType = self.safe_dict(self.options, 'accountsById', {})
4625
+ fromId = self.safe_string(accountsByType, fromAccount, fromAccount)
4626
+ toId = self.safe_string(accountsByType, toAccount, toAccount)
4622
4627
  request = {
4623
4628
  'ccy': currency['id'],
4624
4629
  'amount': amountToPrecision,
@@ -4652,6 +4657,8 @@ class coinex(Exchange, ImplicitAPI):
4652
4657
  '0': 'ok',
4653
4658
  'SUCCESS': 'ok',
4654
4659
  'OK': 'ok',
4660
+ 'finished': 'ok',
4661
+ 'FINISHED': 'ok',
4655
4662
  }
4656
4663
  return self.safe_string(statuses, status, status)
4657
4664
 
@@ -4675,91 +4682,55 @@ class coinex(Exchange, ImplicitAPI):
4675
4682
  async def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> TransferEntries:
4676
4683
  """
4677
4684
  fetch a history of internal transfers made on an account
4678
- :see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot002_account025_margin_transfer_history
4679
- :see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot002_account024_contract_transfer_history
4685
+ :see: https://docs.coinex.com/api/v2/assets/transfer/http/list-transfer-history
4680
4686
  :param str code: unified currency code of the currency transferred
4681
4687
  :param int [since]: the earliest time in ms to fetch transfers for
4682
- :param int [limit]: the maximum number of transfers structures to retrieve
4688
+ :param int [limit]: the maximum number of transfer structures to retrieve
4683
4689
  :param dict [params]: extra parameters specific to the exchange API endpoint
4690
+ :param str [params.marginMode]: 'cross' or 'isolated' for fetching transfers to and from your margin account
4684
4691
  :returns dict[]: a list of `transfer structures <https://docs.ccxt.com/#/?id=transfer-structure>`
4685
4692
  """
4686
4693
  await self.load_markets()
4687
- currency = None
4694
+ if code is None:
4695
+ raise ArgumentsRequired(self.id + ' fetchTransfers() requires a code argument')
4696
+ currency = self.currency(code)
4688
4697
  request = {
4689
- 'page': 1,
4690
- # 'limit': limit,
4691
- # 'asset': 'USDT',
4692
- # 'start_time': since,
4693
- # 'end_time': 1515806440,
4694
- # 'transfer_type': 'transfer_in', # transfer_in: from Spot to Swap Account, transfer_out: from Swap to Spot Account
4698
+ 'ccy': currency['id'],
4695
4699
  }
4696
- page = self.safe_integer(params, 'page')
4697
- if page is not None:
4698
- request['page'] = page
4699
- if code is not None:
4700
- currency = self.currency(code)
4701
- request['asset'] = currency['id']
4702
- if since is not None:
4703
- request['start_time'] = since
4704
- if limit is not None:
4705
- request['limit'] = limit
4706
- else:
4707
- request['limit'] = 100
4708
- params = self.omit(params, 'page')
4709
4700
  marginMode = None
4710
4701
  marginMode, params = self.handle_margin_mode_and_params('fetchTransfers', params)
4711
- response = None
4712
4702
  if marginMode is not None:
4713
- response = await self.v1PrivateGetMarginTransferHistory(self.extend(request, params))
4703
+ request['transfer_type'] = 'MARGIN'
4714
4704
  else:
4715
- response = await self.v1PrivateGetContractTransferHistory(self.extend(request, params))
4716
- #
4717
- # Swap
4705
+ request['transfer_type'] = 'FUTURES'
4706
+ if since is not None:
4707
+ request['start_time'] = since
4708
+ if limit is not None:
4709
+ request['limit'] = limit
4710
+ request, params = self.handle_until_option('end_time', request, params)
4711
+ response = await self.v2PrivateGetAssetsTransferHistory(self.extend(request, params))
4718
4712
  #
4719
4713
  # {
4720
- # "code": 0,
4721
- # "data": {
4722
- # "records": [
4723
- # {
4724
- # "amount": "10",
4725
- # "asset": "USDT",
4726
- # "transfer_type": "transfer_out",
4727
- # "created_at": 1651633422
4728
- # },
4729
- # ],
4730
- # "total": 5
4714
+ # "data": [
4715
+ # {
4716
+ # "created_at": 1715848480646,
4717
+ # "from_account_type": "SPOT",
4718
+ # "to_account_type": "FUTURES",
4719
+ # "ccy": "USDT",
4720
+ # "amount": "10",
4721
+ # "status": "finished"
4722
+ # },
4723
+ # ],
4724
+ # "pagination": {
4725
+ # "total": 8,
4726
+ # "has_next": False
4731
4727
  # },
4732
- # "message": "Success"
4733
- # }
4734
- #
4735
- # Margin
4736
- #
4737
- # {
4738
4728
  # "code": 0,
4739
- # "data": {
4740
- # "records": [
4741
- # {
4742
- # "id": 7580062,
4743
- # "updated_at": 1653684379,
4744
- # "user_id": 3620173,
4745
- # "from_account_id": 0,
4746
- # "to_account_id": 1,
4747
- # "asset": "BTC",
4748
- # "amount": "0.00160829",
4749
- # "balance": "0.00160829",
4750
- # "transfer_type": "IN",
4751
- # "status": "SUCCESS",
4752
- # "created_at": 1653684379
4753
- # }
4754
- # ],
4755
- # "total": 1
4756
- # },
4757
- # "message": "Success"
4729
+ # "message": "OK"
4758
4730
  # }
4759
4731
  #
4760
- data = self.safe_value(response, 'data', {})
4761
- transfers = self.safe_list(data, 'records', [])
4762
- return self.parse_transfers(transfers, currency, since, limit)
4732
+ data = self.safe_list(response, 'data', [])
4733
+ return self.parse_transfers(data, currency, since, limit)
4763
4734
 
4764
4735
  async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
4765
4736
  """
@@ -58,6 +58,9 @@ class kraken(Exchange, ImplicitAPI):
58
58
  'cancelOrder': True,
59
59
  'cancelOrders': True,
60
60
  'createDepositAddress': True,
61
+ 'createMarketBuyOrderWithCost': True,
62
+ 'createMarketOrderWithCost': False,
63
+ 'createMarketSellOrderWithCost': False,
61
64
  'createOrder': True,
62
65
  'createStopLimitOrder': True,
63
66
  'createStopMarketOrder': True,
@@ -1308,6 +1311,33 @@ class kraken(Exchange, ImplicitAPI):
1308
1311
  #
1309
1312
  return self.parse_balance(response)
1310
1313
 
1314
+ async def create_market_order_with_cost(self, symbol: str, side: OrderSide, cost: float, params={}):
1315
+ """
1316
+ create a market order by providing the symbol, side and cost
1317
+ :see: https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
1318
+ :param str symbol: unified symbol of the market to create an order in(only USD markets are supported)
1319
+ :param str side: 'buy' or 'sell'
1320
+ :param float cost: how much you want to trade in units of the quote currency
1321
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1322
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1323
+ """
1324
+ await self.load_markets()
1325
+ # only buy orders are supported by the endpoint
1326
+ params['cost'] = cost
1327
+ return await self.create_order(symbol, 'market', side, cost, None, params)
1328
+
1329
+ async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
1330
+ """
1331
+ create a market buy order by providing the symbol, side and cost
1332
+ :see: https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
1333
+ :param str symbol: unified symbol of the market to create an order in
1334
+ :param float cost: how much you want to trade in units of the quote currency
1335
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1336
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1337
+ """
1338
+ await self.load_markets()
1339
+ return await self.create_market_order_with_cost(symbol, 'buy', cost, params)
1340
+
1311
1341
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1312
1342
  """
1313
1343
  :see: https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
@@ -1336,7 +1366,7 @@ class kraken(Exchange, ImplicitAPI):
1336
1366
  'ordertype': type,
1337
1367
  'volume': self.amount_to_precision(symbol, amount),
1338
1368
  }
1339
- orderRequest = self.order_request('createOrder', symbol, type, request, price, params)
1369
+ orderRequest = self.order_request('createOrder', symbol, type, request, amount, price, params)
1340
1370
  response = await self.privatePostAddOrder(self.extend(orderRequest[0], orderRequest[1]))
1341
1371
  #
1342
1372
  # {
@@ -1616,7 +1646,7 @@ class kraken(Exchange, ImplicitAPI):
1616
1646
  'trades': trades,
1617
1647
  }, market)
1618
1648
 
1619
- def order_request(self, method, symbol, type, request, price=None, params={}):
1649
+ def order_request(self, method: str, symbol: str, type: str, request: dict, amount: Num, price: Num = None, params={}):
1620
1650
  clientOrderId = self.safe_string_2(params, 'userref', 'clientOrderId')
1621
1651
  params = self.omit(params, ['userref', 'clientOrderId'])
1622
1652
  if clientOrderId is not None:
@@ -1630,9 +1660,21 @@ class kraken(Exchange, ImplicitAPI):
1630
1660
  trailingLimitAmount = self.safe_string(params, 'trailingLimitAmount')
1631
1661
  isTrailingAmountOrder = trailingAmount is not None
1632
1662
  isLimitOrder = type.endswith('limit') # supporting limit, stop-loss-limit, take-profit-limit, etc
1633
- if isLimitOrder and not isTrailingAmountOrder:
1663
+ isMarketOrder = type == 'market'
1664
+ cost = self.safe_string(params, 'cost')
1665
+ flags = self.safe_string(params, 'oflags')
1666
+ params = self.omit(params, ['cost', 'oflags'])
1667
+ isViqcOrder = (flags is not None) and (flags.find('viqc') > -1) # volume in quote currency
1668
+ if isMarketOrder and (cost is not None or isViqcOrder):
1669
+ if cost is None and (amount is not None):
1670
+ request['volume'] = self.cost_to_precision(symbol, self.number_to_string(amount))
1671
+ else:
1672
+ request['volume'] = self.cost_to_precision(symbol, cost)
1673
+ extendedOflags = flags + ',viqc' if (flags is not None) else 'viqc'
1674
+ request['oflags'] = extendedOflags
1675
+ elif isLimitOrder and not isTrailingAmountOrder:
1634
1676
  request['price'] = self.price_to_precision(symbol, price)
1635
- reduceOnly = self.safe_value_2(params, 'reduceOnly', 'reduce_only')
1677
+ reduceOnly = self.safe_bool_2(params, 'reduceOnly', 'reduce_only')
1636
1678
  if isStopLossOrTakeProfitTrigger:
1637
1679
  if isStopLossTriggerOrder:
1638
1680
  request['price'] = self.price_to_precision(symbol, stopLossTriggerPrice)
@@ -1666,7 +1708,7 @@ class kraken(Exchange, ImplicitAPI):
1666
1708
  request['reduce_only'] = True # ws request can't have stringified bool
1667
1709
  else:
1668
1710
  request['reduce_only'] = 'true' # not using hasattr(self, boolean) case, because the urlencodedNested transforms it into 'True' string
1669
- close = self.safe_value(params, 'close')
1711
+ close = self.safe_dict(params, 'close')
1670
1712
  if close is not None:
1671
1713
  close = self.extend({}, close)
1672
1714
  closePrice = self.safe_value(close, 'price')
@@ -1683,7 +1725,8 @@ class kraken(Exchange, ImplicitAPI):
1683
1725
  postOnly = None
1684
1726
  postOnly, params = self.handle_post_only(isMarket, False, params)
1685
1727
  if postOnly:
1686
- request['oflags'] = 'post'
1728
+ extendedPostFlags = flags + ',post' if (flags is not None) else 'post'
1729
+ request['oflags'] = extendedPostFlags
1687
1730
  params = self.omit(params, ['timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingLimitAmount', 'offset'])
1688
1731
  return [request, params]
1689
1732
 
@@ -1716,7 +1759,7 @@ class kraken(Exchange, ImplicitAPI):
1716
1759
  }
1717
1760
  if amount is not None:
1718
1761
  request['volume'] = self.amount_to_precision(symbol, amount)
1719
- orderRequest = self.order_request('editOrder', symbol, type, request, price, params)
1762
+ orderRequest = self.order_request('editOrder', symbol, type, request, amount, price, params)
1720
1763
  response = await self.privatePostEditOrder(self.extend(orderRequest[0], orderRequest[1]))
1721
1764
  #
1722
1765
  # {
@@ -2808,6 +2851,8 @@ class kraken(Exchange, ImplicitAPI):
2808
2851
  raise CancelPending(self.id + ' ' + body)
2809
2852
  if body.find('Invalid arguments:volume') >= 0:
2810
2853
  raise InvalidOrder(self.id + ' ' + body)
2854
+ if body.find('Invalid arguments:viqc') >= 0:
2855
+ raise InvalidOrder(self.id + ' ' + body)
2811
2856
  if body.find('Rate limit exceeded') >= 0:
2812
2857
  raise RateLimitExceeded(self.id + ' ' + body)
2813
2858
  if response is None:
@@ -2168,7 +2168,7 @@ class phemex(Exchange, ImplicitAPI):
2168
2168
  if feeCost is not None:
2169
2169
  fee = {
2170
2170
  'cost': feeCost,
2171
- 'currency': None,
2171
+ 'currency': self.safe_currency_code(self.safe_string(order, 'feeCurrency')),
2172
2172
  }
2173
2173
  timeInForce = self.parse_time_in_force(self.safe_string(order, 'timeInForce'))
2174
2174
  stopPrice = self.parse_number(self.omit_zero(self.from_ep(self.safe_string(order, 'stopPxEp'))))
@@ -2313,6 +2313,7 @@ class phemex(Exchange, ImplicitAPI):
2313
2313
  clientOrderId = None
2314
2314
  marketId = self.safe_string(order, 'symbol')
2315
2315
  symbol = self.safe_symbol(marketId, market)
2316
+ market = self.safe_market(marketId, market)
2316
2317
  status = self.parse_order_status(self.safe_string(order, 'ordStatus'))
2317
2318
  side = self.parse_order_side(self.safe_string_lower(order, 'side'))
2318
2319
  type = self.parse_order_type(self.safe_string(order, 'orderType'))
@@ -2338,6 +2339,19 @@ class phemex(Exchange, ImplicitAPI):
2338
2339
  reduceOnly = True
2339
2340
  takeProfit = self.safe_string(order, 'takeProfitRp')
2340
2341
  stopLoss = self.safe_string(order, 'stopLossRp')
2342
+ feeValue = self.omit_zero(self.safe_string(order, 'execFeeRv'))
2343
+ ptFeeRv = self.omit_zero(self.safe_string(order, 'ptFeeRv'))
2344
+ fee = None
2345
+ if feeValue is not None:
2346
+ fee = {
2347
+ 'cost': feeValue,
2348
+ 'currency': market['quote'],
2349
+ }
2350
+ elif ptFeeRv is not None:
2351
+ fee = {
2352
+ 'cost': ptFeeRv,
2353
+ 'currency': 'PT',
2354
+ }
2341
2355
  return self.safe_order({
2342
2356
  'info': order,
2343
2357
  'id': id,
@@ -2362,7 +2376,7 @@ class phemex(Exchange, ImplicitAPI):
2362
2376
  'cost': cost,
2363
2377
  'average': None,
2364
2378
  'status': status,
2365
- 'fee': None,
2379
+ 'fee': fee,
2366
2380
  'trades': None,
2367
2381
  })
2368
2382
 
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.24'
7
+ __version__ = '4.3.27'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -1689,11 +1689,14 @@ class Exchange(object):
1689
1689
  return default
1690
1690
 
1691
1691
  def omit_zero(self, string_number):
1692
- if string_number is None or string_number == '':
1693
- return None
1694
- if float(string_number) == 0:
1695
- return None
1696
- return string_number
1692
+ try:
1693
+ if string_number is None or string_number == '':
1694
+ return None
1695
+ if float(string_number) == 0:
1696
+ return None
1697
+ return string_number
1698
+ except Exception:
1699
+ return string_number
1697
1700
 
1698
1701
  def check_order_arguments(self, market, type, side, amount, price, params):
1699
1702
  if price is None:
@@ -3621,12 +3624,24 @@ class Exchange(object):
3621
3624
  params = self.omit(params, paramName)
3622
3625
  return [value, params]
3623
3626
 
3627
+ def handle_param_string_2(self, params: object, paramName1: str, paramName2: str, defaultValue: Str = None):
3628
+ value = self.safe_string_2(params, paramName1, paramName2, defaultValue)
3629
+ if value is not None:
3630
+ params = self.omit(params, [paramName1, paramName2])
3631
+ return [value, params]
3632
+
3624
3633
  def handle_param_integer(self, params: object, paramName: str, defaultValue: Int = None):
3625
3634
  value = self.safe_integer(params, paramName, defaultValue)
3626
3635
  if value is not None:
3627
3636
  params = self.omit(params, paramName)
3628
3637
  return [value, params]
3629
3638
 
3639
+ def handle_param_integer_2(self, params: object, paramName1: str, paramName2: str, defaultValue: Int = None):
3640
+ value = self.safe_integer_2(params, paramName1, paramName2, defaultValue)
3641
+ if value is not None:
3642
+ params = self.omit(params, [paramName1, paramName2])
3643
+ return [value, params]
3644
+
3630
3645
  def resolve_path(self, path, params):
3631
3646
  return [
3632
3647
  self.implode_params(path, params),
@@ -3752,7 +3767,7 @@ class Exchange(object):
3752
3767
  self.cancelOrder(id, symbol)
3753
3768
  return self.create_order(symbol, type, side, amount, price, params)
3754
3769
 
3755
- def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
3770
+ def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
3756
3771
  self.cancelOrderWs(id, symbol)
3757
3772
  return self.createOrderWs(symbol, type, side, amount, price, params)
3758
3773
 
@@ -3988,25 +4003,13 @@ class Exchange(object):
3988
4003
  value = value if (value is not None) else defaultValue
3989
4004
  return [value, params]
3990
4005
 
3991
- def handle_option_and_params_2(self, params: object, methodName: str, methodName2: str, optionName: str, defaultValue=None):
3992
- # This method can be used to obtain method specific properties, i.e: self.handle_option_and_params(params, 'fetchPosition', 'marginMode', 'isolated')
3993
- defaultOptionName = 'default' + self.capitalize(optionName) # we also need to check the 'defaultXyzWhatever'
3994
- # check if params contain the key
3995
- value = self.safe_value_2(params, optionName, defaultOptionName)
3996
- if value is not None:
3997
- params = self.omit(params, [optionName, defaultOptionName])
3998
- else:
3999
- # check if exchange has properties for self method
4000
- exchangeWideMethodOptions = self.safe_value_2(self.options, methodName, methodName2)
4001
- if exchangeWideMethodOptions is not None:
4002
- # check if the option is defined inside self method's props
4003
- value = self.safe_value_2(exchangeWideMethodOptions, optionName, defaultOptionName)
4004
- if value is None:
4005
- # if it's still None, check if global exchange-wide option exists
4006
- value = self.safe_value_2(self.options, optionName, defaultOptionName)
4007
- # if it's still None, use the default value
4008
- value = value if (value is not None) else defaultValue
4009
- return [value, params]
4006
+ def handle_option_and_params_2(self, params: object, methodName1: str, optionName1: str, optionName2: str, defaultValue=None):
4007
+ value = None
4008
+ value, params = self.handle_option_and_params(params, methodName1, optionName1, defaultValue)
4009
+ # if still None, try optionName2
4010
+ value2 = None
4011
+ value2, params = self.handle_option_and_params(params, methodName1, optionName2, value)
4012
+ return [value2, params]
4010
4013
 
4011
4014
  def handle_option(self, methodName: str, optionName: str, defaultValue=None):
4012
4015
  # eslint-disable-next-line no-unused-vars
ccxt/coinex.py CHANGED
@@ -457,11 +457,16 @@ class coinex(Exchange, ImplicitAPI):
457
457
  'fetchDepositAddress': {
458
458
  'fillResponseFromRequest': True,
459
459
  },
460
- 'accountsById': {
460
+ 'accountsByType': {
461
461
  'spot': 'SPOT',
462
462
  'margin': 'MARGIN',
463
463
  'swap': 'FUTURES',
464
464
  },
465
+ 'accountsById': {
466
+ 'SPOT': 'spot',
467
+ 'MARGIN': 'margin',
468
+ 'FUTURES': 'swap',
469
+ },
465
470
  'networks': {
466
471
  'BEP20': 'BSC',
467
472
  'TRX': 'TRC20',
@@ -4615,9 +4620,9 @@ class coinex(Exchange, ImplicitAPI):
4615
4620
  self.load_markets()
4616
4621
  currency = self.currency(code)
4617
4622
  amountToPrecision = self.currency_to_precision(code, amount)
4618
- accountsById = self.safe_dict(self.options, 'accountsById', {})
4619
- fromId = self.safe_string(accountsById, fromAccount, fromAccount)
4620
- toId = self.safe_string(accountsById, toAccount, toAccount)
4623
+ accountsByType = self.safe_dict(self.options, 'accountsById', {})
4624
+ fromId = self.safe_string(accountsByType, fromAccount, fromAccount)
4625
+ toId = self.safe_string(accountsByType, toAccount, toAccount)
4621
4626
  request = {
4622
4627
  'ccy': currency['id'],
4623
4628
  'amount': amountToPrecision,
@@ -4651,6 +4656,8 @@ class coinex(Exchange, ImplicitAPI):
4651
4656
  '0': 'ok',
4652
4657
  'SUCCESS': 'ok',
4653
4658
  'OK': 'ok',
4659
+ 'finished': 'ok',
4660
+ 'FINISHED': 'ok',
4654
4661
  }
4655
4662
  return self.safe_string(statuses, status, status)
4656
4663
 
@@ -4674,91 +4681,55 @@ class coinex(Exchange, ImplicitAPI):
4674
4681
  def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> TransferEntries:
4675
4682
  """
4676
4683
  fetch a history of internal transfers made on an account
4677
- :see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot002_account025_margin_transfer_history
4678
- :see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot002_account024_contract_transfer_history
4684
+ :see: https://docs.coinex.com/api/v2/assets/transfer/http/list-transfer-history
4679
4685
  :param str code: unified currency code of the currency transferred
4680
4686
  :param int [since]: the earliest time in ms to fetch transfers for
4681
- :param int [limit]: the maximum number of transfers structures to retrieve
4687
+ :param int [limit]: the maximum number of transfer structures to retrieve
4682
4688
  :param dict [params]: extra parameters specific to the exchange API endpoint
4689
+ :param str [params.marginMode]: 'cross' or 'isolated' for fetching transfers to and from your margin account
4683
4690
  :returns dict[]: a list of `transfer structures <https://docs.ccxt.com/#/?id=transfer-structure>`
4684
4691
  """
4685
4692
  self.load_markets()
4686
- currency = None
4693
+ if code is None:
4694
+ raise ArgumentsRequired(self.id + ' fetchTransfers() requires a code argument')
4695
+ currency = self.currency(code)
4687
4696
  request = {
4688
- 'page': 1,
4689
- # 'limit': limit,
4690
- # 'asset': 'USDT',
4691
- # 'start_time': since,
4692
- # 'end_time': 1515806440,
4693
- # 'transfer_type': 'transfer_in', # transfer_in: from Spot to Swap Account, transfer_out: from Swap to Spot Account
4697
+ 'ccy': currency['id'],
4694
4698
  }
4695
- page = self.safe_integer(params, 'page')
4696
- if page is not None:
4697
- request['page'] = page
4698
- if code is not None:
4699
- currency = self.currency(code)
4700
- request['asset'] = currency['id']
4701
- if since is not None:
4702
- request['start_time'] = since
4703
- if limit is not None:
4704
- request['limit'] = limit
4705
- else:
4706
- request['limit'] = 100
4707
- params = self.omit(params, 'page')
4708
4699
  marginMode = None
4709
4700
  marginMode, params = self.handle_margin_mode_and_params('fetchTransfers', params)
4710
- response = None
4711
4701
  if marginMode is not None:
4712
- response = self.v1PrivateGetMarginTransferHistory(self.extend(request, params))
4702
+ request['transfer_type'] = 'MARGIN'
4713
4703
  else:
4714
- response = self.v1PrivateGetContractTransferHistory(self.extend(request, params))
4715
- #
4716
- # Swap
4704
+ request['transfer_type'] = 'FUTURES'
4705
+ if since is not None:
4706
+ request['start_time'] = since
4707
+ if limit is not None:
4708
+ request['limit'] = limit
4709
+ request, params = self.handle_until_option('end_time', request, params)
4710
+ response = self.v2PrivateGetAssetsTransferHistory(self.extend(request, params))
4717
4711
  #
4718
4712
  # {
4719
- # "code": 0,
4720
- # "data": {
4721
- # "records": [
4722
- # {
4723
- # "amount": "10",
4724
- # "asset": "USDT",
4725
- # "transfer_type": "transfer_out",
4726
- # "created_at": 1651633422
4727
- # },
4728
- # ],
4729
- # "total": 5
4713
+ # "data": [
4714
+ # {
4715
+ # "created_at": 1715848480646,
4716
+ # "from_account_type": "SPOT",
4717
+ # "to_account_type": "FUTURES",
4718
+ # "ccy": "USDT",
4719
+ # "amount": "10",
4720
+ # "status": "finished"
4721
+ # },
4722
+ # ],
4723
+ # "pagination": {
4724
+ # "total": 8,
4725
+ # "has_next": False
4730
4726
  # },
4731
- # "message": "Success"
4732
- # }
4733
- #
4734
- # Margin
4735
- #
4736
- # {
4737
4727
  # "code": 0,
4738
- # "data": {
4739
- # "records": [
4740
- # {
4741
- # "id": 7580062,
4742
- # "updated_at": 1653684379,
4743
- # "user_id": 3620173,
4744
- # "from_account_id": 0,
4745
- # "to_account_id": 1,
4746
- # "asset": "BTC",
4747
- # "amount": "0.00160829",
4748
- # "balance": "0.00160829",
4749
- # "transfer_type": "IN",
4750
- # "status": "SUCCESS",
4751
- # "created_at": 1653684379
4752
- # }
4753
- # ],
4754
- # "total": 1
4755
- # },
4756
- # "message": "Success"
4728
+ # "message": "OK"
4757
4729
  # }
4758
4730
  #
4759
- data = self.safe_value(response, 'data', {})
4760
- transfers = self.safe_list(data, 'records', [])
4761
- return self.parse_transfers(transfers, currency, since, limit)
4731
+ data = self.safe_list(response, 'data', [])
4732
+ return self.parse_transfers(data, currency, since, limit)
4762
4733
 
4763
4734
  def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
4764
4735
  """
ccxt/kraken.py CHANGED
@@ -58,6 +58,9 @@ class kraken(Exchange, ImplicitAPI):
58
58
  'cancelOrder': True,
59
59
  'cancelOrders': True,
60
60
  'createDepositAddress': True,
61
+ 'createMarketBuyOrderWithCost': True,
62
+ 'createMarketOrderWithCost': False,
63
+ 'createMarketSellOrderWithCost': False,
61
64
  'createOrder': True,
62
65
  'createStopLimitOrder': True,
63
66
  'createStopMarketOrder': True,
@@ -1308,6 +1311,33 @@ class kraken(Exchange, ImplicitAPI):
1308
1311
  #
1309
1312
  return self.parse_balance(response)
1310
1313
 
1314
+ def create_market_order_with_cost(self, symbol: str, side: OrderSide, cost: float, params={}):
1315
+ """
1316
+ create a market order by providing the symbol, side and cost
1317
+ :see: https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
1318
+ :param str symbol: unified symbol of the market to create an order in(only USD markets are supported)
1319
+ :param str side: 'buy' or 'sell'
1320
+ :param float cost: how much you want to trade in units of the quote currency
1321
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1322
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1323
+ """
1324
+ self.load_markets()
1325
+ # only buy orders are supported by the endpoint
1326
+ params['cost'] = cost
1327
+ return self.create_order(symbol, 'market', side, cost, None, params)
1328
+
1329
+ def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
1330
+ """
1331
+ create a market buy order by providing the symbol, side and cost
1332
+ :see: https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
1333
+ :param str symbol: unified symbol of the market to create an order in
1334
+ :param float cost: how much you want to trade in units of the quote currency
1335
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1336
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1337
+ """
1338
+ self.load_markets()
1339
+ return self.create_market_order_with_cost(symbol, 'buy', cost, params)
1340
+
1311
1341
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1312
1342
  """
1313
1343
  :see: https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
@@ -1336,7 +1366,7 @@ class kraken(Exchange, ImplicitAPI):
1336
1366
  'ordertype': type,
1337
1367
  'volume': self.amount_to_precision(symbol, amount),
1338
1368
  }
1339
- orderRequest = self.order_request('createOrder', symbol, type, request, price, params)
1369
+ orderRequest = self.order_request('createOrder', symbol, type, request, amount, price, params)
1340
1370
  response = self.privatePostAddOrder(self.extend(orderRequest[0], orderRequest[1]))
1341
1371
  #
1342
1372
  # {
@@ -1616,7 +1646,7 @@ class kraken(Exchange, ImplicitAPI):
1616
1646
  'trades': trades,
1617
1647
  }, market)
1618
1648
 
1619
- def order_request(self, method, symbol, type, request, price=None, params={}):
1649
+ def order_request(self, method: str, symbol: str, type: str, request: dict, amount: Num, price: Num = None, params={}):
1620
1650
  clientOrderId = self.safe_string_2(params, 'userref', 'clientOrderId')
1621
1651
  params = self.omit(params, ['userref', 'clientOrderId'])
1622
1652
  if clientOrderId is not None:
@@ -1630,9 +1660,21 @@ class kraken(Exchange, ImplicitAPI):
1630
1660
  trailingLimitAmount = self.safe_string(params, 'trailingLimitAmount')
1631
1661
  isTrailingAmountOrder = trailingAmount is not None
1632
1662
  isLimitOrder = type.endswith('limit') # supporting limit, stop-loss-limit, take-profit-limit, etc
1633
- if isLimitOrder and not isTrailingAmountOrder:
1663
+ isMarketOrder = type == 'market'
1664
+ cost = self.safe_string(params, 'cost')
1665
+ flags = self.safe_string(params, 'oflags')
1666
+ params = self.omit(params, ['cost', 'oflags'])
1667
+ isViqcOrder = (flags is not None) and (flags.find('viqc') > -1) # volume in quote currency
1668
+ if isMarketOrder and (cost is not None or isViqcOrder):
1669
+ if cost is None and (amount is not None):
1670
+ request['volume'] = self.cost_to_precision(symbol, self.number_to_string(amount))
1671
+ else:
1672
+ request['volume'] = self.cost_to_precision(symbol, cost)
1673
+ extendedOflags = flags + ',viqc' if (flags is not None) else 'viqc'
1674
+ request['oflags'] = extendedOflags
1675
+ elif isLimitOrder and not isTrailingAmountOrder:
1634
1676
  request['price'] = self.price_to_precision(symbol, price)
1635
- reduceOnly = self.safe_value_2(params, 'reduceOnly', 'reduce_only')
1677
+ reduceOnly = self.safe_bool_2(params, 'reduceOnly', 'reduce_only')
1636
1678
  if isStopLossOrTakeProfitTrigger:
1637
1679
  if isStopLossTriggerOrder:
1638
1680
  request['price'] = self.price_to_precision(symbol, stopLossTriggerPrice)
@@ -1666,7 +1708,7 @@ class kraken(Exchange, ImplicitAPI):
1666
1708
  request['reduce_only'] = True # ws request can't have stringified bool
1667
1709
  else:
1668
1710
  request['reduce_only'] = 'true' # not using hasattr(self, boolean) case, because the urlencodedNested transforms it into 'True' string
1669
- close = self.safe_value(params, 'close')
1711
+ close = self.safe_dict(params, 'close')
1670
1712
  if close is not None:
1671
1713
  close = self.extend({}, close)
1672
1714
  closePrice = self.safe_value(close, 'price')
@@ -1683,7 +1725,8 @@ class kraken(Exchange, ImplicitAPI):
1683
1725
  postOnly = None
1684
1726
  postOnly, params = self.handle_post_only(isMarket, False, params)
1685
1727
  if postOnly:
1686
- request['oflags'] = 'post'
1728
+ extendedPostFlags = flags + ',post' if (flags is not None) else 'post'
1729
+ request['oflags'] = extendedPostFlags
1687
1730
  params = self.omit(params, ['timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingLimitAmount', 'offset'])
1688
1731
  return [request, params]
1689
1732
 
@@ -1716,7 +1759,7 @@ class kraken(Exchange, ImplicitAPI):
1716
1759
  }
1717
1760
  if amount is not None:
1718
1761
  request['volume'] = self.amount_to_precision(symbol, amount)
1719
- orderRequest = self.order_request('editOrder', symbol, type, request, price, params)
1762
+ orderRequest = self.order_request('editOrder', symbol, type, request, amount, price, params)
1720
1763
  response = self.privatePostEditOrder(self.extend(orderRequest[0], orderRequest[1]))
1721
1764
  #
1722
1765
  # {
@@ -2808,6 +2851,8 @@ class kraken(Exchange, ImplicitAPI):
2808
2851
  raise CancelPending(self.id + ' ' + body)
2809
2852
  if body.find('Invalid arguments:volume') >= 0:
2810
2853
  raise InvalidOrder(self.id + ' ' + body)
2854
+ if body.find('Invalid arguments:viqc') >= 0:
2855
+ raise InvalidOrder(self.id + ' ' + body)
2811
2856
  if body.find('Rate limit exceeded') >= 0:
2812
2857
  raise RateLimitExceeded(self.id + ' ' + body)
2813
2858
  if response is None:
ccxt/phemex.py CHANGED
@@ -2168,7 +2168,7 @@ class phemex(Exchange, ImplicitAPI):
2168
2168
  if feeCost is not None:
2169
2169
  fee = {
2170
2170
  'cost': feeCost,
2171
- 'currency': None,
2171
+ 'currency': self.safe_currency_code(self.safe_string(order, 'feeCurrency')),
2172
2172
  }
2173
2173
  timeInForce = self.parse_time_in_force(self.safe_string(order, 'timeInForce'))
2174
2174
  stopPrice = self.parse_number(self.omit_zero(self.from_ep(self.safe_string(order, 'stopPxEp'))))
@@ -2313,6 +2313,7 @@ class phemex(Exchange, ImplicitAPI):
2313
2313
  clientOrderId = None
2314
2314
  marketId = self.safe_string(order, 'symbol')
2315
2315
  symbol = self.safe_symbol(marketId, market)
2316
+ market = self.safe_market(marketId, market)
2316
2317
  status = self.parse_order_status(self.safe_string(order, 'ordStatus'))
2317
2318
  side = self.parse_order_side(self.safe_string_lower(order, 'side'))
2318
2319
  type = self.parse_order_type(self.safe_string(order, 'orderType'))
@@ -2338,6 +2339,19 @@ class phemex(Exchange, ImplicitAPI):
2338
2339
  reduceOnly = True
2339
2340
  takeProfit = self.safe_string(order, 'takeProfitRp')
2340
2341
  stopLoss = self.safe_string(order, 'stopLossRp')
2342
+ feeValue = self.omit_zero(self.safe_string(order, 'execFeeRv'))
2343
+ ptFeeRv = self.omit_zero(self.safe_string(order, 'ptFeeRv'))
2344
+ fee = None
2345
+ if feeValue is not None:
2346
+ fee = {
2347
+ 'cost': feeValue,
2348
+ 'currency': market['quote'],
2349
+ }
2350
+ elif ptFeeRv is not None:
2351
+ fee = {
2352
+ 'cost': ptFeeRv,
2353
+ 'currency': 'PT',
2354
+ }
2341
2355
  return self.safe_order({
2342
2356
  'info': order,
2343
2357
  'id': id,
@@ -2362,7 +2376,7 @@ class phemex(Exchange, ImplicitAPI):
2362
2376
  'cost': cost,
2363
2377
  'average': None,
2364
2378
  'status': status,
2365
- 'fee': None,
2379
+ 'fee': fee,
2366
2380
  'trades': None,
2367
2381
  })
2368
2382
 
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.24'
7
+ __version__ = '4.3.27'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/binance.py CHANGED
@@ -1951,7 +1951,7 @@ class binance(ccxt.async_support.binance):
1951
1951
  orders = self.parse_orders(result)
1952
1952
  client.resolve(orders, messageHash)
1953
1953
 
1954
- async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
1954
+ async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}) -> Order:
1955
1955
  """
1956
1956
  edit a trade order
1957
1957
  :see: https://binance-docs.github.io/apidocs/websocket_api/en/#cancel-and-replace-order-trade
ccxt/pro/cryptocom.py CHANGED
@@ -103,13 +103,16 @@ class cryptocom(ccxt.async_support.cryptocom):
103
103
  if topicParams is None:
104
104
  params['params'] = {}
105
105
  bookSubscriptionType = None
106
- bookSubscriptionType, params = self.handle_option_and_params_2(params, 'watchOrderBook', 'watchOrderBookForSymbols', 'bookSubscriptionType', 'SNAPSHOT_AND_UPDATE')
107
- if bookSubscriptionType is not None:
108
- params['params']['bookSubscriptionType'] = bookSubscriptionType
106
+ bookSubscriptionType2 = None
107
+ bookSubscriptionType, params = self.handle_option_and_params(params, 'watchOrderBook', 'bookSubscriptionType', 'SNAPSHOT_AND_UPDATE')
108
+ bookSubscriptionType2, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'bookSubscriptionType', bookSubscriptionType)
109
+ params['params']['bookSubscriptionType'] = bookSubscriptionType2
109
110
  bookUpdateFrequency = None
110
- bookUpdateFrequency, params = self.handle_option_and_params_2(params, 'watchOrderBook', 'watchOrderBookForSymbols', 'bookUpdateFrequency')
111
- if bookUpdateFrequency is not None:
112
- params['params']['bookSubscriptionType'] = bookSubscriptionType
111
+ bookUpdateFrequency2 = None
112
+ bookUpdateFrequency, params = self.handle_option_and_params(params, 'watchOrderBook', 'bookUpdateFrequency')
113
+ bookUpdateFrequency2, params = self.handle_option_and_params(params, 'watchOrderBookForSymbols', 'bookUpdateFrequency', bookUpdateFrequency)
114
+ if bookUpdateFrequency2 is not None:
115
+ params['params']['bookSubscriptionType'] = bookUpdateFrequency2
113
116
  for i in range(0, len(symbols)):
114
117
  symbol = symbols[i]
115
118
  market = self.market(symbol)
ccxt/pro/kraken.py CHANGED
@@ -141,7 +141,7 @@ class kraken(ccxt.async_support.kraken):
141
141
  url = self.urls['api']['ws']['private']
142
142
  requestId = self.request_id()
143
143
  messageHash = requestId
144
- request = {
144
+ request: dict = {
145
145
  'event': 'addOrder',
146
146
  'token': token,
147
147
  'reqid': requestId,
@@ -150,7 +150,7 @@ class kraken(ccxt.async_support.kraken):
150
150
  'pair': market['wsId'],
151
151
  'volume': self.amount_to_precision(symbol, amount),
152
152
  }
153
- request, params = self.orderRequest('createOrderWs', symbol, type, request, price, params)
153
+ request, params = self.orderRequest('createOrderWs', symbol, type, request, amount, price, params)
154
154
  return await self.watch(url, messageHash, self.extend(request, params), messageHash)
155
155
 
156
156
  def handle_create_edit_order(self, client, message):
@@ -177,7 +177,7 @@ class kraken(ccxt.async_support.kraken):
177
177
  messageHash = self.safe_value(message, 'reqid')
178
178
  client.resolve(order, messageHash)
179
179
 
180
- async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
180
+ async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}) -> Order:
181
181
  """
182
182
  edit a trade order
183
183
  :see: https://docs.kraken.com/websockets/#message-editOrder
@@ -196,15 +196,16 @@ class kraken(ccxt.async_support.kraken):
196
196
  url = self.urls['api']['ws']['private']
197
197
  requestId = self.request_id()
198
198
  messageHash = requestId
199
- request = {
199
+ request: dict = {
200
200
  'event': 'editOrder',
201
201
  'token': token,
202
202
  'reqid': requestId,
203
203
  'orderid': id,
204
204
  'pair': market['wsId'],
205
- 'volume': self.amount_to_precision(symbol, amount),
206
205
  }
207
- request, params = self.orderRequest('editOrderWs', symbol, type, request, price, params)
206
+ if amount is not None:
207
+ request['volume'] = self.amount_to_precision(symbol, amount)
208
+ request, params = self.orderRequest('editOrderWs', symbol, type, request, amount, price, params)
208
209
  return await self.watch(url, messageHash, self.extend(request, params), messageHash)
209
210
 
210
211
  async def cancel_orders_ws(self, ids: List[str], symbol: Str = None, params={}):
ccxt/pro/okx.py CHANGED
@@ -1336,7 +1336,7 @@ class okx(ccxt.async_support.okx):
1336
1336
  first = self.safe_dict(orders, 0, {})
1337
1337
  client.resolve(first, messageHash)
1338
1338
 
1339
- async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
1339
+ async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}) -> Order:
1340
1340
  """
1341
1341
  edit a trade order
1342
1342
  :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-amend-order
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ccxt
3
- Version: 4.3.24
3
+ Version: 4.3.27
4
4
  Summary: A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges
5
5
  Home-page: https://ccxt.com
6
6
  Author: Igor Kroitor
@@ -264,13 +264,13 @@ console.log(version, Object.keys(exchanges));
264
264
 
265
265
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
266
266
 
267
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.24/dist/ccxt.browser.js
268
- * unpkg: https://unpkg.com/ccxt@4.3.24/dist/ccxt.browser.js
267
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.27/dist/ccxt.browser.js
268
+ * unpkg: https://unpkg.com/ccxt@4.3.27/dist/ccxt.browser.js
269
269
 
270
270
  CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
271
271
 
272
272
  ```HTML
273
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.24/dist/ccxt.browser.js"></script>
273
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.27/dist/ccxt.browser.js"></script>
274
274
  ```
275
275
 
276
276
  Creates a global `ccxt` object:
@@ -1,4 +1,4 @@
1
- ccxt/__init__.py,sha256=B1EFn-tKO_K29PcG0QEnfrDIY1jVqOL-3lliEvXsWx0,15950
1
+ ccxt/__init__.py,sha256=IgvCJzSBBNeqtwC5B_Us1bsp1ZuK0Fl35KXOdp1wu3Y,15950
2
2
  ccxt/ace.py,sha256=IAbVQ73OhU5xdTLO6dtedqa3bSuZ63Me55Se1zotYUY,41656
3
3
  ccxt/alpaca.py,sha256=NadHil-XkNFteqE7GwzIhKCCRjQ7m0xBQBCUlKxS6Sc,47215
4
4
  ccxt/ascendex.py,sha256=UjGRc4PgSi9ZNFl8greVZZZMTQxjEQRF8yF5SSUqeJM,151471
@@ -42,7 +42,7 @@ ccxt/coinbaseadvanced.py,sha256=d5g6nRx-NCcCwZDdtp8FsI2D-pRjSvnAP9ISSKY_nCQ,538
42
42
  ccxt/coinbaseexchange.py,sha256=FeSNMY_lAzYAs3X9QmDCMSHScdyUW-nLv78AoMIPK78,78704
43
43
  ccxt/coinbaseinternational.py,sha256=wieWUwsLsBYAgNpvnnrKseqAE7aOw__apSP6MQK9u9E,87240
44
44
  ccxt/coincheck.py,sha256=jg8KHt_XUMPlbG1BYUiSHu9-DDBWdnQwV15P9IzKqbY,35664
45
- ccxt/coinex.py,sha256=zce54mXGtgS1bqSrt-3IRSZdFHRtflIoqIX8dl2SaXc,259870
45
+ ccxt/coinex.py,sha256=wHFmRYPgMVEeW1ez8wbmAPhq9wgv0gudF7-M36CohDA,258819
46
46
  ccxt/coinlist.py,sha256=EU4jtqWALdcLG5X3m2q4xPbQ3-h5-H63Eeb_R3wW-5s,103140
47
47
  ccxt/coinmate.py,sha256=EsXu0mcAkVFwg2VOg47qr6g95a3bDPN2I9AuFQxgkQg,45946
48
48
  ccxt/coinmetro.py,sha256=tZjLAz5XufybO3BU3QGXMrLzinoY4UBhn0JIyXivnys,80700
@@ -69,7 +69,7 @@ ccxt/hyperliquid.py,sha256=11PVum5F0DV7y2n23KFbFSvInB2F7YYr0QTWfI-MHN0,100695
69
69
  ccxt/idex.py,sha256=yU8HDWBpXS3GREJFdYdGXcp18vj9RAB1E0R4BoXbWVQ,72998
70
70
  ccxt/independentreserve.py,sha256=iobtHiT8KlD1-mDJeoZCzPEPteSZz512mxgnrTnsECo,32175
71
71
  ccxt/indodax.py,sha256=ulvlP7-xpQWXrBfvRn-GWMoOXr_4MBBMrkTDDgM4fbQ,51921
72
- ccxt/kraken.py,sha256=YKMTpaILyYw5kLQkKMH9pl9nB0ek_5NSE0ew5-cUOVQ,125472
72
+ ccxt/kraken.py,sha256=dQfatDpJQ7jfMd6lHbpvI509HrYOsREg-Pxtq-fFeAY,128194
73
73
  ccxt/krakenfutures.py,sha256=S1WRrAtZ_tibYH50N0yb4y4pe12g3yNruLaH0ZWuWw4,116835
74
74
  ccxt/kucoin.py,sha256=0YqwMhzxBt_cmOgZj_JPJ5tOF7QrFJXzyvBrheJiuT4,217796
75
75
  ccxt/kucoinfutures.py,sha256=x5m2yqC5ZEIaKCBmM8alKJ7tk2r9nzpMC-PcpfadnRo,124327
@@ -88,7 +88,7 @@ ccxt/okx.py,sha256=C-RC8I5teheFdZ54ny3hC9zmjcYRmkpClrQQ1kgQ07s,377057
88
88
  ccxt/onetrading.py,sha256=MdzNJW9ViYhpx4S5cmoVu9SCX1nD3oZYfVfnPkhhfwE,88113
89
89
  ccxt/p2b.py,sha256=FYxL36KwtaLIIQ793frJEtqtHyzm39hNK0mJEzAAH0U,54213
90
90
  ccxt/paymium.py,sha256=kuMPTXyqU98kMpKeiSMicD51bSwprXHU0WrgLlAsxGY,24244
91
- ccxt/phemex.py,sha256=l2Ebx9I5uH7lX1yHnG6rtt27ndK2jMCJQWpExG9o_RQ,221696
91
+ ccxt/phemex.py,sha256=larOaYnUVb2xx2i4ayQh9BMFYqsFIYWaWg9s-hP3jm8,222247
92
92
  ccxt/poloniex.py,sha256=WfJ93JWxt5BiIidD2aiC09GSZI-EFhwdeBbJYZ47v1E,101991
93
93
  ccxt/poloniexfutures.py,sha256=3bxdkVWbe_T6r4IvekvM6x-Hd7cSng5SDaDjgPZSk8k,77799
94
94
  ccxt/probit.py,sha256=x6Y3MeRLwRZE02l7zxHbIucwU6pqYciWc05QXdZgxg8,75678
@@ -210,7 +210,7 @@ ccxt/abstract/woofipro.py,sha256=El50vWGAV-4QPIDhgSnd4egfvk246NB6vTC-8h722vs,160
210
210
  ccxt/abstract/yobit.py,sha256=8ycfCO8ORFly9hc0Aa47sZyX4_ZKPXS9h9yJzI-uQ7Q,1339
211
211
  ccxt/abstract/zaif.py,sha256=m15WHdl3gYy0GOXNZ8NEH8eE7sVh8c0T_ITNuU8vXeU,3935
212
212
  ccxt/abstract/zonda.py,sha256=aSfewvRojzmuymX6QbOnDR8v9VFqWTULMHX9Y7kKD1M,5820
213
- ccxt/async_support/__init__.py,sha256=t_VwyA3nEUTkoaRHt7HUyUv8NmHmqiIHEChunLqt2Dg,15723
213
+ ccxt/async_support/__init__.py,sha256=UDfJ00_0aAiIFtcfRRXwnwD9YTxb5cFzQrrbWyoXvjw,15723
214
214
  ccxt/async_support/ace.py,sha256=xVxaTocpMapAIl4ApPApw69Rd-RDuU0_vleJnVt_qhI,41880
215
215
  ccxt/async_support/alpaca.py,sha256=rjD8PdQr1B5e9hvaoTQBKVtWwHLs04e6_-gooXl4eEE,47427
216
216
  ccxt/async_support/ascendex.py,sha256=w4GaR3Xm9fkIAdXostTsu0Pnw9VkRrT6ar57gU9HSHw,152259
@@ -254,7 +254,7 @@ ccxt/async_support/coinbaseadvanced.py,sha256=Kupwnuxiu_qTjwCNV2asacoDUNFQvcaHNA
254
254
  ccxt/async_support/coinbaseexchange.py,sha256=3wEfbKBAVn9JkOfukopSRPhM8unRA6BQLqvm5c2VLBE,79210
255
255
  ccxt/async_support/coinbaseinternational.py,sha256=fuU-h5UpO_nVs1j8KA7oGsQlP0kQefuPycZrc8ph6OQ,87794
256
256
  ccxt/async_support/coincheck.py,sha256=ThRQX8E3NZrGc9Z__UIb7p0AtHgnq_DBhe9GzE9SlaQ,35870
257
- ccxt/async_support/coinex.py,sha256=g_RcySMlUqdpONcOnzJgTOt3JpvMkhGVCYu2OfiHdks,261152
257
+ ccxt/async_support/coinex.py,sha256=PzKHNgqRR6_d97suRqOJh3_JalhWSBk4HdQRazle-6k,260095
258
258
  ccxt/async_support/coinlist.py,sha256=MKLhRyaw0DHkpRfR-Vj9NS0SwCpYUx8nOxZJ26swIMY,103628
259
259
  ccxt/async_support/coinmate.py,sha256=lc8p0aQXu-oSf2whiqvm0QoBhDVx9wf50CcFeucdXcY,46212
260
260
  ccxt/async_support/coinmetro.py,sha256=NLqNdcJ_zXcNqaxqkrloL9PqnogbQ6OzA5e_Gl4ACtk,81020
@@ -281,7 +281,7 @@ ccxt/async_support/hyperliquid.py,sha256=-DmuoRQd5mlkIAxZWbEp7ReWpR0N6e9Tdgdj0bL
281
281
  ccxt/async_support/idex.py,sha256=etgzMUryt3ssiJDmrNWh4Hmo_xP61V-TX1uShRWjXiU,73474
282
282
  ccxt/async_support/independentreserve.py,sha256=8UTpFWJtrfZTeMhRfNK8mGiOu0-p-JCbK13G6spPueY,32435
283
283
  ccxt/async_support/indodax.py,sha256=Duu0r6PCzPlQLNqj2v2smCh6xE65S9LpP7wwQWa5ygM,52229
284
- ccxt/async_support/kraken.py,sha256=_yQEd3_OjqQBDdElH-XTPkLVe6P2tCVt0kl2BjlVnKU,126074
284
+ ccxt/async_support/kraken.py,sha256=6rHDgOa8EBfU1Uelit73ekfrOqPObxWoMBcqQBk-rpc,128832
285
285
  ccxt/async_support/krakenfutures.py,sha256=LwIy5nZe5urJ7Yrb5_KSKtk0giBBUnQl20KlgGKXwLg,117323
286
286
  ccxt/async_support/kucoin.py,sha256=-7kAVv2ghUIBXL6QLWmuZUsgCdq2wW6cHGSFMFGDyMA,218868
287
287
  ccxt/async_support/kucoinfutures.py,sha256=3gdO1HK5avmyseAXEEiufyNifvJAUpW75mUQNYhlmzQ,124965
@@ -300,7 +300,7 @@ ccxt/async_support/okx.py,sha256=smCT2Harj61L4dxsra9SFA70IJydH4EbOgSbjCabevg,378
300
300
  ccxt/async_support/onetrading.py,sha256=Px7iH4HjaGmAVMNjLwZdD8RJwspUleMdABCGQvmoNbA,88565
301
301
  ccxt/async_support/p2b.py,sha256=KrNc3sLbHQCxbgShyqWytuQVaQfKa42Q6_HcUYNUaKI,54455
302
302
  ccxt/async_support/paymium.py,sha256=_YfQn6Xwy0k9VMVOqmDGCfI8FhN_WKmyE7Eo9jR5u9I,24432
303
- ccxt/async_support/phemex.py,sha256=vKKPTW-ONIn3OKm3p0tT1QK07a28-aFv6kFhGqPKyUw,222508
303
+ ccxt/async_support/phemex.py,sha256=L8OyXY8Htq7dJo1rf_NUZz0xKTECBPdEU0fI1Ul49TM,223059
304
304
  ccxt/async_support/poloniex.py,sha256=tGl5AoEd2P0K0Af6twI2uwcNV81WDe2PCN4VAPkb3nQ,102539
305
305
  ccxt/async_support/poloniexfutures.py,sha256=VL4oNy3YJXw-UsiixEsU7wzw4JTpICXu6GdFdpcAKrw,78185
306
306
  ccxt/async_support/probit.py,sha256=xoDPbTB7_gntlKacTzFXFezCIIJpzoWP7CUaiIvu6co,76070
@@ -317,7 +317,7 @@ ccxt/async_support/yobit.py,sha256=kvMIVVjf8XxE7cKt51iHtqH7zgmFKc5ZVhk1dKDtlxE,5
317
317
  ccxt/async_support/zaif.py,sha256=lzrmIYPlNJquYkK-fq9DjqS8EfiAtofXnPcTMf3XOMM,28161
318
318
  ccxt/async_support/zonda.py,sha256=bS_Oq8FVjbLxnxFVVg-_5ZlNS0CH9QxSUVKL91IR9rc,80912
319
319
  ccxt/async_support/base/__init__.py,sha256=aVYSsFi--b4InRs9zDN_wtCpj8odosAB726JdUHavrk,67
320
- ccxt/async_support/base/exchange.py,sha256=IYH0t15nRLoVoENRTCmxOy8ClaroISPnRV0RVIvDyH0,108717
320
+ ccxt/async_support/base/exchange.py,sha256=QyB17V6ZVDZTfmvXf7x1CqTAA5sfnVpOhKrcqvxaQcU,108722
321
321
  ccxt/async_support/base/throttler.py,sha256=tvDVcdRUVYi8fZRlEcnqtgzcgB_KMUMRs5Pu8tuU-tU,1847
322
322
  ccxt/async_support/base/ws/__init__.py,sha256=uockzpLuwntKGZbs5EOWFe-Zg-k6Cj7GhNJLc_RX0so,1791
323
323
  ccxt/async_support/base/ws/aiohttp_client.py,sha256=Ed1765emEde2Hj8Ys6f5EjS54ZI1wQ0qIhd04eB7yhU,5751
@@ -331,14 +331,14 @@ ccxt/async_support/base/ws/order_book_side.py,sha256=Pxrq22nCODckJ6G1OXkYEmUunIu
331
331
  ccxt/base/__init__.py,sha256=eTx1OE3HJjspFUQjGm6LBhaQiMKJnXjkdP-JUXknyQ0,1320
332
332
  ccxt/base/decimal_to_precision.py,sha256=fgWRBzRTtsf3r2INyS4f7WHlzgjB5YM1ekiwqD21aac,6634
333
333
  ccxt/base/errors.py,sha256=FGdyULeNCNcl52gA_CNhe2dZmat9GJGkTdlIyDXAF_A,4213
334
- ccxt/base/exchange.py,sha256=aKmetWxqjo5la1OpqiQnmh6dkTiopP5U_HBg2IVaCTI,278253
334
+ ccxt/base/exchange.py,sha256=gjK_RZrV2v4hfg-0_Nwc0MJauZsbmhzYXM--3VyfEe8,278060
335
335
  ccxt/base/precise.py,sha256=_xfu54sV0vWNnOfGTKRFykeuWP8mn4K1m9lk1tcllX4,8565
336
336
  ccxt/base/types.py,sha256=3hBdiD2EO7W-pwmBrDeDYMEdFGcnT0QqQZa3l8ywTVM,9027
337
- ccxt/pro/__init__.py,sha256=sVg8AyzgbmwugQlnDh4ZA6H-NzqxchL4yuWNT9cx4aI,7107
337
+ ccxt/pro/__init__.py,sha256=M1Gqh1SoehSYMQqeQycis20jhklXJn48O41Cl5QRuvM,7107
338
338
  ccxt/pro/alpaca.py,sha256=7ePyWli0949ti5UheIn553xmnFpedrNc2W5CKauSZio,27167
339
339
  ccxt/pro/ascendex.py,sha256=fCM3EujSfJvtvffqI56UAstTtwjXFIocwukm15cF8rE,35432
340
340
  ccxt/pro/bequant.py,sha256=5zbsP8BHQTUZ8ZNL6uaACxDbUClgkOV4SYfXT_LfQVg,1351
341
- ccxt/pro/binance.py,sha256=--6tQbf691v6GlA8V-c95i50N85GVTM4G8KmKT1p-tY,152488
341
+ ccxt/pro/binance.py,sha256=-zjHYSngMVc3OwFssFFNEq7oSXr6uAX3RQZ15MbLUxQ,152493
342
342
  ccxt/pro/binancecoinm.py,sha256=s_evAyeT23VqscMRuSjrCK2CSaNsP-oc8A8noSuaLwQ,976
343
343
  ccxt/pro/binanceus.py,sha256=mpvmzc7kK3cGShM5EOvadOvwlj1xWsWzX9fIapuq2eQ,2321
344
344
  ccxt/pro/binanceusdm.py,sha256=S0eT662O2ReplsihWk42nhJWqw1XsODpeDQa9eFVVt8,1357
@@ -364,7 +364,7 @@ ccxt/pro/coinbaseinternational.py,sha256=4LMDA9RJhwT2T55kyryGCJBrdRgh_XBVYlJjXGS
364
364
  ccxt/pro/coincheck.py,sha256=MKAPHJeVifQaCKPla-7RY86TIWyDGe4nvjRhNmi617w,7789
365
365
  ccxt/pro/coinex.py,sha256=LVgahnm6laz2e0oQP4C8ki3mLcx5Eh-uz989BFquozM,45042
366
366
  ccxt/pro/coinone.py,sha256=d0s11hTNFVFZiBD3jWWu6iRseyVsHR6dO-njqqZ2WyU,15652
367
- ccxt/pro/cryptocom.py,sha256=c2se33IL7L9Y0F6RIKF3NZH0FeKCkUmrBJBe2U_YJ3U,42643
367
+ ccxt/pro/cryptocom.py,sha256=oHF9Bxe3a5yT8thg7JuIN-47YFAGKYKEQKGoByfFMgA,42910
368
368
  ccxt/pro/currencycom.py,sha256=U3H_inb0V39LYRwlKdVXTeA_akiG1437jZZ-dsejX0k,22355
369
369
  ccxt/pro/deribit.py,sha256=IutkVY1AzcTszpbbhNV1dLF3DUr3zGXxyHhWQVJ96m0,41035
370
370
  ccxt/pro/exmo.py,sha256=gLCAObkmAyL_4BTRnftfDTejsW3-isi18ppKIipidyo,24527
@@ -379,7 +379,7 @@ ccxt/pro/huobijp.py,sha256=fcC66ECLwrR9LN_AYZZltoE_w9EltT5DcXimPOHKJk0,23174
379
379
  ccxt/pro/hyperliquid.py,sha256=V6ev_19ttD0jmlaejvJwTl429_K1eyt0O3mUusQcrgk,20791
380
380
  ccxt/pro/idex.py,sha256=MJWG56eMN8rAE4Tmz-WxXDDO2KacfY7eFSoCwL15DnQ,28282
381
381
  ccxt/pro/independentreserve.py,sha256=39qWY0BpNoOfTpunMA9gwBePU8Ney6SO_zVuDy4uWLM,11179
382
- ccxt/pro/kraken.py,sha256=e4VgjQXUAJaWaCQf2r2PG8qBYjriDYhil-Enx8VTs5E,60764
382
+ ccxt/pro/kraken.py,sha256=Ckkm4clOLM2K-2p_CvRFZARSATgkvt7tqqQl_CosLdg,60837
383
383
  ccxt/pro/krakenfutures.py,sha256=QTeLsAXmM3CxLbDI6ktESj8LYQYhJISsB95Za1nFzh8,63917
384
384
  ccxt/pro/kucoin.py,sha256=wxUoyXjTV0iU5X4C2EdWRFFTzljICccpRJq4b9MWmmg,50705
385
385
  ccxt/pro/kucoinfutures.py,sha256=2aro_LzQFD-U3Bb5C0V1q7nv7WUG4-kKhS7xQIGz9Wk,50026
@@ -388,7 +388,7 @@ ccxt/pro/luno.py,sha256=2Y-8IQrrmwX8Y1lLWVDtrFjZD3t3qtMZJQ_JjNwj65s,12348
388
388
  ccxt/pro/mexc.py,sha256=caL4b1Q1YEJsKKQG5mmscqacYfkbyUuN0xin00eYPoc,43183
389
389
  ccxt/pro/ndax.py,sha256=Yrdy4UxjrDwO7gNMmSy09Wj6kHnRx1n0DTWmfirMEj8,22643
390
390
  ccxt/pro/okcoin.py,sha256=F38UBVjH2O7v6-XZMr5eJytnyBLp-0Uzx8q4qle_gXs,30385
391
- ccxt/pro/okx.py,sha256=7Kg0OihXhuCn2B0YF-B5otHX3rXnqKkXOoCqgduhl0w,72786
391
+ ccxt/pro/okx.py,sha256=kG28xgrUX3yLo16TCPpqsH_8Fj-AMtmbnw7gAYIOqQE,72791
392
392
  ccxt/pro/onetrading.py,sha256=9-WTi6ZNjsG7TJ6CA6pGpnm_6Jg2gg21ny4GZypjr6s,54634
393
393
  ccxt/pro/p2b.py,sha256=lO8mTtBCOU1yHQnmOQAI3USn67tsZd4nTGHDqFd4qEE,17877
394
394
  ccxt/pro/phemex.py,sha256=lD4r2KQdpkgeXGors3jtEMxoaxpEF0tl6MYXZ99GSYg,61032
@@ -534,7 +534,7 @@ ccxt/test/base/test_ticker.py,sha256=cMTIMb1oySNORUCmqI5ZzMswlEyCF6gJMah3vfvo8wQ
534
534
  ccxt/test/base/test_trade.py,sha256=PMtmB8V38dpaP-eb8h488xYMlR6D69yCOhsA1RuWrUA,2336
535
535
  ccxt/test/base/test_trading_fee.py,sha256=2aDCNJtqBkTC_AieO0l1HYGq5hz5qkWlkWb9Nv_fcwk,1066
536
536
  ccxt/test/base/test_transaction.py,sha256=BTbB4UHHXkrvYgwbrhh867nVRlevmIkIrz1W_odlQJI,1434
537
- ccxt-4.3.24.dist-info/METADATA,sha256=bv863nPYUVx5JlZGAu--tTGwa4QRxDiJZm-TEQqWsW0,112795
538
- ccxt-4.3.24.dist-info/WHEEL,sha256=P2T-6epvtXQ2cBOE_U1K4_noqlJFN3tj15djMgEu4NM,110
539
- ccxt-4.3.24.dist-info/top_level.txt,sha256=CkQDuCTDKNcImPV60t36G6MdYfxsAPNiSaEwifVoVMo,5
540
- ccxt-4.3.24.dist-info/RECORD,,
537
+ ccxt-4.3.27.dist-info/METADATA,sha256=qUglZetYt0dfJyQ6Kva9nZOeUfqU7UzFaxldgBwqEZU,112795
538
+ ccxt-4.3.27.dist-info/WHEEL,sha256=P2T-6epvtXQ2cBOE_U1K4_noqlJFN3tj15djMgEu4NM,110
539
+ ccxt-4.3.27.dist-info/top_level.txt,sha256=CkQDuCTDKNcImPV60t36G6MdYfxsAPNiSaEwifVoVMo,5
540
+ ccxt-4.3.27.dist-info/RECORD,,
File without changes