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

ccxt/__init__.py CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.1.82'
25
+ __version__ = '4.1.84'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.1.82'
7
+ __version__ = '4.1.84'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.1.82'
5
+ __version__ = '4.1.84'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -1010,7 +1010,7 @@ class Exchange(BaseExchange):
1010
1010
  async def fetch_funding_history(self, symbol: str = None, since: Int = None, limit: Int = None, params={}):
1011
1011
  raise NotSupported(self.id + ' fetchFundingHistory() is not supported yet')
1012
1012
 
1013
- async def close_position(self, symbol: str, side: OrderSide = None, marginMode: str = None, params={}):
1013
+ async def close_position(self, symbol: str, side: OrderSide = None, params={}):
1014
1014
  raise NotSupported(self.id + ' closePositions() is not supported yet')
1015
1015
 
1016
1016
  async def close_all_positions(self, params={}):
@@ -7939,7 +7939,7 @@ class binance(Exchange, ImplicitAPI):
7939
7939
  extendedParams = self.omit(extendedParams, ['orderidlist', 'origclientorderidlist'])
7940
7940
  query = self.rawencode(extendedParams)
7941
7941
  orderidlistLength = len(orderidlist)
7942
- origclientorderidlistLength = len(orderidlist)
7942
+ origclientorderidlistLength = len(origclientorderidlist)
7943
7943
  if orderidlistLength > 0:
7944
7944
  query = query + '&' + 'orderidlist=[' + ','.join(orderidlist) + ']'
7945
7945
  if origclientorderidlistLength > 0:
@@ -3172,7 +3172,7 @@ class bingx(Exchange, ImplicitAPI):
3172
3172
  :see: https://bitgetlimited.github.io/apidoc/en/mix/#close-all-position
3173
3173
  :param dict [params]: extra parameters specific to the okx api endpoint
3174
3174
  :param str [params.recvWindow]: request valid time window value
3175
- :returns [dict]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
3175
+ :returns dict[]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
3176
3176
  """
3177
3177
  await self.load_markets()
3178
3178
  defaultRecvWindow = self.safe_integer(self.options, 'recvWindow')
@@ -6555,7 +6555,7 @@ class bitget(Exchange, ImplicitAPI):
6555
6555
  :param dict [params]: extra parameters specific to the okx api endpoint
6556
6556
  :param str [params.subType]: 'linear' or 'inverse'
6557
6557
  :param str [params.settle]: *required and only valid when params.subType == "linear"* 'USDT' or 'USDC'
6558
- :returns [dict]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
6558
+ :returns dict[]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
6559
6559
  """
6560
6560
  await self.load_markets()
6561
6561
  subType = None
@@ -5367,8 +5367,10 @@ class bybit(Exchange, ImplicitAPI):
5367
5367
  raise ArgumentsRequired(self.id + ' fetchPositions() does not accept an array with more than one symbol')
5368
5368
  elif symbolsLength == 1:
5369
5369
  symbol = symbols[0]
5370
+ symbols = self.market_symbols(symbols)
5370
5371
  elif symbols is not None:
5371
5372
  symbol = symbols
5373
+ symbols = [self.symbol(symbol)]
5372
5374
  await self.load_markets()
5373
5375
  enableUnifiedMargin, enableUnifiedAccount = await self.is_unified_enabled()
5374
5376
  isUnifiedAccount = (enableUnifiedMargin or enableUnifiedAccount)
@@ -5377,12 +5379,11 @@ class bybit(Exchange, ImplicitAPI):
5377
5379
  isUsdcSettled = False
5378
5380
  if symbol is not None:
5379
5381
  market = self.market(symbol)
5382
+ symbol = market['symbol']
5380
5383
  request['symbol'] = market['id']
5381
5384
  isUsdcSettled = market['settle'] == 'USDC'
5382
5385
  type = None
5383
5386
  type, params = self.get_bybit_type('fetchPositions', market, params)
5384
- if type == 'spot':
5385
- raise NotSupported(self.id + ' fetchPositions() not support spot market')
5386
5387
  if type == 'linear' or type == 'inverse':
5387
5388
  baseCoin = self.safe_string(params, 'baseCoin')
5388
5389
  if type == 'linear':
ccxt/async_support/cex.py CHANGED
@@ -45,6 +45,9 @@ class cex(Exchange, ImplicitAPI):
45
45
  'cancelOrder': True,
46
46
  'cancelOrders': False,
47
47
  'createDepositAddress': False,
48
+ 'createMarketBuyOrderWithCost': True,
49
+ 'createMarketOrderWithCost': False,
50
+ 'createMarketSellOrderWithCost': False,
48
51
  'createOrder': True,
49
52
  'createStopLimitOrder': False,
50
53
  'createStopMarketOrder': False,
@@ -728,27 +731,39 @@ class cex(Exchange, ImplicitAPI):
728
731
  :param float amount: how much of currency you want to trade in units of base currency
729
732
  :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
730
733
  :param dict [params]: extra parameters specific to the exchange API endpoint
734
+ :param float [params.cost]: the quote quantity that can be used alternative for the amount for market buy orders
731
735
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
732
736
  """
733
- # for market buy it requires the amount of quote currency to spend
734
- if (type == 'market') and (side == 'buy'):
735
- if self.options['createMarketBuyOrderRequiresPrice']:
736
- if price is None:
737
- raise InvalidOrder(self.id + " createOrder() requires the price argument with market buy orders to calculate total order cost(amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = False to supply the cost in the amount argument(the exchange-specific behaviour)")
738
- else:
739
- amountString = self.number_to_string(amount)
740
- priceString = self.number_to_string(price)
741
- baseAmount = Precise.string_mul(amountString, priceString)
742
- amount = self.parse_number(baseAmount)
743
737
  await self.load_markets()
744
738
  market = self.market(symbol)
745
739
  request = {
746
740
  'pair': market['id'],
747
741
  'type': side,
748
- 'amount': amount,
749
742
  }
743
+ # for market buy it requires the amount of quote currency to spend
744
+ if (type == 'market') and (side == 'buy'):
745
+ quoteAmount = None
746
+ createMarketBuyOrderRequiresPrice = True
747
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
748
+ cost = self.safe_string(params, 'cost')
749
+ params = self.omit(params, 'cost')
750
+ if cost is not None:
751
+ quoteAmount = self.cost_to_precision(symbol, cost)
752
+ elif createMarketBuyOrderRequiresPrice:
753
+ if price is None:
754
+ raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend in the amount argument')
755
+ else:
756
+ amountString = self.number_to_string(amount)
757
+ priceString = self.number_to_string(price)
758
+ costRequest = Precise.string_mul(amountString, priceString)
759
+ quoteAmount = self.cost_to_precision(symbol, costRequest)
760
+ else:
761
+ quoteAmount = self.cost_to_precision(symbol, amount)
762
+ request['amount'] = quoteAmount
763
+ else:
764
+ request['amount'] = self.amount_to_precision(symbol, amount)
750
765
  if type == 'limit':
751
- request['price'] = price
766
+ request['price'] = self.number_to_string(price)
752
767
  else:
753
768
  request['order_type'] = type
754
769
  response = await self.privatePostPlaceOrderPair(self.extend(request, params))
@@ -54,6 +54,9 @@ class coinsph(Exchange, ImplicitAPI):
54
54
  'closeAllPositions': False,
55
55
  'closePosition': False,
56
56
  'createDepositAddress': False,
57
+ 'createMarketBuyOrderWithCost': True,
58
+ 'createMarketOrderWithCost': False,
59
+ 'createMarketSellOrderWithCost': False,
57
60
  'createOrder': True,
58
61
  'createPostOnlyOrder': False,
59
62
  'createReduceOnlyOrder': False,
@@ -1028,12 +1031,14 @@ class coinsph(Exchange, ImplicitAPI):
1028
1031
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
1029
1032
  """
1030
1033
  create a trade order
1034
+ :see: https://coins-docs.github.io/rest-api/#new-order--trade
1031
1035
  :param str symbol: unified symbol of the market to create an order in
1032
1036
  :param str type: 'market', 'limit', 'stop_loss', 'take_profit', 'stop_loss_limit', 'take_profit_limit' or 'limit_maker'
1033
1037
  :param str side: 'buy' or 'sell'
1034
1038
  :param float amount: how much of currency you want to trade in units of base currency
1035
1039
  :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1036
1040
  :param dict [params]: extra parameters specific to the exchange API endpoint
