ccxt 4.1.28__py2.py3-none-any.whl → 4.1.30__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.1.28'
25
+ __version__ = '4.1.30'
26
26
 
27
27
  # ----------------------------------------------------------------------------
28
28
 
ccxt/abstract/bybit.py CHANGED
@@ -427,6 +427,7 @@ class ImplicitAPI:
427
427
  private_post_v5_position_trading_stop = privatePostV5PositionTradingStop = Entry('v5/position/trading-stop', 'private', 'POST', {'cost': 5})
428
428
  private_post_v5_position_set_auto_add_margin = privatePostV5PositionSetAutoAddMargin = Entry('v5/position/set-auto-add-margin', 'private', 'POST', {'cost': 2.5})
429
429
  private_post_v5_position_add_margin = privatePostV5PositionAddMargin = Entry('v5/position/add-margin', 'private', 'POST', {'cost': 2.5})
430
+ private_post_v5_position_confirm_pending_mmr = privatePostV5PositionConfirmPendingMmr = Entry('v5/position/confirm-pending-mmr', 'private', 'POST', {'cost': 2.5})
430
431
  private_post_v5_account_upgrade_to_uta = privatePostV5AccountUpgradeToUta = Entry('v5/account/upgrade-to-uta', 'private', 'POST', {'cost': 2.5})
431
432
  private_post_v5_account_set_margin_mode = privatePostV5AccountSetMarginMode = Entry('v5/account/set-margin-mode', 'private', 'POST', {'cost': 2.5})
432
433
  private_post_v5_account_mmp_modify = privatePostV5AccountMmpModify = Entry('v5/account/mmp-modify', 'private', 'POST', {'cost': 2.5})
ccxt/abstract/okex.py CHANGED
@@ -190,6 +190,7 @@ class ImplicitAPI:
190
190
  private_post_sprd_order = privatePostSprdOrder = Entry('sprd/order', 'private', 'POST', {'cost': 1})
191
191
  private_post_sprd_cancel_order = privatePostSprdCancelOrder = Entry('sprd/cancel-order', 'private', 'POST', {'cost': 1})
192
192
  private_post_sprd_mass_cancel = privatePostSprdMassCancel = Entry('sprd/mass-cancel', 'private', 'POST', {'cost': 1})
193
+ private_post_sprd_amend_order = privatePostSprdAmendOrder = Entry('sprd/amend-order', 'private', 'POST', {'cost': 1})
193
194
  private_post_trade_order = privatePostTradeOrder = Entry('trade/order', 'private', 'POST', {'cost': 0.3333333333333333})
194
195
  private_post_trade_batch_orders = privatePostTradeBatchOrders = Entry('trade/batch-orders', 'private', 'POST', {'cost': 0.06666666666666667})
195
196
  private_post_trade_cancel_order = privatePostTradeCancelOrder = Entry('trade/cancel-order', 'private', 'POST', {'cost': 0.3333333333333333})
ccxt/abstract/okex5.py CHANGED
@@ -190,6 +190,7 @@ class ImplicitAPI:
190
190
  private_post_sprd_order = privatePostSprdOrder = Entry('sprd/order', 'private', 'POST', {'cost': 1})
191
191
  private_post_sprd_cancel_order = privatePostSprdCancelOrder = Entry('sprd/cancel-order', 'private', 'POST', {'cost': 1})
192
192
  private_post_sprd_mass_cancel = privatePostSprdMassCancel = Entry('sprd/mass-cancel', 'private', 'POST', {'cost': 1})
193
+ private_post_sprd_amend_order = privatePostSprdAmendOrder = Entry('sprd/amend-order', 'private', 'POST', {'cost': 1})
193
194
  private_post_trade_order = privatePostTradeOrder = Entry('trade/order', 'private', 'POST', {'cost': 0.3333333333333333})
194
195
  private_post_trade_batch_orders = privatePostTradeBatchOrders = Entry('trade/batch-orders', 'private', 'POST', {'cost': 0.06666666666666667})
