ccxt 4.4.60__py2.py3-none-any.whl → 4.4.62__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ccxt/__init__.py CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # ----------------------------------------------------------------------------
24
24
 
25
- __version__ = '4.4.60'
25
+ __version__ = '4.4.62'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
ccxt/abstract/bybit.py CHANGED
@@ -48,6 +48,7 @@ class ImplicitAPI:
48
48
  public_get_v5_spot_lever_token_info = publicGetV5SpotLeverTokenInfo = Entry('v5/spot-lever-token/info', 'public', 'GET', {'cost': 5})
49
49
  public_get_v5_spot_lever_token_reference = publicGetV5SpotLeverTokenReference = Entry('v5/spot-lever-token/reference', 'public', 'GET', {'cost': 5})
50
50
  public_get_v5_spot_margin_trade_data = publicGetV5SpotMarginTradeData = Entry('v5/spot-margin-trade/data', 'public', 'GET', {'cost': 5})
51
+ public_get_v5_spot_margin_trade_collateral = publicGetV5SpotMarginTradeCollateral = Entry('v5/spot-margin-trade/collateral', 'public', 'GET', {'cost': 5})
51
52
  public_get_v5_spot_cross_margin_trade_data = publicGetV5SpotCrossMarginTradeData = Entry('v5/spot-cross-margin-trade/data', 'public', 'GET', {'cost': 5})
52
53
  public_get_v5_spot_cross_margin_trade_pledge_token = publicGetV5SpotCrossMarginTradePledgeToken = Entry('v5/spot-cross-margin-trade/pledge-token', 'public', 'GET', {'cost': 5})
53
54
  public_get_v5_spot_cross_margin_trade_borrow_token = publicGetV5SpotCrossMarginTradeBorrowToken = Entry('v5/spot-cross-margin-trade/borrow-token', 'public', 'GET', {'cost': 5})
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.60'
7
+ __version__ = '4.4.62'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.4.60'
5
+ __version__ = '4.4.62'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -74,18 +74,20 @@ class Exchange(BaseExchange):
74
74
  self.verify = config.get('verify', self.verify)
75
75
  self.own_session = 'session' not in config
76
76
  self.cafile = config.get('cafile', certifi.where())
77
+ self.throttler = None
77
78
  super(Exchange, self).__init__(config)
78
- self.throttle = None
79
- self.init_rest_rate_limiter()
80
79
  self.markets_loading = None
81
80
  self.reloading_markets = False
82
81
 
83
- def init_rest_rate_limiter(self):
84
- self.throttle = Throttler(self.tokenBucket, self.asyncio_loop)
85
-
86
82
  def get_event_loop(self):
87
83
  return self.asyncio_loop
88
84
 
85
+ def init_throttler(self, cost=None):
86
+ self.throttler = Throttler(self.tokenBucket, self.asyncio_loop)
87
+
88
+ async def throttle(self, cost=None):
89
+ return await self.throttler(cost)
90
+
89
91
  def get_session(self):
90
92
  return self.session
91
93
 
@@ -107,7 +109,7 @@ class Exchange(BaseExchange):
107
109
  self.asyncio_loop = asyncio.get_running_loop()
108
110
  else:
109
111
  self.asyncio_loop = asyncio.get_event_loop()
110
- self.throttle.loop = self.asyncio_loop
112
+ self.throttler.loop = self.asyncio_loop
111
113
 
112
114
  if self.ssl_context is None:
113
115
  # Create our SSL context object with our CA cert file
@@ -4455,13 +4455,12 @@ class bingx(Exchange, ImplicitAPI):
4455
4455
  :param boolean [params.twap]: if fetching twap orders