1041
+ :param float [params.cost]: the quote quantity that can be used alternative for the amount for market buy orders
1037
1042
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1038
1043
  """
1039
1044
  # todo: add test order low priority
@@ -1065,20 +1070,24 @@ class coinsph(Exchange, ImplicitAPI):
1065
1070
  if orderSide == 'SELL':
1066
1071
  request['quantity'] = self.amount_to_precision(symbol, amount)
1067
1072
  elif orderSide == 'BUY':
1068
- quoteOrderQty = self.safe_number_2(params, 'cost', 'quoteOrderQty')
1069
- createMarketBuyOrderRequiresPrice = self.safe_value(self.options, 'createMarketBuyOrderRequiresPrice', True)
1070
- if quoteOrderQty is not None:
1071
- amount = quoteOrderQty
1073
+ quoteAmount = None
1074
+ createMarketBuyOrderRequiresPrice = True
1075
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
1076
+ cost = self.safe_number_2(params, 'cost', 'quoteOrderQty')
1077
+ params = self.omit(params, 'cost')
1078
+ if cost is not None:
1079
+ quoteAmount = self.cost_to_precision(symbol, cost)
1072
1080
  elif createMarketBuyOrderRequiresPrice:
1073
1081
  if price is None:
1074
- raise InvalidOrder(self.id + " createOrder() requires the price argument with market buy orders to calculate total order cost(amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = False to supply the cost in the amount argument(the exchange-specific behaviour)")
1082
+ raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend in the amount argument')
1075
1083
  else:
1076
1084
  amountString = self.number_to_string(amount)
1077
1085
  priceString = self.number_to_string(price)
1078
- quoteAmount = Precise.string_mul(amountString, priceString)
1079
- amount = self.parse_number(quoteAmount)
1080
- request['quoteOrderQty'] = self.cost_to_precision(symbol, amount)
1081
- params = self.omit(params, 'cost', 'quoteOrderQty')
1086
+ costRequest = Precise.string_mul(amountString, priceString)
1087
+ quoteAmount = self.cost_to_precision(symbol, costRequest)
1088
+ else:
1089
+ quoteAmount = self.cost_to_precision(symbol, amount)
1090
+ request['quoteOrderQty'] = quoteAmount
1082
1091
  if orderType == 'STOP_LOSS' or orderType == 'STOP_LOSS_LIMIT' or orderType == 'TAKE_PROFIT' or orderType == 'TAKE_PROFIT_LIMIT':
1083
1092
  stopPrice = self.safe_string_2(params, 'triggerPrice', 'stopPrice')
1084
1093
  if stopPrice is None:
@@ -48,6 +48,8 @@ class cryptocom(Exchange, ImplicitAPI):
48
48
  'cancelAllOrders': True,
49
49
  'cancelOrder': True,
50
50
  'cancelOrders': True,
51
+ 'closeAllPositions': False,
52
+ 'closePosition': True,
51
53
  'createOrder': True,
52
54
  'createOrders': True,
53
55
  'fetchAccounts': True,
@@ -2683,6 +2685,47 @@ class cryptocom(Exchange, ImplicitAPI):
2683
2685
  returnString += str(value)
2684
2686
  return returnString
2685
2687
 
2688
+ async def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
2689
+ """
2690
+ closes open positions for a market
2691
+ :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-close-position
2692
+ :param str symbol: Unified CCXT market symbol
2693
+ :param str [marginMode]: not used by cryptocom.closePositions
2694
+ :param str [side]: not used by cryptocom.closePositions
2695
+ :param dict [params]: extra parameters specific to the okx api endpoint
2696
+ *
2697
+ * EXCHANGE SPECIFIC PARAMETERS
2698
+ :param str [params.type]: LIMIT or MARKET
2699
+ :param number [params.price]: for limit orders only
2700
+ :returns dict[]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
2701
+ """
2702
+ await self.load_markets()
2703
+ market = self.market(symbol)
2704
+ request = {
2705
+ 'instrument_name': market['id'],
2706
+ 'type': 'MARKET',
2707
+ }
2708
+ type = self.safe_string_upper(params, 'type')
2709
+ price = self.safe_string(params, 'price')
2710
+ if type is not None:
2711
+ request['type'] = type
2712
+ if price is not None:
2713
+ request['price'] = self.price_to_precision(market['symbol'], price)
2714
+ response = await self.v1PrivatePostPrivateClosePosition(self.extend(request, params))
2715
+ #
2716
+ # {
2717
+ # "id" : 1700830813298,
2718
+ # "method" : "private/close-position",
2719
+ # "code" : 0,
2720
+ # "result" : {
2721
+ # "client_oid" : "179a909d-5614-655b-0d0e-9e85c9a25c85",
2722
+ # "order_id" : "6142909897021751347"
2723
+ # }
2724
+ # }
2725
+ #
2726
+ result = self.safe_value(response, 'result')
2727
+ return self.parse_order(result, market)
2728
+
2686
2729
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
2687
2730
  type = self.safe_string(api, 0)
2688
2731
  access = self.safe_string(api, 1)
ccxt/async_support/htx.py CHANGED
@@ -57,6 +57,9 @@ class htx(Exchange, ImplicitAPI):
57
57
  'cancelOrder': True,
58
58
  'cancelOrders': True,
59
59
  'createDepositAddress': None,
60
+ 'createMarketBuyOrderWithCost': True,
61
+ 'createMarketOrderWithCost': False,
62
+ 'createMarketSellOrderWithCost': False,
60
63
  'createOrder': True,
61
64
  'createOrders': True,
62
65
  'createReduceOnlyOrder': False,
@@ -4536,6 +4539,22 @@ class htx(Exchange, ImplicitAPI):
4536
4539
  'trades': trades,
4537
4540
  }, market)
4538
4541
 
4542
+ async def create_market_buy_order_with_cost(self, symbol: str, cost, params={}):
4543
+ """
4544
+ create a market buy order by providing the symbol and cost
4545
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=7ec4ee16-7773-11ed-9966-0242ac110003
4546
+ :param str symbol: unified symbol of the market to create an order in
4547
+ :param float cost: how much you want to trade in units of the quote currency
4548
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4549
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4550
+ """
4551
+ await self.load_markets()
4552
+ market = self.market(symbol)
4553
+ if not market['spot']:
4554
+ raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
4555
+ params['createMarketBuyOrderRequiresPrice'] = False
4556
+ return await self.create_order(symbol, 'market', 'buy', cost, None, params)
4557
+
4539
4558
  async def create_spot_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
4540
4559
  """
4541
4560
  * @ignore
@@ -4547,6 +4566,7 @@ class htx(Exchange, ImplicitAPI):
4547
4566
  :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
4548
4567
  :param dict [params]: extra parameters specific to the exchange API endpoint
4549
4568
  :param str [params.timeInForce]: supports 'IOC' and 'FOK'
4569
+ :param float [params.cost]: the quote quantity that can be used alternative for the amount for market buy orders
4550
4570
  :returns dict: request to be sent to the exchange
4551
4571
  """
4552
4572
  await self.load_markets()
@@ -4608,9 +4628,16 @@ class htx(Exchange, ImplicitAPI):
4608
4628
  elif marginMode == 'c2c':
4609
4629
  request['source'] = 'c2c-margin-api'
4610
4630
  if (orderType == 'market') and (side == 'buy'):
4611
- if self.options['createMarketBuyOrderRequiresPrice']:
4631
+ quoteAmount = None
4632
+ createMarketBuyOrderRequiresPrice = True
4633
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
4634
+ cost = self.safe_number(params, 'cost')
4635
+ params = self.omit(params, 'cost')
4636
+ if cost is not None:
4637
+ quoteAmount = self.amount_to_precision(symbol, cost)
4638
+ elif createMarketBuyOrderRequiresPrice:
4612
4639
  if price is None:
4613
- raise InvalidOrder(self.id + " market buy order requires price argument to calculate cost(total amount of quote currency to spend for buying, amount * price). To switch off self warning exception and specify cost in the amount argument, set .options['createMarketBuyOrderRequiresPrice'] = False. Make sure you know what you're doing.")
4640
+ raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend in the amount argument')
4614
4641
  else:
4615
4642
  # despite that cost = amount * price is in quote currency and should have quote precision
4616
4643
  # the exchange API requires the cost supplied in 'amount' to be of base precision
@@ -4620,9 +4647,10 @@ class htx(Exchange, ImplicitAPI):
4620
4647
  # we use amountToPrecision here because the exchange requires cost in base precision
4621
4648
  amountString = self.number_to_string(amount)
4622
4649
  priceString = self.number_to_string(price)
4623
- request['amount'] = self.cost_to_precision(symbol, Precise.string_mul(amountString, priceString))
4650
+ quoteAmount = self.amount_to_precision(symbol, Precise.string_mul(amountString, priceString))
4624
4651
  else:
4625
- request['amount'] = self.cost_to_precision(symbol, amount)
4652
+ quoteAmount = self.amount_to_precision(symbol, amount)
4653
+ request['amount'] = quoteAmount
4626
4654
  else:
4627
4655
  request['amount'] = self.amount_to_precision(symbol, amount)
4628
4656
  limitOrderTypes = self.safe_value(options, 'limitOrderTypes', {})
@@ -4732,6 +4760,7 @@ class htx(Exchange, ImplicitAPI):
4732
4760
  :param bool [params.postOnly]: *contract only* True or False
4733
4761
  :param int [params.leverRate]: *contract only* required for all contract orders except tpsl, leverage greater than 20x requires prior approval of high-leverage agreement
4734
4762
  :param str [params.timeInForce]: supports 'IOC' and 'FOK'
4763
+ :param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
4735
4764
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4736
4765
  """
4737
4766
  await self.load_markets()
@@ -16,6 +16,7 @@ from ccxt.base.errors import BadSymbol
16
16
  from ccxt.base.errors import InsufficientFunds
17
17
  from ccxt.base.errors import InvalidOrder
18
18
  from ccxt.base.errors import OrderNotFound
19
+ from ccxt.base.errors import NotSupported
19
20
  from ccxt.base.errors import NetworkError
20
21
  from ccxt.base.errors import ExchangeNotAvailable
21
22
  from ccxt.base.errors import OnMaintenance
@@ -49,6 +50,9 @@ class huobijp(Exchange, ImplicitAPI):
49
50
  'cancelAllOrders': True,
50
51
  'cancelOrder': True,
51
52
  'cancelOrders': True,
53
+ 'createMarketBuyOrderWithCost': True,
54
+ 'createMarketOrderWithCost': False,
55
+ 'createMarketSellOrderWithCost': False,
52
56
  'createOrder': True,
53
57
  'createStopLimitOrder': False,
54
58
  'createStopMarketOrder': False,
@@ -1301,6 +1305,21 @@ class huobijp(Exchange, ImplicitAPI):
1301
1305
  'trades': None,
1302
1306
  }, market)
1303
1307
 
