ccxt 4.4.72__py2.py3-none-any.whl → 4.4.74__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 (68) hide show
  1. ccxt/__init__.py +1 -7
  2. ccxt/abstract/bitmart.py +2 -0
  3. ccxt/ace.py +39 -1
  4. ccxt/alpaca.py +49 -0
  5. ccxt/ascendex.py +7 -1
  6. ccxt/async_support/__init__.py +1 -7
  7. ccxt/async_support/ace.py +39 -1
  8. ccxt/async_support/alpaca.py +49 -0
  9. ccxt/async_support/ascendex.py +7 -1
  10. ccxt/async_support/base/exchange.py +1 -1
  11. ccxt/async_support/bequant.py +1 -0
  12. ccxt/async_support/binance.py +18 -14
  13. ccxt/async_support/binanceusdm.py +1 -1
  14. ccxt/async_support/bit2c.py +37 -0
  15. ccxt/async_support/bitbank.py +32 -0
  16. ccxt/async_support/bitbns.py +1 -1
  17. ccxt/async_support/bitflyer.py +1 -0
  18. ccxt/async_support/bitget.py +6 -5
  19. ccxt/async_support/bithumb.py +34 -0
  20. ccxt/async_support/bitmart.py +70 -6
  21. ccxt/async_support/bitrue.py +1 -1
  22. ccxt/async_support/blofin.py +1 -1
  23. ccxt/async_support/bybit.py +42 -26
  24. ccxt/async_support/coinlist.py +81 -11
  25. ccxt/async_support/defx.py +1 -1
  26. ccxt/async_support/deribit.py +19 -0
  27. ccxt/async_support/derive.py +2 -0
  28. ccxt/async_support/gate.py +11 -7
  29. ccxt/async_support/hitbtc.py +7 -1
  30. ccxt/async_support/okx.py +4 -0
  31. ccxt/base/errors.py +0 -6
  32. ccxt/base/exchange.py +26 -14
  33. ccxt/bequant.py +1 -0
  34. ccxt/binance.py +18 -14
  35. ccxt/binanceusdm.py +1 -1
  36. ccxt/bit2c.py +37 -0
  37. ccxt/bitbank.py +32 -0
  38. ccxt/bitbns.py +1 -1
  39. ccxt/bitflyer.py +1 -0
  40. ccxt/bitget.py +6 -5
  41. ccxt/bithumb.py +34 -0
  42. ccxt/bitmart.py +70 -6
  43. ccxt/bitrue.py +1 -1
  44. ccxt/blofin.py +1 -1
  45. ccxt/bybit.py +42 -26
  46. ccxt/coinlist.py +81 -11
  47. ccxt/defx.py +1 -1
  48. ccxt/deribit.py +19 -0
  49. ccxt/derive.py +2 -0
  50. ccxt/gate.py +11 -7
  51. ccxt/hitbtc.py +7 -1
  52. ccxt/okx.py +4 -0
  53. ccxt/pro/__init__.py +1 -7
  54. ccxt/pro/ascendex.py +1 -1
  55. ccxt/pro/bingx.py +9 -1
  56. ccxt/pro/bitget.py +9 -1
  57. ccxt/pro/bitmart.py +9 -1
  58. ccxt/pro/bitopro.py +5 -4
  59. ccxt/test/tests_async.py +6 -3
  60. ccxt/test/tests_sync.py +6 -3
  61. {ccxt-4.4.72.dist-info → ccxt-4.4.74.dist-info}/METADATA +5 -5
  62. {ccxt-4.4.72.dist-info → ccxt-4.4.74.dist-info}/RECORD +65 -68
  63. ccxt/abstract/bitcoincom.py +0 -115
  64. ccxt/abstract/bitfinex1.py +0 -69
  65. ccxt/abstract/bitpanda.py +0 -23
  66. {ccxt-4.4.72.dist-info → ccxt-4.4.74.dist-info}/LICENSE.txt +0 -0
  67. {ccxt-4.4.72.dist-info → ccxt-4.4.74.dist-info}/WHEEL +0 -0
  68. {ccxt-4.4.72.dist-info → ccxt-4.4.74.dist-info}/top_level.txt +0 -0
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.bybit import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Any, Balances, BorrowInterest, Conversion, CrossBorrowRate, Currencies, Currency, DepositAddress, Greeks, Int, LedgerEntry, Leverage, LeverageTier, LeverageTiers, LongShortRatio, Market, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, MarketInterface, TransferEntry
10
+ from ccxt.base.types import Any, Balances, BorrowInterest, Conversion, CrossBorrowRate, Currencies, Currency, DepositAddress, FundingHistory, Greeks, Int, LedgerEntry, Leverage, LeverageTier, LeverageTiers, Liquidation, LongShortRatio, Market, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, MarketInterface, TransferEntry
11
11
  from typing import List
