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
ccxt/bybit.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.bybit import ImplicitAPI
8
8
  import hashlib
9
- 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
9
+ 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
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -2389,6 +2389,7 @@ class bybit(Exchange, ImplicitAPI):
2389
2389
  :returns dict: an array of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
2390
2390
  """
2391
2391
  self.load_markets()
2392
+ code = self.safe_string_n(params, ['code', 'currency', 'baseCoin'])
2392
2393
  market = None
2393
2394
  parsedSymbols = None
2394
2395
  if symbols is not None:
@@ -2410,6 +2411,12 @@ class bybit(Exchange, ImplicitAPI):
2410
2411
  currentType = market['type']
2411
2412
  elif market['type'] != currentType:
2412
2413
  raise BadRequest(self.id + ' fetchTickers can only accept a list of symbols of the same type')
2414
+ if market['option']:
2415
+ if code is not None and code != market['base']:
2416
+ 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')
2417
+ if code is None:
2418
+ code = market['base']
2419
+ params = self.omit(params, ['code', 'currency'])
2413
2420
  parsedSymbols.append(market['symbol'])
2414
2421
  request: dict = {
2415
2422
  # 'symbol': market['id'],
@@ -2429,7 +2436,9 @@ class bybit(Exchange, ImplicitAPI):
2429
2436
  request['category'] = 'spot'
2430
2437
  elif type == 'option':
2431
2438
  request['category'] = 'option'
2432
- request['baseCoin'] = self.safe_string(params, 'baseCoin', 'BTC')
2439
+ if code is None:
2440
+ code = 'BTC'
2441
+ request['baseCoin'] = code
2433
2442
  elif type == 'swap' or type == 'future' or subType is not None:
2434
2443
  request['category'] = subType
2435
2444
  response = self.publicGetV5MarketTickers(self.extend(request, params))
@@ -2475,7 +2484,7 @@ class bybit(Exchange, ImplicitAPI):
2475
2484
  tickerList = self.safe_list(result, 'list', [])
2476
2485
  return self.parse_tickers(tickerList, parsedSymbols)
2477
2486
 
2478
- def fetch_bids_asks(self, symbols: Strings = None, params={}):
2487
+ def fetch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
2479
2488
  """
2480
2489
  fetches the bid and ask price and volume for multiple markets
2481
2490
 
@@ -3689,7 +3698,7 @@ class bybit(Exchange, ImplicitAPI):
3689
3698
  'trades': None,
3690
3699
  }, market)
3691
3700
 
3692
- def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
3701
+ def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}) -> Order:
3693
3702
  """
3694
3703
  create a market buy order by providing the symbol and cost
3695
3704
 
@@ -3706,7 +3715,7 @@ class bybit(Exchange, ImplicitAPI):
3706
3715
  raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
3707
3716
  return self.create_order(symbol, 'market', 'buy', cost, 1, params)
3708
3717
 
3709
- def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}):
3718
+ def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}) -> Order:
3710
3719
  """
3711
3720
  create a market sell order by providing the symbol and cost
3712
3721
 
@@ -3727,7 +3736,7 @@ class bybit(Exchange, ImplicitAPI):
3727
3736
  raise NotSupported(self.id + ' createMarketSellOrderWithCost() supports spot orders only')
3728
3737
  return self.create_order(symbol, 'market', 'sell', cost, 1, params)
3729
3738
 
3730
- def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
3739
+ def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
3731
3740
  """
3732
3741
  create a trade order
3733
3742
 
@@ -3986,7 +3995,7 @@ class bybit(Exchange, ImplicitAPI):
3986
3995
  params = self.omit(params, ['stopPrice', 'timeInForce', 'stopLossPrice', 'takeProfitPrice', 'postOnly', 'clientOrderId', 'triggerPrice', 'stopLoss', 'takeProfit', 'trailingAmount', 'trailingTriggerPrice', 'hedged'])
3987
3996
  return self.extend(request, params)
3988
3997
 
3989
- def create_orders(self, orders: List[OrderRequest], params={}):
3998
+ def create_orders(self, orders: List[OrderRequest], params={}) -> List[Order]:
3990
3999
  """