1308
+ async def create_market_buy_order_with_cost(self, symbol: str, cost, params={}):
1309
+ """
1310
+ create a market buy order by providing the symbol and cost
1311
+ :param str symbol: unified symbol of the market to create an order in
1312
+ :param float cost: how much you want to trade in units of the quote currency
1313
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1314
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1315
+ """
1316
+ await self.load_markets()
1317
+ market = self.market(symbol)
1318
+ if not market['spot']:
1319
+ raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
1320
+ params['createMarketBuyOrderRequiresPrice'] = False
1321
+ return await self.create_order(symbol, 'market', 'buy', cost, None, params)
1322
+
1304
1323
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
1305
1324
  """
1306
1325
  create a trade order
@@ -1329,9 +1348,16 @@ class huobijp(Exchange, ImplicitAPI):
1329
1348
  request['client-order-id'] = clientOrderId
1330
1349
  params = self.omit(params, ['clientOrderId', 'client-order-id'])
1331
1350
  if (type == 'market') and (side == 'buy'):
1332
- if self.options['createMarketBuyOrderRequiresPrice']:
1351
+ quoteAmount = None
1352
+ createMarketBuyOrderRequiresPrice = True
1353
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
1354
+ cost = self.safe_number(params, 'cost')
1355
+ params = self.omit(params, 'cost')
1356
+ if cost is not None:
1357
+ quoteAmount = self.amount_to_precision(symbol, cost)
1358
+ elif createMarketBuyOrderRequiresPrice:
1333
1359
  if price is None:
1334
- raise InvalidOrder(self.id + " market buy order requires price argument to calculate cost(total amount of quote currency to spend for buying, amount * price). To switch off self warning exception and specify cost in the amount argument, set .options['createMarketBuyOrderRequiresPrice'] = False. Make sure you know what you're doing.")
1360
+ raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend in the amount argument')
1335
1361
  else:
1336
1362
  # despite that cost = amount * price is in quote currency and should have quote precision
1337
1363
  # the exchange API requires the cost supplied in 'amount' to be of base precision
@@ -1341,10 +1367,10 @@ class huobijp(Exchange, ImplicitAPI):
1341
1367
  # we use amountToPrecision here because the exchange requires cost in base precision
1342
1368
  amountString = self.number_to_string(amount)
1343
1369
  priceString = self.number_to_string(price)
1344
- baseAmount = Precise.string_mul(amountString, priceString)
1345
- request['amount'] = self.cost_to_precision(symbol, baseAmount)
1370
+ quoteAmount = self.amount_to_precision(symbol, Precise.string_mul(amountString, priceString))
1346
1371
  else:
1347
- request['amount'] = self.cost_to_precision(symbol, amount)
1372
+ quoteAmount = self.amount_to_precision(symbol, amount)
1373
+ request['amount'] = quoteAmount
1348
1374
  else:
1349
1375
  request['amount'] = self.amount_to_precision(symbol, amount)
1350
1376
  if type == 'limit' or type == 'ioc' or type == 'limit-maker' or type == 'stop-limit' or type == 'stop-limit-fok':
ccxt/async_support/okx.py CHANGED
@@ -57,6 +57,8 @@ class okx(Exchange, ImplicitAPI):
57
57
  'cancelAllOrders': False,
58
58
  'cancelOrder': True,
59
59
  'cancelOrders': True,
60
+ 'closeAllPositions': False,
61
+ 'closePosition': True,
60
62
  'createDepositAddress': False,
61
63
  'createMarketBuyOrderWithCost': True,
62
64
  'createMarketSellOrderWithCost': True,
@@ -6692,6 +6694,66 @@ class okx(Exchange, ImplicitAPI):
6692
6694
  'info': greeks,
6693
6695
  }
6694
6696
 
6697
+ async def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
6698
+ """
6699
+ closes open positions for a market
6700
+ :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-close-positions
6701
+ :param str symbol: Unified CCXT market symbol
6702
+ :param str [side]: 'buy' or 'sell', leave in net mode
6703
+ :param dict [params]: extra parameters specific to the okx api endpoint
6704
+ :param str [params.clientOrderId]: a unique identifier for the order
6705
+ :param str [params.marginMode]: 'cross' or 'isolated', default is 'cross
6706
+ :param str [params.code]: *required in the case of closing cross MARGIN position for Single-currency margin* margin currency
6707
+ *
6708
+ * EXCHANGE SPECIFIC PARAMETERS
6709
+ :param boolean [params.autoCxl]: whether any pending orders for closing out needs to be automatically canceled when close position via a market order. False or True, the default is False
6710
+ :param str [params.tag]: order tag a combination of case-sensitive alphanumerics, all numbers, or all letters of up to 16 characters
6711
+ :returns [dict]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
6712
+ """
6713
+ await self.load_markets()
6714
+ market = self.market(symbol)
6715
+ clientOrderId = self.safe_string(params, 'clientOrderId')
6716
+ code = self.safe_string(params, 'code')
6717
+ marginMode = None
6718
+ marginMode, params = self.handle_margin_mode_and_params('closePosition', params, 'cross')
6719
+ request = {
6720
+ 'instId': market['id'],
6721
+ 'mgnMode': marginMode,
6722
+ }
6723
+ if side is not None:
6724
+ if (side == 'buy'):
6725
+ request['posSide'] = 'long'
6726
+ elif side == 'sell':
6727
+ request['posSide'] = 'short'
6728
+ else:
6729
+ request['posSide'] = side
6730
+ if clientOrderId is not None:
6731
+ request['clOrdId'] = clientOrderId
6732
+ if code is not None:
6733
+ currency = self.currency(code)
6734
+ request['ccy'] = currency['id']
6735
+ response = await self.privatePostTradeClosePosition(self.extend(request, params))
6736
+ #
6737
+ # {
6738
+ # "code": "1",
6739
+ # "data": [
6740
+ # {
6741
+ # "clOrdId":"e847386590ce4dBCe903bbc394dc88bf",
6742
+ # "ordId":"",
6743
+ # "sCode":"51000",
6744
+ # "sMsg":"Parameter posSide error ",
6745
+ # "tag":"e847386590ce4dBC"
6746
+ # }
6747
+ # ],
6748
+ # "inTime": "1701877077101064",
6749
+ # "msg": "All operations failed",
6750
+ # "outTime": "1701877077102579"
6751
+ # }
6752
+ #
6753
+ data = self.safe_value(response, 'data')
6754
+ order = self.safe_value(data, 0)
6755
+ return self.parse_order(order, market)
6756
+
6695
6757
  def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
6696
6758
  if not response:
6697
6759
  return None # fallback to default error handler
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.1.82'
7
+ __version__ = '4.1.84'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -3847,7 +3847,7 @@ class Exchange(object):
3847
3847
  def fetch_funding_history(self, symbol: str = None, since: Int = None, limit: Int = None, params={}):
3848
3848
  raise NotSupported(self.id + ' fetchFundingHistory() is not supported yet')
3849
3849
 
3850
- def close_position(self, symbol: str, side: OrderSide = None, marginMode: str = None, params={}):
3850
+ def close_position(self, symbol: str, side: OrderSide = None, params={}):
3851
3851
  raise NotSupported(self.id + ' closePositions() is not supported yet')
3852
3852
 
3853
3853
  def close_all_positions(self, params={}):
ccxt/binance.py CHANGED
@@ -7938,7 +7938,7 @@ class binance(Exchange, ImplicitAPI):
7938
7938
  extendedParams = self.omit(extendedParams, ['orderidlist', 'origclientorderidlist'])
7939
7939
  query = self.rawencode(extendedParams)
7940
7940
  orderidlistLength = len(orderidlist)
7941
- origclientorderidlistLength = len(orderidlist)
7941
+ origclientorderidlistLength = len(origclientorderidlist)
7942
7942
  if orderidlistLength > 0:
7943
7943
  query = query + '&' + 'orderidlist=[' + ','.join(orderidlist) + ']'
7944
7944
  if origclientorderidlistLength > 0:
ccxt/bingx.py CHANGED
@@ -3171,7 +3171,7 @@ class bingx(Exchange, ImplicitAPI):
3171
3171
  :see: https://bitgetlimited.github.io/apidoc/en/mix/#close-all-position
3172
3172
  :param dict [params]: extra parameters specific to the okx api endpoint
3173
3173
  :param str [params.recvWindow]: request valid time window value
3174
- :returns [dict]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
3174
+ :returns dict[]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
3175
3175
  """
3176
3176
  self.load_markets()
3177
3177
  defaultRecvWindow = self.safe_integer(self.options, 'recvWindow')
ccxt/bitget.py CHANGED
@@ -6554,7 +6554,7 @@ class bitget(Exchange, ImplicitAPI):
6554
6554
  :param dict [params]: extra parameters specific to the okx api endpoint
6555
6555
  :param str [params.subType]: 'linear' or 'inverse'
6556
6556
  :param str [params.settle]: *required and only valid when params.subType == "linear"* 'USDT' or 'USDC'
6557
- :returns [dict]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
6557
+ :returns dict[]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
6558
6558
  """
6559
6559
  self.load_markets()
6560
6560
  subType = None
ccxt/bybit.py CHANGED
@@ -5366,8 +5366,10 @@ class bybit(Exchange, ImplicitAPI):
5366
5366
  raise ArgumentsRequired(self.id + ' fetchPositions() does not accept an array with more than one symbol')
5367
5367
  elif symbolsLength == 1:
5368
5368
  symbol = symbols[0]
5369
+ symbols = self.market_symbols(symbols)
5369
5370
  elif symbols is not None:
5370
5371
  symbol = symbols
5372
+ symbols = [self.symbol(symbol)]
5371
5373
  self.load_markets()
5372
5374
  enableUnifiedMargin, enableUnifiedAccount = self.is_unified_enabled()
5373
5375
  isUnifiedAccount = (enableUnifiedMargin or enableUnifiedAccount)
@@ -5376,12 +5378,11 @@ class bybit(Exchange, ImplicitAPI):
5376
5378
  isUsdcSettled = False
5377
5379
  if symbol is not None:
5378
5380
  market = self.market(symbol)
5381
+ symbol = market['symbol']
5379
5382
  request['symbol'] = market['id']
5380
5383
  isUsdcSettled = market['settle'] == 'USDC'
5381
5384
  type = None
5382
5385
  type, params = self.get_bybit_type('fetchPositions', market, params)
5383
- if type == 'spot':
5384
- raise NotSupported(self.id + ' fetchPositions() not support spot market')
5385
5386
  if type == 'linear' or type == 'inverse':
5386
5387
  baseCoin = self.safe_string(params, 'baseCoin')
5387
5388
  if type == 'linear':
ccxt/cex.py CHANGED
@@ -45,6 +45,9 @@ class cex(Exchange, ImplicitAPI):
45
45
  'cancelOrder': True,
46
46
  'cancelOrders': False,
47
47
  'createDepositAddress': False,
48
+ 'createMarketBuyOrderWithCost': True,
49
+ 'createMarketOrderWithCost': False,
50
+ 'createMarketSellOrderWithCost': False,
48
51
  'createOrder': True,
49
52
  'createStopLimitOrder': False,
50
53
  'createStopMarketOrder': False,
@@ -728,27 +731,39 @@ class cex(Exchange, ImplicitAPI):
728
731
  :param float amount: how much of currency you want to trade in units of base currency
729
732
  :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
730
733
  :param dict [params]: extra parameters specific to the exchange API endpoint
734
+ :param float [params.cost]: the quote quantity that can be used alternative for the amount for market buy orders
731
735
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
732
736
  """