12
12
  from ccxt.base.errors import ExchangeError
13
13
  from ccxt.base.errors import AuthenticationError
@@ -2390,6 +2390,7 @@ class bybit(Exchange, ImplicitAPI):
2390
2390
  :returns dict: an array of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
2391
2391
  """
2392
2392
  await self.load_markets()
2393
+ code = self.safe_string_n(params, ['code', 'currency', 'baseCoin'])
2393
2394
  market = None
2394
2395
  parsedSymbols = None
2395
2396
  if symbols is not None:
@@ -2411,6 +2412,12 @@ class bybit(Exchange, ImplicitAPI):
2411
2412
  currentType = market['type']
2412
2413
  elif market['type'] != currentType:
2413
2414
  raise BadRequest(self.id + ' fetchTickers can only accept a list of symbols of the same type')
2415
+ if market['option']:
2416
+ if code is not None and code != market['base']:
2417
+ raise BadRequest(self.id + ' fetchTickers the base currency must be the same for all symbols, self endpoint only supports one base currency at a time. Read more about it here: https://bybit-exchange.github.io/docs/v5/market/tickers')
2418
+ if code is None:
2419
+ code = market['base']
2420
+ params = self.omit(params, ['code', 'currency'])
2414
2421
  parsedSymbols.append(market['symbol'])
2415
2422
  request: dict = {
2416
2423
  # 'symbol': market['id'],
@@ -2430,7 +2437,9 @@ class bybit(Exchange, ImplicitAPI):
2430
2437
  request['category'] = 'spot'
2431
2438
  elif type == 'option':
2432
2439
  request['category'] = 'option'
2433
- request['baseCoin'] = self.safe_string(params, 'baseCoin', 'BTC')
2440
+ if code is None:
2441
+ code = 'BTC'
2442
+ request['baseCoin'] = code
2434
2443
  elif type == 'swap' or type == 'future' or subType is not None:
2435
2444
  request['category'] = subType
2436
2445
  response = await self.publicGetV5MarketTickers(self.extend(request, params))
@@ -2476,7 +2485,7 @@ class bybit(Exchange, ImplicitAPI):
2476
2485
  tickerList = self.safe_list(result, 'list', [])
2477
2486
  return self.parse_tickers(tickerList, parsedSymbols)
2478
2487
 
2479
- async def fetch_bids_asks(self, symbols: Strings = None, params={}):
2488
+ async def fetch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
2480
2489
  """
2481
2490
  fetches the bid and ask price and volume for multiple markets
2482
2491
 
@@ -3690,7 +3699,7 @@ class bybit(Exchange, ImplicitAPI):
3690
3699
  'trades': None,
3691
3700
  }, market)
3692
3701
 
3693
- async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
3702
+ async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}) -> Order:
3694
3703
  """
3695
3704
  create a market buy order by providing the symbol and cost
3696
3705
 
@@ -3707,7 +3716,7 @@ class bybit(Exchange, ImplicitAPI):
3707
3716
  raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
3708
3717
  return await self.create_order(symbol, 'market', 'buy', cost, 1, params)
3709
3718
 
3710
- async def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}):
3719
+ async def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}) -> Order:
3711
3720
  """
3712
3721
  create a market sell order by providing the symbol and cost
3713
3722
 
@@ -3728,7 +3737,7 @@ class bybit(Exchange, ImplicitAPI):
3728
3737
  raise NotSupported(self.id + ' createMarketSellOrderWithCost() supports spot orders only')
3729
3738
  return await self.create_order(symbol, 'market', 'sell', cost, 1, params)
3730
3739
 
3731
- async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
3740
+ async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
3732
3741
  """
3733
3742
  create a trade order
3734
3743
 
@@ -3987,7 +3996,7 @@ class bybit(Exchange, ImplicitAPI):
3987
3996
  params = self.omit(params, ['stopPrice', 'timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'clientOrderId', 'triggerPrice', 'stopLoss', 'takeProfit', 'trailingAmount', 'trailingTriggerPrice', 'hedged'])
3988
3997
  return self.extend(request, params)
3989
3998
 
3990
- async def create_orders(self, orders: List[OrderRequest], params={}):
3999
+ async def create_orders(self, orders: List[OrderRequest], params={}) -> List[Order]:
3991
4000
  """
3992
4001
  create a list of trade orders
3993
4002
 
@@ -4137,7 +4146,7 @@ class bybit(Exchange, ImplicitAPI):
4137
4146
  params = self.omit(params, ['stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerPrice', 'clientOrderId', 'stopLoss', 'takeProfit'])
4138
4147
  return request
4139
4148
 