3991
4000
  create a list of trade orders
3992
4001
 
@@ -4136,7 +4145,7 @@ class bybit(Exchange, ImplicitAPI):
4136
4145
  params = self.omit(params, ['stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerPrice', 'clientOrderId', 'stopLoss', 'takeProfit'])
4137
4146
  return request
4138
4147
 
4139
- def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
4148
+ def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}) -> Order:
4140
4149
  """
4141
4150
  edit a trade order
4142
4151
 
@@ -4186,7 +4195,7 @@ class bybit(Exchange, ImplicitAPI):
4186
4195
  'id': self.safe_string(result, 'orderId'),
4187
4196
  })
4188
4197
 
4189
- def edit_orders(self, orders: List[OrderRequest], params={}):
4198
+ def edit_orders(self, orders: List[OrderRequest], params={}) -> List[Order]:
4190
4199
  """
4191
4200
  edit a list of trade orders
4192
4201
 
@@ -4297,7 +4306,7 @@ class bybit(Exchange, ImplicitAPI):
4297
4306
  request['category'] = 'option'
4298
4307
  return self.extend(request, params)
4299
4308
 
4300
- def cancel_order(self, id: str, symbol: Str = None, params={}):
4309
+ def cancel_order(self, id: str, symbol: Str = None, params={}) -> Order:
4301
4310
  """
4302
4311
  cancels an open order
4303
4312
 
@@ -4332,7 +4341,7 @@ class bybit(Exchange, ImplicitAPI):
4332
4341
  result = self.safe_dict(response, 'result', {})
4333
4342
  return self.parse_order(result, market)
4334
4343
 
4335
- def cancel_orders(self, ids, symbol: Str = None, params={}):
4344
+ def cancel_orders(self, ids, symbol: Str = None, params={}) -> List[Order]:
4336
4345
  """
4337
4346
  cancel multiple orders
4338
4347
 
@@ -4601,7 +4610,7 @@ class bybit(Exchange, ImplicitAPI):
4601
4610
  return response
4602
4611
  return self.parse_orders(orders, market)
4603
4612
 
4604
- def fetch_order_classic(self, id: str, symbol: Str = None, params={}):
4613
+ def fetch_order_classic(self, id: str, symbol: Str = None, params={}) -> Order:
4605
4614
  """
4606
4615
  fetches information on an order made by the user *classic accounts only*
4607
4616
 
@@ -4846,7 +4855,7 @@ classic accounts only/ spot not supported* fetches information on an order made
4846
4855
  data = self.add_pagination_cursor_to_result(response)
4847
4856
  return self.parse_orders(data, market, since, limit)
4848
4857
 
4849
- def fetch_closed_order(self, id: str, symbol: Str = None, params={}):
4858
+ def fetch_closed_order(self, id: str, symbol: Str = None, params={}) -> Order:
4850
4859
  """
4851
4860
  fetches information on a closed order made by the user
4852
4861
 
@@ -4876,7 +4885,7 @@ classic accounts only/ spot not supported* fetches information on an order made
4876
4885
  raise InvalidOrder(self.id + ' returned more than one order')
4877
4886
  return self.safe_value(result, 0)
4878
4887
 
4879
- def fetch_open_order(self, id: str, symbol: Str = None, params={}):
4888
+ def fetch_open_order(self, id: str, symbol: Str = None, params={}) -> Order:
4880
4889
  """
4881
4890
  fetches information on an open order made by the user
4882
4891
 
@@ -5032,7 +5041,7 @@ classic accounts only/ spot not supported* fetches information on an order made
5032
5041
  }
5033
5042
  return self.fetch_canceled_and_closed_orders(symbol, since, limit, self.extend(request, params))
5034
5043
 
5035
- def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5044
+ def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
5036
5045
  """
5037
5046
  fetches information on multiple canceled orders made by the user
5038
5047
 