195
196
  private_post_trade_cancel_order = privatePostTradeCancelOrder = Entry('trade/cancel-order', 'private', 'POST', {'cost': 0.3333333333333333})
ccxt/abstract/okx.py CHANGED
@@ -190,6 +190,7 @@ class ImplicitAPI:
190
190
  private_post_sprd_order = privatePostSprdOrder = Entry('sprd/order', 'private', 'POST', {'cost': 1})
191
191
  private_post_sprd_cancel_order = privatePostSprdCancelOrder = Entry('sprd/cancel-order', 'private', 'POST', {'cost': 1})
192
192
  private_post_sprd_mass_cancel = privatePostSprdMassCancel = Entry('sprd/mass-cancel', 'private', 'POST', {'cost': 1})
193
+ private_post_sprd_amend_order = privatePostSprdAmendOrder = Entry('sprd/amend-order', 'private', 'POST', {'cost': 1})
193
194
  private_post_trade_order = privatePostTradeOrder = Entry('trade/order', 'private', 'POST', {'cost': 0.3333333333333333})
194
195
  private_post_trade_batch_orders = privatePostTradeBatchOrders = Entry('trade/batch-orders', 'private', 'POST', {'cost': 0.06666666666666667})
195
196
  private_post_trade_cancel_order = privatePostTradeCancelOrder = Entry('trade/cancel-order', 'private', 'POST', {'cost': 0.3333333333333333})
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.1.28'
7
+ __version__ = '4.1.30'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # -----------------------------------------------------------------------------
4
4
 
5
- __version__ = '4.1.28'
5
+ __version__ = '4.1.30'
6
6
 
7
7
  # -----------------------------------------------------------------------------
8
8
 
@@ -9,7 +9,7 @@ import datetime
9
9
 
10
10
 
11
11
  def inflate(data):
12
- return decompress(data, -MAX_WBITS).decode('utf-8')
12
+ return decompress(data, -MAX_WBITS)
13
13
 
14
14
 
15
15
  def inflate64(data):