4140
- async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
4149
+ async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}) -> Order:
4141
4150
  """
4142
4151
  edit a trade order
4143
4152
 
@@ -4187,7 +4196,7 @@ class bybit(Exchange, ImplicitAPI):
4187
4196
  'id': self.safe_string(result, 'orderId'),
4188
4197
  })
4189
4198
 
4190
- async def edit_orders(self, orders: List[OrderRequest], params={}):
4199
+ async def edit_orders(self, orders: List[OrderRequest], params={}) -> List[Order]:
4191
4200
  """
4192
4201
  edit a list of trade orders
4193
4202
 
@@ -4298,7 +4307,7 @@ class bybit(Exchange, ImplicitAPI):
4298
4307
  request['category'] = 'option'
4299
4308
  return self.extend(request, params)
4300
4309
 
4301
- async def cancel_order(self, id: str, symbol: Str = None, params={}):
4310
+ async def cancel_order(self, id: str, symbol: Str = None, params={}) -> Order:
4302
4311
  """
4303
4312
  cancels an open order
4304
4313
 
@@ -4333,7 +4342,7 @@ class bybit(Exchange, ImplicitAPI):
4333
4342
  result = self.safe_dict(response, 'result', {})
4334
4343
  return self.parse_order(result, market)
4335
4344
 
4336
- async def cancel_orders(self, ids, symbol: Str = None, params={}):
4345
+ async def cancel_orders(self, ids, symbol: Str = None, params={}) -> List[Order]:
4337
4346
  """
4338
4347
  cancel multiple orders
4339
4348
 
@@ -4602,7 +4611,7 @@ class bybit(Exchange, ImplicitAPI):
4602
4611
  return response
4603
4612
  return self.parse_orders(orders, market)
4604
4613
 
4605
- async def fetch_order_classic(self, id: str, symbol: Str = None, params={}):
4614
+ async def fetch_order_classic(self, id: str, symbol: Str = None, params={}) -> Order:
4606
4615
  """
4607
4616
  fetches information on an order made by the user *classic accounts only*
4608
4617
 
@@ -4847,7 +4856,7 @@ classic accounts only/ spot not supported* fetches information on an order made
4847
4856
  data = self.add_pagination_cursor_to_result(response)
4848
4857
  return self.parse_orders(data, market, since, limit)
4849
4858
 
4850
- async def fetch_closed_order(self, id: str, symbol: Str = None, params={}):
4859
+ async def fetch_closed_order(self, id: str, symbol: Str = None, params={}) -> Order:
4851
4860
  """
4852
4861
  fetches information on a closed order made by the user
4853
4862
 
@@ -4877,7 +4886,7 @@ classic accounts only/ spot not supported* fetches information on an order made
4877
4886
  raise InvalidOrder(self.id + ' returned more than one order')
4878
4887
  return self.safe_value(result, 0)
4879
4888
 
4880
- async def fetch_open_order(self, id: str, symbol: Str = None, params={}):
4889
+ async def fetch_open_order(self, id: str, symbol: Str = None, params={}) -> Order:
4881
4890
  """
4882
4891
  fetches information on an open order made by the user
4883
4892
 
@@ -5033,7 +5042,7 @@ classic accounts only/ spot not supported* fetches information on an order made
5033
5042
  }
5034
5043
  return await self.fetch_canceled_and_closed_orders(symbol, since, limit, self.extend(request, params))
5035
5044
 
5036
- async def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5045
+ async def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
5037
5046
  """
5038
5047
  fetches information on multiple canceled orders made by the user
5039
5048
 
@@ -5156,7 +5165,7 @@ classic accounts only/ spot not supported* fetches information on an order made
5156
5165
  data = self.add_pagination_cursor_to_result(response)
5157
5166
  return self.parse_orders(data, market, since, limit)
5158
5167
 
5159
- async def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5168
+ async def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
5160
5169
  """
5161
5170
  fetch all the trades made from a single order
5162
5171
 
@@ -5178,7 +5187,7 @@ classic accounts only/ spot not supported* fetches information on an order made
5178
5187
  params = self.omit(params, ['clientOrderId', 'orderLinkId'])
5179
5188
  return await self.fetch_my_trades(symbol, since, limit, self.extend(request, params))
5180
5189
 
5181
- async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5190
+ async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
5182
5191
  """
5183
5192
  fetch all trades made by the user
5184
5193
 
@@ -5901,7 +5910,7 @@ classic accounts only/ spot not supported* fetches information on an order made
5901
5910
  result = self.safe_dict(response, 'result', {})
5902
5911
  return self.parse_transaction(result, currency)
5903
5912
 