733
- # for market buy it requires the amount of quote currency to spend
734
- if (type == 'market') and (side == 'buy'):
735
- if self.options['createMarketBuyOrderRequiresPrice']:
736
- if price is None:
737
- raise InvalidOrder(self.id + " createOrder() requires the price argument with market buy orders to calculate total order cost(amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = False to supply the cost in the amount argument(the exchange-specific behaviour)")
738
- else:
739
- amountString = self.number_to_string(amount)
740
- priceString = self.number_to_string(price)
741
- baseAmount = Precise.string_mul(amountString, priceString)
742
- amount = self.parse_number(baseAmount)
743
737
  self.load_markets()
744
738
  market = self.market(symbol)
745
739
  request = {
746
740
  'pair': market['id'],
747
741
  'type': side,
748
- 'amount': amount,
749
742
  }
743
+ # for market buy it requires the amount of quote currency to spend
744
+ if (type == 'market') and (side == 'buy'):
745
+ quoteAmount = None
746
+ createMarketBuyOrderRequiresPrice = True
747
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
748
+ cost = self.safe_string(params, 'cost')
749
+ params = self.omit(params, 'cost')
750
+ if cost is not None:
751
+ quoteAmount = self.cost_to_precision(symbol, cost)
752
+ elif createMarketBuyOrderRequiresPrice:
753
+ if price is None:
754
+ raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend in the amount argument')
755
+ else:
756
+ amountString = self.number_to_string(amount)
757
+ priceString = self.number_to_string(price)
758
+ costRequest = Precise.string_mul(amountString, priceString)
759
+ quoteAmount = self.cost_to_precision(symbol, costRequest)
760
+ else:
761
+ quoteAmount = self.cost_to_precision(symbol, amount)
762
+ request['amount'] = quoteAmount
763
+ else:
764
+ request['amount'] = self.amount_to_precision(symbol, amount)
750
765
  if type == 'limit':
751
- request['price'] = price
766
+ request['price'] = self.number_to_string(price)
752
767
  else:
753
768
  request['order_type'] = type
754
769
  response = self.privatePostPlaceOrderPair(self.extend(request, params))
ccxt/coinsph.py CHANGED
@@ -54,6 +54,9 @@ class coinsph(Exchange, ImplicitAPI):
54
54
  'closeAllPositions': False,
55
55
  'closePosition': False,
56
56
  'createDepositAddress': False,
57
+ 'createMarketBuyOrderWithCost': True,
58
+ 'createMarketOrderWithCost': False,
59
+ 'createMarketSellOrderWithCost': False,
57
60
  'createOrder': True,
58
61
  'createPostOnlyOrder': False,
59
62
  'createReduceOnlyOrder': False,
@@ -1028,12 +1031,14 @@ class coinsph(Exchange, ImplicitAPI):
1028
1031
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
1029
1032
  """
1030
1033
  create a trade order
1034
+ :see: https://coins-docs.github.io/rest-api/#new-order--trade
1031
1035
  :param str symbol: unified symbol of the market to create an order in
1032
1036
  :param str type: 'market', 'limit', 'stop_loss', 'take_profit', 'stop_loss_limit', 'take_profit_limit' or 'limit_maker'
1033
1037
  :param str side: 'buy' or 'sell'
1034
1038
  :param float amount: how much of currency you want to trade in units of base currency
1035
1039
  :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1036
1040
  :param dict [params]: extra parameters specific to the exchange API endpoint
1041
+ :param float [params.cost]: the quote quantity that can be used alternative for the amount for market buy orders
1037
1042
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1038
1043
  """
1039
1044
  # todo: add test order low priority
@@ -1065,20 +1070,24 @@ class coinsph(Exchange, ImplicitAPI):
1065
1070
  if orderSide == 'SELL':
1066
1071
  request['quantity'] = self.amount_to_precision(symbol, amount)
1067
1072
  elif orderSide == 'BUY':
1068
- quoteOrderQty = self.safe_number_2(params, 'cost', 'quoteOrderQty')
1069
- createMarketBuyOrderRequiresPrice = self.safe_value(self.options, 'createMarketBuyOrderRequiresPrice', True)
1070
- if quoteOrderQty is not None:
1071
- amount = quoteOrderQty
1073
+ quoteAmount = None
1074
+ createMarketBuyOrderRequiresPrice = True
1075
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
1076
+ cost = self.safe_number_2(params, 'cost', 'quoteOrderQty')
1077
+ params = self.omit(params, 'cost')
1078
+ if cost is not None:
1079
+ quoteAmount = self.cost_to_precision(symbol, cost)
1072
1080
  elif createMarketBuyOrderRequiresPrice:
1073
1081
  if price is None:
1074
- raise InvalidOrder(self.id + " createOrder() requires the price argument with market buy orders to calculate total order cost(amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = False to supply the cost in the amount argument(the exchange-specific behaviour)")
1082
+ raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend in the amount argument')
1075
1083
  else:
1076
1084
  amountString = self.number_to_string(amount)
1077
1085
  priceString = self.number_to_string(price)
1078
- quoteAmount = Precise.string_mul(amountString, priceString)
1079
- amount = self.parse_number(quoteAmount)
1080
- request['quoteOrderQty'] = self.cost_to_precision(symbol, amount)
1081
- params = self.omit(params, 'cost', 'quoteOrderQty')
1086
+ costRequest = Precise.string_mul(amountString, priceString)
1087
+ quoteAmount = self.cost_to_precision(symbol, costRequest)
1088
+ else:
1089
+ quoteAmount = self.cost_to_precision(symbol, amount)
1090
+ request['quoteOrderQty'] = quoteAmount
1082
1091
  if orderType == 'STOP_LOSS' or orderType == 'STOP_LOSS_LIMIT' or orderType == 'TAKE_PROFIT' or orderType == 'TAKE_PROFIT_LIMIT':
1083
1092
  stopPrice = self.safe_string_2(params, 'triggerPrice', 'stopPrice')
1084
1093
  if stopPrice is None:
ccxt/cryptocom.py CHANGED
@@ -48,6 +48,8 @@ class cryptocom(Exchange, ImplicitAPI):
48
48
  'cancelAllOrders': True,
49
49
  'cancelOrder': True,
50
50
  'cancelOrders': True,
51
+ 'closeAllPositions': False,
52
+ 'closePosition': True,
51
53
  'createOrder': True,
52
54
  'createOrders': True,
53
55
  'fetchAccounts': True,
@@ -2683,6 +2685,47 @@ class cryptocom(Exchange, ImplicitAPI):
2683
2685
  returnString += str(value)
2684
2686
  return returnString
2685
2687
 
2688
+ def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
2689
+ """
2690
+ closes open positions for a market
2691
+ :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-close-position
2692
+ :param str symbol: Unified CCXT market symbol
2693
+ :param str [marginMode]: not used by cryptocom.closePositions
2694
+ :param str [side]: not used by cryptocom.closePositions
2695
+ :param dict [params]: extra parameters specific to the okx api endpoint
2696
+ *
2697
+ * EXCHANGE SPECIFIC PARAMETERS
2698
+ :param str [params.type]: LIMIT or MARKET
2699
+ :param number [params.price]: for limit orders only
2700
+ :returns dict[]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
2701
+ """
2702
+ self.load_markets()
2703
+ market = self.market(symbol)
2704
+ request = {
2705
+ 'instrument_name': market['id'],
2706
+ 'type': 'MARKET',
2707
+ }
2708
+ type = self.safe_string_upper(params, 'type')
2709
+ price = self.safe_string(params, 'price')
2710
+ if type is not None:
2711
+ request['type'] = type
2712
+ if price is not None:
2713
+ request['price'] = self.price_to_precision(market['symbol'], price)
2714
+ response = self.v1PrivatePostPrivateClosePosition(self.extend(request, params))
2715
+ #
2716
+ # {
2717
+ # "id" : 1700830813298,
2718
+ # "method" : "private/close-position",
2719
+ # "code" : 0,
2720
+ # "result" : {
2721
+ # "client_oid" : "179a909d-5614-655b-0d0e-9e85c9a25c85",
2722
+ # "order_id" : "6142909897021751347"
2723
+ # }
2724
+ # }
2725
+ #
2726
+ result = self.safe_value(response, 'result')
2727
+ return self.parse_order(result, market)
2728
+
2686
2729
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
2687
2730
  type = self.safe_string(api, 0)
2688
2731
  access = self.safe_string(api, 1)
ccxt/htx.py CHANGED
@@ -56,6 +56,9 @@ class htx(Exchange, ImplicitAPI):
56
56
  'cancelOrder': True,
57
57
  'cancelOrders': True,
58
58
  'createDepositAddress': None,
59
+ 'createMarketBuyOrderWithCost': True,
60
+ 'createMarketOrderWithCost': False,
61
+ 'createMarketSellOrderWithCost': False,
59
62
  'createOrder': True,
60
63
  'createOrders': True,
61
64
  'createReduceOnlyOrder': False,
@@ -4535,6 +4538,22 @@ class htx(Exchange, ImplicitAPI):
4535
4538
  'trades': trades,
4536
4539
  }, market)
4537
4540
 
4541
+ def create_market_buy_order_with_cost(self, symbol: str, cost, params={}):
4542
+ """
4543
+ create a market buy order by providing the symbol and cost
4544
+ :see: https://www.htx.com/en-us/opend/newApiPages/?id=7ec4ee16-7773-11ed-9966-0242ac110003
4545
+ :param str symbol: unified symbol of the market to create an order in
4546
+ :param float cost: how much you want to trade in units of the quote currency
4547
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4548
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4549
+ """
4550
+ self.load_markets()
4551
+ market = self.market(symbol)
4552
+ if not market['spot']:
4553
+ raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
4554
+ params['createMarketBuyOrderRequiresPrice'] = False
4555
+ return self.create_order(symbol, 'market', 'buy', cost, None, params)
4556
+
4538
4557
  def create_spot_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
4539
4558
  """
4540
4559
  * @ignore
@@ -4546,6 +4565,7 @@ class htx(Exchange, ImplicitAPI):
4546
4565
  :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
4547
4566
  :param dict [params]: extra parameters specific to the exchange API endpoint
4548
4567
  :param str [params.timeInForce]: supports 'IOC' and 'FOK'
4568
+ :param float [params.cost]: the quote quantity that can be used alternative for the amount for market buy orders
4549
4569
  :returns dict: request to be sent to the exchange
4550
4570
  """
4551
4571
  self.load_markets()