@@ -50,7 +50,7 @@ class bitget(Exchange, ImplicitAPI):
50
50
  'has': {
51
51
  'CORS': None,
52
52
  'spot': True,
53
- 'margin': None,
53
+ 'margin': True,
54
54
  'swap': True,
55
55
  'future': True,
56
56
  'option': False,
@@ -65,6 +65,7 @@ class bitget(Exchange, ImplicitAPI):
65
65
  'editOrder': True,
66
66
  'fetchAccounts': False,
67
67
  'fetchBalance': True,
68
+ 'fetchBorrowInterest': True,
68
69
  'fetchBorrowRate': True,
69
70
  'fetchBorrowRateHistories': False,
70
71
  'fetchBorrowRateHistory': False,
@@ -1488,19 +1489,43 @@ class bitget(Exchange, ImplicitAPI):
1488
1489
  """
1489
1490
  retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes for a single market
1490
1491
  :see: https://bitgetlimited.github.io/apidoc/en/mix/#get-position-tier
1492
+ :see: https://bitgetlimited.github.io/apidoc/en/margin/#get-isolated-tier-data
1493
+ :see: https://bitgetlimited.github.io/apidoc/en/margin/#get-cross-tier-data
1491
1494
  :param str symbol: unified market symbol
1492
1495
  :param dict [params]: extra parameters specific to the bitget api endpoint
1496
+ :param str [params.marginMode]: for spot margin 'cross' or 'isolated', default is 'isolated'
1497
+ :param str [params.code]: required for cross spot margin
1493
1498
  :returns dict: a `leverage tiers structure <https://github.com/ccxt/ccxt/wiki/Manual#leverage-tiers-structure>`
1494
1499
  """
1495
1500
  await self.load_markets()
1496
1501
  request = {}
1497
- market = None
1498
1502
  market = self.market(symbol)
1499
- if market['spot']:
1503
+ type = None
1504
+ type, params = self.handle_market_type_and_params('fetchMarketLeverageTiers', market, params)
1505
+ response = None
1506
+ marginMode = None
1507
+ marginMode, params = self.handle_margin_mode_and_params('fetchMarketLeverageTiers', params, 'isolated')
1508
+ if (type == 'swap') or (type == 'future'):
1509
+ marketId = market['id']
1510
+ parts = marketId.split('_')
1511
+ productType = self.safe_string_upper(parts, 1)
1512
+ request['symbol'] = marketId
1513
+ request['productType'] = productType
1514
+ response = await self.publicMixGetMarketQueryPositionLever(self.extend(request, params))
1515
+ elif marginMode == 'isolated':
1516
+ request['symbol'] = market['info']['symbolName']
1517
+ response = await self.publicMarginGetIsolatedPublicTierData(self.extend(request, params))
1518
+ elif marginMode == 'cross':
1519
+ code = self.safe_string(params, 'code')
1520
+ self.check_required_argument('fetchMarketLeverageTiers', code, 'code')
1521
+ params = self.omit(params, 'code')
1522
+ currency = self.currency(code)
1523
+ request['coin'] = currency['code']
1524
+ response = await self.publicMarginGetCrossPublicTierData(self.extend(request, params))
1525
+ else:
1500
1526
  raise BadRequest(self.id + ' fetchMarketLeverageTiers() symbol does not support market ' + symbol)
1501
- request['symbol'] = market['id']
1502
- request['productType'] = 'UMCBL'
1503
- response = await self.publicMixGetMarketQueryPositionLever(self.extend(request, params))
1527
+ #
1528
+ # swap and future
1504
1529
  #
1505
1530
  # {
1506
1531
  # "code":"00000",
@@ -1517,10 +1542,50 @@ class bitget(Exchange, ImplicitAPI):
1517
1542
  # "requestTime":1627292076687
1518
1543
  # }
1519
1544
  #
1520
- result = self.safe_value(response, 'data')
1545
+ # isolated
1546
+ #
1547
+ # {
1548
+ # "code": "00000",
1549
+ # "msg": "success",
1550
+ # "requestTime": 1698352496622,
1551
+ # "data": [
1552
+ # {
1553
+ # "tier": "1",
1554
+ # "symbol": "BTCUSDT",
1555
+ # "leverage": "10",
1556
+ # "baseCoin": "BTC",
1557
+ # "quoteCoin": "USDT",
1558
+ # "baseMaxBorrowableAmount": "3",
1559
+ # "quoteMaxBorrowableAmount": "30000",
1560
+ # "maintainMarginRate": "0.05",
1561
+ # "initRate": "0.1111"
1562
+ # },
1563
+ # ]
1564
+ # }
1565
+ #
1566
+ # cross
1567
+ #
1568
+ # {
1569
+ # "code": "00000",
1570
+ # "msg": "success",
1571
+ # "requestTime": 1698352997077,
1572
+ # "data": [
1573
+ # {
1574
+ # "tier": "1",
1575
+ # "leverage": "3",
1576
+ # "coin": "BTC",
1577
+ # "maxBorrowableAmount": "26",
1578
+ # "maintainMarginRate": "0.1"
1579
+ # }
1580
+ # ]
1581
+ # }
1582
+ #
1583
+ result = self.safe_value(response, 'data', [])
1521
1584
  return self.parse_market_leverage_tiers(result, market)
1522
1585
 
1523
1586
  def parse_market_leverage_tiers(self, info, market=None):
1587
+ #
1588
+ # swap and future
1524
1589
  #
1525
1590
  # [
1526
1591
  # {
@@ -1530,22 +1595,56 @@ class bitget(Exchange, ImplicitAPI):
1530
1595
  # "leverage": 125,
1531
1596
  # "keepMarginRate": "0.004"
1532
1597
  # }
1533
- # ],
1598
+ # ]
1599
+ #
1600
+ # isolated
1601
+ #
1602
+ # [
1603
+ # {
1604
+ # "tier": "1",
1605
+ # "symbol": "BTCUSDT",
1606
+ # "leverage": "10",
1607
+ # "baseCoin": "BTC",
1608
+ # "quoteCoin": "USDT",
1609
+ # "baseMaxBorrowableAmount": "3",
1610
+ # "quoteMaxBorrowableAmount": "30000",
1611
+ # "maintainMarginRate": "0.05",
1612
+ # "initRate": "0.1111"
1613
+ # }
1614
+ # ]
1615
+ #
1616
+ # cross
1617
+ #
1618
+ # [
1619
+ # {
1620
+ # "tier": "1",
1621
+ # "leverage": "3",
1622
+ # "coin": "BTC",
1623
+ # "maxBorrowableAmount": "26",
1624
+ # "maintainMarginRate": "0.1"
1625
+ # }
1626
+ # ]
1534
1627
  #
1535
1628
  tiers = []
1629
+ minNotional = 0
1536
1630
  for i in range(0, len(info)):
1537
1631
  item = info[i]
1538
- minNotional = self.safe_number(item, 'startUnit')
1539
- maxNotional = self.safe_number(item, 'endUnit')
1632
+ minimumNotional = self.safe_number(item, 'startUnit')
1633
+ if minimumNotional is not None:
1634
+ minNotional = minimumNotional
1635
+ maxNotional = self.safe_number_n(item, ['endUnit', 'maxBorrowableAmount', 'baseMaxBorrowableAmount'])
1636
+ marginCurrency = self.safe_string_2(item, 'coin', 'baseCoin')
1637
+ currencyId = marginCurrency if (marginCurrency is not None) else market['base']
1540
1638
  tiers.append({
1541
- 'tier': self.sum(i, 1),
1542
- 'currency': market['base'],
1639
+ 'tier': self.safe_integer_2(item, 'level', 'tier'),
1640
+ 'currency': self.safe_currency_code(currencyId),
1543
1641
  'minNotional': minNotional,
1544
1642
  'maxNotional': maxNotional,
1545
- 'maintenanceMarginRate': self.safe_number(item, 'keepMarginRate'),
1643
+ 'maintenanceMarginRate': self.safe_number_2(item, 'keepMarginRate', 'maintainMarginRate'),
1546
1644
  'maxLeverage': self.safe_number(item, 'leverage'),
1547
1645
  'info': item,
1548
1646
  })
1647
+ minNotional = maxNotional
1549
1648
  return tiers
1550
1649
 
1551
1650
  async def fetch_deposits(self, code: Optional[str] = None, since: Optional[int] = None, limit: Optional[int] = None, params={}):
@@ -3168,12 +3267,16 @@ class bitget(Exchange, ImplicitAPI):
3168
3267
  create a list of trade orders(all orders should be of the same symbol)
3169
3268
  :see: https://bitgetlimited.github.io/apidoc/en/spot/#batch-order
3170
3269
  :see: https://bitgetlimited.github.io/apidoc/en/mix/#batch-order
3270
+ :see: https://bitgetlimited.github.io/apidoc/en/margin/#isolated-batch-order
3271
+ :see: https://bitgetlimited.github.io/apidoc/en/margin/#cross-batch-order
3171
3272
  :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
3273
+ :param dict [params]: extra parameters specific to the api endpoint
3172
3274
  :returns dict: an `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
3173
3275
  """
3174
3276
  await self.load_markets()
3175
3277
  ordersRequests = []
3176
3278
  symbol = None
3279
+ marginMode = None
3177
3280
  for i in range(0, len(orders)):
3178
3281
  rawOrder = orders[i]
3179
3282
  marketId = self.safe_string(rawOrder, 'symbol')
@@ -3187,20 +3290,34 @@ class bitget(Exchange, ImplicitAPI):
3187
3290
  amount = self.safe_value(rawOrder, 'amount')
3188
3291
  price = self.safe_value(rawOrder, 'price')
3189
3292
  orderParams = self.safe_value(rawOrder, 'params', {})
3293
+ marginResult = self.handle_margin_mode_and_params('createOrders', params)
3294
+ currentMarginMode = marginResult[0]
3295
+ if currentMarginMode is not None:
3296
+ if marginMode is None:
3297
+ marginMode = currentMarginMode
3298
+ else:
3299
+ if marginMode != currentMarginMode:
3300
+ raise BadRequest(self.id + ' createOrders() requires all orders to have the same margin mode(isolated or cross)')
3190
3301
  orderRequest = self.create_order_request(marketId, type, side, amount, price, orderParams)
3191
3302
  ordersRequests.append(orderRequest)
3192
3303
  market = self.market(symbol)
3304
+ symbolRequest = (market['info']['symbolName']) if (marginMode is not None) else (market['id'])
3193
3305
  request = {
3194
- 'symbol': market['id'],
3306
+ 'symbol': symbolRequest,
3195
3307
  }
3196
3308
  response = None
3197
3309
  if market['spot']:
3198
3310
  request['orderList'] = ordersRequests
3199
- response = await self.privateSpotPostTradeBatchOrders(request)
3200
- else:
3311
+ if (market['swap']) or (market['future']):
3201
3312
  request['orderDataList'] = ordersRequests
3202
3313
  request['marginCoin'] = market['settleId']
3203
3314
  response = await self.privateMixPostOrderBatchOrders(request)
3315
+ elif marginMode == 'isolated':
3316
+ response = await self.privateMarginPostIsolatedOrderBatchPlaceOrder(request)
3317
+ elif marginMode == 'cross':
3318
+ response = await self.privateMarginPostCrossOrderBatchPlaceOrder(request)
3319
+ else:
3320
+ response = await self.privateSpotPostTradeBatchOrders(request)
3204
3321
  #
3205
3322
  # {
3206
3323
  # "code": "00000",
@@ -5955,6 +6072,138 @@ class bitget(Exchange, ImplicitAPI):
5955
6072
  'info': info,
5956
6073
  }
5957
6074
 
6075
+ async def fetch_borrow_interest(self, code: Optional[str] = None, symbol: Optional[str] = None, since: Optional[int] = None, limit: Optional[int] = None, params={}):
6076
+ """
6077
+ fetch the interest owed by the user for borrowing currency for margin trading
6078
+ :see: https://bitgetlimited.github.io/apidoc/en/margin/#get-isolated-interest-records
6079
+ :see: https://bitgetlimited.github.io/apidoc/en/margin/#get-cross-interest-records
6080
+ :param str [code]: unified currency code
6081
+ :param str [symbol]: unified market symbol when fetching interest in isolated markets
6082
+ :param int [since]: the earliest time in ms to fetch borrow interest for
6083
+ :param int [limit]: the maximum number of structures to retrieve
6084
+ :param dict [params]: extra parameters specific to the bitget api endpoint
6085
+ :returns dict[]: a list of `borrow interest structures <https://github.com/ccxt/ccxt/wiki/Manual#borrow-interest-structure>`
6086
+ """
6087
+ await self.load_markets()
6088
+ market = None
6089
+ if symbol is not None:
6090
+ market = self.market(symbol)
6091
+ request = {}
6092
+ currency = None
6093
+ if code is not None:
6094
+ currency = self.currency(code)
6095
+ request['coin'] = currency['id']
6096
+ if since is not None:
6097
+ request['startTime'] = since
6098
+ else:
6099
+ request['startTime'] = self.milliseconds() - 7776000000
6100
+ if limit is not None:
6101
+ request['pageSize'] = limit
6102
+ response = None
6103
+ marginMode = None
6104
+ marginMode, params = self.handle_margin_mode_and_params('fetchBorrowInterest', params, 'cross')
6105
+ if marginMode == 'isolated':
6106
+ self.check_required_symbol('fetchBorrowInterest', symbol)
6107
+ request['symbol'] = market['info']['symbolName']
6108
+ response = await self.privateMarginGetIsolatedInterestList(self.extend(request, params))
6109
+ elif marginMode == 'cross':
6110
+ response = await self.privateMarginGetCrossInterestList(self.extend(request, params))
6111
+ #
6112
+ # isolated
6113
+ #
6114
+ # {
6115
+ # "code": "00000",
6116
+ # "msg": "success",
6117
+ # "requestTime": 1698282523888,
6118
+ # "data": {
6119
+ # "resultList": [
6120
+ # {
6121
+ # "interestId": "1100560904468705284",
6122
+ # "interestCoin": "USDT",
6123
+ # "interestRate": "0.000126279",
6124
+ # "loanCoin": "USDT",
6125
+ # "amount": "0.00000298",
6126
+ # "type": "scheduled",
6127
+ # "symbol": "BTCUSDT",
6128
+ # "ctime": "1698120000000"
6129
+ # },
6130
+ # ],
6131
+ # "maxId": "1100560904468705284",
6132
+ # "minId": "1096915487398965249"
6133
+ # }
6134
+ # }
6135
+ #
6136
+ # cross
6137
+ #
6138
+ # {
6139
+ # "code": "00000",
6140
+ # "msg": "success",
6141
+ # "requestTime": 1698282552126,
6142
+ # "data": {
6143
+ # "resultList": [
6144
+ # {
6145
+ # "interestId": "1099126154352799744",
6146
+ # "interestCoin": "USDT",
6147
+ # "interestRate": "0.000126279",
6148
+ # "loanCoin": "USDT",
6149
+ # "amount": "0.00002631",
6150
+ # "type": "scheduled",
6151
+ # "ctime": "1697778000000"
6152
+ # },
6153
+ # ],
6154
+ # "maxId": "1099126154352799744",
6155
+ # "minId": "1096917004629716993"
6156
+ # }
6157
+ # }
6158
+ #
6159
+ data = self.safe_value(response, 'data', {})
6160
+ rows = self.safe_value(data, 'resultList', [])
6161
+ interest = self.parse_borrow_interests(rows, market)
6162
+ return self.filter_by_currency_since_limit(interest, code, since, limit)
6163
+
6164
+ def parse_borrow_interest(self, info, market=None):
6165
+ #
6166
+ # isolated
6167
+ #
6168
+ # {
6169
+ # "interestId": "1100560904468705284",
6170
+ # "interestCoin": "USDT",
6171
+ # "interestRate": "0.000126279",
6172
+ # "loanCoin": "USDT",
6173
+ # "amount": "0.00000298",
6174
+ # "type": "scheduled",
6175
+ # "symbol": "BTCUSDT",
6176
+ # "ctime": "1698120000000"
6177
+ # }
6178
+ #
6179
+ # cross
6180
+ #
6181
+ # {
6182
+ # "interestId": "1099126154352799744",
6183
+ # "interestCoin": "USDT",
6184
+ # "interestRate": "0.000126279",
6185
+ # "loanCoin": "USDT",
6186
+ # "amount": "0.00002631",
6187
+ # "type": "scheduled",
6188
+ # "ctime": "1697778000000"
6189
+ # }
6190
+ #
6191
+ marketId = self.safe_string(info, 'symbol')
6192
+ market = self.safe_market(marketId, market)
6193
+ marginMode = 'isolated' if (marketId is not None) else 'cross'
6194
+ timestamp = self.safe_integer(info, 'ctime')
6195
+ return {
6196
+ 'symbol': self.safe_string(market, 'symbol'),
6197
+ 'marginMode': marginMode,
6198
+ 'currency': self.safe_currency_code(self.safe_string(info, 'interestCoin')),
6199
+ 'interest': self.safe_number(info, 'amount'),
6200
+ 'interestRate': self.safe_number(info, 'interestRate'),
6201
+ 'amountBorrowed': None,
6202
+ 'timestamp': timestamp,
6203
+ 'datetime': self.iso8601(timestamp),
6204
+ 'info': info,
6205
+ }
6206
+
5958
6207
  def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
5959
6208
  if not response:
5960
6209
  return None # fallback to default error handler
@@ -1071,13 +1071,13 @@ class bitopro(Exchange, ImplicitAPI):
1071
1071
  request = {
1072
1072
  # 'pair': market['id'], # optional
1073
1073
  }
1074
- # privateDeleteOrdersAll or privateDeleteOrdersPair
1075
- method = self.safe_string(self.options, 'privateDeleteOrdersPair', 'privateDeleteOrdersAll')
1074
+ response = None
1076
1075
  if symbol is not None:
1077
1076
  market = self.market(symbol)
1078
1077
  request['pair'] = market['id']
1079
- method = 'privateDeleteOrdersPair'
1080
- response = await getattr(self, method)(self.extend(request, params))
1078
+ response = await self.privateDeleteOrdersPair(self.extend(request, params))
1079
+ else:
1080
+ response = await self.privateDeleteOrdersAll(self.extend(request, params))
1081
1081
  result = self.safe_value(response, 'data', {})
1082
1082
  #
1083
1083
  # {
@@ -794,6 +794,16 @@ class bitrue(Exchange, ImplicitAPI):
794
794
  return orderbook
795
795
 
796
796
  def parse_ticker(self, ticker, market=None):
797
+ #
798
+ # fetchBidsAsks
799
+ #
800
+ # {
801
+ # "symbol": "LTCBTC",
802
+ # "bidPrice": "4.00000000",
803
+ # "bidQty": "431.00000000",
804
+ # "askPrice": "4.00000200",
805
+ # "askQty": "9.00000000"
806
+ # }
797
807
  #
798
808
  # fetchTicker
799
809
  #
@@ -818,10 +828,10 @@ class bitrue(Exchange, ImplicitAPI):
818
828
  'datetime': None,
819
829
  'high': self.safe_string(ticker, 'high24hr'),
820
830
  'low': self.safe_string(ticker, 'low24hr'),
821
- 'bid': self.safe_string(ticker, 'highestBid'),
822
- 'bidVolume': None,
823
- 'ask': self.safe_string(ticker, 'lowestAsk'),
824
- 'askVolume': None,
831
+ 'bid': self.safe_string_2(ticker, 'highestBid', 'bidPrice'),
832
+ 'bidVolume': self.safe_string(ticker, 'bidQty'),
833
+ 'ask': self.safe_string_2(ticker, 'lowestAsk', 'askPrice'),
834
+ 'askVolume': self.safe_string(ticker, 'askQty'),
825
835
  'vwap': None,
826
836
  'open': None,
827
837
  'close': last,
@@ -941,23 +951,30 @@ class bitrue(Exchange, ImplicitAPI):
941
951
  async def fetch_bids_asks(self, symbols: Optional[List[str]] = None, params={}):
942
952
  """
943
953
  fetches the bid and ask price and volume for multiple markets
954
+ :see: https://github.com/Bitrue-exchange/Spot-official-api-docs#symbol-order-book-ticker
944
955
  :param str[]|None symbols: unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
945
956
  :param dict [params]: extra parameters specific to the bitrue api endpoint
946
957
  :returns dict: a dictionary of `ticker structures <https://github.com/ccxt/ccxt/wiki/Manual#ticker-structure>`
947
958
  """
948
959
  await self.load_markets()
949
- defaultType = self.safe_string_2(self.options, 'fetchBidsAsks', 'defaultType', 'spot')
950
- type = self.safe_string(params, 'type', defaultType)
951
- query = self.omit(params, 'type')
952
- method = None
953
- if type == 'future':
954
- method = 'fapiPublicGetTickerBookTicker'
955
- elif type == 'delivery':
956
- method = 'dapiPublicGetTickerBookTicker'
957
- else:
958
- method = 'publicGetTickerBookTicker'
959
- response = await getattr(self, method)(query)
960
- return self.parse_tickers(response, symbols)
960
+ symbols = self.market_symbols(symbols)
961
+ market = None
962
+ request = {}
963
+ if symbols is not None:
964
+ first = self.safe_string(symbols, 0)
965
+ market = self.market(first)
966
+ request['symbol'] = market['id']
967
+ response = await self.v1PublicGetTickerBookTicker(self.extend(request, params))
968
+ # {
969
+ # "symbol": "LTCBTC",
970
+ # "bidPrice": "4.00000000",
971
+ # "bidQty": "431.00000000",
972
+ # "askPrice": "4.00000200",
973
+ # "askQty": "9.00000000"
974
+ # }
975
+ data = {}
976
+ data[market['id']] = response
977
+ return self.parse_tickers(data, symbols)
961
978
 
962
979
  async def fetch_tickers(self, symbols: Optional[List[str]] = None, params={}):
963
980
  """
@@ -635,6 +635,7 @@ class bybit(Exchange, ImplicitAPI):
635
635
  'v5/position/trading-stop': 5, # 10/s => cost = 50 / 10 = 5
636
636
  'v5/position/set-auto-add-margin': 2.5,
637
637
  'v5/position/add-margin': 2.5,
638
+ 'v5/position/confirm-pending-mmr': 2.5,
638
639
  # account
639
640
  'v5/account/upgrade-to-uta': 2.5,
640
641
  'v5/account/set-margin-mode': 2.5,
@@ -3072,8 +3073,11 @@ class bybit(Exchange, ImplicitAPI):
3072
3073
  # "time": 1672125441042
3073
3074
  # }
3074
3075
  #
3076
+ timestamp = self.safe_integer(response, 'time')
3075
3077
  result = {
3076
3078
  'info': response,
3079
+ 'timestamp': timestamp,
3080
+ 'datetime': self.iso8601(timestamp),
3077
3081
  }
3078
3082
  responseResult = self.safe_value(response, 'result', {})
3079
3083
  currencyList = self.safe_value_n(responseResult, ['loanAccountList', 'list', 'balance'])
@@ -50,6 +50,7 @@ class cryptocom(Exchange, ImplicitAPI):
50
50
  'borrowMargin': True,
51
51
  'cancelAllOrders': True,
52
52
  'cancelOrder': True,
53
+ 'cancelOrders': True,
53
54
  'createOrder': True,
54
55
  'createOrders': True,
55
56
  'fetchAccounts': True,
@@ -1323,6 +1324,34 @@ class cryptocom(Exchange, ImplicitAPI):
1323
1324
  result = self.safe_value(response, 'result', {})
1324
1325
  return self.parse_order(result, market)
1325
1326
 
1327
+ async def cancel_orders(self, ids, symbol: Optional[str] = None, params={}):
1328
+ """
1329
+ cancel multiple orders
1330
+ :see: https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-cancel-order-list-list
1331
+ :param str[] ids: order ids
1332
+ :param str symbol: unified market symbol
1333
+ :param dict [params]: extra parameters specific to the okx api endpoint
1334
+ :returns dict: an list of `order structures <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
1335
+ """
1336
+ self.check_required_symbol('cancelOrders', symbol)
1337
+ await self.load_markets()
1338
+ market = self.market(symbol)
1339
+ orderRequests = []
1340
+ for i in range(0, len(ids)):
1341
+ id = ids[i]
1342
+ order = {
1343
+ 'instrument_name': market['id'],
1344
+ 'order_id': str(id),
1345
+ }
1346
+ orderRequests.append(order)
1347
+ request = {
1348
+ 'contingency_type': 'LIST',
1349
+ 'order_list': orderRequests,
1350
+ }
1351
+ response = await self.v1PrivatePostPrivateCancelOrderList(self.extend(request, params))
1352
+ result = self.safe_value(response, 'result', [])
1353
+ return self.parse_orders(result, market, None, None, params)
1354
+
1326
1355
  async def fetch_open_orders(self, symbol: Optional[str] = None, since: Optional[int] = None, limit: Optional[int] = None, params={}):
1327
1356
  """
1328
1357
  fetch all unfilled currently open orders