5904
- async def fetch_position(self, symbol: str, params={}):
5913
+ async def fetch_position(self, symbol: str, params={}) -> Position:
5905
5914
  """
5906
5915
  fetch data on a single open contract trade position
5907
5916
 
@@ -5972,7 +5981,7 @@ classic accounts only/ spot not supported* fetches information on an order made
5972
5981
  position['datetime'] = self.iso8601(timestamp)
5973
5982
  return position
5974
5983
 
5975
- async def fetch_positions(self, symbols: Strings = None, params={}):
5984
+ async def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
5976
5985
  """
5977
5986
  fetch all open positions
5978
5987
 
@@ -5984,9 +5993,14 @@ classic accounts only/ spot not supported* fetches information on an order made
5984
5993
  :param str [params.subType]: market subType, ['linear', 'inverse']
5985
5994
  :param str [params.baseCoin]: Base coin. Supports linear, inverse & option
5986
5995
  :param str [params.settleCoin]: Settle coin. Supports linear, inverse & option
5996
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times
5987
5997
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
5988
5998
  """
5989
5999
  await self.load_markets()
6000
+ paginate = False
6001
+ paginate, params = self.handle_option_and_params(params, 'fetchPositions', 'paginate')
6002
+ if paginate:
6003
+ return await self.fetch_paginated_call_cursor('fetchPositions', symbols, None, None, params, 'nextPageCursor', 'cursor', None, 200)
5990
6004
  symbol = None
5991
6005
  if (symbols is not None) and isinstance(symbols, list):
5992
6006
  symbolsLength = len(symbols)
@@ -6017,6 +6031,8 @@ classic accounts only/ spot not supported* fetches information on an order made
6017
6031
  # inverse
6018
6032
  if symbol is None and baseCoin is None:
6019
6033
  request['category'] = 'inverse'
6034
+ if self.safe_integer(params, 'limit') is None:
6035
+ request['limit'] = 200 # max limit
6020
6036
  params = self.omit(params, ['type'])
6021
6037
  request['category'] = type
6022
6038
  response = await self.privateGetV5PositionList(self.extend(request, params))
@@ -6065,7 +6081,7 @@ classic accounts only/ spot not supported* fetches information on an order made
6065
6081
  results.append(self.parse_position(rawPosition))
6066
6082
  return self.filter_by_array_positions(results, 'symbol', symbols, False)
6067
6083
 
6068
- def parse_position(self, position: dict, market: Market = None):
6084
+ def parse_position(self, position: dict, market: Market = None) -> Position:
6069
6085
  #
6070
6086
  # linear swap
6071
6087
  #
@@ -7016,7 +7032,7 @@ classic accounts only/ spot not supported* fetches information on an order made
7016
7032
  'amount': amount,
7017
7033
  })
7018
7034
 
7019
- def parse_margin_loan(self, info, currency: Currency = None):
7035
+ def parse_margin_loan(self, info, currency: Currency = None) -> dict:
7020
7036
  #
7021
7037
  # borrowCrossMargin
7022
7038
  #
@@ -7254,7 +7270,7 @@ classic accounts only/ spot not supported* fetches information on an order made
7254
7270
  result[symbol] = fee
7255
7271
  return result
7256
7272
 
7257
- def parse_deposit_withdraw_fee(self, fee, currency: Currency = None):
7273
+ def parse_deposit_withdraw_fee(self, fee, currency: Currency = None) -> Any:
7258
7274
  #
7259
7275
  # {
7260
7276
  # "name": "BTC",
@@ -7702,7 +7718,7 @@ classic accounts only/ spot not supported* fetches information on an order made
7702
7718
  'info': greeks,
7703
7719
  }
7704
7720
 
7705
- async def fetch_my_liquidations(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
7721
+ async def fetch_my_liquidations(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
7706
7722
  """
7707
7723
  retrieves the users liquidated positions
7708
7724
 
@@ -7781,7 +7797,7 @@ classic accounts only/ spot not supported* fetches information on an order made
7781
7797
  liquidations = self.add_pagination_cursor_to_result(response)
7782
7798
  return self.parse_liquidations(liquidations, market, since, limit)
7783
7799
 
7784
- def parse_liquidation(self, liquidation, market: Market = None):
7800
+ def parse_liquidation(self, liquidation, market: Market = None) -> Liquidation:
7785
7801
  #
7786
7802
  # {
7787
7803
  # "symbol": "ETHPERP",
@@ -7944,7 +7960,7 @@ classic accounts only/ spot not supported* fetches information on an order made
7944
7960
  })
7945
7961
  return tiers
7946
7962
 
