ccxt 4.3.42__py2.py3-none-any.whl → 4.3.44__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.

Potentially problematic release.


This version of ccxt might be problematic. Click here for more details.

@@ -32,7 +32,7 @@ class coinex(Exchange, ImplicitAPI):
32
32
  return self.deep_extend(super(coinex, self).describe(), {
33
33
  'id': 'coinex',
34
34
  'name': 'CoinEx',
35
- 'version': 'v1',
35
+ 'version': 'v2',
36
36
  'countries': ['CN'],
37
37
  # IP ratelimit is 400 requests per second
38
38
  # rateLimit = 1000ms / 400 = 2.5
@@ -329,6 +329,8 @@ class coinex(Exchange, ImplicitAPI):
329
329
  'futures/position-level': 1,
330
330
  'futures/liquidation-history': 1,
331
331
  'futures/basis-history': 1,
332
+ 'assets/deposit-withdraw-config': 1,
333
+ 'assets/all-deposit-withdraw-config': 1,
332
334
  },
333
335
  },
334
336
  'private': {
@@ -351,7 +353,6 @@ class coinex(Exchange, ImplicitAPI):
351
353
  'assets/deposit-address': 40,
352
354
  'assets/deposit-history': 40,
353
355
  'assets/withdraw': 40,
354
- 'assets/deposit-withdraw-config': 1,
355
356
  'assets/transfer-history': 40,
356
357
  'spot/order-status': 8,
357
358
  'spot/batch-order-status': 8,
@@ -545,126 +546,125 @@ class coinex(Exchange, ImplicitAPI):
545
546
  })
546
547
 
547
548
  async def fetch_currencies(self, params={}) -> Currencies:
548
- response = await self.v1PublicGetCommonAssetConfig(params)
549
+ """
550
+ fetches all available currencies on an exchange
551
+ :see: https://docs.coinex.com/api/v2/assets/deposit-withdrawal/http/list-all-deposit-withdrawal-config
552
+ :param dict [params]: extra parameters specific to the exchange API endpoint
553
+ :returns dict: an associative dictionary of currencies
554
+ """
555
+ response = await self.v2PublicGetAssetsAllDepositWithdrawConfig(params)
556
+ #
549
557
  # {
550
558
  # "code": 0,
551
- # "data": {
552
- # "USDT-ERC20": {
553
- # "asset": "USDT",
554
- # "chain": "ERC20",
555
- # "withdrawal_precision": 6,
556
- # "can_deposit": True,
557
- # "can_withdraw": True,
558
- # "deposit_least_amount": "4.9",
559
- # "withdraw_least_amount": "4.9",
560
- # "withdraw_tx_fee": "4.9",
561
- # "explorer_asset_url": "https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7"
562
- # },
563
- # ...
564
- # },
565
- # "message": "Success",
559
+ # "data": [
560
+ # {
561
+ # "asset": {
562
+ # "ccy": "CET",
563
+ # "deposit_enabled": True,
564
+ # "withdraw_enabled": True,
565
+ # "inter_transfer_enabled": True,
566
+ # "is_st": False
567
+ # },
568
+ # "chains": [
569
+ # {
570
+ # "chain": "CSC",
571
+ # "min_deposit_amount": "0.8",
572
+ # "min_withdraw_amount": "8",
573
+ # "deposit_enabled": True,
574
+ # "withdraw_enabled": True,
575
+ # "deposit_delay_minutes": 0,
576
+ # "safe_confirmations": 10,
577
+ # "irreversible_confirmations": 20,
578
+ # "deflation_rate": "0",
579
+ # "withdrawal_fee": "0.026",
580
+ # "withdrawal_precision": 8,
581
+ # "memo": "",
582
+ # "is_memo_required_for_deposit": False,
583
+ # "explorer_asset_url": ""
584
+ # },
585
+ # ]
586
+ # }
587
+ # ],
588
+ # "message": "OK"
566
589
  # }
