ccxt 4.0.100__py2.py3-none-any.whl → 4.0.102__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.
Files changed (65) hide show
  1. ccxt/__init__.py +1 -3
  2. ccxt/abstract/binance.py +8 -0
  3. ccxt/abstract/binancecoinm.py +8 -0
  4. ccxt/abstract/binanceus.py +8 -0
  5. ccxt/abstract/binanceusdm.py +8 -0
  6. ccxt/abstract/bingx.py +16 -1
  7. ccxt/async_support/__init__.py +1 -3
  8. ccxt/async_support/base/exchange.py +1 -1
  9. ccxt/async_support/binance.py +36 -1
  10. ccxt/async_support/bingx.py +41 -4
  11. ccxt/async_support/bitbank.py +11 -0
  12. ccxt/async_support/bitfinex.py +12 -8
  13. ccxt/async_support/bitflyer.py +39 -10
  14. ccxt/async_support/bitforex.py +0 -8
  15. ccxt/async_support/bitget.py +15 -5
  16. ccxt/async_support/bitmart.py +66 -0
  17. ccxt/async_support/bitstamp1.py +22 -0
  18. ccxt/async_support/bl3p.py +32 -0
  19. ccxt/async_support/bybit.py +120 -48
  20. ccxt/async_support/coinbasepro.py +11 -0
  21. ccxt/async_support/currencycom.py +1 -1
  22. ccxt/async_support/gemini.py +1 -0
  23. ccxt/async_support/huobi.py +1 -1
  24. ccxt/async_support/huobijp.py +1 -1
  25. ccxt/async_support/idex.py +1 -1
  26. ccxt/async_support/kucoinfutures.py +46 -51
  27. ccxt/async_support/lbank.py +1 -1
  28. ccxt/async_support/lbank2.py +1 -1
  29. ccxt/base/exchange.py +1 -1
  30. ccxt/binance.py +36 -1
  31. ccxt/bingx.py +41 -4
  32. ccxt/bitbank.py +11 -0
  33. ccxt/bitfinex.py +12 -8
  34. ccxt/bitflyer.py +39 -10
  35. ccxt/bitforex.py +0 -8
  36. ccxt/bitget.py +15 -5
  37. ccxt/bitmart.py +66 -0
  38. ccxt/bitstamp1.py +22 -0
  39. ccxt/bl3p.py +32 -0
  40. ccxt/bybit.py +120 -48
  41. ccxt/coinbasepro.py +11 -0
  42. ccxt/currencycom.py +1 -1
  43. ccxt/gemini.py +1 -0
  44. ccxt/huobi.py +1 -1
  45. ccxt/huobijp.py +1 -1
  46. ccxt/idex.py +1 -1
  47. ccxt/kucoinfutures.py +46 -51
  48. ccxt/lbank.py +1 -1
  49. ccxt/lbank2.py +1 -1
  50. ccxt/pro/__init__.py +1 -1
  51. ccxt/pro/binance.py +7 -7
  52. ccxt/pro/bybit.py +16 -16
  53. ccxt/pro/coinbasepro.py +10 -10
  54. ccxt/pro/huobijp.py +1 -2
  55. ccxt/pro/krakenfutures.py +7 -7
  56. ccxt/pro/kucoin.py +42 -2
  57. ccxt/pro/kucoinfutures.py +3 -3
  58. ccxt/pro/phemex.py +2 -2
  59. ccxt/test/test_async.py +1 -1
  60. ccxt/test/test_sync.py +1 -1
  61. {ccxt-4.0.100.dist-info → ccxt-4.0.102.dist-info}/METADATA +6 -7
  62. {ccxt-4.0.100.dist-info → ccxt-4.0.102.dist-info}/RECORD +64 -65
  63. ccxt/abstract/bkex.py +0 -58
  64. {ccxt-4.0.100.dist-info → ccxt-4.0.102.dist-info}/WHEEL +0 -0
  65. {ccxt-4.0.100.dist-info → ccxt-4.0.102.dist-info}/top_level.txt +0 -0
ccxt/bl3p.py CHANGED
@@ -35,6 +35,9 @@ class bl3p(Exchange, ImplicitAPI):
35
35
  'cancelOrder': True,
36
36
  'createOrder': True,
37
37
  'createReduceOnlyOrder': False,
38
+ 'createStopLimitOrder': False,
39
+ 'createStopMarketOrder': False,
40
+ 'createStopOrder': False,
38
41
  'fetchBalance': True,
39
42
  'fetchBorrowRate': False,
40
43
  'fetchBorrowRateHistories': False,
@@ -237,6 +240,16 @@ class bl3p(Exchange, ImplicitAPI):
237
240
  return self.parse_ticker(ticker, market)
238
241
 
239
242
  def parse_trade(self, trade, market=None):