@@ -4607,9 +4627,16 @@ class htx(Exchange, ImplicitAPI):
4607
4627
  elif marginMode == 'c2c':
4608
4628
  request['source'] = 'c2c-margin-api'
4609
4629
  if (orderType == 'market') and (side == 'buy'):
4610
- if self.options['createMarketBuyOrderRequiresPrice']:
4630
+ quoteAmount = None
4631
+ createMarketBuyOrderRequiresPrice = True
4632
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
4633
+ cost = self.safe_number(params, 'cost')
4634
+ params = self.omit(params, 'cost')
4635
+ if cost is not None:
4636
+ quoteAmount = self.amount_to_precision(symbol, cost)
4637
+ elif createMarketBuyOrderRequiresPrice:
4611
4638
  if price is None:
4612
- raise InvalidOrder(self.id + " market buy order requires price argument to calculate cost(total amount of quote currency to spend for buying, amount * price). To switch off self warning exception and specify cost in the amount argument, set .options['createMarketBuyOrderRequiresPrice'] = False. Make sure you know what you're doing.")
4639
+ raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend in the amount argument')
4613
4640
  else:
4614
4641
  # despite that cost = amount * price is in quote currency and should have quote precision
4615
4642
  # the exchange API requires the cost supplied in 'amount' to be of base precision
@@ -4619,9 +4646,10 @@ class htx(Exchange, ImplicitAPI):
4619
4646
  # we use amountToPrecision here because the exchange requires cost in base precision
4620
4647
  amountString = self.number_to_string(amount)
4621
4648
  priceString = self.number_to_string(price)
4622
- request['amount'] = self.cost_to_precision(symbol, Precise.string_mul(amountString, priceString))
4649
+ quoteAmount = self.amount_to_precision(symbol, Precise.string_mul(amountString, priceString))
4623
4650
  else:
4624
- request['amount'] = self.cost_to_precision(symbol, amount)
4651
+ quoteAmount = self.amount_to_precision(symbol, amount)
4652
+ request['amount'] = quoteAmount
4625
4653
  else:
4626
4654
  request['amount'] = self.amount_to_precision(symbol, amount)
4627
4655
  limitOrderTypes = self.safe_value(options, 'limitOrderTypes', {})
@@ -4731,6 +4759,7 @@ class htx(Exchange, ImplicitAPI):
4731
4759
  :param bool [params.postOnly]: *contract only* True or False
4732
4760
  :param int [params.leverRate]: *contract only* required for all contract orders except tpsl, leverage greater than 20x requires prior approval of high-leverage agreement
4733
4761
  :param str [params.timeInForce]: supports 'IOC' and 'FOK'
4762
+ :param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
4734
4763
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4735
4764
  """
4736
4765
  self.load_markets()
ccxt/huobijp.py CHANGED
@@ -16,6 +16,7 @@ from ccxt.base.errors import BadSymbol
16
16
  from ccxt.base.errors import InsufficientFunds
17
17
  from ccxt.base.errors import InvalidOrder
18
18
  from ccxt.base.errors import OrderNotFound
19
+ from ccxt.base.errors import NotSupported
19
20
  from ccxt.base.errors import NetworkError
20
21
  from ccxt.base.errors import ExchangeNotAvailable
21
22
  from ccxt.base.errors import OnMaintenance
@@ -49,6 +50,9 @@ class huobijp(Exchange, ImplicitAPI):
49
50
  'cancelAllOrders': True,
50
51
  'cancelOrder': True,
51
52
  'cancelOrders': True,
53
+ 'createMarketBuyOrderWithCost': True,
54
+ 'createMarketOrderWithCost': False,
55
+ 'createMarketSellOrderWithCost': False,
52
56
  'createOrder': True,
53
57
  'createStopLimitOrder': False,
54
58
  'createStopMarketOrder': False,
@@ -1301,6 +1305,21 @@ class huobijp(Exchange, ImplicitAPI):
1301
1305
  'trades': None,
1302
1306
  }, market)
1303
1307
 
1308
+ def create_market_buy_order_with_cost(self, symbol: str, cost, params={}):
1309
+ """
1310
+ create a market buy order by providing the symbol and cost
1311
+ :param str symbol: unified symbol of the market to create an order in
1312
+ :param float cost: how much you want to trade in units of the quote currency
1313
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1314
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1315
+ """
1316
+ self.load_markets()
1317
+ market = self.market(symbol)
1318
+ if not market['spot']:
1319
+ raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
1320
+ params['createMarketBuyOrderRequiresPrice'] = False
1321
+ return self.create_order(symbol, 'market', 'buy', cost, None, params)
1322
+
1304
1323
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
1305
1324
  """
1306
1325
  create a trade order
@@ -1329,9 +1348,16 @@ class huobijp(Exchange, ImplicitAPI):
1329
1348
  request['client-order-id'] = clientOrderId
1330
1349
  params = self.omit(params, ['clientOrderId', 'client-order-id'])
1331
1350
  if (type == 'market') and (side == 'buy'):
1332
- if self.options['createMarketBuyOrderRequiresPrice']:
1351
+ quoteAmount = None
1352
+ createMarketBuyOrderRequiresPrice = True
1353
+ createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
1354
+ cost = self.safe_number(params, 'cost')
1355
+ params = self.omit(params, 'cost')
1356
+ if cost is not None:
1357
+ quoteAmount = self.amount_to_precision(symbol, cost)
1358
+ elif createMarketBuyOrderRequiresPrice:
1333
1359
  if price is None:
1334
- raise InvalidOrder(self.id + " market buy order requires price argument to calculate cost(total amount of quote currency to spend for buying, amount * price). To switch off self warning exception and specify cost in the amount argument, set .options['createMarketBuyOrderRequiresPrice'] = False. Make sure you know what you're doing.")
1360
+ raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend in the amount argument')
1335
1361
  else:
1336
1362
  # despite that cost = amount * price is in quote currency and should have quote precision
1337
1363
  # the exchange API requires the cost supplied in 'amount' to be of base precision
@@ -1341,10 +1367,10 @@ class huobijp(Exchange, ImplicitAPI):
1341
1367
  # we use amountToPrecision here because the exchange requires cost in base precision
1342
1368
  amountString = self.number_to_string(amount)
1343
1369
  priceString = self.number_to_string(price)
1344
- baseAmount = Precise.string_mul(amountString, priceString)
1345
- request['amount'] = self.cost_to_precision(symbol, baseAmount)
1370
+ quoteAmount = self.amount_to_precision(symbol, Precise.string_mul(amountString, priceString))
1346
1371
  else:
1347
- request['amount'] = self.cost_to_precision(symbol, amount)
1372
+ quoteAmount = self.amount_to_precision(symbol, amount)
1373
+ request['amount'] = quoteAmount
1348
1374
  else:
1349
1375
  request['amount'] = self.amount_to_precision(symbol, amount)
1350
1376
  if type == 'limit' or type == 'ioc' or type == 'limit-maker' or type == 'stop-limit' or type == 'stop-limit-fok':
ccxt/okx.py CHANGED
@@ -56,6 +56,8 @@ class okx(Exchange, ImplicitAPI):
56
56
  'cancelAllOrders': False,
57
57
  'cancelOrder': True,
58
58
  'cancelOrders': True,
59
+ 'closeAllPositions': False,
60
+ 'closePosition': True,
59
61
  'createDepositAddress': False,
60
62
  'createMarketBuyOrderWithCost': True,
61
63
  'createMarketSellOrderWithCost': True,
@@ -6691,6 +6693,66 @@ class okx(Exchange, ImplicitAPI):
6691
6693
  'info': greeks,
6692
6694
  }
6693
6695
 
6696
+ def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
6697
+ """
6698
+ closes open positions for a market
6699
+ :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-close-positions
6700
+ :param str symbol: Unified CCXT market symbol
6701
+ :param str [side]: 'buy' or 'sell', leave in net mode
6702
+ :param dict [params]: extra parameters specific to the okx api endpoint
6703
+ :param str [params.clientOrderId]: a unique identifier for the order
6704
+ :param str [params.marginMode]: 'cross' or 'isolated', default is 'cross
6705
+ :param str [params.code]: *required in the case of closing cross MARGIN position for Single-currency margin* margin currency
6706
+ *
6707
+ * EXCHANGE SPECIFIC PARAMETERS
6708
+ :param boolean [params.autoCxl]: whether any pending orders for closing out needs to be automatically canceled when close position via a market order. False or True, the default is False
6709
+ :param str [params.tag]: order tag a combination of case-sensitive alphanumerics, all numbers, or all letters of up to 16 characters
6710
+ :returns [dict]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
6711
+ """
6712
+ self.load_markets()
6713
+ market = self.market(symbol)
6714
+ clientOrderId = self.safe_string(params, 'clientOrderId')
6715
+ code = self.safe_string(params, 'code')
6716
+ marginMode = None
6717
+ marginMode, params = self.handle_margin_mode_and_params('closePosition', params, 'cross')
6718
+ request = {
6719
+ 'instId': market['id'],
6720
+ 'mgnMode': marginMode,
6721
+ }
6722
+ if side is not None:
6723
+ if (side == 'buy'):
6724
+ request['posSide'] = 'long'
6725
+ elif side == 'sell':
6726
+ request['posSide'] = 'short'
6727
+ else:
6728
+ request['posSide'] = side
6729
+ if clientOrderId is not None:
6730
+ request['clOrdId'] = clientOrderId
6731
+ if code is not None:
6732
+ currency = self.currency(code)
6733
+ request['ccy'] = currency['id']
6734
+ response = self.privatePostTradeClosePosition(self.extend(request, params))
6735
+ #
6736
+ # {
6737
+ # "code": "1",
6738
+ # "data": [
6739
+ # {
6740
+ # "clOrdId":"e847386590ce4dBCe903bbc394dc88bf",
6741
+ # "ordId":"",
6742
+ # "sCode":"51000",
6743
+ # "sMsg":"Parameter posSide error ",
6744
+ # "tag":"e847386590ce4dBC"
6745
+ # }
6746
+ # ],
6747
+ # "inTime": "1701877077101064",
6748
+ # "msg": "All operations failed",
6749
+ # "outTime": "1701877077102579"
6750
+ # }
6751
+ #
6752
+ data = self.safe_value(response, 'data')
6753
+ order = self.safe_value(data, 0)
6754
+ return self.parse_order(order, market)
6755
+
6694
6756
  def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