@@ -5155,7 +5164,7 @@ classic accounts only/ spot not supported* fetches information on an order made
5155
5164
  data = self.add_pagination_cursor_to_result(response)
5156
5165
  return self.parse_orders(data, market, since, limit)
5157
5166
 
5158
- def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5167
+ def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
5159
5168
  """
5160
5169
  fetch all the trades made from a single order
5161
5170
 
@@ -5177,7 +5186,7 @@ classic accounts only/ spot not supported* fetches information on an order made
5177
5186
  params = self.omit(params, ['clientOrderId', 'orderLinkId'])
5178
5187
  return self.fetch_my_trades(symbol, since, limit, self.extend(request, params))
5179
5188
 
5180
- def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5189
+ def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
5181
5190
  """
5182
5191
  fetch all trades made by the user
5183
5192
 
@@ -5900,7 +5909,7 @@ classic accounts only/ spot not supported* fetches information on an order made
5900
5909
  result = self.safe_dict(response, 'result', {})
5901
5910
  return self.parse_transaction(result, currency)
5902
5911
 
5903
- def fetch_position(self, symbol: str, params={}):
5912
+ def fetch_position(self, symbol: str, params={}) -> Position:
5904
5913
  """
5905
5914
  fetch data on a single open contract trade position
5906
5915
 
@@ -5971,7 +5980,7 @@ classic accounts only/ spot not supported* fetches information on an order made
5971
5980
  position['datetime'] = self.iso8601(timestamp)
5972
5981
  return position
5973
5982
 
5974
- def fetch_positions(self, symbols: Strings = None, params={}):
5983
+ def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
5975
5984
  """
5976
5985
  fetch all open positions
5977
5986
 
@@ -5983,9 +5992,14 @@ classic accounts only/ spot not supported* fetches information on an order made
5983
5992
  :param str [params.subType]: market subType, ['linear', 'inverse']
5984
5993
  :param str [params.baseCoin]: Base coin. Supports linear, inverse & option
5985
5994
  :param str [params.settleCoin]: Settle coin. Supports linear, inverse & option
5995
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times
5986
5996
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
5987
5997
  """
5988
5998
  self.load_markets()
5999
+ paginate = False
6000
+ paginate, params = self.handle_option_and_params(params, 'fetchPositions', 'paginate')
6001
+ if paginate:
6002
+ return self.fetch_paginated_call_cursor('fetchPositions', symbols, None, None, params, 'nextPageCursor', 'cursor', None, 200)
5989
6003
  symbol = None
5990
6004
  if (symbols is not None) and isinstance(symbols, list):
5991
6005
  symbolsLength = len(symbols)
@@ -6016,6 +6030,8 @@ classic accounts only/ spot not supported* fetches information on an order made
6016
6030
  # inverse
6017
6031
  if symbol is None and baseCoin is None:
6018
6032
  request['category'] = 'inverse'
6033
+ if self.safe_integer(params, 'limit') is None:
6034
+ request['limit'] = 200 # max limit
6019
6035
  params = self.omit(params, ['type'])
6020
6036
  request['category'] = type
6021
6037
  response = self.privateGetV5PositionList(self.extend(request, params))
@@ -6064,7 +6080,7 @@ classic accounts only/ spot not supported* fetches information on an order made
6064
6080
  results.append(self.parse_position(rawPosition))
6065
6081
  return self.filter_by_array_positions(results, 'symbol', symbols, False)
6066
6082
 
6067
- def parse_position(self, position: dict, market: Market = None):
6083
+ def parse_position(self, position: dict, market: Market = None) -> Position:
6068
6084
  #
6069
6085
  # linear swap
6070
6086
  #
@@ -7015,7 +7031,7 @@ classic accounts only/ spot not supported* fetches information on an order made
7015
7031
  'amount': amount,
7016
7032
  })
7017
7033
 
7018
- def parse_margin_loan(self, info, currency: Currency = None):
7034
+ def parse_margin_loan(self, info, currency: Currency = None) -> dict:
7019
7035
  #
7020
7036
  # borrowCrossMargin
7021
7037
  #
@@ -7253,7 +7269,7 @@ classic accounts only/ spot not supported* fetches information on an order made
7253
7269
  result[symbol] = fee
7254
7270
  return result
7255
7271
 
7256
- def parse_deposit_withdraw_fee(self, fee, currency: Currency = None):
7272
+ def parse_deposit_withdraw_fee(self, fee, currency: Currency = None) -> Any:
7257
7273
  #
7258
7274
  # {
7259
7275
  # "name": "BTC",
@@ -7701,7 +7717,7 @@ classic accounts only/ spot not supported* fetches information on an order made
7701
7717
  'info': greeks,
7702
7718
  }
7703
7719
 
7704
- def fetch_my_liquidations(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
7720
+ def fetch_my_liquidations(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
7705
7721
  """