567
590
  #
568
- data = self.safe_value(response, 'data', [])
569
- coins = list(data.keys())
591
+ data = self.safe_list(response, 'data', [])
570
592
  result: dict = {}
571
- for i in range(0, len(coins)):
572
- coin = coins[i]
573
- currency = data[coin]
574
- currencyId = self.safe_string(currency, 'asset')
575
- networkId = self.safe_string(currency, 'chain')
593
+ for i in range(0, len(data)):
594
+ coin = data[i]
595
+ asset = self.safe_dict(coin, 'asset', {})
596
+ chains = self.safe_list(coin, 'chains', [])
597
+ currencyId = self.safe_string(asset, 'ccy')
598
+ if currencyId is None:
599
+ continue # coinex returns empty structures for some reason
576
600
  code = self.safe_currency_code(currencyId)
577
- precisionString = self.parse_precision(self.safe_string(currency, 'withdrawal_precision'))
578
- precision = self.parse_number(precisionString)
579
- canDeposit = self.safe_value(currency, 'can_deposit')
580
- canWithdraw = self.safe_value(currency, 'can_withdraw')
581
- feeString = self.safe_string(currency, 'withdraw_tx_fee')
582
- fee = self.parse_number(feeString)
583
- minNetworkDepositString = self.safe_string(currency, 'deposit_least_amount')
584
- minNetworkDeposit = self.parse_number(minNetworkDepositString)
585
- minNetworkWithdrawString = self.safe_string(currency, 'withdraw_least_amount')
586
- minNetworkWithdraw = self.parse_number(minNetworkWithdrawString)
587
- if self.safe_value(result, code) is None:
588
- result[code] = {
589
- 'id': currencyId,
590
- 'numericId': None,
591
- 'code': code,
592
- 'info': None,
593
- 'name': None,
594
- 'active': canDeposit and canWithdraw,
595
- 'deposit': canDeposit,
596
- 'withdraw': canWithdraw,
597
- 'fee': fee,
598
- 'precision': precision,
599
- 'limits': {
600
- 'amount': {
601
- 'min': None,
602
- 'max': None,
603
- },
604
- 'deposit': {
605
- 'min': minNetworkDeposit,
606
- 'max': None,
607
- },
608
- 'withdraw': {
609
- 'min': minNetworkWithdraw,
610
- 'max': None,
611
- },
612
- },
613
- }
614
- minFeeString = self.safe_string(result[code], 'fee')
615
- if feeString is not None:
616
- minFeeString = feeString if (minFeeString is None) else Precise.string_min(feeString, minFeeString)
617
- depositAvailable = self.safe_value(result[code], 'deposit')
618
- depositAvailable = canDeposit if (canDeposit) else depositAvailable
619
- withdrawAvailable = self.safe_value(result[code], 'withdraw')
620
- withdrawAvailable = canWithdraw if (canWithdraw) else withdrawAvailable
621
- minDepositString = self.safe_string(result[code]['limits']['deposit'], 'min')
622
- if minNetworkDepositString is not None:
623
- minDepositString = minNetworkDepositString if (minDepositString is None) else Precise.string_min(minNetworkDepositString, minDepositString)
624
- minWithdrawString = self.safe_string(result[code]['limits']['withdraw'], 'min')
625
- if minNetworkWithdrawString is not None:
626
- minWithdrawString = minNetworkWithdrawString if (minWithdrawString is None) else Precise.string_min(minNetworkWithdrawString, minWithdrawString)
627
- minPrecisionString = self.safe_string(result[code], 'precision')
628
- if precisionString is not None:
629
- minPrecisionString = precisionString if (minPrecisionString is None) else Precise.string_min(precisionString, minPrecisionString)
630
- networks = self.safe_value(result[code], 'networks', {})
631
- network: dict = {
632
- 'info': currency,
633
- 'id': networkId,
634
- 'network': networkId,
601
+ canDeposit = self.safe_bool(asset, 'deposit_enabled')
602
+ canWithdraw = self.safe_bool(asset, 'withdraw_enabled')
603
+ firstChain = self.safe_dict(chains, 0, {})
604
+ firstPrecisionString = self.parse_precision(self.safe_string(firstChain, 'withdrawal_precision'))
605
+ result[code] = {
606
+ 'id': currencyId,
607
+ 'code': code,
635
608
  'name': None,
609
+ 'active': canDeposit and canWithdraw,
610
+ 'deposit': canDeposit,
611
+ 'withdraw': canWithdraw,
612
+ 'fee': None,
613
+ 'precision': self.parse_number(firstPrecisionString),
636
614
  'limits': {
637
615
  'amount': {
638
616
  'min': None,
639
617
  'max': None,
640
618
  },
641
619
  'deposit': {
642
- 'min': self.safe_number(currency, 'deposit_least_amount'),
620
+ 'min': None,
643
621
  'max': None,
644
622
  },
645
623
  'withdraw': {
646
- 'min': self.safe_number(currency, 'withdraw_least_amount'),
624
+ 'min': None,
647
625
  'max': None,
648
626
  },
649
627
  },
650
- 'active': canDeposit and canWithdraw,
651
- 'deposit': canDeposit,
652
- 'withdraw': canWithdraw,
653
- 'fee': fee,
654
- 'precision': precision,
628
+ 'networks': {},
629
+ 'info': coin,
655
630
  }
656
- networks[networkId] = network
657
- result[code]['networks'] = networks
658
- result[code]['active'] = depositAvailable and withdrawAvailable
659
- result[code]['deposit'] = depositAvailable
660
- result[code]['withdraw'] = withdrawAvailable
661
- info = self.safe_value(result[code], 'info', [])
662
- info.append(currency)
663
- result[code]['info'] = info
664
- result[code]['fee'] = self.parse_number(minFeeString)
665
- result[code]['precision'] = self.parse_number(minPrecisionString)
666
- result[code]['limits']['deposit']['min'] = self.parse_number(minDepositString)
667
- result[code]['limits']['withdraw']['min'] = self.parse_number(minWithdrawString)
631
+ for j in range(0, len(chains)):
632
+ chain = chains[j]
633
+ networkId = self.safe_string(chain, 'chain')
634
+ precisionString = self.parse_precision(self.safe_string(chain, 'withdrawal_precision'))
635
+ feeString = self.safe_string(chain, 'withdrawal_fee')
636
+ minNetworkDepositString = self.safe_string(chain, 'min_deposit_amount')
637
+ minNetworkWithdrawString = self.safe_string(chain, 'min_withdraw_amount')
638
+ canDepositChain = self.safe_bool(chain, 'deposit_enabled')
639
+ canWithdrawChain = self.safe_bool(chain, 'withdraw_enabled')
640
+ network: dict = {
641
+ 'id': networkId,
642
+ 'network': networkId,
643
+ 'name': None,
644
+ 'active': canDepositChain and canWithdrawChain,
645
+ 'deposit': canDepositChain,
646
+ 'withdraw': canWithdrawChain,
647
+ 'fee': self.parse_number(feeString),
648
+ 'precision': self.parse_number(precisionString),
649
+ 'limits': {
650
+ 'amount': {
651
+ 'min': None,
652
+ 'max': None,
653
+ },
654
+ 'deposit': {
655
+ 'min': self.parse_number(minNetworkDepositString),
656
+ 'max': None,
657
+ },
658
+ 'withdraw': {
659
+ 'min': self.parse_number(minNetworkWithdrawString),
660
+ 'max': None,
661
+ },
662
+ },
663
+ 'info': chain,
664
+ }
665
+ networks = self.safe_dict(result[code], 'networks', {})
666
+ networks[networkId] = network
667
+ result[code]['networks'] = networks
668
668
  return result
669
669
 
670
670
  async def fetch_markets(self, params={}) -> List[Market]:
@@ -5108,7 +5108,7 @@ class coinex(Exchange, ImplicitAPI):
5108
5108
  request: dict = {
5109
5109
  'ccy': currency['id'],
5110
5110
  }
5111
- response = await self.v2PrivateGetAssetsDepositWithdrawConfig(self.extend(request, params))
5111
+ response = await self.v2PublicGetAssetsDepositWithdrawConfig(self.extend(request, params))
5112
5112
  #
5113
5113
  # {
5114
5114
  # "code": 0,
@@ -858,7 +858,10 @@ class lykke(Exchange, ImplicitAPI):
858
858
  # "error":null
859
859
  # }
860
860
  #
861
- return await self.privateDeleteOrdersOrderId(self.extend(request, params))
861
+ response = await self.privateDeleteOrdersOrderId(self.extend(request, params))
862
+ return self.safe_order({
863
+ 'info': response,
864
+ })
862
865
 
863
866
  async def cancel_all_orders(self, symbol: Str = None, params={}):
864
867
  """
@@ -882,7 +885,12 @@ class lykke(Exchange, ImplicitAPI):
882
885
  # "error":null
883
886
  # }
884
887
  #
885
- return await self.privateDeleteOrders(self.extend(request, params))
888
+ response = await self.privateDeleteOrders(self.extend(request, params))
889
+ return [
890
+ self.safe_order({
891
+ 'info': response,
892
+ }),
893
+ ]
886
894
 
887
895
  async def fetch_order(self, id: str, symbol: Str = None, params={}):
888
896
  """
@@ -1510,7 +1510,11 @@ class ndax(Exchange, ImplicitAPI):
1510
1510
  # "detail":null
1511
1511
  # }
1512
1512
  #
1513
- return response
1513
+ return [
1514
+ self.safe_order({
1515
+ 'info': response,
1516
+ }),
1517
+ ]
1514
1518
 
1515
1519
  async def cancel_order(self, id: str, symbol: Str = None, params={}):
1516
1520
  """
@@ -21,7 +21,6 @@ from ccxt.base.errors import InvalidOrder
21
21
  from ccxt.base.errors import OrderNotFound
22
22
  from ccxt.base.errors import CancelPending
23
23
  from ccxt.base.errors import DuplicateOrderId
24
- from ccxt.base.errors import NotSupported
25
24
  from ccxt.base.errors import DDoSProtection
26
25
  from ccxt.base.errors import RateLimitExceeded
27
26
  from ccxt.base.decimal_to_precision import TICK_SIZE
@@ -2772,6 +2771,7 @@ class phemex(Exchange, ImplicitAPI):
2772
2771
 
2773
2772
  async def fetch_order(self, id: str, symbol: Str = None, params={}):
2774
2773
  """
2774
+ :see: https://phemex-docs.github.io/#query-orders-by-ids
2775
2775
  fetches information on an order made by the user
2776
2776
  :param str symbol: unified symbol of the market the order was made in
2777
2777
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2781,8 +2781,6 @@ class phemex(Exchange, ImplicitAPI):
2781
2781
  raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
2782
2782
  await self.load_markets()
2783
2783
  market = self.market(symbol)
2784
- if market['settle'] == 'USDT':
2785
- raise NotSupported(self.id + 'fetchOrder() is not supported yet for USDT settled swap markets') # https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query-user-order-by-orderid-or-query-user-order-by-client-order-id
2786
2784
  request: dict = {
2787
2785
  'symbol': market['id'],
2788
2786
  }
@@ -2793,7 +2791,9 @@ class phemex(Exchange, ImplicitAPI):
2793
2791
  else:
2794
2792
  request['orderID'] = id
2795
2793
  response = None
2796
- if market['spot']:
2794
+ if market['settle'] == 'USDT':
2795
+ response = await self.privateGetApiDataGFuturesOrdersByOrderId(self.extend(request, params))
2796
+ elif market['spot']:
2797
2797
  response = await self.privateGetSpotOrdersActive(self.extend(request, params))
2798
2798
  else:
2799
2799
  response = await self.privateGetExchangeOrder(self.extend(request, params))
@@ -1180,7 +1180,7 @@ class poloniexfutures(Exchange, ImplicitAPI):
1180
1180
  cancelledOrderIdsLength = len(cancelledOrderIds)
1181
1181
  for i in range(0, cancelledOrderIdsLength):
1182
1182
  cancelledOrderId = self.safe_string(cancelledOrderIds, i)
1183
- result.append({
1183
+ result.append(self.safe_order({
1184
1184
  'id': cancelledOrderId,
1185
1185
  'clientOrderId': None,
1186
1186
  'timestamp': None,
@@ -1202,7 +1202,7 @@ class poloniexfutures(Exchange, ImplicitAPI):
1202
1202
  'postOnly': None,
1203
1203
  'stopPrice': None,
1204
1204
  'info': response,
1205
- })
1205
+ }))
1206
1206
  return result
1207
1207
 
1208
1208
  async def fetch_orders_by_status(self, status, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
@@ -9,6 +9,7 @@ from ccxt.base.types import IndexType, Int, Market, Num, Order, OrderSide, Order
9
9
  from typing import List
10
10
  from ccxt.base.errors import ExchangeError
11
11
  from ccxt.base.errors import AuthenticationError
12
+ from ccxt.base.errors import ArgumentsRequired
12
13
  from ccxt.base.errors import BadRequest
13
14
  from ccxt.base.errors import InsufficientFunds
14
15
  from ccxt.base.decimal_to_precision import TICK_SIZE
@@ -441,7 +442,7 @@ class tradeogre(Exchange, ImplicitAPI):
441
442
  """
442
443
  create a trade order
443
444
  :param str symbol: unified symbol of the market to create an order in
444
- :param str type: not used by tradeogre
445
+ :param str type: must be 'limit'
445
446
  :param str side: 'buy' or 'sell'
446
447
  :param float amount: how much of currency you want to trade in units of base currency
447
448
  :param float price: the price at which the order is to be fullfilled, in units of the quote currency
@@ -450,13 +451,15 @@ class tradeogre(Exchange, ImplicitAPI):
450
451
  """
451
452
  await self.load_markets()
452
453
  market = self.market(symbol)
454
+ if type == 'market':
455
+ raise BadRequest(self.id + ' createOrder does not support market orders')
456
+ if price is None:
457
+ raise ArgumentsRequired(self.id + ' createOrder requires a limit parameter')
453
458
  request: dict = {
454
459
  'market': market['id'],
455
460
  'quantity': self.parse_to_numeric(self.amount_to_precision(symbol, amount)),
456
461
  'price': self.parse_to_numeric(self.price_to_precision(symbol, price)),
457
462
  }
458
- if type == 'market':
459
- raise BadRequest(self.id + ' createOrder does not support market orders')
460
463
  response = None
461
464
  if side == 'buy':
462
465
  response = await self.privatePostOrderBuy(self.extend(request, params))
@@ -487,7 +490,10 @@ class tradeogre(Exchange, ImplicitAPI):
487
490
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
488
491
  """
489
492
  await self.load_markets()
490
- return await self.cancel_order('all', symbol, params)
493
+ response = await self.cancel_order('all', symbol, params)
494
+ return [
495
+ response,
496
+ ]
491
497
 
492
498
  async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
493
499
  """
@@ -1422,7 +1422,7 @@ class wavesexchange(Exchange, ImplicitAPI):
1422
1422
  firstMessage = self.safe_value(message, 0)
1423
1423
  firstOrder = self.safe_value(firstMessage, 0)
1424
1424
  returnedId = self.safe_string(firstOrder, 'orderId')
1425
- return {
1425
+ return self.safe_order({
1426
1426
  'info': response,
1427
1427
  'id': returnedId,
1428
1428
  'clientOrderId': None,
@@ -1441,7 +1441,7 @@ class wavesexchange(Exchange, ImplicitAPI):
1441
1441
  'status': None,
1442
1442
  'fee': None,
1443
1443
  'trades': None,
1444
- }
1444
+ })
1445
1445
 
1446
1446
  async def fetch_order(self, id: str, symbol: Str = None, params={}):
1447
1447
  """
@@ -763,7 +763,26 @@ class wazirx(Exchange, ImplicitAPI):
763
763
  request: dict = {
764
764
  'symbol': market['id'],
765
765
  }
766
- return await self.privateDeleteOpenOrders(self.extend(request, params))
766
+ response = await self.privateDeleteOpenOrders(self.extend(request, params))
767
+ #
768
+ # [
769
+ # {
770
+ # id: "4565421197",
771
+ # symbol: "adausdt",
772
+ # type: "limit",
773
+ # side: "buy",
774
+ # status: "wait",
775
+ # price: "0.41",
776
+ # origQty: "11.00",
777
+ # executedQty: "0.00",
778
+ # avgPrice: "0.00",
779
+ # createdTime: "1718089507000",
780
+ # updatedTime: "1718089507000",
781
+ # clientOrderId: "93d2a838-e272-405d-91e7-3a7bc6d3a003"
782
+ # }
783
+ # ]
784
+ #
785
+ return self.parse_orders(response)
767
786
 
768
787
  async def cancel_order(self, id: str, symbol: Str = None, params={}):
769
788
  """
@@ -831,18 +850,22 @@ class wazirx(Exchange, ImplicitAPI):
831
850
  return self.parse_order(response, market)
832
851
 
833
852
  def parse_order(self, order: dict, market: Market = None) -> Order:
834
- # {
835
- # "id":1949417813,
836
- # "symbol":"ltcusdt",
837
- # "type":"limit",
838
- # "side":"sell",
839
- # "status":"done",
840
- # "price":"146.2",
841
- # "origQty":"0.05",
842
- # "executedQty":"0.05",
843
- # "createdTime":1641252564000,
844
- # "updatedTime":1641252564000
845
- # },
853
+ #
854
+ # {
855
+ # "id": 1949417813,
856
+ # "symbol": "ltcusdt",
857
+ # "type": "limit",
858
+ # "side": "sell",
859
+ # "status": "done",
860
+ # "price": "146.2",
861
+ # "origQty": "0.05",
862
+ # "executedQty": "0.05",
863
+ # "avgPrice": "0.00",
864
+ # "createdTime": 1641252564000,
865
+ # "updatedTime": 1641252564000
866
+ # "clientOrderId": "93d2a838-e272-405d-91e7-3a7bc6d3a003"
867
+ # }
868
+ #
846
869
  created = self.safe_integer(order, 'createdTime')
847
870
  updated = self.safe_integer(order, 'updatedTime')
848
871
  marketId = self.safe_string(order, 'symbol')
@@ -857,7 +880,7 @@ class wazirx(Exchange, ImplicitAPI):
857
880
  return self.safe_order({
858
881
  'info': order,
859
882
  'id': id,
860
- 'clientOrderId': None,
883
+ 'clientOrderId': self.safe_string(order, 'clientOrderId'),
861
884
  'timestamp': created,
862
885
  'datetime': self.iso8601(created),
863
886
  'lastTradeTimestamp': updated,
@@ -873,7 +896,7 @@ class wazirx(Exchange, ImplicitAPI):
873
896
  'remaining': None,
874
897
  'cost': None,
875
898
  'fee': None,
876
- 'average': None,
899
+ 'average': self.safe_string(order, 'avgPrice'),
877
900
  'trades': [],
878
901
  }, market)
879
902