ccxt 3.0.97__py2.py3-none-any.whl → 3.0.98__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__ = '3.0.97'
25
+ __version__ = '3.0.98'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '3.0.97'
7
+ __version__ = '3.0.98'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '3.0.97'
5
+ __version__ = '3.0.98'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -1679,6 +1679,12 @@ class coinex(Exchange, ImplicitAPI):
1679
1679
  async def create_order(self, symbol: str, type, side: OrderSide, amount, price=None, params={}):
1680
1680
  """
1681
1681
  create a trade order
1682
+ see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http017_put_limit
1683
+ see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http018_put_market
1684
+ see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http019_put_limit_stop
1685
+ see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http020_put_market_stop
1686
+ see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http031_market_close
1687
+ see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http030_limit_close
1682
1688
  :param str symbol: unified symbol of the market to create an order in
1683
1689
  :param str type: 'market' or 'limit'
1684
1690
  :param str side: 'buy' or 'sell'
@@ -1692,6 +1698,7 @@ class coinex(Exchange, ImplicitAPI):
1692
1698
  :param str params['timeInForce']: "GTC", "IOC", "FOK", "PO"
1693
1699
  :param bool params.postOnly:
1694
1700
  :param bool params.reduceOnly:
1701
+ :param bool|None params['position_id']: *required for reduce only orders* the position id to reduce
1695
1702
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1696
1703
  """
1697
1704
  await self.load_markets()
@@ -1706,9 +1713,11 @@ class coinex(Exchange, ImplicitAPI):
1706
1713
  positionId = self.safe_integer_2(params, 'position_id', 'positionId') # Required for closing swap positions
1707
1714
  timeInForceRaw = self.safe_string(params, 'timeInForce') # Spot: IOC, FOK, PO, GTC, ... NORMAL(default), MAKER_ONLY
1708
1715
  reduceOnly = self.safe_value(params, 'reduceOnly')
1709
- if reduceOnly is not None:
1716
+ if reduceOnly:
1710
1717
  if market['type'] != 'swap':
1711
1718
  raise InvalidOrder(self.id + ' createOrder() does not support reduceOnly for ' + market['type'] + ' orders, reduceOnly orders are supported for swap markets only')
1719
+ if positionId is None:
1720
+ raise ArgumentsRequired(self.id + ' createOrder() requires a position_id/positionId parameter for reduceOnly orders')
1712
1721
  method = None