243
+ #
244
+ # fetchTrades
245
+ #
246
+ # {
247
+ # "trade_id": "2518789",
248
+ # "date": "1694348697745",
249
+ # "amount_int": "2959153",
250
+ # "price_int": "2416231440"
251
+ # }
252
+ #
240
253
  id = self.safe_string(trade, 'trade_id')
241
254
  timestamp = self.safe_integer(trade, 'date')
242
255
  price = self.safe_string(trade, 'price_int')
@@ -271,6 +284,20 @@ class bl3p(Exchange, ImplicitAPI):
271
284
  response = self.publicGetMarketTrades(self.extend({
272
285
  'market': market['id'],
273
286
  }, params))
287
+ #
288
+ # {
289
+ # "result": "success",
290
+ # "data": {
291
+ # "trades": [
292
+ # {
293
+ # "trade_id": "2518789",
294
+ # "date": "1694348697745",
295
+ # "amount_int": "2959153",
296
+ # "price_int": "2416231440"
297
+ # },
298
+ # ]
299
+ # }
300
+ # }
274
301
  result = self.parse_trades(response['data']['trades'], market, since, limit)
275
302
  return result
276
303
 
@@ -329,12 +356,17 @@ class bl3p(Exchange, ImplicitAPI):
329
356
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
330
357
  """
331
358
  create a trade order
359
+ see https://github.com/BitonicNL/bl3p-api/blob/master/examples/nodejs/example.md#21---create-an-order
332
360
  :param str symbol: unified symbol of the market to create an order in
333
361
  :param str type: 'market' or 'limit'
334
362
  :param str side: 'buy' or 'sell'
335
363
  :param float amount: how much of currency you want to trade in units of base currency
336
364
  :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
337
365
  :param dict [params]: extra parameters specific to the bl3p api endpoint
366
+ *
367
+ * EXCHANGE SPECIFIC PARAMETERS
368
+ :param int [params.amount_funds]: maximal EUR amount to spend(*1e5)
369
+ :param str [params.fee_currency]: 'EUR' or 'BTC'
338
370
  :returns dict: an `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
339
371
  """
340
372
  market = self.market(symbol)
ccxt/bybit.py CHANGED
@@ -741,7 +741,7 @@ class bybit(Exchange, ImplicitAPI):
741
741
  '110023': InvalidOrder, # This contract only supports position reduction operation, please contact customer service for details
742
742
  '110024': InvalidOrder, # You have an existing position, so position mode cannot be switched
743
743
  '110025': InvalidOrder, # Position mode is not modified
744
- '110026': InvalidOrder, # Cross/isolated margin mode is not modified
744
+ '110026': BadRequest, # Cross/isolated margin mode is not modified
745
745
  '110027': InvalidOrder, # Margin is not modified
746
746
  '110028': InvalidOrder, # Open orders exist, so you cannot change position mode
747
747
  '110029': InvalidOrder, # Hedge mode is not available for self symbol
@@ -2337,26 +2337,27 @@ class bybit(Exchange, ImplicitAPI):
2337
2337
  if limit is not None:
2338
2338
  request['limit'] = limit # max 1000, default 1000
2339
2339
  request['interval'] = self.safe_string(self.timeframes, timeframe, timeframe)
2340
- method = None
2340
+ response = None
2341
2341
  if market['spot']:
2342
2342
  request['category'] = 'spot'
2343
- method = 'publicGetV5MarketKline'
2343
+ response = self.publicGetV5MarketKline(self.extend(request, params))
2344
2344
  else:
2345
2345
  price = self.safe_string(params, 'price')
2346
2346
  params = self.omit(params, 'price')
2347
- methods = {
2348
- 'mark': 'publicGetV5MarketMarkPriceKline',
2349
- 'index': 'publicGetV5MarketIndexPriceKline',
2350
- 'premiumIndex': 'publicGetV5MarketPremiumIndexPriceKline',
2351
- }
2352
- method = self.safe_value(methods, price, 'publicGetV5MarketKline')
2353
2347
  if market['linear']:
2354
2348
  request['category'] = 'linear'
2355
2349
  elif market['inverse']:
2356
2350
  request['category'] = 'inverse'
2357
2351
  else:
2358
2352
  raise NotSupported(self.id + ' fetchOHLCV() is not supported for option markets')
2359
- response = getattr(self, method)(self.extend(request, params))
2353
+ if price == 'mark':
2354
+ response = self.publicGetV5MarketMarkPriceKline(self.extend(request, params))
2355
+ elif price == 'index':
2356
+ response = self.publicGetV5MarketIndexPriceKline(self.extend(request, params))
2357
+ elif price == 'premiumIndex':
2358
+ response = self.publicGetV5MarketPremiumIndexPriceKline(self.extend(request, params))
2359
+ else:
2360
+ response = self.publicGetV5MarketKline(self.extend(request, params))
2360
2361
  #