6695
6757
  if not response:
6696
6758
  return None # fallback to default error handler
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.1.82'
7
+ __version__ = '4.1.84'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ccxt
3
- Version: 4.1.82
3
+ Version: 4.1.84
4
4
  Summary: A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 130+ exchanges
5
5
  Home-page: https://ccxt.com
6
6
  Author: Igor Kroitor
@@ -258,13 +258,13 @@ console.log(version, Object.keys(exchanges));
258
258
 
259
259
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
260
260
 
261
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.1.82/dist/ccxt.browser.js
262
- * unpkg: https://unpkg.com/ccxt@4.1.82/dist/ccxt.browser.js
261
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.1.84/dist/ccxt.browser.js
262
+ * unpkg: https://unpkg.com/ccxt@4.1.84/dist/ccxt.browser.js
263
263
 
264
264
  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.
265
265
 
266
266
  ```HTML
267
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.1.82/dist/ccxt.browser.js"></script>
267
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.1.84/dist/ccxt.browser.js"></script>
268
268
  ```
269
269
 
270
270
  Creates a global `ccxt` object:
@@ -1,14 +1,14 @@
1
- ccxt/__init__.py,sha256=PUXnx5A3khro0JqLS_jx3LJFgWjVDM03sHSMx2Kte_s,15081
1
+ ccxt/__init__.py,sha256=-7gemumtcpcufGkxg_rEKsE1C55aBy7JUFKvjpHTBoA,15081
2
2
  ccxt/ace.py,sha256=bB8RjymWAEI2MYEHMW70GwbIowmOMN9r4RY1tlj4gjY,41348
3
3
  ccxt/alpaca.py,sha256=Tnc7yGp1b1iRLCZiR14iphBLEe5_01vZdbZsoy3FRao,46028
4
4
  ccxt/ascendex.py,sha256=EQjZX2RRa2vBCIPnKsfaRpam9MCEGHe_zWOwMkGJ_b0,143331
5
5
  ccxt/bequant.py,sha256=O9tDvk7O1De-k3-G5lwXUVoNqzgfo_AJqQy4bXifdhM,1148
6
6
  ccxt/bigone.py,sha256=yMtRGGNuf_cAP5ISEkq_DzILRusim8aQkKWpA5LpFsM,79464
7
- ccxt/binance.py,sha256=jIPu6e63jpirjppsCYNTLuRGR9mN5ybPnKT5_9z0yHM,444225
7
+ ccxt/binance.py,sha256=1XAu6exZKTGVd3sotTWQwghQbffYqgjYbZ8HAkXdpd4,444235
8
8
  ccxt/binancecoinm.py,sha256=pncdw6Xw2X1Po-vEvAB4nL37scoS_axGAVxetPy1YQs,1645
9
9
  ccxt/binanceus.py,sha256=VuAty9YMKtrRhPzu9uN9OtLpEcTuih_rwW5y24QILkU,3554
10
10
  ccxt/binanceusdm.py,sha256=KPQGlCalQ0eGlPCs2tSanOxaP8O0zFRQjGntA16Yprw,2480
11
- ccxt/bingx.py,sha256=RVq3AFEYfnSd_7QKE0PmZ5j-byFxO-7e22y1H9tj1ks,136912
11
+ ccxt/bingx.py,sha256=ZEUU2co4uFAxztU0uYeQHIMI-RjCW3lJytoaEaAXmEU,136912
12
12
  ccxt/bit2c.py,sha256=hIqfedh-2SauVWQnhiZyuS4sf9dy-NApYL7USMayqKo,36068
13
13
  ccxt/bitbank.py,sha256=eGEd_9eGcSJHCRpSETeqvJQJoiguLU-nLZrkq3nVze4,41604
14
14
  ccxt/bitbay.py,sha256=xAIjzGRDVGwoy-Gygd99H0YN4wiaz_0lR0Z14oxaaxc,478
@@ -18,7 +18,7 @@ ccxt/bitfinex.py,sha256=jZaKtVwezPEjvRmPI1P2hvBKLmHzz3BysCiXJjprfyw,69725
18
18
  ccxt/bitfinex2.py,sha256=6fxd__vHHZ0CjXWLrg2JShLkoT8Szdm3ueT-rYX_ZRE,128904
19
19
  ccxt/bitflyer.py,sha256=q-lKdcT9mZ6jdswP4AGIj_6yhKxcCXyePueTd_nrmAk,40105
20
20
  ccxt/bitforex.py,sha256=pdgV_sR-qHkMUBmASOSGinbmGCn0FKZN10hJgwXlY0Y,33761
21
- ccxt/bitget.py,sha256=ZVOWEubby6FyZUIpCdSrmtHX1xjnTSP5TtdYN9VIUT8,336863
21
+ ccxt/bitget.py,sha256=MBw-1oFzTlh3jBclt5CsO0AS5HCf_PblhAmZBXOeDXE,336863
22
22
  ccxt/bithumb.py,sha256=mji93l7rEBQVhoJKxHQnEIMtMvk7wkIRrfN7o0hxYPI,43325
23
23
  ccxt/bitmart.py,sha256=HetfUULwuQU-0FDQ44D7Lk_qnbxPtMIg8kaLkEstCFo,183673
24
24
  ccxt/bitmex.py,sha256=YK2AOrNmvWcxVdNwh33Zv86U1MUjpD3qHARKn1ZJ0WY,119673
@@ -35,8 +35,8 @@ ccxt/btcalpha.py,sha256=TxEyASsptUwEXr1sQBM4Fc2RZy_iZOrQ8SMwo6iPXN0,35628
35
35
  ccxt/btcbox.py,sha256=ZrOJ_VC4n5113Sn2C1whQZTAhMxX5gYYe0QoayvvmKY,22849
36
36
  ccxt/btcmarkets.py,sha256=d9il29c2YsdPO56SKy1WsfxuILIHxQJRF-fVJ37rl4E,48582
37
37
  ccxt/btcturk.py,sha256=j51LBBkUqnikl6Xa7AZ1Wl8XAvA_KnFLzb42dMZoSds,35458
38
- ccxt/bybit.py,sha256=vWITFdYmYJVqUx2NylvdthFXBmvzU9mMNnKluxelJU4,354600
39
- ccxt/cex.py,sha256=XCdjEFY0ulfeUucO4rKZnVHXSl6wESq9u_FujLGGuB8,68727
38
+ ccxt/bybit.py,sha256=sq8hijZGNPv44EIEU5s-7EZixIb6i1p9hZ0Up-TW6Hc,354620
39
+ ccxt/cex.py,sha256=vz2cWRDEOLVBJQOWEFK4CwuASndkUe8ZmgIw80v0sAE,69502
40
40
  ccxt/coinbase.py,sha256=AoSEUwJ_jFVjByN_72lTm-NwP7y2G6Az4cZ5kL-q8T8,145521
41
41
  ccxt/coinbaseprime.py,sha256=Ygvljulxb2uKdei5yimCj1LMjLlUJNvP-G7ns1HpUFk,1219
42
42
  ccxt/coinbasepro.py,sha256=gpe6UVg4pDDpvzjVGE_fKeoDmkdIyzNucANptY9FeH8,80087
@@ -45,9 +45,9 @@ ccxt/coinex.py,sha256=rckWclZBEV3S512geUL0HPSAOZWwv9tO9-Sr4xIdlKo,221860
45
45
  ccxt/coinlist.py,sha256=636Ggz7GYKg5HSdamAlVZtepdVfIcTI0dE4kQv0_1VA,102234
46
46
  ccxt/coinmate.py,sha256=CpLkuF-T12P_q-W-nYrnl4PXcHjnGKt8us66ebHSFtI,39954
47
47
  ccxt/coinone.py,sha256=LE5LfNq5q6Ryg7Rw6FNSIpimvQAcDFIm8vpDfnMu-nA,35708
48
- ccxt/coinsph.py,sha256=nqOmK8QDR7C6mRMCwJ9S3v4jzP9KF0Q9FsAlNlhJbmc,88364
48
+ ccxt/coinsph.py,sha256=JMJJaMdi3p7s0W5ziZB5m_wIZaUFEX1s0d9WxOi0KGk,88759
49
49
  ccxt/coinspot.py,sha256=j8xSGIHF_WhLGZcDmdIwpCMw77vjvdaNcNNk0_kEu-Y,23024
50
- ccxt/cryptocom.py,sha256=oRx7itDTf4lkGbhXa2nf1oRQRSCSQvn0jcmyoIAOv4c,125495
50
+ ccxt/cryptocom.py,sha256=qJsrkJTr2nUTfR4Hg_omBQVB_5X_BIY8tgrf-I9dhwY,127359
51
51
  ccxt/currencycom.py,sha256=JqJEzS_6UBomIGqf_y5LwsnBTOXCwbgiQfnSghvIGuU,84218
52
52
  ccxt/delta.py,sha256=qdmqSJ_P2S0eOiodtcquSd9LxTGwt1uWMMRGamVgmbw,138693
53
53
  ccxt/deribit.py,sha256=sRg16zOi9PGxaexxsa9ewCEeknFvM7OHqd2fp77GmgQ,143732
@@ -61,9 +61,9 @@ ccxt/gemini.py,sha256=uKUl5-1e1fXUmTgItn_CiIa9oyCxzhCe1QtgdWTi9Uw,74637
61
61
  ccxt/hitbtc.py,sha256=jh4tPgRzycCffo0zXDAcv8yKKMXg9z8Wjtdzj6Ds0g4,148532
62
62
  ccxt/hitbtc3.py,sha256=qRAr4Zvaju9IQWRZUohdoN7xRnzIMPq8AyYb3gPv-Is,455
63
63
  ccxt/hollaex.py,sha256=Be8erGcnmxZGOdlgmSmsJSVq4xf9_zIgW5Epg6_cbkI,74416
64
- ccxt/htx.py,sha256=R7Vx155ym55bU_W3oCVQDJ9I0kPDW0EvG2P8ETCqPpw,394566
64
+ ccxt/htx.py,sha256=80nSWtjUqrBi6Lmo4-DQGpHq3Dm2le5rVarrvygIqw8,396320
65
65
  ccxt/huobi.py,sha256=4vaG7IRN7fyjaJ_ac6S-njlHOfSEN5de7aq0noznxYw,438