1713
1722
  request = {
1714
1723
  'market': market['id'],
@@ -2309,8 +2309,7 @@ class huobi(Exchange, ImplicitAPI):
2309
2309
  # request['end-time'] = self.sum(since, 172800000) # 48 hours window
2310
2310
  method = 'spotPrivateGetV1OrderMatchresults'
2311
2311
  else:
2312
- if symbol is None:
2313
- raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol for ' + marketType + ' orders')
2312
+ self.check_required_symbol('fetchMyTrades', symbol)
2314
2313
  request['contract'] = market['id']
2315
2314
  request['trade_type'] = 0 # 0 all, 1 open long, 2 open short, 3 close short, 4 close long, 5 liquidate long positions, 6 liquidate short positions
2316
2315
  if since is not None:
@@ -3095,8 +3094,7 @@ class huobi(Exchange, ImplicitAPI):
3095
3094
  else:
3096
3095
  request['order-id'] = id
3097
3096
  else:
3098
- if symbol is None:
3099
- raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol for ' + marketType + ' orders')
3097
+ self.check_required_symbol('fetchOrder', symbol)
3100
3098
  request['contract_code'] = market['id']
3101
3099
  if market['linear']:
3102
3100
  marginMode = None
@@ -3266,8 +3264,7 @@ class huobi(Exchange, ImplicitAPI):
3266
3264
  async def fetch_spot_orders_by_states(self, states, symbol: Optional[str] = None, since: Optional[int] = None, limit: Optional[int] = None, params={}):
3267
3265
  method = self.safe_string(self.options, 'fetchOrdersByStatesMethod', 'spot_private_get_v1_order_orders') # spot_private_get_v1_order_history
3268
3266
  if method == 'spot_private_get_v1_order_orders':
3269
- if symbol is None:
3270
- raise ArgumentsRequired(self.id + ' fetchOrders() requires a symbol argument')
3267
+ self.check_required_symbol('fetchOrders', symbol)
3271
3268
  await self.load_markets()
3272
3269
  market = None
3273
3270
  request = {
@@ -3332,8 +3329,7 @@ class huobi(Exchange, ImplicitAPI):
3332
3329
  return await self.fetch_spot_orders_by_states('filled,partial-canceled,canceled', symbol, since, limit, params)
3333
3330
 
3334
3331
  async def fetch_contract_orders(self, symbol: Optional[str] = None, since: Optional[int] = None, limit: Optional[int] = None, params={}):
3335
- if symbol is None:
3336
- raise ArgumentsRequired(self.id + ' fetchContractOrders() requires a symbol argument')
3332
+ self.check_required_symbol('fetchContractOrders', symbol)
3337
3333
  await self.load_markets()
3338
3334
  market = self.market(symbol)
3339
3335
  request = {
@@ -3640,8 +3636,7 @@ class huobi(Exchange, ImplicitAPI):
3640
3636
  params = self.omit(params, 'account-id')
3641
3637
  response = await self.spotPrivateGetV1OrderOpenOrders(self.extend(request, params))
3642
3638
  else:
3643
- if symbol is None:
3644
- raise ArgumentsRequired(self.id + ' fetchOpenOrders() requires a symbol for ' + marketType + ' orders')
3639
+ self.check_required_symbol('fetchOpenOrders', symbol)
3645
3640
  if limit is not None:
3646
3641
  request['page_size'] = limit
3647
3642
  request['contract_code'] = market['id']
@@ -4518,8 +4513,7 @@ class huobi(Exchange, ImplicitAPI):
4518
4513
  params = self.omit(params, ['client-order-id', 'clientOrderId'])
4519
4514
  response = await self.spotPrivatePostV1OrderOrdersSubmitCancelClientOrder(self.extend(request, params))
4520
4515
  else:
4521
- if symbol is None:
4522
- raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol for ' + marketType + ' orders')
4516
+ self.check_required_symbol('cancelOrder', symbol)
4523
4517
  clientOrderId = self.safe_string_2(params, 'client_order_id', 'clientOrderId')
4524
4518
  if clientOrderId is None:
4525
4519
  request['order_id'] = id
@@ -4598,6 +4592,8 @@ class huobi(Exchange, ImplicitAPI):
4598
4592
  :param [str] ids: order ids
4599
4593
  :param str|None symbol: unified market symbol, default is None
4600
4594
  :param dict params: extra parameters specific to the huobi api endpoint
4595
+ :param bool|None params['stop']: *contract only* if the orders are stop trigger orders or not
4596
+ :param bool|None params['stopLossTakeProfit']: *contract only* if the orders are stop-loss or take-profit orders
4601
4597
  :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4602
4598
  """
4603
4599
  await self.load_markets()
@@ -4608,7 +4604,7 @@ class huobi(Exchange, ImplicitAPI):
4608
4604
  marketType, params = self.handle_market_type_and_params('cancelOrders', market, params)
4609
4605
  request = {
4610
4606
  # spot -----------------------------------------------------------
4611
- # 'order-ids': ids.jsoin(','), # max 50
4607
+ # 'order-ids': ','.join(ids), # max 50
4612
4608
  # 'client-order-ids': ','.join(ids), # max 50
4613
4609
  # contracts ------------------------------------------------------
4614
4610
  # 'order_id': id, # comma separated, max 10
@@ -4616,43 +4612,24 @@ class huobi(Exchange, ImplicitAPI):
4616
4612
  # 'contract_code': market['id'],
4617
4613
  # 'symbol': market['settleId'],
4618
4614
  }
4619
- method = None
4615
+ response = None
4620
4616
  if marketType == 'spot':
4621
4617
  clientOrderIds = self.safe_value_2(params, 'client-order-id', 'clientOrderId')
4622
4618
  clientOrderIds = self.safe_value_2(params, 'client-order-ids', 'clientOrderIds', clientOrderIds)
4623
4619
  if clientOrderIds is None:
4624
4620
  if isinstance(clientOrderIds, str):
4625
- request['order-ids'] = ids
4621
+ request['order-ids'] = [ids]
4626
4622
  else:
4627
- request['order-ids'] = ','.join(ids)
4623
+ request['order-ids'] = ids
4628
4624
  else:
4629
4625
  if isinstance(clientOrderIds, str):
4630
- request['client-order-ids'] = clientOrderIds
4626
+ request['client-order-ids'] = [clientOrderIds]
4631
4627
  else:
4632
- request['client-order-ids'] = ','.join(clientOrderIds)
4628
+ request['client-order-ids'] = clientOrderIds
4633
4629
  params = self.omit(params, ['client-order-id', 'client-order-ids', 'clientOrderId', 'clientOrderIds'])
4634
- method = 'spotPrivatePostV1OrderOrdersBatchcancel'
4630
+ response = await self.spotPrivatePostV1OrderOrdersBatchcancel(self.extend(request, params))
4635
4631
  else:
4636
- if symbol is None:
4637
- raise ArgumentsRequired(self.id + ' cancelOrders() requires a symbol for ' + marketType + ' orders')
4638
- marketInner = self.market(symbol)
4639
- request['contract_code'] = marketInner['id']
4640
- if marketInner['linear']:
4641
- marginMode = None
4642
- marginMode, params = self.handle_margin_mode_and_params('cancelOrders', params)
4643
- marginMode = 'cross' if (marginMode is None) else marginMode
4644
- if marginMode == 'isolated':
4645
- method = 'contractPrivatePostLinearSwapApiV1SwapCancel'
4646
- elif marginMode == 'cross':
4647
- method = 'contractPrivatePostLinearSwapApiV1SwapCrossCancel'
4648
- elif marketInner['inverse']:
4649
- if marketInner['future']:
4650
- method = 'contractPrivatePostApiV1ContractCancel'
4651
- request['symbol'] = marketInner['settleId']
4652
- elif marketInner['swap']:
4653
- method = 'contractPrivatePostSwapApiV1SwapCancel'
4654
- else:
4655
- raise NotSupported(self.id + ' cancelOrders() does not support ' + marketType + ' markets')
4632
+ self.check_required_symbol('cancelOrders', symbol)
4656
4633
  clientOrderIds = self.safe_string_2(params, 'client_order_id', 'clientOrderId')
4657
4634
  clientOrderIds = self.safe_string_2(params, 'client_order_ids', 'clientOrderIds', clientOrderIds)
4658
4635
  if clientOrderIds is None:
@@ -4660,7 +4637,48 @@ class huobi(Exchange, ImplicitAPI):
4660
4637
  else:
4661
4638
  request['client_order_id'] = clientOrderIds
4662
4639
  params = self.omit(params, ['client_order_id', 'client_order_ids', 'clientOrderId', 'clientOrderIds'])
4663
- response = await getattr(self, method)(self.extend(request, params))
4640
+ if market['future']:
4641
+ request['symbol'] = market['settleId']
4642
+ else:
4643
+ request['contract_code'] = market['id']
4644
+ stop = self.safe_value(params, 'stop')
4645
+ stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
4646
+ params = self.omit(params, ['stop', 'stopLossTakeProfit'])
4647
+ if market['linear']:
4648
+ marginMode = None
4649
+ marginMode, params = self.handle_margin_mode_and_params('cancelOrders', params)
4650
+ marginMode = 'cross' if (marginMode is None) else marginMode
4651
+ if marginMode == 'isolated':
4652
+ if stop:
4653
+ response = await self.contractPrivatePostLinearSwapApiV1SwapTriggerCancel(self.extend(request, params))
4654
+ elif stopLossTakeProfit:
4655
+ response = await self.contractPrivatePostLinearSwapApiV1SwapTpslCancel(self.extend(request, params))
4656
+ else:
4657
+ response = await self.contractPrivatePostLinearSwapApiV1SwapCancel(self.extend(request, params))
4658
+ elif marginMode == 'cross':
4659
+ if stop:
4660
+ response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerCancel(self.extend(request, params))
4661
+ elif stopLossTakeProfit:
4662
+ response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTpslCancel(self.extend(request, params))
4663
+ else:
4664
+ response = await self.contractPrivatePostLinearSwapApiV1SwapCrossCancel(self.extend(request, params))
4665
+ elif market['inverse']:
4666
+ if market['swap']:
4667
+ if stop:
4668
+ response = await self.contractPrivatePostSwapApiV1SwapTriggerCancel(self.extend(request, params))
4669
+ elif stopLossTakeProfit:
4670
+ response = await self.contractPrivatePostSwapApiV1SwapTpslCancel(self.extend(request, params))
4671
+ else:
4672
+ response = await self.contractPrivatePostSwapApiV1SwapCancel(self.extend(request, params))
4673
+ elif market['future']:
4674
+ if stop:
4675
+ response = await self.contractPrivatePostApiV1ContractTriggerCancel(self.extend(request, params))
4676
+ elif stopLossTakeProfit:
4677
+ response = await self.contractPrivatePostApiV1ContractTpslCancel(self.extend(request, params))
4678
+ else:
4679
+ response = await self.contractPrivatePostApiV1ContractCancel(self.extend(request, params))
4680
+ else:
4681
+ raise NotSupported(self.id + ' cancelOrders() does not support ' + marketType + ' markets')
4664
4682
  #
4665
4683
  # spot
4666
4684
  #
@@ -4695,7 +4713,7 @@ class huobi(Exchange, ImplicitAPI):
4695
4713
  # }
4696
4714
  # }
4697
4715
  #
4698
- # contracts
4716
+ # future and swap
4699
4717
  #
4700
4718
  # {
4701
4719
  # "status": "ok",
@@ -4719,6 +4737,8 @@ class huobi(Exchange, ImplicitAPI):
4719
4737
  cancel all open orders
4720
4738
  :param str|None symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
4721
4739
  :param dict params: extra parameters specific to the huobi api endpoint
4740
+ :param bool|None params['stop']: *contract only* if the orders are stop trigger orders or not
4741
+ :param bool|None params['stopLossTakeProfit']: *contract only* if the orders are stop-loss or take-profit orders
4722
4742
  :returns [dict]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4723
4743
  """
4724
4744
  await self.load_markets()
@@ -4741,34 +4761,56 @@ class huobi(Exchange, ImplicitAPI):
4741
4761
  # 'direction': 'buy': # buy, sell
4742
4762
  # 'offset': 'open', # open, close
4743
4763
  }
4744
- method = None
4764
+ response = None
4745
4765
  if marketType == 'spot':
4746
4766
  if symbol is not None:
4747
- market = self.market(symbol)
4748
4767
  request['symbol'] = market['id']
4749
- method = 'spotPrivatePostV1OrderOrdersBatchCancelOpenOrders'
4768
+ response = await self.spotPrivatePostV1OrderOrdersBatchCancelOpenOrders(self.extend(request, params))
4750
4769
  else:
4751
- if symbol is None:
4752
- raise ArgumentsRequired(self.id + ' cancelAllOrders() requires a symbol for ' + marketType + ' orders')
4753
- marketInner = self.market(symbol)
4754
- request['contract_code'] = marketInner['id']
4755
- if marketInner['linear']:
4770
+ self.check_required_symbol('cancelAllOrders', symbol)
4771
+ if market['future']:
4772
+ request['symbol'] = market['settleId']
4773
+ request['contract_code'] = market['id']
4774
+ stop = self.safe_value(params, 'stop')
4775
+ stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
4776
+ params = self.omit(params, ['stop', 'stopLossTakeProfit'])
4777
+ if market['linear']:
4756
4778
  marginMode = None
4757
4779
  marginMode, params = self.handle_margin_mode_and_params('cancelAllOrders', params)
4758
4780
  marginMode = 'cross' if (marginMode is None) else marginMode
4759
4781
  if marginMode == 'isolated':
4760
- method = 'contractPrivatePostLinearSwapApiV1SwapCancelallall'
4782
+ if stop:
4783
+ response = await self.contractPrivatePostLinearSwapApiV1SwapTriggerCancelall(self.extend(request, params))
4784
+ elif stopLossTakeProfit:
4785
+ response = await self.contractPrivatePostLinearSwapApiV1SwapTpslCancelall(self.extend(request, params))
4786
+ else:
4787
+ response = await self.contractPrivatePostLinearSwapApiV1SwapCancelall(self.extend(request, params))
4761
4788
  elif marginMode == 'cross':
4762
- method = 'contractPrivatePostLinearSwapApiV1SwapCrossCancelall'
4763
- elif marketInner['inverse']:
4764
- if marketType == 'future':
4765
- method = 'contractPrivatePostApiV1ContractCancelall'
4766
- request['symbol'] = marketInner['settleId']
4767
- elif marketType == 'swap':
4768
- method = 'contractPrivatePostSwapApiV1SwapCancelall'
4769
- else:
4770
- raise NotSupported(self.id + ' cancelAllOrders() does not support ' + marketType + ' markets')
4771
- response = await getattr(self, method)(self.extend(request, params))
4789
+ if stop:
4790
+ response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerCancelall(self.extend(request, params))
4791
+ elif stopLossTakeProfit:
4792
+ response = await self.contractPrivatePostLinearSwapApiV1SwapCrossTpslCancelall(self.extend(request, params))
4793
+ else:
4794
+ response = await self.contractPrivatePostLinearSwapApiV1SwapCrossCancelall(self.extend(request, params))
4795
+ elif market['inverse']:
4796
+ if market['swap']:
4797
+ if stop:
4798
+ response = await self.contractPrivatePostSwapApiV1SwapTriggerCancelall(self.extend(request, params))
4799
+ elif stopLossTakeProfit:
4800
+ response = await self.contractPrivatePostSwapApiV1SwapTpslCancelall(self.extend(request, params))
4801
+ else:
4802
+ response = await self.contractPrivatePostSwapApiV1SwapCancelall(self.extend(request, params))
4803
+ elif market['future']:
4804
+ if stop:
4805
+ response = await self.contractPrivatePostApiV1ContractTriggerCancelall(self.extend(request, params))
4806
+ elif stopLossTakeProfit:
4807
+ response = await self.contractPrivatePostApiV1ContractTpslCancelall(self.extend(request, params))
4808
+ else:
4809
+ response = await self.contractPrivatePostApiV1ContractCancelall(self.extend(request, params))
4810
+ else:
4811
+ raise NotSupported(self.id + ' cancelAllOrders() does not support ' + marketType + ' markets')
4812
+ #
4813
+ # spot
4772
4814
  #
4773
4815
  # {
4774
4816
  # code: 200,
@@ -4779,6 +4821,17 @@ class huobi(Exchange, ImplicitAPI):
4779
4821
  # }
4780
4822
  # }
4781
4823
  #
4824
+ # future and swap
4825
+ #
4826
+ # {
4827
+ # status: "ok",
4828
+ # data: {
4829
+ # errors: [],
4830
+ # successes: "1104754904426696704"
4831
+ # },
4832
+ # ts: "1683435723755"
4833
+ # }
4834
+ #
4782
4835
  return response
4783
4836
 
4784
4837
  def parse_deposit_address(self, depositAddress, currency=None):
@@ -5380,8 +5433,7 @@ class huobi(Exchange, ImplicitAPI):
5380
5433
  :param dict params: extra parameters specific to the huobi api endpoint
5381
5434
  :returns [dict]: a list of `funding rate structures <https://docs.ccxt.com/en/latest/manual.html?#funding-rate-history-structure>`
5382
5435
  """
5383
- if symbol is None:
5384
- raise ArgumentsRequired(self.id + ' fetchFundingRateHistory() requires a symbol argument')
5436
+ self.check_required_symbol('fetchFundingRateHistory', symbol)
5385
5437
  await self.load_markets()
5386
5438
  market = self.market(symbol)
5387
5439
  request = {
@@ -5885,8 +5937,7 @@ class huobi(Exchange, ImplicitAPI):
5885
5937
  :param dict params: extra parameters specific to the huobi api endpoint
5886
5938
  :returns dict: response from the exchange
5887
5939
  """
5888
- if symbol is None:
5889
- raise ArgumentsRequired(self.id + ' setLeverage() requires a symbol argument')
5940
+ self.check_required_symbol('setLeverage', symbol)
5890
5941
  await self.load_markets()
5891
5942
  market = self.market(symbol)
5892
5943
  marketType, query = self.handle_market_type_and_params('setLeverage', market, params)
@@ -6965,8 +7016,7 @@ class huobi(Exchange, ImplicitAPI):
6965
7016
  marginMode = 'cross' if (marginMode is None) else marginMode
6966
7017
  method = None
6967
7018
  if marginMode == 'isolated':
6968
- if symbol is None:
6969
- raise ArgumentsRequired(self.id + ' borrowMargin() requires a symbol argument for isolated margin')
7019
+ self.check_required_symbol('borrowMargin', symbol)
6970
7020
  market = self.market(symbol)
6971
7021
  request['symbol'] = market['id']
6972
7022
  method = 'privatePostMarginOrders'
@@ -2399,7 +2399,7 @@ class phemex(Exchange, ImplicitAPI):
2399
2399
  :param float amount: how much of currency you want to trade in units of base currency
2400
2400
  :param float|None price: the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
2401
2401
  :param dict params: extra parameters specific to the phemex api endpoint
2402
- :param str|None params['posSide']: either 'Hedged' or 'OneWay' or 'Merged'
2402
+ :param str|None params['posSide']: either 'Merged' or 'Long' or 'Short'
2403
2403
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2404
2404
  """
2405
2405
  if symbol is None:
@@ -2457,7 +2457,7 @@ class phemex(Exchange, ImplicitAPI):
2457
2457
  :param str id: order id
2458
2458
  :param str symbol: unified symbol of the market the order was made in
2459
2459
  :param dict params: extra parameters specific to the phemex api endpoint
2460
- :param str|None params['posSide']: either 'Hedged' or 'OneWay' or 'Merged'
2460
+ :param str|None params['posSide']: either 'Merged' or 'Long' or 'Short'
2461
2461
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2462
2462
  """
2463
2463
  if symbol is None:
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '3.0.97'
7
+ __version__ = '3.0.98'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
ccxt/coinex.py CHANGED
@@ -1678,6 +1678,12 @@ class coinex(Exchange, ImplicitAPI):
1678
1678
  def create_order(self, symbol: str, type, side: OrderSide, amount, price=None, params={}):
1679
1679
  """
1680
1680
  create a trade order
1681
+ see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http017_put_limit
1682
+ see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http018_put_market
1683
+ see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http019_put_limit_stop
1684
+ see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http020_put_market_stop
1685
+ see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http031_market_close
1686
+ see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http030_limit_close
1681
1687
  :param str symbol: unified symbol of the market to create an order in
1682
1688
  :param str type: 'market' or 'limit'
1683
1689
  :param str side: 'buy' or 'sell'
@@ -1691,6 +1697,7 @@ class coinex(Exchange, ImplicitAPI):
1691
1697
  :param str params['timeInForce']: "GTC", "IOC", "FOK", "PO"
1692
1698
  :param bool params.postOnly:
1693
1699
  :param bool params.reduceOnly:
1700
+ :param bool|None params['position_id']: *required for reduce only orders* the position id to reduce
1694
1701
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1695
1702
  """
1696
1703
  self.load_markets()
@@ -1705,9 +1712,11 @@ class coinex(Exchange, ImplicitAPI):
1705
1712
  positionId = self.safe_integer_2(params, 'position_id', 'positionId') # Required for closing swap positions
1706
1713
  timeInForceRaw = self.safe_string(params, 'timeInForce') # Spot: IOC, FOK, PO, GTC, ... NORMAL(default), MAKER_ONLY
1707
1714
  reduceOnly = self.safe_value(params, 'reduceOnly')
1708
- if reduceOnly is not None:
1715
+ if reduceOnly:
1709
1716
  if market['type'] != 'swap':
1710
1717
  raise InvalidOrder(self.id + ' createOrder() does not support reduceOnly for ' + market['type'] + ' orders, reduceOnly orders are supported for swap markets only')
1718
+ if positionId is None:
1719
+ raise ArgumentsRequired(self.id + ' createOrder() requires a position_id/positionId parameter for reduceOnly orders')
1711
1720
  method = None
1712
1721
  request = {
1713
1722
  'market': market['id'],
ccxt/huobi.py CHANGED
@@ -2308,8 +2308,7 @@ class huobi(Exchange, ImplicitAPI):
2308
2308
  # request['end-time'] = self.sum(since, 172800000) # 48 hours window
2309
2309
  method = 'spotPrivateGetV1OrderMatchresults'
2310
2310
  else:
2311
- if symbol is None:
2312
- raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol for ' + marketType + ' orders')
2311
+ self.check_required_symbol('fetchMyTrades', symbol)
2313
2312
  request['contract'] = market['id']
2314
2313
  request['trade_type'] = 0 # 0 all, 1 open long, 2 open short, 3 close short, 4 close long, 5 liquidate long positions, 6 liquidate short positions
2315
2314
  if since is not None:
@@ -3094,8 +3093,7 @@ class huobi(Exchange, ImplicitAPI):
3094
3093
  else:
3095
3094
  request['order-id'] = id
3096
3095
  else:
3097
- if symbol is None:
3098
- raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol for ' + marketType + ' orders')
3096
+ self.check_required_symbol('fetchOrder', symbol)
3099
3097
  request['contract_code'] = market['id']
3100
3098
  if market['linear']:
3101
3099
  marginMode = None
@@ -3265,8 +3263,7 @@ class huobi(Exchange, ImplicitAPI):
3265
3263
  def fetch_spot_orders_by_states(self, states, symbol: Optional[str] = None, since: Optional[int] = None, limit: Optional[int] = None, params={}):
3266
3264
  method = self.safe_string(self.options, 'fetchOrdersByStatesMethod', 'spot_private_get_v1_order_orders') # spot_private_get_v1_order_history
3267
3265
  if method == 'spot_private_get_v1_order_orders':
3268
- if symbol is None:
3269
- raise ArgumentsRequired(self.id + ' fetchOrders() requires a symbol argument')
3266
+ self.check_required_symbol('fetchOrders', symbol)
3270
3267
  self.load_markets()
3271
3268
  market = None
3272
3269
  request = {
@@ -3331,8 +3328,7 @@ class huobi(Exchange, ImplicitAPI):
3331
3328
  return self.fetch_spot_orders_by_states('filled,partial-canceled,canceled', symbol, since, limit, params)
3332
3329
 
3333
3330
  def fetch_contract_orders(self, symbol: Optional[str] = None, since: Optional[int] = None, limit: Optional[int] = None, params={}):
3334
- if symbol is None:
3335
- raise ArgumentsRequired(self.id + ' fetchContractOrders() requires a symbol argument')
3331
+ self.check_required_symbol('fetchContractOrders', symbol)
3336
3332
  self.load_markets()
3337
3333
  market = self.market(symbol)
3338
3334
  request = {
@@ -3639,8 +3635,7 @@ class huobi(Exchange, ImplicitAPI):
3639
3635
  params = self.omit(params, 'account-id')
3640
3636
  response = self.spotPrivateGetV1OrderOpenOrders(self.extend(request, params))
3641
3637
  else:
3642
- if symbol is None:
3643
- raise ArgumentsRequired(self.id + ' fetchOpenOrders() requires a symbol for ' + marketType + ' orders')
3638
+ self.check_required_symbol('fetchOpenOrders', symbol)
3644
3639
  if limit is not None:
3645
3640
  request['page_size'] = limit
3646
3641
  request['contract_code'] = market['id']
@@ -4517,8 +4512,7 @@ class huobi(Exchange, ImplicitAPI):
4517
4512
  params = self.omit(params, ['client-order-id', 'clientOrderId'])
4518
4513
  response = self.spotPrivatePostV1OrderOrdersSubmitCancelClientOrder(self.extend(request, params))
4519
4514
  else:
4520
- if symbol is None:
4521
- raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol for ' + marketType + ' orders')
4515
+ self.check_required_symbol('cancelOrder', symbol)
4522
4516
  clientOrderId = self.safe_string_2(params, 'client_order_id', 'clientOrderId')
4523
4517
  if clientOrderId is None:
4524
4518
  request['order_id'] = id
@@ -4597,6 +4591,8 @@ class huobi(Exchange, ImplicitAPI):
4597
4591
  :param [str] ids: order ids
4598
4592
  :param str|None symbol: unified market symbol, default is None
4599
4593
  :param dict params: extra parameters specific to the huobi api endpoint
4594
+ :param bool|None params['stop']: *contract only* if the orders are stop trigger orders or not
4595
+ :param bool|None params['stopLossTakeProfit']: *contract only* if the orders are stop-loss or take-profit orders
4600
4596
  :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4601
4597
  """
4602
4598
  self.load_markets()
@@ -4607,7 +4603,7 @@ class huobi(Exchange, ImplicitAPI):
4607
4603
  marketType, params = self.handle_market_type_and_params('cancelOrders', market, params)
4608
4604
  request = {
4609
4605
  # spot -----------------------------------------------------------
4610
- # 'order-ids': ids.jsoin(','), # max 50
4606
+ # 'order-ids': ','.join(ids), # max 50
4611
4607
  # 'client-order-ids': ','.join(ids), # max 50
4612
4608
  # contracts ------------------------------------------------------
4613
4609
  # 'order_id': id, # comma separated, max 10
@@ -4615,43 +4611,24 @@ class huobi(Exchange, ImplicitAPI):
4615
4611
  # 'contract_code': market['id'],
4616
4612
  # 'symbol': market['settleId'],
4617
4613
  }
4618
- method = None
4614
+ response = None
4619
4615
  if marketType == 'spot':
4620
4616
  clientOrderIds = self.safe_value_2(params, 'client-order-id', 'clientOrderId')
4621
4617
  clientOrderIds = self.safe_value_2(params, 'client-order-ids', 'clientOrderIds', clientOrderIds)
4622
4618
  if clientOrderIds is None:
4623
4619
  if isinstance(clientOrderIds, str):
4624
- request['order-ids'] = ids
4620
+ request['order-ids'] = [ids]
4625
4621
  else:
4626
- request['order-ids'] = ','.join(ids)
4622
+ request['order-ids'] = ids
4627
4623
  else:
4628
4624
  if isinstance(clientOrderIds, str):
4629
- request['client-order-ids'] = clientOrderIds
4625
+ request['client-order-ids'] = [clientOrderIds]
4630
4626
  else:
4631
- request['client-order-ids'] = ','.join(clientOrderIds)
4627
+ request['client-order-ids'] = clientOrderIds
4632
4628
  params = self.omit(params, ['client-order-id', 'client-order-ids', 'clientOrderId', 'clientOrderIds'])
4633
- method = 'spotPrivatePostV1OrderOrdersBatchcancel'
4629
+ response = self.spotPrivatePostV1OrderOrdersBatchcancel(self.extend(request, params))
4634
4630
  else:
4635
- if symbol is None:
4636
- raise ArgumentsRequired(self.id + ' cancelOrders() requires a symbol for ' + marketType + ' orders')
4637
- marketInner = self.market(symbol)
4638
- request['contract_code'] = marketInner['id']
4639
- if marketInner['linear']:
4640
- marginMode = None
4641
- marginMode, params = self.handle_margin_mode_and_params('cancelOrders', params)
4642
- marginMode = 'cross' if (marginMode is None) else marginMode
4643
- if marginMode == 'isolated':
4644
- method = 'contractPrivatePostLinearSwapApiV1SwapCancel'
4645
- elif marginMode == 'cross':
4646
- method = 'contractPrivatePostLinearSwapApiV1SwapCrossCancel'
4647
- elif marketInner['inverse']:
4648
- if marketInner['future']:
4649
- method = 'contractPrivatePostApiV1ContractCancel'
4650
- request['symbol'] = marketInner['settleId']
4651
- elif marketInner['swap']:
4652
- method = 'contractPrivatePostSwapApiV1SwapCancel'
4653
- else:
4654
- raise NotSupported(self.id + ' cancelOrders() does not support ' + marketType + ' markets')
4631
+ self.check_required_symbol('cancelOrders', symbol)
4655
4632
  clientOrderIds = self.safe_string_2(params, 'client_order_id', 'clientOrderId')
4656
4633
  clientOrderIds = self.safe_string_2(params, 'client_order_ids', 'clientOrderIds', clientOrderIds)
4657
4634
  if clientOrderIds is None:
@@ -4659,7 +4636,48 @@ class huobi(Exchange, ImplicitAPI):
4659
4636
  else:
4660
4637
  request['client_order_id'] = clientOrderIds
4661
4638
  params = self.omit(params, ['client_order_id', 'client_order_ids', 'clientOrderId', 'clientOrderIds'])
4662
- response = getattr(self, method)(self.extend(request, params))
4639
+ if market['future']:
4640
+ request['symbol'] = market['settleId']
4641
+ else:
4642
+ request['contract_code'] = market['id']
4643
+ stop = self.safe_value(params, 'stop')
4644
+ stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
4645
+ params = self.omit(params, ['stop', 'stopLossTakeProfit'])
4646
+ if market['linear']:
4647
+ marginMode = None
4648
+ marginMode, params = self.handle_margin_mode_and_params('cancelOrders', params)
4649
+ marginMode = 'cross' if (marginMode is None) else marginMode
4650
+ if marginMode == 'isolated':
4651
+ if stop:
4652
+ response = self.contractPrivatePostLinearSwapApiV1SwapTriggerCancel(self.extend(request, params))
4653
+ elif stopLossTakeProfit:
4654
+ response = self.contractPrivatePostLinearSwapApiV1SwapTpslCancel(self.extend(request, params))
4655
+ else:
4656
+ response = self.contractPrivatePostLinearSwapApiV1SwapCancel(self.extend(request, params))
4657
+ elif marginMode == 'cross':
4658
+ if stop:
4659
+ response = self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerCancel(self.extend(request, params))
4660
+ elif stopLossTakeProfit:
4661
+ response = self.contractPrivatePostLinearSwapApiV1SwapCrossTpslCancel(self.extend(request, params))
4662
+ else:
4663
+ response = self.contractPrivatePostLinearSwapApiV1SwapCrossCancel(self.extend(request, params))
4664
+ elif market['inverse']:
4665
+ if market['swap']:
4666
+ if stop:
4667
+ response = self.contractPrivatePostSwapApiV1SwapTriggerCancel(self.extend(request, params))
4668
+ elif stopLossTakeProfit:
4669
+ response = self.contractPrivatePostSwapApiV1SwapTpslCancel(self.extend(request, params))
4670
+ else:
4671
+ response = self.contractPrivatePostSwapApiV1SwapCancel(self.extend(request, params))
4672
+ elif market['future']:
4673
+ if stop:
4674
+ response = self.contractPrivatePostApiV1ContractTriggerCancel(self.extend(request, params))
4675
+ elif stopLossTakeProfit:
4676
+ response = self.contractPrivatePostApiV1ContractTpslCancel(self.extend(request, params))
4677
+ else:
4678
+ response = self.contractPrivatePostApiV1ContractCancel(self.extend(request, params))
4679
+ else:
4680
+ raise NotSupported(self.id + ' cancelOrders() does not support ' + marketType + ' markets')
4663
4681
  #
4664
4682
  # spot
4665
4683
  #
@@ -4694,7 +4712,7 @@ class huobi(Exchange, ImplicitAPI):
4694
4712
  # }
4695
4713
  # }
4696
4714
  #
4697
- # contracts
4715
+ # future and swap
4698
4716
  #
4699
4717
  # {
4700
4718
  # "status": "ok",
@@ -4718,6 +4736,8 @@ class huobi(Exchange, ImplicitAPI):
4718
4736
  cancel all open orders
4719
4737
  :param str|None symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
4720
4738
  :param dict params: extra parameters specific to the huobi api endpoint
4739
+ :param bool|None params['stop']: *contract only* if the orders are stop trigger orders or not
4740
+ :param bool|None params['stopLossTakeProfit']: *contract only* if the orders are stop-loss or take-profit orders
4721
4741
  :returns [dict]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4722
4742
  """
4723
4743
  self.load_markets()
@@ -4740,34 +4760,56 @@ class huobi(Exchange, ImplicitAPI):
4740
4760
  # 'direction': 'buy': # buy, sell
4741
4761
  # 'offset': 'open', # open, close
4742
4762
  }
4743
- method = None
4763
+ response = None
4744
4764
  if marketType == 'spot':
4745
4765
  if symbol is not None:
4746
- market = self.market(symbol)
4747
4766
  request['symbol'] = market['id']
4748
- method = 'spotPrivatePostV1OrderOrdersBatchCancelOpenOrders'
4767
+ response = self.spotPrivatePostV1OrderOrdersBatchCancelOpenOrders(self.extend(request, params))
4749
4768
  else:
4750
- if symbol is None:
4751
- raise ArgumentsRequired(self.id + ' cancelAllOrders() requires a symbol for ' + marketType + ' orders')
4752
- marketInner = self.market(symbol)
4753
- request['contract_code'] = marketInner['id']
4754
- if marketInner['linear']:
4769
+ self.check_required_symbol('cancelAllOrders', symbol)
4770
+ if market['future']:
4771
+ request['symbol'] = market['settleId']
4772
+ request['contract_code'] = market['id']
4773
+ stop = self.safe_value(params, 'stop')
4774
+ stopLossTakeProfit = self.safe_value(params, 'stopLossTakeProfit')
4775
+ params = self.omit(params, ['stop', 'stopLossTakeProfit'])
4776
+ if market['linear']:
4755
4777
  marginMode = None
4756
4778
  marginMode, params = self.handle_margin_mode_and_params('cancelAllOrders', params)
4757
4779
  marginMode = 'cross' if (marginMode is None) else marginMode
4758
4780
  if marginMode == 'isolated':
4759
- method = 'contractPrivatePostLinearSwapApiV1SwapCancelallall'
4781
+ if stop:
4782
+ response = self.contractPrivatePostLinearSwapApiV1SwapTriggerCancelall(self.extend(request, params))
4783
+ elif stopLossTakeProfit:
4784
+ response = self.contractPrivatePostLinearSwapApiV1SwapTpslCancelall(self.extend(request, params))
4785
+ else:
4786
+ response = self.contractPrivatePostLinearSwapApiV1SwapCancelall(self.extend(request, params))
4760
4787
  elif marginMode == 'cross':
4761
- method = 'contractPrivatePostLinearSwapApiV1SwapCrossCancelall'
4762
- elif marketInner['inverse']:
4763
- if marketType == 'future':
4764
- method = 'contractPrivatePostApiV1ContractCancelall'
4765
- request['symbol'] = marketInner['settleId']
4766
- elif marketType == 'swap':
4767
- method = 'contractPrivatePostSwapApiV1SwapCancelall'
4768
- else:
4769
- raise NotSupported(self.id + ' cancelAllOrders() does not support ' + marketType + ' markets')
4770
- response = getattr(self, method)(self.extend(request, params))
4788
+ if stop:
4789
+ response = self.contractPrivatePostLinearSwapApiV1SwapCrossTriggerCancelall(self.extend(request, params))
4790
+ elif stopLossTakeProfit:
4791
+ response = self.contractPrivatePostLinearSwapApiV1SwapCrossTpslCancelall(self.extend(request, params))
4792
+ else:
4793
+ response = self.contractPrivatePostLinearSwapApiV1SwapCrossCancelall(self.extend(request, params))
4794
+ elif market['inverse']:
4795
+ if market['swap']:
4796
+ if stop:
4797
+ response = self.contractPrivatePostSwapApiV1SwapTriggerCancelall(self.extend(request, params))
4798
+ elif stopLossTakeProfit:
4799
+ response = self.contractPrivatePostSwapApiV1SwapTpslCancelall(self.extend(request, params))
4800
+ else:
4801
+ response = self.contractPrivatePostSwapApiV1SwapCancelall(self.extend(request, params))
4802
+ elif market['future']:
4803
+ if stop:
4804
+ response = self.contractPrivatePostApiV1ContractTriggerCancelall(self.extend(request, params))
4805
+ elif stopLossTakeProfit:
4806
+ response = self.contractPrivatePostApiV1ContractTpslCancelall(self.extend(request, params))
4807
+ else:
4808
+ response = self.contractPrivatePostApiV1ContractCancelall(self.extend(request, params))
4809
+ else:
4810
+ raise NotSupported(self.id + ' cancelAllOrders() does not support ' + marketType + ' markets')
4811
+ #
4812
+ # spot
4771
4813
  #
4772
4814
  # {
4773
4815
  # code: 200,
@@ -4778,6 +4820,17 @@ class huobi(Exchange, ImplicitAPI):
4778
4820
  # }
4779
4821
  # }
4780
4822
  #
4823
+ # future and swap
4824
+ #
4825
+ # {
4826
+ # status: "ok",
4827
+ # data: {
4828
+ # errors: [],
4829
+ # successes: "1104754904426696704"
4830
+ # },
4831
+ # ts: "1683435723755"
4832
+ # }
4833
+ #
4781
4834
  return response
4782
4835
 
4783
4836
  def parse_deposit_address(self, depositAddress, currency=None):
@@ -5379,8 +5432,7 @@ class huobi(Exchange, ImplicitAPI):
5379
5432
  :param dict params: extra parameters specific to the huobi api endpoint
5380
5433
  :returns [dict]: a list of `funding rate structures <https://docs.ccxt.com/en/latest/manual.html?#funding-rate-history-structure>`
5381
5434
  """
5382
- if symbol is None:
5383
- raise ArgumentsRequired(self.id + ' fetchFundingRateHistory() requires a symbol argument')
5435
+ self.check_required_symbol('fetchFundingRateHistory', symbol)
5384
5436
  self.load_markets()
5385
5437
  market = self.market(symbol)
5386
5438
  request = {
@@ -5884,8 +5936,7 @@ class huobi(Exchange, ImplicitAPI):
5884
5936
  :param dict params: extra parameters specific to the huobi api endpoint
5885
5937
  :returns dict: response from the exchange
5886
5938
  """
5887
- if symbol is None:
5888
- raise ArgumentsRequired(self.id + ' setLeverage() requires a symbol argument')
5939
+ self.check_required_symbol('setLeverage', symbol)
5889
5940
  self.load_markets()
5890
5941
  market = self.market(symbol)
5891
5942
  marketType, query = self.handle_market_type_and_params('setLeverage', market, params)
@@ -6964,8 +7015,7 @@ class huobi(Exchange, ImplicitAPI):
6964
7015
  marginMode = 'cross' if (marginMode is None) else marginMode
6965
7016
  method = None
6966
7017
  if marginMode == 'isolated':
6967
- if symbol is None:
6968
- raise ArgumentsRequired(self.id + ' borrowMargin() requires a symbol argument for isolated margin')
7018
+ self.check_required_symbol('borrowMargin', symbol)
6969
7019
  market = self.market(symbol)
6970
7020
  request['symbol'] = market['id']
6971
7021
  method = 'privatePostMarginOrders'
ccxt/phemex.py CHANGED
@@ -2399,7 +2399,7 @@ class phemex(Exchange, ImplicitAPI):
2399
2399
  :param float amount: how much of currency you want to trade in units of base currency
2400
2400
  :param float|None price: the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
2401
2401
  :param dict params: extra parameters specific to the phemex api endpoint
2402
- :param str|None params['posSide']: either 'Hedged' or 'OneWay' or 'Merged'
2402
+ :param str|None params['posSide']: either 'Merged' or 'Long' or 'Short'
2403
2403
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2404
2404
  """
2405
2405
  if symbol is None:
@@ -2457,7 +2457,7 @@ class phemex(Exchange, ImplicitAPI):
2457
2457
  :param str id: order id
2458
2458
  :param str symbol: unified symbol of the market the order was made in
2459
2459
  :param dict params: extra parameters specific to the phemex api endpoint
2460
- :param str|None params['posSide']: either 'Hedged' or 'OneWay' or 'Merged'
2460
+ :param str|None params['posSide']: either 'Merged' or 'Long' or 'Short'
2461
2461
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2462
2462
  """
2463
2463
  if symbol is None:
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '3.0.97'
7
+ __version__ = '3.0.98'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/bitfinex2.py CHANGED
@@ -618,10 +618,14 @@ class bitfinex2(ccxt.async_support.bitfinex2):
618
618
  asks = book['asks']
619
619
  # pepperoni pizza from bitfinex
620
620
  for i in range(0, depth):
621
- stringArray.append(self.number_to_string(bids[i][0]))
622
- stringArray.append(self.number_to_string(bids[i][1]))
623
- stringArray.append(self.number_to_string(asks[i][0]))
624
- stringArray.append(self.number_to_string(-asks[i][1]))
621
+ bid = self.safe_value(bids, i)
622
+ ask = self.safe_value(asks, i)
623
+ if bid is not None:
624
+ stringArray.append(self.number_to_string(bids[i][0]))
625
+ stringArray.append(self.number_to_string(bids[i][1]))
626
+ if ask is not None:
627
+ stringArray.append(self.number_to_string(asks[i][0]))
628
+ stringArray.append(self.number_to_string(-asks[i][1]))
625
629
  payload = ':'.join(stringArray)
626
630
  localChecksum = self.crc32(payload, True)
627
631
  responseChecksum = self.safe_integer(message, 2)
ccxt/test/test_async.py CHANGED
@@ -239,10 +239,6 @@ class testMainClass(baseMainTestClass):
239
239
  else:
240
240
  finalValue = exchangeSettings[key]
241
241
  set_exchange_prop(exchange, key, finalValue)
242
- # support simple proxy
243
- proxy = get_exchange_prop(exchange, 'httpProxy')
244
- if proxy:
245
- add_proxy(exchange, proxy)
246
242
  # credentials
247
243
  reqCreds = get_exchange_prop(exchange, 're' + 'quiredCredentials') # dont glue the r-e-q-u-i-r-e phrase, because leads to messed up transpilation
248
244
  objkeys = list(reqCreds.keys())
@@ -267,7 +263,9 @@ class testMainClass(baseMainTestClass):
267
263
  if exchange.alias:
268
264
  dump('[SKIPPED] Alias exchange. ', 'exchange', exchangeId, 'symbol', symbol)
269
265
  exit_script()
270
- #
266
+ proxy = exchange.safe_string(skippedSettingsForExchange, 'httpProxy')
267
+ if proxy is not None:
268
+ add_proxy(exchange, proxy)
271
269
  self.skippedMethods = exchange.safe_value(skippedSettingsForExchange, 'skipMethods', {})
272
270
  self.checkedPublicTests = {}
273
271
 
ccxt/test/test_sync.py CHANGED
@@ -238,10 +238,6 @@ class testMainClass(baseMainTestClass):
238
238
  else:
239
239
  finalValue = exchangeSettings[key]
240
240
  set_exchange_prop(exchange, key, finalValue)
241
- # support simple proxy
242
- proxy = get_exchange_prop(exchange, 'httpProxy')
243
- if proxy:
244
- add_proxy(exchange, proxy)
245
241
  # credentials
246
242
  reqCreds = get_exchange_prop(exchange, 're' + 'quiredCredentials') # dont glue the r-e-q-u-i-r-e phrase, because leads to messed up transpilation
247
243
  objkeys = list(reqCreds.keys())
@@ -266,7 +262,9 @@ class testMainClass(baseMainTestClass):
266
262
  if exchange.alias:
267
263
  dump('[SKIPPED] Alias exchange. ', 'exchange', exchangeId, 'symbol', symbol)
268
264
  exit_script()
269
- #
265
+ proxy = exchange.safe_string(skippedSettingsForExchange, 'httpProxy')
266
+ if proxy is not None:
267
+ add_proxy(exchange, proxy)
270
268
  self.skippedMethods = exchange.safe_value(skippedSettingsForExchange, 'skipMethods', {})
271
269
  self.checkedPublicTests = {}
272
270
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ccxt
3
- Version: 3.0.97
3
+ Version: 3.0.98
4
4
  Summary: A JavaScript / Python / PHP cryptocurrency trading library with support for 130+ exchanges
5
5
  Home-page: https://ccxt.com
6
6
  Author: Igor Kroitor
@@ -262,13 +262,13 @@ console.log(version, Object.keys(exchanges));
262
262
 
263
263
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
264
264
 
265
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@3.0.97/dist/ccxt.browser.js
266
- * unpkg: https://unpkg.com/ccxt@3.0.97/dist/ccxt.browser.js
265
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@3.0.98/dist/ccxt.browser.js
266
+ * unpkg: https://unpkg.com/ccxt@3.0.98/dist/ccxt.browser.js
267
267
 
268
268
  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.
269
269
 
270
270
  ```HTML
271
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@3.0.97/dist/ccxt.browser.js"></script>
271
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@3.0.98/dist/ccxt.browser.js"></script>
272
272
  ```
273
273
 
274
274
  Creates a global `ccxt` object:
@@ -1,4 +1,4 @@
1
- ccxt/__init__.py,sha256=ZIoWnZXlkiIB6hSwRjb8WVL6u6uRJDe-32y2rOuCGag,15626
1
+ ccxt/__init__.py,sha256=PIK3fyuDakVVbODC0cKd2CzjMfNUyiI28iBAXq478NM,15626
2
2
  ccxt/ace.py,sha256=EF63BJQ3hYZO9atvTrzpLrBeA80bH5mdfdzhBUSSULE,41329
3
3
  ccxt/alpaca.py,sha256=cn5ABCJszrfE2qWMCDIW_1F-dGHtBbG-7zeo8tpNaeE,33161
4
4
  ccxt/ascendex.py,sha256=xnGosk4KDav71stiZTvNblisCI_iYPyD8YjPacyQLyQ,127668
@@ -45,7 +45,7 @@ ccxt/coinbase.py,sha256=8rWOG3xL0N00ambXF8IfcjhiZ-e14_n4KtO1tyxutYQ,124586
45
45
  ccxt/coinbaseprime.py,sha256=Ygvljulxb2uKdei5yimCj1LMjLlUJNvP-G7ns1HpUFk,1219
46
46
  ccxt/coinbasepro.py,sha256=2jxW50mkvpEmKcw_m1AOMNdp_arFtxbCIzkOUXNhpP0,73787
47
47
  ccxt/coincheck.py,sha256=MGrYXtfJ_7IWubPVMDUWdTYNeFPJ7_aeAoinpDPG2TQ,34208
48
- ccxt/coinex.py,sha256=mogHtj2i5Iv_wYV624ErJ1ZikJFNsJ92ntqeSsT6KSQ,190913
48
+ ccxt/coinex.py,sha256=btpiJl9HuaQQxJ-YBqvDvztrWGBDYxQwqba5uIkp7Z4,191777
49
49
  ccxt/coinfalcon.py,sha256=UqVISPG0eKIv68jyMUoMw_R9OnV4rvcyAYYz90ngtQ0,38956
50
50
  ccxt/coinmate.py,sha256=aP3Qtp-XKoTzZg4KsyP0h2AXeWvb1qdh56hVYGah16M,39565
51
51
  ccxt/coinone.py,sha256=3-90dTFPpkX1F5hZKIshG85a_gu2XTfHrZ4r3fVERso,34455
@@ -65,7 +65,7 @@ ccxt/gemini.py,sha256=Hfx5cQs1qlTSnfWMsIGnbUz6tcGxpbyVvkj-4ub07_k,69001
65
65
  ccxt/hitbtc.py,sha256=PGRZH3ZckgaywW3yXJsJT6HCzU8oMs72EWnlyQ3LihM,62241
66
66
  ccxt/hitbtc3.py,sha256=TJG3C-9YqsRQNiZMCokkhTdlMQ2VDReMnLiXXgo12fA,116511
67
67
  ccxt/hollaex.py,sha256=SqWtRE6OCxxT8XSMfMRvB8O6Rks5GAq69Bbs-GBwq-g,69194
68
- ccxt/huobi.py,sha256=CdAtUUSBKENZGioE9wiM2UinULZ4D0RKaAQvyG1Wh90,357866
68
+ ccxt/huobi.py,sha256=aclzJwOe_X89TOhpVuQ-POvCvCDWUrxz7eLbLLsGuy0,361004
69
69
  ccxt/huobijp.py,sha256=0bRTYo9KS924MD9hFF9ybkqdSqhwfKTauBUmEWMHsLc,86605
70
70
  ccxt/huobipro.py,sha256=zdi6Dk59pKqYoaHZDD-mJ57ZvomXBoIUiS5oT3B3BAE,572
71
71
  ccxt/idex.py,sha256=3GEGwM-Fdc20kyLa36H2yRJBJ-8_CniZ8LyYvsuvp38,67332
@@ -93,7 +93,7 @@ ccxt/okex.py,sha256=nVDSzVztmboH593DVByjzFoOpFTzumcQFH_T9kdVKlE,434
93
93
  ccxt/okex5.py,sha256=LKTogVF1svNkqW_-Cx0AuAopu6esgFf7ucbv7CaodUg,441
94
94
  ccxt/okx.py,sha256=jq3p7kHtn85EB1zGq2aqRm7wmSU4wcisShQveo7IjEw,264325
95
95
  ccxt/paymium.py,sha256=N6QpUWpA-Sky6y8x5Y_We-nuYCuZC8E1qfN201X_hdA,22745
96
- ccxt/phemex.py,sha256=WOrrEB_HXVjiqp7XdpGZ5UWV-I0k999pawVDUfthOMk,191812
96
+ ccxt/phemex.py,sha256=oKxCWAVodmHI5IxGtnyh_DHtjLLz211bY2rczXOoJgo,191806
97
97
  ccxt/poloniex.py,sha256=HtvaZC220BmjLJorSoBPyUxc7LQJdff53XmN2_i6EMw,88311
98
98
  ccxt/poloniexfutures.py,sha256=hefNN2MPIJgjILdKx6fKR5qZ1JnHDtoaimx_2ynSNVA,75104
99
99
  ccxt/probit.py,sha256=-EPcl55gYeA0eIhHwUiaitYPEpUy4hFEcPPvDEc1-og,69752
@@ -221,7 +221,7 @@ ccxt/abstract/xt.py,sha256=LJ9BPnPZUwQAZ0zdtLinnC-XZM9YY5Smm2TtK9ZANGA,25850
221
221
  ccxt/abstract/yobit.py,sha256=8ycfCO8ORFly9hc0Aa47sZyX4_ZKPXS9h9yJzI-uQ7Q,1339
222
222
  ccxt/abstract/zaif.py,sha256=m15WHdl3gYy0GOXNZ8NEH8eE7sVh8c0T_ITNuU8vXeU,3935
223
223
  ccxt/abstract/zonda.py,sha256=VoxuPkSq8vAvKnDvOqnByhwsIf09m7yIrs8HejFrDk4,5482
224
- ccxt/async_support/__init__.py,sha256=PqFz9tEPQfC6SiZ-zaYT1csUvZ0UomyMajewLcP_pPM,15429
224
+ ccxt/async_support/__init__.py,sha256=wuHh0B7ns5erd35Hte9sYA5uFoRShYcmKLVaBW-5bHs,15429
225
225
  ccxt/async_support/ace.py,sha256=4RAmTYdlzO2yA9jnTopavGHBWZ9jDC7ceXMXxgiCrHY,41553
226
226
  ccxt/async_support/alpaca.py,sha256=0WxBRJDp4Rem6VKCzoVPZsgrPNFr4g5Iv7_P0RFxMkE,33307
227
227
  ccxt/async_support/ascendex.py,sha256=1tUMFAr3Sew5D6hN6h5-XHV-XtoZv1pMALaCtcarP_4,128282
@@ -268,7 +268,7 @@ ccxt/async_support/coinbase.py,sha256=hLlthooZ705YMF1NgrfDQUC5ae2s6YzdaJDNaawzUd
268
268
  ccxt/async_support/coinbaseprime.py,sha256=M5Ez1DsFcW3-vJ-4QoZzwYBAKjAAtJnJpkfnV4sWAIc,1233
269
269
  ccxt/async_support/coinbasepro.py,sha256=0Zo_K_Mi8LzHuUAWJzJ0gqeUJ4n2Cb6xiWLLXJzwu40,74293
270
270
  ccxt/async_support/coincheck.py,sha256=BsEcdRkNFuXhZEMR6hxw0S9c3wYO-3-G3Bv5X2Fee8M,34414
271
- ccxt/async_support/coinex.py,sha256=q_3VZzXtUu6vv7ge7U7vhwf08F0t7ivOaqnDsWtnpjY,191811
271
+ ccxt/async_support/coinex.py,sha256=34XyQgCMsQFVMvVbrgSc31EIFIoes_GJDUuA7udQlVQ,192675
272
272
  ccxt/async_support/coinfalcon.py,sha256=J4i9h1HPd5VvgjNXrFenq4bQ52XVLR7VMbUmgoqurLE,39252
273
273
  ccxt/async_support/coinmate.py,sha256=kHRj-PyzwqSBXzCv2PNOiudC1C4L9pHUhb6FDaeX51w,39813
274
274
  ccxt/async_support/coinone.py,sha256=5vVJvX_n1B3GNWXbKpqaHd4Dter_UnkeSvB4N8JobqY,34679
@@ -288,7 +288,7 @@ ccxt/async_support/gemini.py,sha256=swYmah05q-ETaxgMAZAD8VplnqLnPW5gXHwx2aN5d4A,
288
288
  ccxt/async_support/hitbtc.py,sha256=oHY4A0hhmAF0XKe_Zi919gWpwS3ccEA2xb8YlNQk5_g,62675
289
289
  ccxt/async_support/hitbtc3.py,sha256=QMJYs2s621V3WP7FLFIy9EZ8mefyPzBgIAX8tWO-p7U,117197
290
290
  ccxt/async_support/hollaex.py,sha256=CzQJC6HWlknBgJ0HQwaLKpAGooFYHzeeOAB80fhgKRc,69616
291
- ccxt/async_support/huobi.py,sha256=GRzDGglbxMmWOx2PvRgiFWH2vZ7LPV1T3DICRwRfeT8,359250
291
+ ccxt/async_support/huobi.py,sha256=0Drz3H5VJ4skMHq3GH2ih0xpOg2eIlD2P9rl4pkAwhc,362532
292
292
  ccxt/async_support/huobijp.py,sha256=HN5eIVSNATXbCMYatgMW8gugiDzzcyoK430x3lQNDhI,87087
293
293
  ccxt/async_support/huobipro.py,sha256=Xb148Da6Mlf8nYhB_c8frd8ZMt6C59VjWgk4o9tIZWA,586
294
294
  ccxt/async_support/idex.py,sha256=lokrHXP-Jxzu4xttfCGHsU5j1iw9df65WYeIaiAQ8H0,67772
@@ -316,7 +316,7 @@ ccxt/async_support/okex.py,sha256=6dbtH4bC1C2x4cQUK6W62y7PuDgO3YazuFa7DYhM4Jw,44
316
316
  ccxt/async_support/okex5.py,sha256=tq41tKx06j3DDO9pu9iKInpjayVprbobVNTK8qb7hoM,455
317
317
  ccxt/async_support/okx.py,sha256=ASkrbxGG92o3TlGdbOr_dGM9fD4T9dDWfxpIS8sanrM,265343
318
318
  ccxt/async_support/paymium.py,sha256=gdx3EHYGMAFSzWvCbCpNngQNFz_ttFljR4tDMGHg4ow,22933
319
- ccxt/async_support/phemex.py,sha256=cGGsxOkaq_33L5Pf0Qsjiswjnboh3IUdVOOFumz5Ku4,192396
319
+ ccxt/async_support/phemex.py,sha256=0w1NOGNoYIfccIg9uFSKUR1KYDgWarGRb_ilOtbndYc,192390
320
320
  ccxt/async_support/poloniex.py,sha256=u2pDmyUWTzKhvN80ffGWdAQoWfif30eanyCgHW4Pti4,88811
321
321
  ccxt/async_support/poloniexfutures.py,sha256=IY36Rj8jNkTEru5KoflGP36ukFci73eKzmL1r_eJ4lA,75472
322
322
  ccxt/async_support/probit.py,sha256=f_YF-lQ3YfMn2tv1mNbwmpJXuH1VJMc42mDrAsmIW0M,70102
@@ -336,7 +336,7 @@ ccxt/async_support/zaif.py,sha256=Tye_zrffs7Ua22_o7fp68C3Ti1qdJ3H26dbz6j1bVRc,28
336
336
  ccxt/async_support/zb.py,sha256=W8HHyssjCLTugSRs80TnAwGJl85vp7nyNPOn9RLpXFk,184533
337
337
  ccxt/async_support/zonda.py,sha256=0ABz8ApeophACxwTL4hxonco2Yc6uTF5torKmDLQSN0,74326
338
338
  ccxt/async_support/base/__init__.py,sha256=aVYSsFi--b4InRs9zDN_wtCpj8odosAB726JdUHavrk,67
339
- ccxt/async_support/base/exchange.py,sha256=ECtCwZS7AdcXW-xt8FIxLJivRU3qcsFbU7I11HaLwnw,128268
339
+ ccxt/async_support/base/exchange.py,sha256=QHirw229QKal4FnzgX5pAG48chERAgTkUHoMfcxtecA,128268
340
340
  ccxt/async_support/base/throttler.py,sha256=tvDVcdRUVYi8fZRlEcnqtgzcgB_KMUMRs5Pu8tuU-tU,1847
341
341
  ccxt/async_support/base/ws/__init__.py,sha256=uockzpLuwntKGZbs5EOWFe-Zg-k6Cj7GhNJLc_RX0so,1791
342
342
  ccxt/async_support/base/ws/aiohttp_client.py,sha256=xmlZV30Vb9Kq7JCm3D5FuEmuj1zp5H4F4hrz8-Y-Ir4,4999
@@ -350,10 +350,10 @@ ccxt/async_support/base/ws/order_book_side.py,sha256=GH-475Ni0mLOx7mUDnz4jjzaGkh
350
350
  ccxt/base/__init__.py,sha256=eTx1OE3HJjspFUQjGm6LBhaQiMKJnXjkdP-JUXknyQ0,1320
351
351
  ccxt/base/decimal_to_precision.py,sha256=fgWRBzRTtsf3r2INyS4f7WHlzgjB5YM1ekiwqD21aac,6634
352
352
  ccxt/base/errors.py,sha256=-LVeTNyXvu3QEgb-p-KzMpcBgzHlvFTwDzmZK7Gfc14,3401
353
- ccxt/base/exchange.py,sha256=2F7_pfmGF2TBYNqCdEn5W8sGEHIc6fH4Yuru_i1MMO0,169527
353
+ ccxt/base/exchange.py,sha256=YyUELs-4l04f1fdoVmtS3Vh4CcJ8IsBVhFdC1-3WGro,169527
354
354
  ccxt/base/precise.py,sha256=_xfu54sV0vWNnOfGTKRFykeuWP8mn4K1m9lk1tcllX4,8565
355
355
  ccxt/base/types.py,sha256=7GG9G_EXiOzmAD_ZjmhV5a5VfIU4EqF5IxFE0KAPXa4,1071
356
- ccxt/pro/__init__.py,sha256=7cEQkv2w_WZGJ13V6Gsga1g4yhjVyH6oUqMtMSbKvYM,6039
356
+ ccxt/pro/__init__.py,sha256=X5wkGsNvy_sjfkrua6q15L9XVQ187HlHcTajM_nxsj8,6039
357
357
  ccxt/pro/alpaca.py,sha256=dlnmYTvTxrKB84YuH-RCmDopFJRTI1efIhdLlCCKefQ,26668
358
358
  ccxt/pro/ascendex.py,sha256=0MGpQ5fbYbAb0cB-iJsZ1fXvM3Llo06uis6BbwbjEkg,34553
359
359
  ccxt/pro/bequant.py,sha256=qz8JjnpkAQY_CFiFSKGqrjjgZ2167_TBKjSJOb9NeDw,1081
@@ -363,7 +363,7 @@ ccxt/pro/binanceus.py,sha256=xKL-1cOHyqlLTwLGg-DPf6g3JMM1oU2Kv708FiGJwrY,2016
363
363
  ccxt/pro/binanceusdm.py,sha256=S0eT662O2ReplsihWk42nhJWqw1XsODpeDQa9eFVVt8,1357
364
364
  ccxt/pro/bitcoincom.py,sha256=ipRe4xMqvwh81FAJhzQI8P_sGCmmHFw42owF-FwcoD4,914
365
365
  ccxt/pro/bitfinex.py,sha256=1INbXru2OeKVWsJDSw16VxClZAhr5KqI0_oKDpn9v5o,24762
366
- ccxt/pro/bitfinex2.py,sha256=_M7WiN3PSrNRpX9KI7FBpk01vgnp6sWleWYylIqv_6Q,41903
366
+ ccxt/pro/bitfinex2.py,sha256=weFRSGO48Zq4GAmbh-hprjtHUFY-yYMkqCdZKFC5MW8,42069
367
367
  ccxt/pro/bitget.py,sha256=cUvvvml8UZ-gT-3SiffeS0gw1UbiwD94dC9OYLMZcqI,44698
368
368
  ccxt/pro/bitmart.py,sha256=ZkM-YHvMNuQPp18i7a5V5Bm-Tvirq-xZhsKGQKZnxWQ,24486
369
369
  ccxt/pro/bitmex.py,sha256=2zcf-7S5YP3PfNtEfIZYF3Wh6HJIyrOmU7EYKfFdqNY,55606
@@ -425,8 +425,8 @@ ccxt/static_dependencies/ecdsa/util.py,sha256=M0NQZ4dDQFTd8afSkF-7YyP9KbsXzOn-VU
425
425
  ccxt/static_dependencies/keccak/__init__.py,sha256=mfcrTChnMXsr-JmfN2VbzscTRt9XA2RRGchfHRMYncU,45
426
426
  ccxt/static_dependencies/keccak/keccak.py,sha256=RblmQEQkGpMhug0EU3hyE0kBjs1NDfGQqbwrBK7ZycY,6934
427
427
  ccxt/test/__init__.py,sha256=GKPbEcj0Rrz5HG-GUm-iY1IHhDYmlvcBXZAGk6-m2CI,141
428
- ccxt/test/test_async.py,sha256=5_fAiv00ZdfjV6NLFhbn3JOte_EHq3MjmcDna0UG0j8,26500
429
- ccxt/test/test_sync.py,sha256=0Uvni1l7K3p7ATcTiwqhT0VybVdHiJfV4kLVlf6xPWc,26096
428
+ ccxt/test/test_async.py,sha256=9jB_3_lTDtL3bLKlor80GeXSZ_GvVmJOpiMn0tBM8sk,26476
429
+ ccxt/test/test_sync.py,sha256=2vo4wsgrCHPG9bfcSUuHAZQk5CM9a2Ff-ykWeq9lrlE,26072
430
430
  ccxt/test/base/__init__.py,sha256=hQPmjR9gxzFFd-nZRo-ICCD89Yk4hoQjQSnEKGHvhVM,1745
431
431
  ccxt/test/base/test_account.py,sha256=QrPiPEB0iOsmPMIFKF7HAaHWIRZ94KLccgI3GtjpY1o,922
432
432
  ccxt/test/base/test_balance.py,sha256=FkBGDLdVL445KGNFV-kbrkuvndajuRo0irbIwcNx3qI,2110
@@ -459,7 +459,7 @@ ccxt/test/base/test_ticker.py,sha256=WAyiRzelQe7nxyFPcJWS84_EQh7hv9HaYmiBKZ6-Hwk
459
459
  ccxt/test/base/test_trade.py,sha256=w8CPWfyqXxQCgPfk2vpdKnJpDF2ZFiKDjmna7WZVQzw,1850
460
460
  ccxt/test/base/test_trading_fee.py,sha256=l9QJXlV9R6GTIcpCavbUqgZdHQosRrBVxqGQWIxyftQ,1081
461
461
  ccxt/test/base/test_transaction.py,sha256=BTbB4UHHXkrvYgwbrhh867nVRlevmIkIrz1W_odlQJI,1434
462
- ccxt-3.0.97.dist-info/METADATA,sha256=nEUeiCObLIBU4Xar2N3AePx3D_deUJLS7yJCDrKwjTQ,109229
463
- ccxt-3.0.97.dist-info/WHEEL,sha256=a-zpFRIJzOq5QfuhBzbhiA1eHTzNCJn8OdRvhdNX0Rk,110
464
- ccxt-3.0.97.dist-info/top_level.txt,sha256=CkQDuCTDKNcImPV60t36G6MdYfxsAPNiSaEwifVoVMo,5
465
- ccxt-3.0.97.dist-info/RECORD,,
462
+ ccxt-3.0.98.dist-info/METADATA,sha256=6xmhu7eh3LKfKVakoPrx51Q1yZtTRHDxWgOQnBtA81o,109229
463
+ ccxt-3.0.98.dist-info/WHEEL,sha256=a-zpFRIJzOq5QfuhBzbhiA1eHTzNCJn8OdRvhdNX0Rk,110
464
+ ccxt-3.0.98.dist-info/top_level.txt,sha256=CkQDuCTDKNcImPV60t36G6MdYfxsAPNiSaEwifVoVMo,5
465
+ ccxt-3.0.98.dist-info/RECORD,,
File without changes