7706
7722
  retrieves the users liquidated positions
7707
7723
 
@@ -7780,7 +7796,7 @@ classic accounts only/ spot not supported* fetches information on an order made
7780
7796
  liquidations = self.add_pagination_cursor_to_result(response)
7781
7797
  return self.parse_liquidations(liquidations, market, since, limit)
7782
7798
 
7783
- def parse_liquidation(self, liquidation, market: Market = None):
7799
+ def parse_liquidation(self, liquidation, market: Market = None) -> Liquidation:
7784
7800
  #
7785
7801
  # {
7786
7802
  # "symbol": "ETHPERP",
@@ -7943,7 +7959,7 @@ classic accounts only/ spot not supported* fetches information on an order made
7943
7959
  })
7944
7960
  return tiers
7945
7961
 
7946
- def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
7962
+ def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[FundingHistory]:
7947
7963
  """
7948
7964
  fetch the history of funding payments paid and received on self account
7949
7965
 
@@ -7984,7 +8000,7 @@ classic accounts only/ spot not supported* fetches information on an order made
7984
8000
  fundings = self.add_pagination_cursor_to_result(response)
7985
8001
  return self.parse_incomes(fundings, market, since, limit)
7986
8002
 
7987
- def parse_income(self, income, market: Market = None):
8003
+ def parse_income(self, income, market: Market = None) -> object:
7988
8004
  #
7989
8005
  # {
7990
8006
  # "symbol": "XMRUSDT",
ccxt/coinlist.py CHANGED
@@ -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,
ccxt/defx.py CHANGED
@@ -613,7 +613,7 @@ class defx(Exchange, ImplicitAPI):
613
613
  'active': self.safe_string(market, 'status', '') == 'active',
614
614
  'contract': True,
615
615
  'linear': True,
616
- 'inverse': None,
616
+ 'inverse': False,
617
617
  'taker': self.safe_number(fees, 'taker'),
618
618
  'maker': self.safe_number(fees, 'maker'),
619
619
  'contractSize': self.parse_number('1'),
ccxt/deribit.py CHANGED
@@ -1321,13 +1321,32 @@ class deribit(Exchange, ImplicitAPI):
1321
1321
  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 = self.publicGetGetBookSummaryByCurrency(self.extend(request, params))
1332
1351
  #
1333
1352
  # {
ccxt/derive.py CHANGED
@@ -640,6 +640,8 @@ class derive(Exchange, ImplicitAPI):
640
640
  optionType = 'put'
641
641
  else:
642
642
  optionType = 'call'
643
+ linear = True
644
+ inverse = False
643
645
  return self.safe_market_structure({
644
646
  'id': marketId,
645
647
  'symbol': symbol,
ccxt/gate.py CHANGED
@@ -1484,6 +1484,10 @@ class gate(Exchange, ImplicitAPI):
1484
1484
  takerPercent = self.safe_string(market, 'taker_fee_rate')
1485
1485
  makerPercent = self.safe_string(market, 'maker_fee_rate', takerPercent)
1486
1486
  isLinear = quote == settle
1487
+ contractSize = self.safe_string(market, 'quanto_multiplier')
1488
+ # exception only for one market: https://api.gateio.ws/api/v4/futures/btc/contracts
1489
+ if contractSize == '0':
1490
+ contractSize = '1' # 1 USD in WEB: https://i.imgur.com/MBBUI04.png
1487
1491
  return {
1488
1492
  'id': id,
1489
1493
  'symbol': symbol,
@@ -1505,7 +1509,7 @@ class gate(Exchange, ImplicitAPI):
1505
1509
  'inverse': not isLinear,
1506
1510
  'taker': self.parse_number(Precise.string_div(takerPercent, '100')), # Fee is in %, so divide by 100
1507
1511
  'maker': self.parse_number(Precise.string_div(makerPercent, '100')),
1508
- 'contractSize': self.safe_number(market, 'quanto_multiplier'),
1512
+ 'contractSize': self.parse_number(contractSize),
1509
1513
  'expiry': expiry,
1510
1514
  'expiryDatetime': self.iso8601(expiry),
1511
1515
  'strike': None,
@@ -1818,9 +1822,9 @@ class gate(Exchange, ImplicitAPI):
1818
1822
  partFirst = self.safe_string(parts, 0)
1819
1823
  # if there's an underscore then the second part is always the chain name(except the _OLD suffix)
1820
1824
  currencyName = currencyId if currencyId.endswith('_OLD') else partFirst
1821
- withdrawEnabled = not self.safe_bool(entry, 'withdraw_disabled')
1822
- depositEnabled = not self.safe_bool(entry, 'deposit_disabled')
1823
- tradeDisabled = not self.safe_bool(entry, 'trade_disabled')
1825
+ withdrawDisabled = self.safe_bool(entry, 'withdraw_disabled', False)
1826
+ depositDisabled = self.safe_bool(entry, 'deposit_disabled', False)
1827
+ tradeDisabled = self.safe_bool(entry, 'trade_disabled', False)
1824
1828
  precision = self.parse_number('0.0001') # temporary safe default, because no value provided from API
1825
1829
  code = self.safe_currency_code(currencyName)
1826
1830
  # check leveraged tokens(e.g. BTC3S, ETH5L)
@@ -1848,8 +1852,8 @@ class gate(Exchange, ImplicitAPI):
1848
1852
  },
1849
1853
  },
1850
1854
  'active': not tradeDisabled,
1851
- 'deposit': depositEnabled,
1852
- 'withdraw': withdrawEnabled,
1855
+ 'deposit': not depositDisabled,
1856
+ 'withdraw': not withdrawDisabled,
1853
1857
  'fee': None,
1854
1858
  'precision': precision,
1855
1859
  }
@@ -6365,7 +6369,7 @@ class gate(Exchange, ImplicitAPI):
6365
6369
  queryString = self.urlencode(query)
6366
6370
  # https://github.com/ccxt/ccxt/issues/25570
6367
6371
  if queryString.find('currencies=') >= 0 and queryString.find('%2C') >= 0:
6368
- queryString = queryString.replace('%2', ',')
6372
+ queryString = queryString.replace('%2C', ',')
6369
6373
  url += '?' + queryString
6370
6374
  if method == 'PATCH':
6371
6375
  body = self.json(query)
ccxt/hitbtc.py CHANGED
@@ -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/okx.py CHANGED
@@ -1293,6 +1293,7 @@ class okx(Exchange, ImplicitAPI):
1293
1293
  },
1294
1294
  'fetchOHLCV': {
1295
1295
  'limit': 300,
1296
+ 'historical': 100,
1296
1297
  },
1297
1298
  },
1298
1299
  'spot': {
@@ -2384,6 +2385,8 @@ class okx(Exchange, ImplicitAPI):
2384
2385
  timezone = self.safe_string(options, 'timezone', 'UTC')
2385
2386
  if limit is None:
2386
2387
  limit = 100 # default 100, max 100
2388
+ else:
2389
+ limit = min(limit, 300) # max 100
2387
2390
  duration = self.parse_timeframe(timeframe)
2388
2391
  bar = self.safe_string(self.timeframes, timeframe, timeframe)
2389
2392
  if (timezone == 'UTC') and (duration >= 21600): # if utc and timeframe >= 6h
@@ -2401,6 +2404,7 @@ class okx(Exchange, ImplicitAPI):
2401
2404
  historyBorder = now - ((1440 - 1) * durationInMilliseconds)
2402
2405
  if since < historyBorder:
2403
2406
  defaultType = 'HistoryCandles'
2407
+ limit = min(limit, 100) # max 100 for historical endpoint
2404
2408
  startTime = max(since - 1, 0)
2405
2409
  request['before'] = startTime
2406
2410
  request['after'] = self.sum(since, durationInMilliseconds * limit)
ccxt/pro/__init__.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
 
@@ -20,15 +20,12 @@ from ccxt.pro.binancecoinm import binancecoinm # noqa
20
20
  from ccxt.pro.binanceus import binanceus # noqa: F401
21
21
  from ccxt.pro.binanceusdm import binanceusdm # noqa: F401
22
22
  from ccxt.pro.bingx import bingx # noqa: F401
23
- from ccxt.pro.bitcoincom import bitcoincom # noqa: F401
24
23
  from ccxt.pro.bitfinex import bitfinex # noqa: F401
25
- from ccxt.pro.bitfinex1 import bitfinex1 # noqa: F401
26
24
  from ccxt.pro.bitget import bitget # noqa: F401
27
25
  from ccxt.pro.bithumb import bithumb # noqa: F401
28
26
  from ccxt.pro.bitmart import bitmart # noqa: F401
29
27
  from ccxt.pro.bitmex import bitmex # noqa: F401
30
28
  from ccxt.pro.bitopro import bitopro # noqa: F401
31
- from ccxt.pro.bitpanda import bitpanda # noqa: F401
32
29
  from ccxt.pro.bitrue import bitrue # noqa: F401
33
30
  from ccxt.pro.bitstamp import bitstamp # noqa: F401
34
31
  from ccxt.pro.bitvavo import bitvavo # noqa: F401
@@ -95,15 +92,12 @@ exchanges = [
95
92
  'binanceus',
96
93
  'binanceusdm',
97
94
  'bingx',
98
- 'bitcoincom',
99
95
  'bitfinex',
100
- 'bitfinex1',
101
96
  'bitget',
102
97
  'bithumb',
103
98
  'bitmart',
104
99
  'bitmex',
105
100
  'bitopro',
106
- 'bitpanda',
107
101
  'bitrue',
108
102
  'bitstamp',
109
103
  'bitvavo',
ccxt/pro/ascendex.py CHANGED
@@ -412,7 +412,7 @@ class ascendex(ccxt.async_support.ascendex):
412
412
  #
413
413
  # {
414
414
  # "m": "balance",
415
- # "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
415
+ # "accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqEo",
416
416
  # "ac": "CASH",
417
417
  # "data": {
418
418
  # "a" : "USDT",
ccxt/pro/bingx.py CHANGED
@@ -86,6 +86,9 @@ class bingx(ccxt.async_support.bingx):
86
86
  'depth': 100, # 5, 10, 20, 50, 100
87
87
  'interval': 500, # 100, 200, 500, 1000
88
88
  },
89
+ 'watchTrades': {
90
+ 'ignoreDuplicates': True,
91
+ },
89
92
  },
90
93
  'streaming': {
91
94
  'keepAlive': 1800000, # 30 minutes
@@ -468,7 +471,12 @@ class bingx(ccxt.async_support.bingx):
468
471
  trades = await self.watch(url, messageHash, self.extend(request, params), messageHash)
469
472
  if self.newUpdates:
470
473
  limit = trades.getLimit(symbol, limit)
471
- return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
474
+ result = self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
475
+ if self.handle_option('watchTrades', 'ignoreDuplicates', True):
476
+ filtered = self.remove_repeated_trades_from_array(result)
477
+ filtered = self.sort_by(filtered, 'timestamp')
478
+ return filtered
479
+ return result
472
480
 
473
481
  def handle_trades(self, client: Client, message):
474
482
  #