66
- ccxt/huobijp.py,sha256=2grbjVCLn5zGfyF6IVCQEEaGYnmNyy5fM8LeO54pnTw,86489
66
+ ccxt/huobijp.py,sha256=22xidSkRT0KKKo_lrntNh0TJivI3OWS_X4JeqAu7Azc,87899
67
67
  ccxt/idex.py,sha256=gBerY3h1aZQ4UuuVcBaPOkaqMTTDSYlnHDhdPrGWfck,68258
68
68
  ccxt/independentreserve.py,sha256=GjkE6vVy6jaOPgrfi44WTk5dSKS7-p7cY8DuPzLcfMA,29918
69
69
  ccxt/indodax.py,sha256=70M5Vi9cRq-tmB33SagjCnQSatdMuKQN6N7iaKB69gI,42749
@@ -82,7 +82,7 @@ ccxt/ndax.py,sha256=sVd5ZqZf1UnOlF58WNBMp-8mgT7qbchDz59w8E_I_GQ,107204
82
82
  ccxt/novadax.py,sha256=M_aaFcbm5lgFYXG2iM5IRadiN4bjgTtOhyxdOw1nCJc,63225
83
83
  ccxt/oceanex.py,sha256=aEnK9rjZYACIw_heL0NQ9AsvxlTq2dnhXx_LTkZyIgw,37630
84
84
  ccxt/okcoin.py,sha256=nv6n4Hu0rQcD2vzgxEQXgxIEfZUXL0OX0QFPLidqUWU,145598
85
- ccxt/okx.py,sha256=EOOP8efIq78hvNSUAR73OtNWWo6XGeHMrKw3npPyevM,324241
85
+ ccxt/okx.py,sha256=f9TUgTwJ2YJN__eSVLkxEbTSEMpZVP78djr1mjAA5xc,327196
86
86
  ccxt/p2b.py,sha256=drrJDIulMgC3ZicZTTCNQuiHJ4Q5yWKQZp8WglUmrjA,54043
87
87
  ccxt/paymium.py,sha256=oH4zQkMF7IGkq9co953Riz8wuhUj6xxKSmqs7Rz2n1s,24122
88
88
  ccxt/phemex.py,sha256=LgkusilxAEpZazFkIaiUbRX4RF4hOMHlpYctVtqZQ1Q,205280
@@ -199,17 +199,17 @@ ccxt/abstract/woo.py,sha256=xilL7EbvUmJ_zBb_r1Q7cTi4bHsBQN2mFu0TGu7WHG0,8890
199
199
  ccxt/abstract/yobit.py,sha256=8ycfCO8ORFly9hc0Aa47sZyX4_ZKPXS9h9yJzI-uQ7Q,1339
200
200
  ccxt/abstract/zaif.py,sha256=m15WHdl3gYy0GOXNZ8NEH8eE7sVh8c0T_ITNuU8vXeU,3935
201
201
  ccxt/abstract/zonda.py,sha256=aSfewvRojzmuymX6QbOnDR8v9VFqWTULMHX9Y7kKD1M,5820
202
- ccxt/async_support/__init__.py,sha256=voL5kKcsI2NOjHZm3kUcnbkwmasNmKnDsr39IlccYi8,14794
202
+ ccxt/async_support/__init__.py,sha256=9ODMCvlOp0WFkqRtXSe1AtcaDrHOLUBWZwvhE3CES-E,14794
203
203
  ccxt/async_support/ace.py,sha256=5fHmmLyH7G-Dh0RvvHYmO7X6kmuMlanS4LmD_RqX8-s,41572
204
204
  ccxt/async_support/alpaca.py,sha256=Hx87_BHTcOWoyogACXP1OoBWIMGq9TuuN4AfpGeKjVI,46240
205
205
  ccxt/async_support/ascendex.py,sha256=GHeezJpE30VFKhVC-AKtLM5GJsGav0nNgCrvlRkN5gE,144071
206
206
  ccxt/async_support/bequant.py,sha256=kLA0e9URC1rDEHgpb61pEGAn5jZXzE715lEcJjPdLRo,1162
207
207
  ccxt/async_support/bigone.py,sha256=ZMIngs1xG4GrxQHp_L7k8t6hb0Ps21SXtvOU7hE4mQA,79862
208
- ccxt/async_support/binance.py,sha256=HP2EYa_FLXG14dLIxaA-5Yp31NGMmMWbOLRbZXM2Aes,445771
208
+ ccxt/async_support/binance.py,sha256=UiTeeXuhcbn12BE711WEgl2vlLY_fVRA3_NMhI0w3YI,445781
209
209
  ccxt/async_support/binancecoinm.py,sha256=IY3RLZptQA2nmZaUYRGfTa5ZY4VMWBpFYfwHc8zTHw0,1683
210
210
  ccxt/async_support/binanceus.py,sha256=ENoZ52LuAo4x-OLdAlXJvEdD3VjofqWQpUzgiGoSZIw,3568
211
211
  ccxt/async_support/binanceusdm.py,sha256=-1r4A4tmV2pCiLGO80hzq7MIIj4MTzOD7buZGv6JauA,2518
212
- ccxt/async_support/bingx.py,sha256=yhRZPUluhAvHsEkETXqtqPxWMms54HfZbiu5dc5MMWg,137738
212
+ ccxt/async_support/bingx.py,sha256=-a87SAo1KCypkj-_0GUNc4PUCgw1ngcf-TYxaC4-lfs,137738
213
213
  ccxt/async_support/bit2c.py,sha256=yl5ur2ejyyxTSoc5_Bj8LNWx_GhK9Aows-v9NZuu8x0,36274
214
214
  ccxt/async_support/bitbank.py,sha256=rUeL8JyeagI5HOy00UrTPvwB2xFX6Rf0rwXhoXK3oEs,41864
215
215
  ccxt/async_support/bitbay.py,sha256=jcaEXi2IhYTva8ezO_SfJhwxEZk7HST4J3NaxD16BQA,492
@@ -219,7 +219,7 @@ ccxt/async_support/bitfinex.py,sha256=PNzSR9cYWQRIsTG4uz6tcYg0jrH0nqH2N7WDtbVUEX
219
219
  ccxt/async_support/bitfinex2.py,sha256=A1krXmnYd8UsQwPYgqzU_lYYxx8mjHbFih61_i6EeAI,129464
220
220
  ccxt/async_support/bitflyer.py,sha256=mmoPJEr2nBxfthieD8rLH7gxo0Wn5c_FkRm4DD5_1Ns,40413
221
221
  ccxt/async_support/bitforex.py,sha256=B0YnnDV8OCcY9VPY3UXo4DBZ8QF9xYH1jHNdBFi7ZfQ,33985
222
- ccxt/async_support/bitget.py,sha256=isBW1WPcfM_SjjPu139rxfdXWN-B_9JzrcECXIQd-Xs,338295
222
+ ccxt/async_support/bitget.py,sha256=jI2QrGQYPMRdQ2Rn1R-hRHFXBwHB3QL6Lw0LCdk5Cio,338295
223
223
  ccxt/async_support/bithumb.py,sha256=D2vQybc5kOv5S5VfwQUjw2Ri_tvItfZkzw4FW3TlGvo,43543
224
224
  ccxt/async_support/bitmart.py,sha256=qdFTP-Y5c9KcCn8D45hXfrot2Ph5V2XV8dAc6hJCBjY,184581
225
225
  ccxt/async_support/bitmex.py,sha256=3JhJOASP0TF4rwJlsXdW5yrA2EKZKjqDxDfSSV3otHY,120215
@@ -236,8 +236,8 @@ ccxt/async_support/btcalpha.py,sha256=7OVYRu01mPKOnn73NrVT5TTO1QnvVJsqEi0TVS-63R
236
236
  ccxt/async_support/btcbox.py,sha256=EywXOm_odHotrJdsaGMYfB3n3jKCIai0pWbShX-Z06I,23043
237
237
  ccxt/async_support/btcmarkets.py,sha256=i1H6KESr8nL7xDuFqmRvy0VQmHnAKrQkD_RPP7ZtV2Y,48932
238
238
  ccxt/async_support/btcturk.py,sha256=3zAGyyBqjTTbMhQNijsf5C9I1CdpElWz8B8gOkNYYCM,35676
239
- ccxt/async_support/bybit.py,sha256=iTaPFj-OVSMV54-Pb7WLmPhhRFKftW9IzSqibSaQaRg,356062
240
- ccxt/async_support/cex.py,sha256=Y7BhBRl240JStGJc9PeeVWP2Q4ESiQyUtAnPfbd1Vyw,69071
239
+ ccxt/async_support/bybit.py,sha256=TVEMQDXryopx-gmaXBKwdMIBvyglu2tpuRi-cO2EO1w,356082
240
+ ccxt/async_support/cex.py,sha256=cQEKg7b7m8StCLiAqTqIgzJ_3j6LcTxG0gFO_x_fLTs,69846
241
241
  ccxt/async_support/coinbase.py,sha256=Me7cHM8OFnVDwYwxNk9yWdEYaQJ3yJ765IVXIA93wYY,146303
242
242
  ccxt/async_support/coinbaseprime.py,sha256=M5Ez1DsFcW3-vJ-4QoZzwYBAKjAAtJnJpkfnV4sWAIc,1233
243
243
  ccxt/async_support/coinbasepro.py,sha256=yfHm6Hx0afMSogFlNLtKPc38YPip1l211285XYewRfk,80611
@@ -246,9 +246,9 @@ ccxt/async_support/coinex.py,sha256=BGmhU8ObgFJVyEHLWvrUKO5xw_GjqyULCMGJeabF-48,
246
246
  ccxt/async_support/coinlist.py,sha256=SmRsjnXZez2P6_7yWhKiBa8pQFVAGdZneIMO3fnbi9o,102722
247
247
  ccxt/async_support/coinmate.py,sha256=BGiq-0tma9yngBGGyXoqDVRhiVfUxOo_IfKpX9h-pv0,40202
248
248
  ccxt/async_support/coinone.py,sha256=VywuP8WcZonpRAj4pB99RJNpaGSTvGtVBuKN1eR__K0,35932
249
- ccxt/async_support/coinsph.py,sha256=08JYv2_F6lPAiiTslHzZ-yq5SboDtqxDYAXkq614jdQ,88786
249
+ ccxt/async_support/coinsph.py,sha256=pbUu4dbT30LWmFBZKcIBFJXKjjPCYN0GxQtYa3fUsJc,89181
250
250
  ccxt/async_support/coinspot.py,sha256=py_wOzt-2jYuD6W8LyD9Vtij2NbwcfmTAJRb-tPJUa0,23176