4456
4456
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
4457
4457
  """
4458
- if symbol is None:
4459
- raise ArgumentsRequired(self.id + ' fetchClosedOrders() requires a symbol argument')
4460
4458
  await self.load_markets()
4461
- market = self.market(symbol)
4462
- request: dict = {
4463
- 'symbol': market['id'],
4464
- }
4459
+ market = None
4460
+ request: dict = {}
4461
+ if symbol is not None:
4462
+ market = self.market(symbol)
4463
+ request['symbol'] = market['id']
4465
4464
  type = None
4466
4465
  subType = None
4467
4466
  standard = None
@@ -74,7 +74,9 @@ class bybit(Exchange, ImplicitAPI):
74
74
  'createTrailingAmountOrder': True,
75
75
  'createTriggerOrder': True,
76
76
  'editOrder': True,
77
+ 'editOrders': True,
77
78
  'fetchBalance': True,
79
+ 'fetchBidsAsks': 'emulated',
78
80
  'fetchBorrowInterest': False, # temporarily disabled, doesn't work
79
81
  'fetchBorrowRateHistories': False,
80
82
  'fetchBorrowRateHistory': False,
@@ -255,6 +257,7 @@ class bybit(Exchange, ImplicitAPI):
255
257
  'v5/spot-lever-token/reference': 5,
256
258
  # spot margin trade
257
259
  'v5/spot-margin-trade/data': 5,
260
+ 'v5/spot-margin-trade/collateral': 5,
258
261
  'v5/spot-cross-margin-trade/data': 5,
259
262
  'v5/spot-cross-margin-trade/pledge-token': 5,
260
263
  'v5/spot-cross-margin-trade/borrow-token': 5,
@@ -1240,6 +1243,9 @@ class bybit(Exchange, ImplicitAPI):
1240
1243
  'fetchOHLCV': {
1241
1244
  'limit': 1000,
1242
1245
  },
1246
+ 'editOrders': {
1247
+ 'max': 10,
1248
+ },
1243
1249
  },
1244
1250
  'spot': {
1245
1251
  'extends': 'default',
@@ -2463,6 +2469,20 @@ class bybit(Exchange, ImplicitAPI):
2463
2469
  tickerList = self.safe_list(result, 'list', [])
2464
2470
  return self.parse_tickers(tickerList, parsedSymbols)
2465
2471
 
2472
+ async def fetch_bids_asks(self, symbols: Strings = None, params={}):
2473
+ """
2474
+ fetches the bid and ask price and volume for multiple markets
2475
+
2476
+ https://bybit-exchange.github.io/docs/v5/market/tickers
2477
+
2478
+ :param str[]|None symbols: unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
2479
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2480
+ :param str [params.subType]: *contract only* 'linear', 'inverse'
2481
+ :param str [params.baseCoin]: *option only* base coin, default is 'BTC'
2482
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
2483
+ """
2484
+ return await self.fetch_tickers(symbols, params)
2485
+
2466
2486
  def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
2467
2487
  #
2468
2488
  # [
@@ -3985,13 +4005,15 @@ class bybit(Exchange, ImplicitAPI):
3985
4005
  price = self.safe_value(rawOrder, 'price')
3986
4006
  orderParams = self.safe_dict(rawOrder, 'params', {})
3987
4007
  orderRequest = self.create_order_request(marketId, type, side, amount, price, orderParams, isUta)
4008
+ del orderRequest['category']
3988
4009
  ordersRequests.append(orderRequest)
3989
4010
  symbols = self.market_symbols(orderSymbols, None, False, True, True)
3990
4011
  market = self.market(symbols[0])
4012
+ unifiedMarginStatus = self.safe_integer(self.options, 'unifiedMarginStatus', 3)
3991
4013
  category = None
3992
4014
  category, params = self.get_bybit_type('createOrders', market, params)
3993
- if category == 'inverse':
3994
- raise NotSupported(self.id + ' createOrders does not allow inverse orders')
4015
+ if (category == 'inverse') and (unifiedMarginStatus < 5):
4016
+ raise NotSupported(self.id + ' createOrders does not allow inverse orders for non UTA2.0 account')
3995
4017
  request: dict = {
3996
4018
  'category': category,
3997
4019
  'request': ordersRequests,
@@ -4158,6 +4180,91 @@ class bybit(Exchange, ImplicitAPI):
4158
4180
  'id': self.safe_string(result, 'orderId'),
4159
4181
  })
4160
4182
 
4183
+ async def edit_orders(self, orders: List[OrderRequest], params={}):
4184
+ """
4185
+ edit a list of trade orders
4186
+
4187
+ https://bybit-exchange.github.io/docs/v5/order/batch-amend
4188
+
4189
+ :param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
4190
+ :param dict [params]: extra parameters specific to the exchange API endpoint
4191
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
4192
+ """
4193
+ await self.load_markets()
4194
+ ordersRequests = []
4195
+ orderSymbols = []
4196
+ for i in range(0, len(orders)):
4197
+ rawOrder = orders[i]
4198
+ symbol = self.safe_string(rawOrder, 'symbol')
4199
+ orderSymbols.append(symbol)
4200
+ id = self.safe_string(rawOrder, 'id')
4201
+ type = self.safe_string(rawOrder, 'type')
4202
+ side = self.safe_string(rawOrder, 'side')
4203
+ amount = self.safe_value(rawOrder, 'amount')
4204
+ price = self.safe_value(rawOrder, 'price')
4205
+ orderParams = self.safe_dict(rawOrder, 'params', {})
4206
+ orderRequest = self.edit_order_request(id, symbol, type, side, amount, price, orderParams)
4207
+ del orderRequest['category']
4208
+ ordersRequests.append(orderRequest)
4209
+ orderSymbols = self.market_symbols(orderSymbols, None, False, True, True)
4210
+ market = self.market(orderSymbols[0])
4211
+ unifiedMarginStatus = self.safe_integer(self.options, 'unifiedMarginStatus', 3)
4212
+ category = None
4213
+ category, params = self.get_bybit_type('editOrders', market, params)
4214
+ if (category == 'inverse') and (unifiedMarginStatus < 5):
4215
+ raise NotSupported(self.id + ' editOrders does not allow inverse orders for non UTA2.0 account')
4216
+ request: dict = {
4217
+ 'category': category,
4218
+ 'request': ordersRequests,
4219
+ }
4220
+ response = await self.privatePostV5OrderAmendBatch(self.extend(request, params))
4221
+ result = self.safe_dict(response, 'result', {})
4222
+ data = self.safe_list(result, 'list', [])
4223
+ retInfo = self.safe_dict(response, 'retExtInfo', {})
4224
+ codes = self.safe_list(retInfo, 'list', [])
4225
+ # self.extend the error with the unsuccessful orders
4226
+ for i in range(0, len(codes)):
4227
+ code = codes[i]
4228
+ retCode = self.safe_integer(code, 'code')
4229
+ if retCode != 0:
4230
+ data[i] = self.extend(data[i], code)
4231
+ #
4232
+ # {
4233
+ # "retCode": 0,
4234
+ # "retMsg": "OK",
4235
+ # "result": {
4236
+ # "list": [
4237
+ # {
4238
+ # "category": "option",
4239
+ # "symbol": "ETH-30DEC22-500-C",
4240
+ # "orderId": "b551f227-7059-4fb5-a6a6-699c04dbd2f2",
4241
+ # "orderLinkId": ""
4242
+ # },
4243
+ # {
4244
+ # "category": "option",
4245
+ # "symbol": "ETH-30DEC22-700-C",
4246
+ # "orderId": "fa6a595f-1a57-483f-b9d3-30e9c8235a52",
4247
+ # "orderLinkId": ""
4248
+ # }
4249
+ # ]
4250
+ # },
4251
+ # "retExtInfo": {
4252
+ # "list": [
4253
+ # {
4254
+ # "code": 0,
4255
+ # "msg": "OK"
4256
+ # },
4257
+ # {
4258
+ # "code": 0,
4259
+ # "msg": "OK"
4260
+ # }
4261
+ # ]
4262
+ # },
4263
+ # "time": 1672222808060
4264
+ # }
4265
+ #
4266
+ return self.parse_orders(data)
4267
+
4161
4268
  def cancel_order_request(self, id: str, symbol: Str = None, params={}):
4162
4269
  market = self.market(symbol)
4163
4270
  request: dict = {
@@ -675,23 +675,67 @@ class gate(Exchange, ImplicitAPI):
675
675
  },
676
676
  'createMarketBuyOrderRequiresPrice': True,
677
677
  'networks': {
678
- 'LINEA': 'LINEAETH',
679
- 'KON': 'KONET',
680
- 'AVAXC': 'AVAX_C',
678
+ 'BTC': 'BTC',
679
+ 'BRC20': 'BTCBRC', # for eg: ORDI, RATS, ...
680
+ 'ETH': 'ETH',
681
+ 'ERC20': 'ETH',
682
+ 'TRX': 'TRX',
683
+ 'TRC20': 'TRX',
684
+ 'HECO': 'HT',
685
+ 'HRC20': 'HT',
686
+ 'BSC': 'BSC',
681
687
  'BEP20': 'BSC',
688
+ 'SOL': 'SOL',
689
+ 'POLYGON': 'POL',
690
+ 'MATIC': 'POL',
691
+ 'OP': 'OPETH',
692
+ 'OPTIMISM': 'OPETH',
693
+ 'ADA': 'ADA', # CARDANO
694
+ 'AVAXC': 'AVAX_C',
695
+ 'NEAR': 'NEAR',
696
+ 'ARBONE': 'ARBEVM',
697
+ 'BASE': 'BASEEVM',
698
+ 'SUI': 'SUI',
699
+ 'CRONOS': 'CRO',
700
+ 'CRO': 'CRO',
701
+ 'APT': 'APT',
702
+ 'SCROLL': 'SCROLLETH',
703
+ 'TAIKO': 'TAIKOETH',
704
+ 'HYPE': 'HYPE',
705
+ 'ALGO': 'ALGO',
706
+ # KAVA: ['KAVA', 'KAVAEVM']
707
+ # SEI: ['SEI', 'SEIEVM']
708
+ 'LINEA': 'LINEAETH',
709
+ 'BLAST': 'BLASTETH',
710
+ 'XLM': 'XLM',
711
+ 'RSK': 'RBTC',
712
+ 'TON': 'TON',
713
+ 'MNT': 'MNT',
714
+ # 'RUNE': 'BTCRUNES', probably, cant verify atm
715
+ 'CELO': 'CELO',
716
+ 'HBAR': 'HBAR',
717
+ # 'FTM': SONIC REBRAND, todo
718
+ 'ZKSERA': 'ZKSERA',
719
+ 'KLAY': 'KLAY',
682
720
  'EOS': 'EOS',
683
- 'ERC20': 'ETH',
721
+ 'ACA': 'ACA',
722
+ # TLOS: ['TLOS', 'TLOSEVM']
723
+ # ASTR: ['ASTR', 'ASTREVM']
724
+ # CFX: ['CFX', 'CFXEVM']
725
+ 'XTZ': 'XTZ',
726
+ 'EGLD': 'EGLD',
727
+ 'GLMR': 'GLMR',
728
+ 'AURORA': 'AURORAEVM',
729
+ # others
730
+ 'KON': 'KONET',
684
731
  'GATECHAIN': 'GTEVM',
685
- 'HRC20': 'HT',
686
732
  'KUSAMA': 'KSMSM',
687
- 'NEAR': 'NEAR',
688
733
  'OKC': 'OKT',
689
- 'OPTIMISM': 'OPETH',
690
- 'POLKADOT': 'DOTSM',
691
- 'TRC20': 'TRX',
734
+ 'POLKADOT': 'DOTSM', # todo: DOT for main DOT
692
735
  'LUNA': 'LUNC',
693
- 'BASE': 'BASEEVM',
694
- 'BRC20': 'BTCBRC',
736
+ },
737
+ 'networksById': {
738
+ 'OPETH': 'OP',
695
739
  },
696
740
  'timeInForce': {
697
741
  'GTC': 'gtc',
@@ -3526,6 +3570,7 @@ class gate(Exchange, ImplicitAPI):
3526
3570
  #
3527
3571
  # public
3528
3572
  #
3573
+ # spot:
3529
3574
  # {
3530
3575
  # "id": "1334253759",
3531
3576
  # "create_time": "1626342738",
@@ -3536,6 +3581,18 @@ class gate(Exchange, ImplicitAPI):
3536
3581
  # "price": "32452.16"
3537
3582
  # }
3538
3583
  #
3584
+ # swap:
3585
+ #
3586
+ # {
3587
+ # "id": "442288327",
3588
+ # "contract": "BTC_USDT",
3589
+ # "create_time": "1739814676.707",
3590
+ # "create_time_ms": "1739814676.707",
3591
+ # "size": "-105",
3592
+ # "price": "95594.8"
3593
+ # }
3594
+ #
3595
+ #
3539
3596
  # public ws
3540
3597
  #
3541
3598
  # {
@@ -3612,8 +3669,14 @@ class gate(Exchange, ImplicitAPI):
3612
3669
  # }
3613
3670
  #
3614
3671
  id = self.safe_string_2(trade, 'id', 'trade_id')
3615
- timestamp = self.safe_timestamp_2(trade, 'time', 'create_time')
3616
- timestamp = self.safe_integer(trade, 'create_time_ms', timestamp)
3672
+ timestamp: Int = None
3673
+ msString = self.safe_string(trade, 'create_time_ms')
3674
+ if msString is not None:
3675
+ msString = Precise.string_mul(msString, '1000')
3676
+ msString = msString[0:13]
3677
+ timestamp = self.parse_to_int(msString)
3678
+ else:
3679
+ timestamp = self.safe_timestamp_2(trade, 'time', 'create_time')
3617
3680
  marketId = self.safe_string_2(trade, 'currency_pair', 'contract')
3618
3681
  marketType = 'contract' if ('contract' in trade) else 'spot'
3619
3682
  market = self.safe_market(marketId, market, '_', marketType)
@@ -981,9 +981,9 @@ class kraken(Exchange, ImplicitAPI):
981
981
  'high': self.safe_string(high, 1),
982
982
  'low': self.safe_string(low, 1),
983
983
  'bid': self.safe_string(bid, 0),
984
- 'bidVolume': None,
984
+ 'bidVolume': self.safe_string(bid, 2),
985
985
  'ask': self.safe_string(ask, 0),
986
- 'askVolume': None,
986
+ 'askVolume': self.safe_string(ask, 2),
987
987
  'vwap': vwap,
988
988
  'open': self.safe_string(ticker, 'o'),
989
989
  'close': last,