7947
- async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
7963
+ async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[FundingHistory]:
7948
7964
  """
7949
7965
  fetch the history of funding payments paid and received on self account
7950
7966
 
@@ -7985,7 +8001,7 @@ classic accounts only/ spot not supported* fetches information on an order made
7985
8001
  fundings = self.add_pagination_cursor_to_result(response)
7986
8002
  return self.parse_incomes(fundings, market, since, limit)
7987
8003
 
7988
- def parse_income(self, income, market: Market = None):
8004
+ def parse_income(self, income, market: Market = None) -> object:
7989
8005
  #
7990
8006
  # {
7991
8007
  # "symbol": "XMRUSDT",
@@ -501,7 +501,7 @@ class coinlist(Exchange, ImplicitAPI):
501
501
  # {
502
502
  # "symbols": [
503
503
  # {
504
- # "symbol": "CQT-USDT",
504
+ # "symbol": "CQT-USDT", # spot
505
505
  # "base_currency": "CQT",
506
506
  # "is_trader_geofenced": False,
507
507
  # "list_time": "2021-06-15T00:00:00.000Z",
@@ -526,6 +526,62 @@ class coinlist(Exchange, ImplicitAPI):
526
526
  return self.parse_markets(markets)
527
527
 
528
528
  def parse_market(self, market: dict) -> Market:
529
+ # perp
530
+ # {
531
+ # "symbol":"BTC-PERP",
532
+ # "base_currency":"BTC",
533
+ # "is_trader_geofenced":false,
534
+ # "expiry_name":null,
535
+ # "expiry_time":null,
536
+ # "list_time":"2024-09-16T00:00:00.000Z",
537
+ # "type":"perp-swap",
538
+ # "series_code":"BTC",
539
+ # "long_name":"Bitcoin",
540
+ # "asset_class":"CRYPTO",
541
+ # "minimum_price_increment":"0.01",
542
+ # "minimum_size_increment":"0.0001",
543
+ # "quote_currency":"USDT",
544
+ # "multiplier":"1",
545
+ # "contract_frequency":"FGHJKMNQUVXZ",
546
+ # "index_code":".BTC-USDT",
547
+ # "price_band_threshold_market":"0.05",
548
+ # "price_band_threshold_limit":"0.25",
549
+ # "maintenance_initial_ratio":"0.500000000000000000",
550
+ # "liquidation_initial_ratio":"0.500000000000000000",
551
+ # "last_price":"75881.36000000",
552
+ # "fair_price":"76256.00000000",
553
+ # "index_price":"77609.90000000",
554
+ # "mark_price":"76237.75000000",
555
+ # "mark_price_dollarizer":"0.99950000",
556
+ # "funding_interval":{
557
+ # "hours":"8"
558
+ # },
559
+ # "funding_rate_index_code":".BTC-USDT-FR8H",
560
+ # "initial_margin_base":"0.200000000000000000",
561
+ # "initial_margin_per_contract":"0.160000000000000000",
562
+ # "position_limit":"5.0000"
563
+ # }
564
+ # spot
565
+ # {
566
+ # "symbol": "CQT-USDT", # spot
567
+ # "base_currency": "CQT",
568
+ # "is_trader_geofenced": False,
569
+ # "list_time": "2021-06-15T00:00:00.000Z",
570
+ # "type": "spot",
571
+ # "series_code": "CQT-USDT-SPOT",
572
+ # "long_name": "Covalent",
573
+ # "asset_class": "CRYPTO",
574
+ # "minimum_price_increment": "0.0001",
575
+ # "minimum_size_increment": "0.0001",
576
+ # "quote_currency": "USDT",
577
+ # "index_code": null,
578
+ # "price_band_threshold_market": "0.05",
579
+ # "price_band_threshold_limit": "0.25",
580
+ # "last_price": "0.12160000",
581
+ # "fair_price": "0.12300000",
582
+ # "index_price": null
583
+ # }
584
+ isSwap = self.safe_string(market, 'type') == 'perp-swap'
529
585
  id = self.safe_string(market, 'symbol')
530
586
  baseId = self.safe_string(market, 'base_currency')
531
587
  quoteId = self.safe_string(market, 'quote_currency')
@@ -534,26 +590,40 @@ class coinlist(Exchange, ImplicitAPI):
534
590
  amountPrecision = self.safe_string(market, 'minimum_size_increment')
535
591
  pricePrecision = self.safe_string(market, 'minimum_price_increment')
536
592
  created = self.safe_string(market, 'list_time')
593
+ settledId = None
594
+ settled = None
595
+ linear = None
596
+ inverse = None
597
+ contractSize = None
598
+ symbol = base + '/' + quote
599
+ if isSwap:
600
+ contractSize = self.parse_number('1')
601
+ linear = True
602
+ inverse = False
603
+ settledId = quoteId
604
+ settled = quote
605
+ symbol = symbol + ':' + quote
606
+ type = 'swap' if isSwap else 'spot'
537
607
  return {
538
608
  'id': id,
539
- 'symbol': base + '/' + quote,
609
+ 'symbol': symbol,
540
610
  'base': base,
541
611
  'quote': quote,
542
- 'settle': None,
612
+ 'settle': settled,
543
613
  'baseId': baseId,
544
614
  'quoteId': quoteId,
545
- 'settleId': None,
546
- 'type': 'spot',
547
- 'spot': True,
615
+ 'settleId': settledId,
616
+ 'type': type,
617
+ 'spot': not isSwap,
548
618
  'margin': False,
549
- 'swap': False,
619
+ 'swap': isSwap,
550
620
  'future': False,
551
621
  'option': False,
552
622
  'active': True,
553
- 'contract': False,
554
- 'linear': None,
555
- 'inverse': None,
556
- 'contractSize': None,
623
+ 'contract': isSwap,
624
+ 'linear': linear,
625
+ 'inverse': inverse,
626
+ 'contractSize': contractSize,
557
627
  'expiry': None,
558
628
  'expiryDatetime': None,
559
629
  'strike': None,
@@ -614,7 +614,7 @@ class defx(Exchange, ImplicitAPI):
614
614
  'active': self.safe_string(market, 'status', '') == 'active',
615
615
  'contract': True,
616
616
  'linear': True,
617
- 'inverse': None,
617
+ 'inverse': False,
618
618
  'taker': self.safe_number(fees, 'taker'),
619
619
  'maker': self.safe_number(fees, 'maker'),
620
620
  'contractSize': self.parse_number('1'),
@@ -1321,13 +1321,32 @@ class deribit(Exchange, ImplicitAPI):
1321
1321
  await self.load_markets()
1322
1322
  symbols = self.market_symbols(symbols)
1323
1323
  code = self.safe_string_2(params, 'code', 'currency')
1324
+ type = None
1324
1325
  params = self.omit(params, ['code'])
1326
+ if symbols is not None:
1327
+ for i in range(0, len(symbols)):
1328
+ market = self.market(symbols[i])
1329
+ if code is not None and code != market['base']:
1330
+ raise BadRequest(self.id + ' fetchTickers the base currency must be the same for all symbols, self endpoint only supports one base currency at a time. Read more about it here: https://docs.deribit.com/#public-get_book_summary_by_currency')
1331
+ if code is None:
1332
+ code = market['base']
1333
+ type = market['type']
1325
1334
  if code is None:
1326
1335
  raise ArgumentsRequired(self.id + ' fetchTickers requires a currency/code(eg: BTC/ETH/USDT) parameter to fetch tickers for')
1327
1336
  currency = self.currency(code)
1328
1337
  request: dict = {
1329
1338
  'currency': currency['id'],
1330
1339
  }
1340
+ if type is not None:
1341
+ requestType = None
1342
+ if type == 'spot':
1343
+ requestType = 'spot'
1344
+ elif type == 'future' or (type == 'contract'):
1345
+ requestType = 'future'
1346
+ elif type == 'option':
1347
+ requestType = 'option'
1348
+ if requestType is not None:
1349
+ request['kind'] = requestType
1331
1350
  response = await self.publicGetGetBookSummaryByCurrency(self.extend(request, params))
1332
1351
  #
1333
1352
  # {
@@ -641,6 +641,8 @@ class derive(Exchange, ImplicitAPI):
641
641
  optionType = 'put'
642
642
  else:
643
643
  optionType = 'call'
644
+ linear = True
645
+ inverse = False
644
646
  return self.safe_market_structure({
645
647
  'id': marketId,
646
648
  'symbol': symbol,
@@ -1485,6 +1485,10 @@ class gate(Exchange, ImplicitAPI):
1485
1485
  takerPercent = self.safe_string(market, 'taker_fee_rate')
1486
1486
  makerPercent = self.safe_string(market, 'maker_fee_rate', takerPercent)
1487
1487
  isLinear = quote == settle
1488
+ contractSize = self.safe_string(market, 'quanto_multiplier')
1489
+ # exception only for one market: https://api.gateio.ws/api/v4/futures/btc/contracts
1490
+ if contractSize == '0':
1491
+ contractSize = '1' # 1 USD in WEB: https://i.imgur.com/MBBUI04.png
1488
1492
  return {
1489
1493
  'id': id,
1490
1494
  'symbol': symbol,
@@ -1506,7 +1510,7 @@ class gate(Exchange, ImplicitAPI):
1506
1510
  'inverse': not isLinear,
1507
1511
  'taker': self.parse_number(Precise.string_div(takerPercent, '100')), # Fee is in %, so divide by 100
1508
1512
  'maker': self.parse_number(Precise.string_div(makerPercent, '100')),
1509
- 'contractSize': self.safe_number(market, 'quanto_multiplier'),
1513
+ 'contractSize': self.parse_number(contractSize),
1510
1514
  'expiry': expiry,
1511
1515
  'expiryDatetime': self.iso8601(expiry),
1512
1516
  'strike': None,
@@ -1819,9 +1823,9 @@ class gate(Exchange, ImplicitAPI):
1819
1823
  partFirst = self.safe_string(parts, 0)
1820
1824
  # if there's an underscore then the second part is always the chain name(except the _OLD suffix)
1821
1825
  currencyName = currencyId if currencyId.endswith('_OLD') else partFirst
1822
- withdrawEnabled = not self.safe_bool(entry, 'withdraw_disabled')
1823
- depositEnabled = not self.safe_bool(entry, 'deposit_disabled')
1824
- tradeDisabled = not self.safe_bool(entry, 'trade_disabled')
1826
+ withdrawDisabled = self.safe_bool(entry, 'withdraw_disabled', False)
1827
+ depositDisabled = self.safe_bool(entry, 'deposit_disabled', False)
1828
+ tradeDisabled = self.safe_bool(entry, 'trade_disabled', False)
1825
1829
  precision = self.parse_number('0.0001') # temporary safe default, because no value provided from API
1826
1830
  code = self.safe_currency_code(currencyName)
1827
1831
  # check leveraged tokens(e.g. BTC3S, ETH5L)
@@ -1849,8 +1853,8 @@ class gate(Exchange, ImplicitAPI):
1849
1853
  },
1850
1854
  },
1851
1855
  'active': not tradeDisabled,
1852
- 'deposit': depositEnabled,
1853
- 'withdraw': withdrawEnabled,
1856
+ 'deposit': not depositDisabled,
1857
+ 'withdraw': not withdrawDisabled,
1854
1858
  'fee': None,
1855
1859
  'precision': precision,
1856
1860
  }
@@ -6366,7 +6370,7 @@ class gate(Exchange, ImplicitAPI):
6366
6370
  queryString = self.urlencode(query)
6367
6371
  # https://github.com/ccxt/ccxt/issues/25570
6368
6372
  if queryString.find('currencies=') >= 0 and queryString.find('%2C') >= 0:
6369
- queryString = queryString.replace('%2', ',')
6373
+ queryString = queryString.replace('%2C', ',')
6370
6374
  url += '?' + queryString
6371
6375
  if method == 'PATCH':
6372
6376
  body = self.json(query)
@@ -44,7 +44,7 @@ class hitbtc(Exchange, ImplicitAPI):
44
44
  'margin': True,
45
45
  'swap': True,
46
46
  'future': False,
47
- 'option': None,
47
+ 'option': False,
48
48
  'addMargin': True,
49
49
  'cancelAllOrders': True,
50
50
  'cancelOrder': True,
@@ -76,6 +76,7 @@ class hitbtc(Exchange, ImplicitAPI):
76
76
  'fetchFundingRate': True,
77
77
  'fetchFundingRateHistory': True,
78
78
  'fetchFundingRates': True,
79
+ 'fetchGreeks': False,
79
80
  'fetchIndexOHLCV': True,
80
81
  'fetchIsolatedBorrowRate': False,
81
82
  'fetchIsolatedBorrowRates': False,
@@ -88,6 +89,7 @@ class hitbtc(Exchange, ImplicitAPI):
88
89
  'fetchMarkets': True,
89
90
  'fetchMarkOHLCV': True,
90
91
  'fetchMyLiquidations': False,
92
+ 'fetchMySettlementHistory': False,
91
93
  'fetchMyTrades': True,
92
94
  'fetchOHLCV': True,
93
95
  'fetchOpenInterest': True,
@@ -95,6 +97,8 @@ class hitbtc(Exchange, ImplicitAPI):
95
97
  'fetchOpenInterests': True,
96
98
  'fetchOpenOrder': True,
97
99
  'fetchOpenOrders': True,
100
+ 'fetchOption': False,
101
+ 'fetchOptionChain': False,
98
102
  'fetchOrder': True,
99
103
  'fetchOrderBook': True,
100
104
  'fetchOrderBooks': True,
@@ -103,12 +107,14 @@ class hitbtc(Exchange, ImplicitAPI):
103
107
  'fetchPosition': True,
104
108
  'fetchPositions': True,
105
109
  'fetchPremiumIndexOHLCV': True,
110
+ 'fetchSettlementHistory': False,
106
111
  'fetchTicker': True,
107
112
  'fetchTickers': True,
108
113
  'fetchTrades': True,
109
114
  'fetchTradingFee': True,
110
115
  'fetchTradingFees': True,
111
116
  'fetchTransactions': 'emulated',
117
+ 'fetchVolatilityHistory': False,
112
118
  'fetchWithdrawals': True,
113
119
  'reduceMargin': True,
114
120
  'sandbox': True,
ccxt/async_support/okx.py CHANGED
@@ -1294,6 +1294,7 @@ class okx(Exchange, ImplicitAPI):
1294
1294
  },
1295
1295
  'fetchOHLCV': {
1296
1296
  'limit': 300,
1297
+ 'historical': 100,
1297
1298
  },
1298
1299
  },
1299
1300
  'spot': {
@@ -2385,6 +2386,8 @@ class okx(Exchange, ImplicitAPI):
2385
2386
  timezone = self.safe_string(options, 'timezone', 'UTC')
2386
2387
  if limit is None:
2387
2388
  limit = 100 # default 100, max 100
2389
+ else:
2390
+ limit = min(limit, 300) # max 100
2388
2391
  duration = self.parse_timeframe(timeframe)
2389
2392
  bar = self.safe_string(self.timeframes, timeframe, timeframe)
2390
2393
  if (timezone == 'UTC') and (duration >= 21600): # if utc and timeframe >= 6h
@@ -2402,6 +2405,7 @@ class okx(Exchange, ImplicitAPI):
2402
2405
  historyBorder = now - ((1440 - 1) * durationInMilliseconds)
2403
2406
  if since < historyBorder:
2404
2407
  defaultType = 'HistoryCandles'
2408
+ limit = min(limit, 100) # max 100 for historical endpoint
2405
2409
  startTime = max(since - 1, 0)
2406
2410
  request['before'] = startTime
2407
2411
  request['after'] = self.sum(since, durationInMilliseconds * limit)
ccxt/base/errors.py CHANGED
@@ -1,9 +1,3 @@
1
- # ----------------------------------------------------------------------------
2
-
3
- # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
- # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
- # EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
-
7
1
  error_hierarchy = {
8
2
  'BaseError': {
9
3
  'ExchangeError': {
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.72'
7
+ __version__ = '4.4.74'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -6471,24 +6471,36 @@ class Exchange(object):
6471
6471
  return self.sort_by(result, 'id', True)
6472
6472
  return result
6473
6473
 
6474
- def remove_repeated_elements_from_array(self, input):
6474
+ def remove_repeated_elements_from_array(self, input, fallbackToTimestamp: bool = True):
6475
+ uniqueDic = {}
6476
+ uniqueResult = []
6477
+ for i in range(0, len(input)):
6478
+ entry = input[i]
6479
+ uniqValue = self.safe_string_n(entry, ['id', 'timestamp', 0]) if fallbackToTimestamp else self.safe_string(entry, 'id')
6480
+ if uniqValue is not None and not (uniqValue in uniqueDic):
6481
+ uniqueDic[uniqValue] = 1
6482
+ uniqueResult.append(entry)
6483
+ valuesLength = len(uniqueResult)
6484
+ if valuesLength > 0:
6485
+ return uniqueResult
6486
+ return input
6487
+
6488
+ def remove_repeated_trades_from_array(self, input):
6475
6489
  uniqueResult = {}
6476
6490
  for i in range(0, len(input)):
6477
6491
  entry = input[i]
6478
6492
  id = self.safe_string(entry, 'id')
6479
- if id is not None:
6480
- if self.safe_string(uniqueResult, id) is None:
6481
- uniqueResult[id] = entry
6482
- else:
6483
- timestamp = self.safe_integer_2(entry, 'timestamp', 0)
6484
- if timestamp is not None:
6485
- if self.safe_string(uniqueResult, timestamp) is None:
6486
- uniqueResult[timestamp] = entry
6493
+ if id is None:
6494
+ price = self.safe_string(entry, 'price')
6495
+ amount = self.safe_string(entry, 'amount')
6496
+ timestamp = self.safe_string(entry, 'timestamp')
6497
+ side = self.safe_string(entry, 'side')
6498
+ # unique trade identifier
6499
+ id = 't_' + str(timestamp) + '_' + side + '_' + price + '_' + amount
6500
+ if id is not None and not (id in uniqueResult):
6501
+ uniqueResult[id] = entry
6487
6502
  values = list(uniqueResult.values())
6488
- valuesLength = len(values)
6489
- if valuesLength > 0:
6490
- return values
6491
- return input
6503
+ return values
6492
6504
 
6493
6505
  def handle_until_option(self, key: str, request, params, multiplier=1):
6494
6506
  until = self.safe_integer_2(params, 'until', 'till')
ccxt/bequant.py CHANGED
@@ -19,6 +19,7 @@ class bequant(hitbtc, ImplicitAPI):
19
19
  'urls': {
20
20
  'logo': 'https://github.com/user-attachments/assets/0583ef1f-29fe-4b7c-8189-63565a0e2867',
21
21
  'api': {
22
+ # v3
22
23
  'public': 'https://api.bequant.io/api/3',
23
24
  'private': 'https://api.bequant.io/api/3',
24
25
  },