251
- ccxt/async_support/cryptocom.py,sha256=1ek7rf_qFTXHgg0TNYw9E6ozr0U6jwgJRpML4EP3nJI,126031
251
+ ccxt/async_support/cryptocom.py,sha256=vmxtGU7RmeHiJKNCyvDpLzjf6Shjdt7bMwjQ4LzbKhw,127913
252
252
  ccxt/async_support/currencycom.py,sha256=1b_wbCu-M74vRVpTQHBc7ELkWP0YEtPBm0axIGJ7yEs,84640
253
253
  ccxt/async_support/delta.py,sha256=Bh7341LXF70gqLe5NfbP76-a1vWP8Kf5Aa_DH05rnH0,139241
254
254
  ccxt/async_support/deribit.py,sha256=62Z2o98VFpB-5q2m71lXb4PO-IHXN38OD8SCjr5zGvo,144406
@@ -262,9 +262,9 @@ ccxt/async_support/gemini.py,sha256=n9DU6a648p32Wfcb6z9hQ8swQFq-BXTWY7dA1BXPUBk,
262
262
  ccxt/async_support/hitbtc.py,sha256=liXx0nqtWQB1AL5gnYcumPUt1ZzjumWJxvzlsDLuyJM,149566
263
263
  ccxt/async_support/hitbtc3.py,sha256=dmSYoD2o4av_zzbZI8HNIoj8BWxA7QozsVpy8JaOXzU,469
264
264
  ccxt/async_support/hollaex.py,sha256=XftSb4pI6PhLJClM34Im7XVqzuzPRWNKPjDiYUZvIFA,74850
265
- ccxt/async_support/htx.py,sha256=_3U-7aIiV1FOmLiEqbHNWZayUl-dqFofKTv98l11JQo,396280
265
+ ccxt/async_support/htx.py,sha256=Iuj82yxE7LcY9xAPBR1wS3fTne1zSpxwaTZ351Z3xEY,398052
266
266
  ccxt/async_support/huobi.py,sha256=fup0j6wQ1khAtfbb1H4CSyJAOzhxuoHMmrM6sgTuhr8,452
267
- ccxt/async_support/huobijp.py,sha256=a1jmkSALXTfKgpsXwATdIU08u8QhqyaToTeNbuOHfG4,86971
267
+ ccxt/async_support/huobijp.py,sha256=IIExVoDzxnQqhel296-CMKZiO3yQPle7YUc2bNHdg_0,88399
268
268
  ccxt/async_support/idex.py,sha256=gBc4Ps3iYtImjQlRb_QTFG05kKsA6R3uYu9bHzZUI58,68704
269
269
  ccxt/async_support/independentreserve.py,sha256=291UiW2vFfXKjnalGOm74w8kukLgVQqQ0fsTLiwdO80,30154
270
270
  ccxt/async_support/indodax.py,sha256=vF2P5PagGBUvXIyzTJ-D8ba2USy8q4uZ59Zq1fD6ZNs,43021
@@ -283,7 +283,7 @@ ccxt/async_support/ndax.py,sha256=zK8hVmTJwum2ilEOyjHpq44M3nyePE2xiEgfsD0m_n8,10
283
283
  ccxt/async_support/novadax.py,sha256=ovj8kj6bN2hjTNeH3UpjR7SKzmQGuNATI_02J6Fy9Ns,63593
284
284
  ccxt/async_support/oceanex.py,sha256=fvjFGdRVza2wPzwLCeShmf9ujJfsoSG2mieY-jiPxXU,37950
285
285
  ccxt/async_support/okcoin.py,sha256=S06CKWHUzXM8GCRV0RgWzG0IOfPHs6HVYIy4KznHoIo,146080
286
- ccxt/async_support/okx.py,sha256=AN5alnF5yZifhm1qJC7NMp5HFR05LQTaVmMWdzezLd8,325588
286
+ ccxt/async_support/okx.py,sha256=oliD76GqjCYTPB2SSZwK4LuSjlNXT3IiOl7-LWywAS4,328561
287
287
  ccxt/async_support/p2b.py,sha256=c5EU7roZl3hfIqznpNgl7HtTLtSwb6hNy8b2j31EuV0,54285
288
288
  ccxt/async_support/paymium.py,sha256=ytSECSpo34-Uz_AcKYmcXgfewmymtBEspkHlVyHLPAE,24310
289
289
  ccxt/async_support/phemex.py,sha256=bwvM7vG3aQ4aWYa07LnOyvaopaRS94rXp9dmz6XmQiI,206062
@@ -301,7 +301,7 @@ ccxt/async_support/yobit.py,sha256=d9bkNQqL47g7zwt4g_PnhoTQETISVwL8TfhmInvKvkU,5
301
301
  ccxt/async_support/zaif.py,sha256=-YCjZLw87m9m-JXxUCr6AEC8KfnNX8b7IVSv5caW3QQ,28158
302
302
  ccxt/async_support/zonda.py,sha256=huZYyfwcqQ6kxkxnkf7CW0nXbYWe6nTWnSJjxy5W3po,80676
303
303
  ccxt/async_support/base/__init__.py,sha256=aVYSsFi--b4InRs9zDN_wtCpj8odosAB726JdUHavrk,67
304
- ccxt/async_support/base/exchange.py,sha256=jeFY9YKera7o_Pv2mHcRMab1qvUYCrUPQbWqLTIyOak,70409
304
+ ccxt/async_support/base/exchange.py,sha256=L1SrM45buA4YiwMcRgbpq1wqmhvu-LJVLXfOknZUjiU,70385
305
305
  ccxt/async_support/base/throttler.py,sha256=tvDVcdRUVYi8fZRlEcnqtgzcgB_KMUMRs5Pu8tuU-tU,1847
306
306
  ccxt/async_support/base/ws/__init__.py,sha256=uockzpLuwntKGZbs5EOWFe-Zg-k6Cj7GhNJLc_RX0so,1791
307
307
  ccxt/async_support/base/ws/aiohttp_client.py,sha256=_qjsl_x-rd88QmzQeGVWovMDK0XoD3f4m5GHqxZRajs,5203
@@ -315,10 +315,10 @@ ccxt/async_support/base/ws/order_book_side.py,sha256=Pxrq22nCODckJ6G1OXkYEmUunIu
315
315
  ccxt/base/__init__.py,sha256=eTx1OE3HJjspFUQjGm6LBhaQiMKJnXjkdP-JUXknyQ0,1320
316
316
  ccxt/base/decimal_to_precision.py,sha256=fgWRBzRTtsf3r2INyS4f7WHlzgjB5YM1ekiwqD21aac,6634
317
317
  ccxt/base/errors.py,sha256=1C38u76jlNGq06N_uwfw8b8FZHK8_3_90wM1rKfU_Rg,3878
318
- ccxt/base/exchange.py,sha256=ecaxBTNX6R8twq7St1RwPHUW8d6eTGp2f1wWM_Ng5-k,216767
318
+ ccxt/base/exchange.py,sha256=RoIOmncGzS65wdr0SpUvNYNKrKQONUib7K1JiaNvI-M,216743
319
319
  ccxt/base/precise.py,sha256=_xfu54sV0vWNnOfGTKRFykeuWP8mn4K1m9lk1tcllX4,8565
320
320
  ccxt/base/types.py,sha256=LN8MOE5oGr8ATL6VNuMAnE9f6o2fZ9zbeLLyXLndlEk,5528
321
- ccxt/pro/__init__.py,sha256=zxOG5fk6_7DSnWXT99sZTeysNINv13sRiRSOjcxMJo4,6376
321
+ ccxt/pro/__init__.py,sha256=k1GPx7RFqclPMpkBTzzoRuyeDghMfof70x_GTkBGvOA,6376
322
322
  ccxt/pro/alpaca.py,sha256=fy1mLmw4yac7DKvGPpaqEBuA8briQqaRwPbvKsKUJwY,26974
323
323
  ccxt/pro/ascendex.py,sha256=GqH6QOPZfQtbAYhdB65zJ9iIMQDGsXugSyAPUsKXk40,34730
324
324
  ccxt/pro/bequant.py,sha256=3IeQ0vPg-eVqPiGMfX7yqH9qtXKm1ZqocQDeLwpA8EE,1093
@@ -428,7 +428,7 @@ ccxt/test/base/test_ticker.py,sha256=5J8KHgFhJLgcWyFwt3bhJ-tldMho3K7LD5yJnnUyrT4
428
428
  ccxt/test/base/test_trade.py,sha256=AN3emAdEPhdFyunap43cKqZTS1cbaShZKTjYue67jEU,2297
429
429
  ccxt/test/base/test_trading_fee.py,sha256=2_WCp3qJ2UpraQQoGFlGJYwHD-T0Bm5W7KIw4zpFvSM,1068
430
430
  ccxt/test/base/test_transaction.py,sha256=BTbB4UHHXkrvYgwbrhh867nVRlevmIkIrz1W_odlQJI,1434
431
- ccxt-4.1.82.dist-info/METADATA,sha256=s68jVYzX140m868YqdbEL13fARLmDOo6TxBtn0kYfbA,106154
432
- ccxt-4.1.82.dist-info/WHEEL,sha256=P2T-6epvtXQ2cBOE_U1K4_noqlJFN3tj15djMgEu4NM,110
433
- ccxt-4.1.82.dist-info/top_level.txt,sha256=CkQDuCTDKNcImPV60t36G6MdYfxsAPNiSaEwifVoVMo,5
434
- ccxt-4.1.82.dist-info/RECORD,,
431
+ ccxt-4.1.84.dist-info/METADATA,sha256=VLq3GLbFBYVVXA2soT4zlXttjHt35DX-xIWxAh4P-4E,106154
432
+ ccxt-4.1.84.dist-info/WHEEL,sha256=P2T-6epvtXQ2cBOE_U1K4_noqlJFN3tj15djMgEu4NM,110
433
+ ccxt-4.1.84.dist-info/top_level.txt,sha256=CkQDuCTDKNcImPV60t36G6MdYfxsAPNiSaEwifVoVMo,5
434
+ ccxt-4.1.84.dist-info/RECORD,,
File without changes