2361
2362
  # {
2362
2363
  # "retCode": 0,
@@ -3458,6 +3459,7 @@ class bybit(Exchange, ImplicitAPI):
3458
3459
  :param boolean [params.isLeverage]: *unified spot only* False then spot trading True then margin trading
3459
3460
  :param str [params.tpslMode]: *contract only* 'full' or 'partial'
3460
3461
  :param str [params.mmp]: *option only* market maker protection
3462
+ :param int [params.triggerDirection]: *contract only* conditional orders, 1: triggered when market price rises to triggerPrice, 2: triggered when market price falls to triggerPrice
3461
3463
  :returns dict: an `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
3462
3464
  """
3463
3465
  self.load_markets()
@@ -3548,7 +3550,6 @@ class bybit(Exchange, ImplicitAPI):
3548
3550
  isBuy = side == 'buy'
3549
3551
  ascending = not isBuy if stopLossTriggerPrice else isBuy
3550
3552
  if triggerPrice is not None:
3551
- request['triggerDirection'] = 2 if ascending else 1
3552
3553
  request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
3553
3554
  elif isStopLossTriggerOrder or isTakeProfitTriggerOrder:
3554
3555
  request['triggerDirection'] = 2 if ascending else 1
@@ -3557,11 +3558,11 @@ class bybit(Exchange, ImplicitAPI):
3557
3558
  request['reduceOnly'] = True
3558
3559
  elif isStopLoss or isTakeProfit:
3559
3560
  if isStopLoss:
3560
- stopLossTriggerPrice = self.safe_value_2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss)
3561
- request['stopLoss'] = self.price_to_precision(symbol, stopLossTriggerPrice)
3561
+ slTriggerPrice = self.safe_value_2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss)
3562
+ request['stopLoss'] = self.price_to_precision(symbol, slTriggerPrice)
3562
3563
  if isTakeProfit:
3563
- takeProfitTriggerPrice = self.safe_value_2(takeProfit, 'triggerPrice', 'stopPrice', takeProfit)
3564
- request['takeProfit'] = self.price_to_precision(symbol, takeProfitTriggerPrice)
3564
+ tpTriggerPrice = self.safe_value_2(takeProfit, 'triggerPrice', 'stopPrice', takeProfit)
3565
+ request['takeProfit'] = self.price_to_precision(symbol, tpTriggerPrice)
3565
3566
  if market['spot']:
3566
3567
  # only works for spot market
3567
3568
  if triggerPrice is not None:
@@ -3655,11 +3656,11 @@ class bybit(Exchange, ImplicitAPI):
3655
3656
  request['basePrice'] = Precise.string_sub(preciseStopPrice, delta) if isStopLossTriggerOrder else Precise.string_add(preciseStopPrice, delta)
3656
3657
  elif isStopLoss or isTakeProfit:
3657
3658
  if isStopLoss:
3658
- stopLossTriggerPrice = self.safe_value_2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss)
3659
- request['stopLoss'] = self.price_to_precision(symbol, stopLossTriggerPrice)
3659
+ slTriggerPrice = self.safe_value_2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss)
3660
+ request['stopLoss'] = self.price_to_precision(symbol, slTriggerPrice)
3660
3661
  if isTakeProfit:
3661
- takeProfitTriggerPrice = self.safe_value_2(takeProfit, 'triggerPrice', 'stopPrice', takeProfit)
3662
- request['takeProfit'] = self.price_to_precision(symbol, takeProfitTriggerPrice)
3662
+ tpTriggerPrice = self.safe_value_2(takeProfit, 'triggerPrice', 'stopPrice', takeProfit)
3663
+ request['takeProfit'] = self.price_to_precision(symbol, tpTriggerPrice)
3663
3664
  else:
3664
3665
  request['orderFilter'] = 'Order'
3665
3666
  clientOrderId = self.safe_string(params, 'clientOrderId')
@@ -3669,8 +3670,11 @@ class bybit(Exchange, ImplicitAPI):
3669
3670
  # mandatory field for options
3670
3671
  request['orderLinkId'] = self.uuid16()
3671
3672
  params = self.omit(params, ['stopPrice', 'timeInForce', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'clientOrderId'])
3672
- method = 'privatePostOptionUsdcOpenapiPrivateV1PlaceOrder' if market['option'] else 'privatePostPerpetualUsdcOpenapiPrivateV1PlaceOrder'
3673
- response = getattr(self, method)(self.extend(request, params))
3673
+ response = None
3674
+ if market['option']:
3675
+ response = self.privatePostOptionUsdcOpenapiPrivateV1PlaceOrder(self.extend(request, params))
3676
+ else:
3677
+ response = self.privatePostPerpetualUsdcOpenapiPrivateV1PlaceOrder(self.extend(request, params))
3674
3678
  #
3675
3679
  # {
3676
3680
  # "retCode":0,
@@ -3710,11 +3714,10 @@ class bybit(Exchange, ImplicitAPI):
3710
3714
  request['orderQty'] = self.amount_to_precision(symbol, amount)
3711
3715
  if price is not None:
3712
3716
  request['orderPrice'] = self.price_to_precision(symbol, price)
3713
- method = None
3717
+ response = None
3714
3718
  if market['option']:
3715
- method = 'privatePostOptionUsdcOpenapiPrivateV1ReplaceOrder'
3719
+ response = self.privatePostOptionUsdcOpenapiPrivateV1ReplaceOrder(self.extend(request, params))
3716
3720
  else:
3717
- method = 'privatePostPerpetualUsdcOpenapiPrivateV1ReplaceOrder'
3718
3721
  isStop = self.safe_value(params, 'stop', False)
3719
3722
  triggerPrice = self.safe_value_2(params, 'stopPrice', 'triggerPrice')
3720
3723
  stopLossPrice = self.safe_value(params, 'stopLossPrice')
@@ -3731,7 +3734,7 @@ class bybit(Exchange, ImplicitAPI):
3731
3734
  if takeProfitPrice is not None:
3732
3735
  request['takeProfit'] = self.price_to_precision(symbol, takeProfitPrice)
3733
3736
  params = self.omit(params, ['stop', 'stopPrice', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice'])
3734
- response = getattr(self, method)(self.extend(request, params))
3737
+ response = self.privatePostPerpetualUsdcOpenapiPrivateV1ReplaceOrder(self.extend(request, params))
3735
3738
  #
3736
3739
  # {
3737
3740
  # "retCode": 0,
@@ -3811,11 +3814,11 @@ class bybit(Exchange, ImplicitAPI):
3811
3814
  request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
3812
3815
  if isStopLoss or isTakeProfit:
3813
3816
  if isStopLoss:
3814
- stopLossTriggerPrice = self.safe_value_2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss)
3815
- request['stopLoss'] = self.price_to_precision(symbol, stopLossTriggerPrice)
3817
+ slTriggerPrice = self.safe_value_2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss)
3818
+ request['stopLoss'] = self.price_to_precision(symbol, slTriggerPrice)
3816
3819
  if isTakeProfit:
3817
- takeProfitTriggerPrice = self.safe_value_2(takeProfit, 'triggerPrice', 'stopPrice', takeProfit)
3818
- request['takeProfit'] = self.price_to_precision(symbol, takeProfitTriggerPrice)
3820
+ tpTriggerPrice = self.safe_value_2(takeProfit, 'triggerPrice', 'stopPrice', takeProfit)
3821
+ request['takeProfit'] = self.price_to_precision(symbol, tpTriggerPrice)
3819
3822
  clientOrderId = self.safe_string(params, 'clientOrderId')
3820
3823
  if clientOrderId is not None:
3821
3824
  request['orderLinkId'] = clientOrderId
@@ -3850,15 +3853,14 @@ class bybit(Exchange, ImplicitAPI):
3850
3853
  }
3851
3854
  isStop = self.safe_value(params, 'stop', False)
3852
3855
  params = self.omit(params, ['stop'])
3853
- method = None
3854
3856
  if id is not None: # The user can also use argument params["order_link_id"]
3855
3857
  request['orderId'] = id
3858
+ response = None
3856
3859
  if market['option']:
3857
- method = 'privatePostOptionUsdcOpenapiPrivateV1CancelOrder'
3860
+ response = self.privatePostOptionUsdcOpenapiPrivateV1CancelOrder(self.extend(request, params))
3858
3861
  else:
3859
- method = 'privatePostPerpetualUsdcOpenapiPrivateV1CancelOrder'
3860
3862
  request['orderFilter'] = 'StopOrder' if isStop else 'Order'
3861
- response = getattr(self, method)(self.extend(request, params))
3863
+ response = self.privatePostPerpetualUsdcOpenapiPrivateV1CancelOrder(self.extend(request, params))
3862
3864
  #
3863
3865
  # {
3864
3866
  # "retCode": 0,
@@ -4936,13 +4938,16 @@ class bybit(Exchange, ImplicitAPI):
4936
4938
  else:
4937
4939
  if since is not None:
4938
4940
  request['start_date'] = self.yyyymmdd(since)
4939
- method = 'privateGetV5AccountTransactionLog' if (enableUnified[1]) else 'privateGetV2PrivateWalletFundRecords'
4940
4941
  if code is not None:
4941
4942
  currency = self.currency(code)
4942
4943
  request[currencyKey] = currency['id']
4943
4944
  if limit is not None:
4944
4945
  request['limit'] = limit
4945
- response = getattr(self, method)(self.extend(request, params))
4946
+ response = None
4947
+ if enableUnified[1]:
4948
+ response = self.privateGetV5AccountTransactionLog(self.extend(request, params))
4949
+ else:
4950
+ response = self.privateGetV2PrivateWalletFundRecords(self.extend(request, params))
4946
4951
  #
4947
4952
  # {
4948
4953
  # "ret_code": 0,
@@ -5623,18 +5628,85 @@ class bybit(Exchange, ImplicitAPI):
5623
5628
  })
5624
5629
 
5625
5630
  def set_margin_mode(self, marginMode, symbol: Optional[str] = None, params={}):
5631
+ """
5632
+ set margin mode(account) or trade mode(symbol)
5633
+ see https://bybit-exchange.github.io/docs/v5/account/set-margin-mode
5634
+ see https://bybit-exchange.github.io/docs/v5/position/cross-isolate
5635
+ :param str marginMode: account mode must be either [isolated, cross, portfolio], trade mode must be either [isolated, cross]
5636
+ :param str symbol: unified market symbol of the market the position is held in, default is None
5637
+ :param dict [params]: extra parameters specific to the bybit api endpoint
5638
+ :param str [params.leverage]: the rate of leverage, is required if setting trade mode(symbol)
5639
+ :returns dict: response from the exchange
5640
+ """
5626
5641
  self.load_markets()
5627
5642
  enableUnifiedMargin, enableUnifiedAccount = self.is_unified_enabled()
5628
5643
  isUnifiedAccount = (enableUnifiedMargin or enableUnifiedAccount)
5629
- if marginMode == 'ISOLATED_MARGIN':
5630
- if not isUnifiedAccount:
5631
- raise NotSupported(self.id + ' setMarginMode() Normal Account not support ISOLATED_MARGIN')
5632
- elif (marginMode != 'REGULAR_MARGIN') and (marginMode != 'PORTFOLIO_MARGIN'):
5633
- raise NotSupported(self.id + ' setMarginMode() marginMode must be either ISOLATED_MARGIN or REGULAR_MARGIN or PORTFOLIO_MARGIN')
5634
- request = {
5635
- 'setMarginMode': marginMode,
5636
- }
5637
- response = self.privatePostV5AccountSetMarginMode(self.extend(request, params))
5644
+ market = None
5645
+ response = None
5646
+ if isUnifiedAccount:
5647
+ if marginMode == 'isolated':
5648
+ marginMode = 'ISOLATED_MARGIN'
5649
+ elif marginMode == 'cross':
5650
+ marginMode = 'REGULAR_MARGIN'
5651
+ elif marginMode == 'portfolio':
5652
+ marginMode = 'PORTFOLIO_MARGIN'
5653
+ else:
5654
+ raise NotSupported(self.id + ' setMarginMode() marginMode must be either [isolated, cross, portfolio]')
5655
+ request = {
5656
+ 'setMarginMode': marginMode,
5657
+ }
5658
+ response = self.privatePostV5AccountSetMarginMode(self.extend(request, params))
5659
+ else:
5660
+ if symbol is None:
5661
+ raise ArgumentsRequired(self.id + ' setMarginMode() requires a symbol parameter for non unified account')
5662
+ market = self.market(symbol)
5663
+ isUsdcSettled = market['settle'] == 'USDC'
5664
+ if isUsdcSettled:
5665
+ if marginMode == 'cross':
5666
+ marginMode = 'REGULAR_MARGIN'
5667
+ elif marginMode == 'portfolio':
5668
+ marginMode = 'PORTFOLIO_MARGIN'
5669
+ else:
5670
+ raise NotSupported(self.id + ' setMarginMode() for usdc market marginMode must be either [cross, portfolio]')
5671
+ request = {
5672
+ 'setMarginMode': marginMode,
5673
+ }
5674
+ response = self.privatePostV5AccountSetMarginMode(self.extend(request, params))
5675
+ else:
5676
+ type = None
5677
+ type, params = self.get_bybit_type('setPositionMode', market, params)
5678
+ tradeMode = None
5679
+ if marginMode == 'cross':
5680
+ tradeMode = 0
5681
+ elif marginMode == 'isolated':
5682
+ tradeMode = 1
5683
+ else:
5684
+ raise NotSupported(self.id + ' setMarginMode() with symbol marginMode must be either [isolated, cross]')
5685
+ sellLeverage = None
5686
+ buyLeverage = None
5687
+ leverage = self.safe_string(params, 'leverage')
5688
+ if leverage is None:
5689
+ sellLeverage = self.safe_string_2(params, 'sell_leverage', 'sellLeverage')
5690
+ buyLeverage = self.safe_string_2(params, 'buy_leverage', 'buyLeverage')
5691
+ if sellLeverage is None and buyLeverage is None:
5692
+ raise ArgumentsRequired(self.id + ' setMarginMode() requires a leverage parameter or sell_leverage and buy_leverage parameters')
5693
+ if buyLeverage is None:
5694
+ buyLeverage = sellLeverage
5695
+ if sellLeverage is None:
5696
+ sellLeverage = buyLeverage
5697
+ params = self.omit(params, ['buy_leverage', 'sell_leverage', 'sellLeverage', 'buyLeverage'])
5698
+ else:
5699
+ sellLeverage = leverage
5700
+ buyLeverage = leverage
5701
+ params = self.omit(params, 'leverage')
5702
+ request = {
5703
+ 'category': type,
5704
+ 'symbol': market['id'],
5705
+ 'tradeMode': tradeMode,
5706
+ 'buyLeverage': buyLeverage,
5707
+ 'sellLeverage': sellLeverage,
5708
+ }
5709
+ response = self.privatePostV5PositionSwitchIsolated(self.extend(request, params))
5638
5710
  return response
5639
5711
 
5640
5712
  def set_leverage(self, leverage, symbol: Optional[str] = None, params={}):
@@ -5664,21 +5736,21 @@ class bybit(Exchange, ImplicitAPI):
5664
5736
  'buyLeverage': leverage,
5665
5737
  'sellLeverage': leverage,
5666
5738
  }
5667
- method = None
5739
+ response = None
5668
5740
  if isUsdcSettled and not isUnifiedAccount:
5669
5741
  request['leverage'] = leverage
5670
- method = 'privatePostPerpetualUsdcOpenapiPrivateV1PositionLeverageSave'
5742
+ response = self.privatePostPerpetualUsdcOpenapiPrivateV1PositionLeverageSave(self.extend(request, params))
5671
5743
  else:
5672
5744
  request['buyLeverage'] = leverage
5673
5745
  request['sellLeverage'] = leverage
5674
- method = 'privatePostV5PositionSetLeverage'
5675
5746
  if market['linear']:
5676
5747
  request['category'] = 'linear'
5677
5748
  elif market['inverse']:
5678
5749
  request['category'] = 'inverse'
5679
5750
  else:
5680
5751
  raise NotSupported(self.id + ' setLeverage() only support linear and inverse market')
5681
- return getattr(self, method)(self.extend(request, params))
5752
+ response = self.privatePostV5PositionSetLeverage(self.extend(request, params))
5753
+ return response
5682
5754
 
5683
5755
  def set_position_mode(self, hedged, symbol: Optional[str] = None, params={}):
5684
5756
  """
ccxt/coinbasepro.py CHANGED
@@ -799,6 +799,17 @@ class coinbasepro(Exchange, ImplicitAPI):
799
799
  if limit is not None:
800
800
  request['limit'] = limit # default 100
801
801
  response = self.publicGetProductsIdTrades(self.extend(request, params))
802
+ #
803
+ # [
804
+ # {
805
+ # "trade_id": "15035219",
806
+ # "side": "sell",
807
+ # "size": "0.27426731",
808
+ # "price": "25820.42000000",
809
+ # "time": "2023-09-10T13:47:41.447577Z"
810
+ # },
811
+ # ]
812
+ #
802
813
  return self.parse_trades(response, market, since, limit)
803
814
 
804
815
  def fetch_trading_fees(self, params={}):
ccxt/currencycom.py CHANGED
@@ -1054,7 +1054,7 @@ class currencycom(Exchange, ImplicitAPI):
1054
1054
  # 'limit': 500, # default 500, max 1000
1055
1055
  }
1056
1056
  if limit is not None:
1057
- request['limit'] = limit # default 500, max 1000
1057
+ request['limit'] = min(limit, 1000) # default 500, max 1000
1058
1058
  if since is not None:
1059
1059
  request['startTime'] = since
1060
1060
  response = self.publicGetV2AggTrades(self.extend(request, params))
ccxt/gemini.py CHANGED
@@ -237,6 +237,7 @@ class gemini(Exchange, ImplicitAPI):
237
237
  'InsufficientFunds': InsufficientFunds, # The order was rejected because of insufficient funds
238
238
  'InvalidJson': BadRequest, # The JSON provided is invalid
239
239
  'InvalidNonce': InvalidNonce, # The nonce was not greater than the previously used nonce, or was not present
240
+ 'InvalidApiKey': AuthenticationError, # Invalid API key
240
241
  'InvalidOrderType': InvalidOrder, # An unknown order type was provided
241
242
  'InvalidPrice': InvalidOrder, # For new orders, the price was invalid
242
243
  'InvalidQuantity': InvalidOrder, # A negative or otherwise invalid quantity was specified
ccxt/huobi.py CHANGED
@@ -2445,7 +2445,7 @@ class huobi(Exchange, ImplicitAPI):
2445
2445
  fieldName = 'contract_code'
2446
2446
  request[fieldName] = market['id']
2447
2447
  if limit is not None:
2448
- request['size'] = limit # max 2000
2448
+ request['size'] = min(limit, 2000) # max 2000
2449
2449
  response = getattr(self, method)(self.extend(request, params))
2450
2450
  #
2451
2451
  # {
ccxt/huobijp.py CHANGED
@@ -850,7 +850,7 @@ class huobijp(Exchange, ImplicitAPI):
850
850
  'symbol': market['id'],
851
851
  }
852
852
  if limit is not None:
853
- request['size'] = limit
853
+ request['size'] = min(limit, 2000)
854
854
  response = self.marketGetHistoryTrade(self.extend(request, params))
855
855
  #
856
856
  # {
ccxt/idex.py CHANGED
@@ -504,7 +504,7 @@ class idex(Exchange, ImplicitAPI):
504
504
  if since is not None:
505
505
  request['start'] = since
506
506
  if limit is not None:
507
- request['limit'] = limit
507
+ request['limit'] = min(limit, 1000)
508
508
  # [
509
509
  # {
510
510
  # fillId: 'b5467d00-b13e-3fa9-8216-dd66735550fc',
ccxt/kucoinfutures.py CHANGED
@@ -850,58 +850,53 @@ class kucoinfutures(kucoin, ImplicitAPI):
850
850
  request = {
851
851
  'symbol': market['id'],
852
852
  }
853
- response = self.futuresPrivateGetPositions(self.extend(request, params))
853
+ response = self.futuresPrivateGetPosition(self.extend(request, params))
854
854
  #
855
- # {
856
- # "code": "200000",
857
- # "data": [
858
- # {
859
- # "id": "63b3599e6c41f50001c47d44",
860
- # "symbol": "XBTUSDTM",
861
- # "autoDeposit": False,
862
- # "maintMarginReq": 0.004,
863
- # "riskLimit": 25000,
864
- # "realLeverage": 5.0,
865
- # "crossMode": False,
866
- # "delevPercentage": 0.57,
867
- # "openingTimestamp": 1684000025528,
868
- # "currentTimestamp": 1684000052160,
869
- # "currentQty": 1,
870
- # "currentCost": 26.821,
871
- # "currentComm": 0.0160926,
872
- # "unrealisedCost": 26.821,
873
- # "realisedGrossCost": 0.0,
874
- # "realisedCost": 0.0160926,
875
- # "isOpen": True,
876
- # "markPrice": 26821.13,
877
- # "markValue": 26.82113,
878
- # "posCost": 26.821,
879
- # "posCross": 0.0,
880
- # "posCrossMargin": 0.0,
881
- # "posInit": 5.3642,
882
- # "posComm": 0.01931112,
883
- # "posCommCommon": 0.01931112,
884
- # "posLoss": 0.0,
885
- # "posMargin": 5.38351112,
886
- # "posMaint": 0.12927722,
887
- # "maintMargin": 5.38364112,
888
- # "realisedGrossPnl": 0.0,
889
- # "realisedPnl": -0.0160926,
890
- # "unrealisedPnl": 1.3E-4,
891
- # "unrealisedPnlPcnt": 0.0,
892
- # "unrealisedRoePcnt": 0.0,
893
- # "avgEntryPrice": 26821.0,
894
- # "liquidationPrice": 21567.0,
895
- # "bankruptPrice": 21456.0,
896
- # "settleCurrency": "USDT",
897
- # "isInverse": False,
898
- # "maintainMargin": 0.004
899
- # }
900
- # ]
901
- # }
855
+ # {
856
+ # "code": "200000",
857
+ # "data": {
858
+ # "id": "6505ee6eaff4070001f651c4",
859
+ # "symbol": "XBTUSDTM",
860
+ # "autoDeposit": False,
861
+ # "maintMarginReq": 0,
862
+ # "riskLimit": 200,
863
+ # "realLeverage": 0.0,
864
+ # "crossMode": False,
865
+ # "delevPercentage": 0.0,
866
+ # "currentTimestamp": 1694887534594,
867
+ # "currentQty": 0,
868
+ # "currentCost": 0.0,
869
+ # "currentComm": 0.0,
870
+ # "unrealisedCost": 0.0,
871
+ # "realisedGrossCost": 0.0,
872
+ # "realisedCost": 0.0,
873
+ # "isOpen": False,
874
+ # "markPrice": 26611.71,
875
+ # "markValue": 0.0,
876
+ # "posCost": 0.0,
877
+ # "posCross": 0,
878
+ # "posInit": 0.0,
879
+ # "posComm": 0.0,
880
+ # "posLoss": 0.0,
881
+ # "posMargin": 0.0,
882
+ # "posMaint": 0.0,
883
+ # "maintMargin": 0.0,
884
+ # "realisedGrossPnl": 0.0,
885
+ # "realisedPnl": 0.0,
886
+ # "unrealisedPnl": 0.0,
887
+ # "unrealisedPnlPcnt": 0,
888
+ # "unrealisedRoePcnt": 0,
889
+ # "avgEntryPrice": 0.0,
890
+ # "liquidationPrice": 0.0,
891
+ # "bankruptPrice": 0.0,
892
+ # "settleCurrency": "USDT",
893
+ # "maintainMargin": 0,
894
+ # "riskLimitLevel": 1
895
+ # }
896
+ # }
902
897
  #
903
- data = self.safe_value(response, 'data', [])
904
- return self.parse_position(data[0], market)
898
+ data = self.safe_value(response, 'data', {})
899
+ return self.parse_position(data, market)
905
900
 
906
901
  def fetch_positions(self, symbols: Optional[List[str]] = None, params={}):
907
902
  """
@@ -1043,7 +1038,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
1043
1038
  'unrealizedPnl': self.parse_number(unrealisedPnl),
1044
1039
  'contracts': self.parse_number(Precise.string_abs(size)),
1045
1040
  'contractSize': self.safe_value(market, 'contractSize'),
1046
- 'realizedPnl': self.safe_number(position, 'realised_pnl'),
1041
+ 'realizedPnl': self.safe_number(position, 'realisedPnl'),
1047
1042
  'marginRatio': None,
1048
1043
  'liquidationPrice': self.safe_number(position, 'liquidationPrice'),
1049
1044
  'markPrice': self.safe_number(position, 'markPrice'),
ccxt/lbank.py CHANGED
@@ -394,7 +394,7 @@ class lbank(Exchange, ImplicitAPI):
394
394
  if since is not None:
395
395
  request['time'] = since
396
396
  if limit is not None:
397
- request['size'] = limit
397
+ request['size'] = min(limit, 600)
398
398
  response = self.publicGetTrades(self.extend(request, params))
399
399
  return self.parse_trades(response, market, since, limit)
400
400
 
ccxt/lbank2.py CHANGED
@@ -894,7 +894,7 @@ class lbank2(Exchange, ImplicitAPI):
894
894
  if since is not None:
895
895
  request['time'] = since
896
896
  if limit is not None:
897
- request['size'] = limit
897
+ request['size'] = min(limit, 600)
898
898
  else:
899
899
  request['size'] = 600 # max
900
900
  method = self.safe_string(params, 'method')
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.0.100'
7
+ __version__ = '4.0.102'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/binance.py CHANGED
@@ -466,8 +466,8 @@ class binance(ccxt.async_support.binance):
466
466
  for i in range(0, len(symbols)):
467
467
  symbol = symbols[i]
468
468
  market = self.market(symbol)
469
- messageHash = market['lowercaseId'] + '@' + name
470
- subParams.append(messageHash)
469
+ currentMessageHash = market['lowercaseId'] + '@' + name
470
+ subParams.append(currentMessageHash)
471
471
  messageHash = 'multipleTrades::' + ','.join(symbols)
472
472
  query = self.omit(params, 'type')
473
473
  url = self.urls['api']['ws'][type] + '/' + self.stream(type, messageHash)
@@ -763,17 +763,17 @@ class binance(ccxt.async_support.binance):
763
763
  hashes = []
764
764
  for i in range(0, len(symbolsAndTimeframes)):
765
765
  data = symbolsAndTimeframes[i]
766
- symbol = data[0]
767
- timeframe = data[1]
768
- interval = self.safe_string(self.timeframes, timeframe, timeframe)
769
- market = self.market(symbol)
766
+ symbolString = data[0]
767
+ timeframeString = data[1]
768
+ interval = self.safe_string(self.timeframes, timeframeString, timeframeString)
769
+ market = self.market(symbolString)
770
770
  marketId = market['lowercaseId']
771
771
  if name == 'indexPriceKline':
772
772
  # weird behavior for index price kline we can't use the perp suffix
773
773
  marketId = marketId.replace('_perp', '')
774
774
  topic = marketId + '@' + name + '_' + interval
775
775
  subParams.append(topic)
776
- hashes.append(symbol + '#' + timeframe)
776
+ hashes.append(symbolString + '#' + timeframeString)
777
777
  messageHash = 'multipleOHLCV::' + ','.join(hashes)
778
778
  url = self.urls['api']['ws'][type] + '/' + self.stream(type, messageHash)
779
779
  requestId = self.request_id(url)