ccxt 4.4.71__py2.py3-none-any.whl → 4.4.73__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 (99) hide show
  1. ccxt/__init__.py +1 -3
  2. ccxt/abstract/bingx.py +1 -1
  3. ccxt/ace.py +36 -1
  4. ccxt/alpaca.py +46 -0
  5. ccxt/ascendex.py +2 -2
  6. ccxt/async_support/__init__.py +1 -3
  7. ccxt/async_support/ace.py +36 -1
  8. ccxt/async_support/alpaca.py +46 -0
  9. ccxt/async_support/ascendex.py +2 -2
  10. ccxt/async_support/base/exchange.py +1 -1
  11. ccxt/async_support/binance.py +19 -15
  12. ccxt/async_support/bingx.py +2 -2
  13. ccxt/async_support/bit2c.py +11 -0
  14. ccxt/async_support/bitfinex.py +1 -1
  15. ccxt/async_support/bitfinex1.py +1 -1
  16. ccxt/async_support/bitget.py +6 -5
  17. ccxt/async_support/bitrue.py +1 -1
  18. ccxt/async_support/bl3p.py +2 -2
  19. ccxt/async_support/bybit.py +32 -25
  20. ccxt/async_support/cex.py +1 -0
  21. ccxt/async_support/coinbase.py +3 -2
  22. ccxt/async_support/coinbaseexchange.py +3 -2
  23. ccxt/async_support/coinbaseinternational.py +3 -2
  24. ccxt/async_support/coinex.py +1 -1
  25. ccxt/async_support/defx.py +1 -1
  26. ccxt/async_support/deribit.py +2 -1
  27. ccxt/async_support/derive.py +13 -7
  28. ccxt/async_support/gate.py +3 -0
  29. ccxt/async_support/gemini.py +2 -1
  30. ccxt/async_support/hitbtc.py +1 -1
  31. ccxt/async_support/hyperliquid.py +38 -0
  32. ccxt/async_support/kraken.py +1 -1
  33. ccxt/async_support/krakenfutures.py +4 -0
  34. ccxt/async_support/kucoin.py +1 -1
  35. ccxt/async_support/kuna.py +1 -1
  36. ccxt/async_support/mexc.py +1 -1
  37. ccxt/async_support/ndax.py +1 -1
  38. ccxt/async_support/okcoin.py +4 -0
  39. ccxt/async_support/okx.py +21 -30
  40. ccxt/async_support/paradex.py +65 -7
  41. ccxt/async_support/paymium.py +1 -1
  42. ccxt/async_support/poloniex.py +2 -1
  43. ccxt/async_support/upbit.py +1 -1
  44. ccxt/async_support/whitebit.py +98 -2
  45. ccxt/async_support/woo.py +3 -1
  46. ccxt/async_support/woofipro.py +1 -1
  47. ccxt/async_support/yobit.py +2 -1
  48. ccxt/base/errors.py +6 -0
  49. ccxt/base/exchange.py +13 -12
  50. ccxt/binance.py +19 -15
  51. ccxt/bingx.py +2 -2
  52. ccxt/bit2c.py +11 -0
  53. ccxt/bitfinex.py +1 -1
  54. ccxt/bitfinex1.py +1 -1
  55. ccxt/bitget.py +6 -5
  56. ccxt/bitrue.py +1 -1
  57. ccxt/bl3p.py +2 -2
  58. ccxt/bybit.py +32 -25
  59. ccxt/cex.py +1 -0
  60. ccxt/coinbase.py +3 -2
  61. ccxt/coinbaseexchange.py +3 -2
  62. ccxt/coinbaseinternational.py +3 -2
  63. ccxt/coinex.py +1 -1
  64. ccxt/defx.py +1 -1
  65. ccxt/deribit.py +2 -1
  66. ccxt/derive.py +13 -7
  67. ccxt/gate.py +3 -0
  68. ccxt/gemini.py +2 -1
  69. ccxt/hitbtc.py +1 -1
  70. ccxt/hyperliquid.py +38 -0
  71. ccxt/kraken.py +1 -1
  72. ccxt/krakenfutures.py +4 -0
  73. ccxt/kucoin.py +1 -1
  74. ccxt/kuna.py +1 -1
  75. ccxt/mexc.py +1 -1
  76. ccxt/ndax.py +1 -1
  77. ccxt/okcoin.py +4 -0
  78. ccxt/okx.py +21 -30
  79. ccxt/paradex.py +65 -7
  80. ccxt/paymium.py +1 -1
  81. ccxt/poloniex.py +2 -1
  82. ccxt/pro/__init__.py +1 -3
  83. ccxt/pro/bingx.py +1 -1
  84. ccxt/pro/bitmart.py +15 -7
  85. ccxt/pro/derive.py +2 -2
  86. ccxt/pro/krakenfutures.py +1 -1
  87. ccxt/test/tests_async.py +6 -3
  88. ccxt/test/tests_sync.py +6 -3
  89. ccxt/upbit.py +1 -1
  90. ccxt/whitebit.py +98 -2
  91. ccxt/woo.py +3 -1
  92. ccxt/woofipro.py +1 -1
  93. ccxt/yobit.py +2 -1
  94. {ccxt-4.4.71.dist-info → ccxt-4.4.73.dist-info}/METADATA +5 -5
  95. {ccxt-4.4.71.dist-info → ccxt-4.4.73.dist-info}/RECORD +98 -99
  96. ccxt/abstract/bitfinex1.py +0 -69
  97. {ccxt-4.4.71.dist-info → ccxt-4.4.73.dist-info}/LICENSE.txt +0 -0
  98. {ccxt-4.4.71.dist-info → ccxt-4.4.73.dist-info}/WHEEL +0 -0
  99. {ccxt-4.4.71.dist-info → ccxt-4.4.73.dist-info}/top_level.txt +0 -0
@@ -51,6 +51,10 @@ class krakenfutures(Exchange, ImplicitAPI):
51
51
  'cancelOrders': True,
52
52
  'createMarketOrder': False,
53
53
  'createOrder': True,
54
+ 'createPostOnlyOrder': True,
55
+ 'createReduceOnlyOrder': True,
56
+ 'createStopLimitOrder': True,
57
+ 'createStopMarketOrder': True,
54
58
  'createStopOrder': True,
55
59
  'createTriggerOrder': True,
56
60
  'editOrder': True,
@@ -1960,7 +1960,7 @@ class kucoin(Exchange, ImplicitAPI):
1960
1960
  data = self.safe_list(response, 'data', [])
1961
1961
  return self.parse_ohlcvs(data, market, timeframe, since, limit)
1962
1962
 
1963
- async def create_deposit_address(self, code: str, params={}):
1963
+ async def create_deposit_address(self, code: str, params={}) -> DepositAddress:
1964
1964
  """
1965
1965
 
1966
1966
  https://www.kucoin.com/docs/rest/funding/deposit/create-deposit-address-v3-
@@ -1572,7 +1572,7 @@ class kuna(Exchange, ImplicitAPI):
1572
1572
  data = self.safe_dict(response, 'data', {})
1573
1573
  return self.parse_transaction(data)
1574
1574
 
1575
- async def create_deposit_address(self, code: str, params={}):
1575
+ async def create_deposit_address(self, code: str, params={}) -> DepositAddress:
1576
1576
  """
1577
1577
  create a currency deposit address
1578
1578
 
@@ -4538,7 +4538,7 @@ class mexc(Exchange, ImplicitAPI):
4538
4538
  addressStructures = self.parse_deposit_addresses(response, None, False)
4539
4539
  return self.index_by(addressStructures, 'network')
4540
4540
 
4541
- async def create_deposit_address(self, code: str, params={}):
4541
+ async def create_deposit_address(self, code: str, params={}) -> DepositAddress:
4542
4542
  """
4543
4543
  create a currency deposit address
4544
4544
 
@@ -2083,7 +2083,7 @@ class ndax(Exchange, ImplicitAPI):
2083
2083
  'tag': tag,
2084
2084
  }
2085
2085
 
2086
- async def create_deposit_address(self, code: str, params={}):
2086
+ async def create_deposit_address(self, code: str, params={}) -> DepositAddress:
2087
2087
  """
2088
2088
  create a currency deposit address
2089
2089
  :param str code: unified currency code of the currency for the deposit address
@@ -56,6 +56,10 @@ class okcoin(Exchange, ImplicitAPI):
56
56
  'createMarketOrderWithCost': False,
57
57
  'createMarketSellOrderWithCost': False,
58
58
  'createOrder': True,
59
+ 'createPostOnlyOrder': True,
60
+ 'createReduceOnlyOrder': True,
61
+ 'createStopLimitOrder': True,
62
+ 'createStopMarketOrder': True,
59
63
  'createStopOrder': True,
60
64
  'createTriggerOrder': True,
61
65
  'fetchBalance': True,
ccxt/async_support/okx.py CHANGED
@@ -1624,11 +1624,12 @@ class okx(Exchange, ImplicitAPI):
1624
1624
  optionType = None
1625
1625
  if contract:
1626
1626
  symbol = symbol + ':' + settle
1627
- expiry = self.safe_integer(market, 'expTime')
1628
1627
  if future:
1628
+ expiry = self.safe_integer(market, 'expTime')
1629
1629
  ymd = self.yymmdd(expiry)
1630
1630
  symbol = symbol + '-' + ymd
1631
1631
  elif option:
1632
+ expiry = self.safe_integer(market, 'expTime')
1632
1633
  strikePrice = self.safe_string(market, 'stk')
1633
1634
  optionType = self.safe_string(market, 'optType')
1634
1635
  ymd = self.yymmdd(expiry)
@@ -1819,38 +1820,24 @@ class okx(Exchange, ImplicitAPI):
1819
1820
  code = currency['code']
1820
1821
  chains = dataByCurrencyId[currencyId]
1821
1822
  networks: dict = {}
1822
- currencyActive = False
1823
- depositEnabled = False
1824
- withdrawEnabled = False
1825
- maxPrecision = None
1826
- for j in range(0, len(chains)):
1823
+ type = 'crypto'
1824
+ chainsLength = len(chains)
1825
+ for j in range(0, chainsLength):
1827
1826
  chain = chains[j]
1828
- canDeposit = self.safe_bool(chain, 'canDep')
1829
- depositEnabled = canDeposit if (canDeposit) else depositEnabled
1830
- canWithdraw = self.safe_bool(chain, 'canWd')
1831
- withdrawEnabled = canWithdraw if (canWithdraw) else withdrawEnabled
1832
- canInternal = self.safe_bool(chain, 'canInternal')
1833
- active = True if (canDeposit and canWithdraw and canInternal) else False
1834
- currencyActive = active if (active) else currencyActive
1835
- networkId = self.safe_string(chain, 'chain')
1836
- if (networkId is not None) and (networkId.find('-') >= 0):
1827
+ networkId = self.safe_string(chain, 'chain') # USDT-BEP20, USDT-Avalance-C, etc
1828
+ if networkId is not None:
1837
1829
  idParts = networkId.split('-')
1838
1830
  parts = self.array_slice(idParts, 1)
1839
1831
  chainPart = '-'.join(parts)
1840
1832
  networkCode = self.network_id_to_code(chainPart, currency['code'])
1841
- precision = self.parse_precision(self.safe_string(chain, 'wdTickSz'))
1842
- if maxPrecision is None:
1843
- maxPrecision = precision
1844
- else:
1845
- maxPrecision = Precise.string_min(maxPrecision, precision)
1846
1833
  networks[networkCode] = {
1847
1834
  'id': networkId,
1848
1835
  'network': networkCode,
1849
- 'active': active,
1850
- 'deposit': canDeposit,
1851
- 'withdraw': canWithdraw,
1836
+ 'active': None,
1837
+ 'deposit': self.safe_bool(chain, 'canDep'),
1838
+ 'withdraw': self.safe_bool(chain, 'canWd'),
1852
1839
  'fee': self.safe_number(chain, 'fee'),
1853
- 'precision': self.parse_number(precision),
1840
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'wdTickSz'))),
1854
1841
  'limits': {
1855
1842
  'withdraw': {
1856
1843
  'min': self.safe_number(chain, 'minWd'),
@@ -1859,25 +1846,29 @@ class okx(Exchange, ImplicitAPI):
1859
1846
  },
1860
1847
  'info': chain,
1861
1848
  }
1849
+ else:
1850
+ # only happens for FIAT currency
1851
+ type = 'fiat'
1862
1852
  firstChain = self.safe_dict(chains, 0, {})
1863
- result[code] = {
1853
+ result[code] = self.safe_currency_structure({
1864
1854
  'info': chains,
1865
1855
  'code': code,
1866
1856
  'id': currencyId,
1867
1857
  'name': self.safe_string(firstChain, 'name'),
1868
- 'active': currencyActive,
1869
- 'deposit': depositEnabled,
1870
- 'withdraw': withdrawEnabled,
1858
+ 'active': None,
1859
+ 'deposit': None,
1860
+ 'withdraw': None,
1871
1861
  'fee': None,
1872
- 'precision': self.parse_number(maxPrecision),
1862
+ 'precision': None,
1873
1863
  'limits': {
1874
1864
  'amount': {
1875
1865
  'min': None,
1876
1866
  'max': None,
1877
1867
  },
1878
1868
  },
1869
+ 'type': type,
1879
1870
  'networks': networks,
1880
- }
1871
+ })
1881
1872
  return result
1882
1873
 
1883
1874
  async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
@@ -496,6 +496,57 @@ class paradex(Exchange, ImplicitAPI):
496
496
  # "max_tob_spread": "0.2"
497
497
  # }
498
498
  #
499
+ # {
500
+ # "symbol":"BTC-USD-96000-C",
501
+ # "base_currency":"BTC",
502
+ # "quote_currency":"USD",
503
+ # "settlement_currency":"USDC",
504
+ # "order_size_increment":"0.001",
505
+ # "price_tick_size":"0.01",
506
+ # "min_notional":"100",
507
+ # "open_at":"1736764200000",
508
+ # "expiry_at":"0",
509
+ # "asset_kind":"PERP_OPTION",
510
+ # "market_kind":"cross",
511
+ # "position_limit":"10",
512
+ # "price_bands_width":"0.05",
513
+ # "iv_bands_width":"0.05",
514
+ # "max_open_orders":"100",
515
+ # "max_funding_rate":"0.02",
516
+ # "option_cross_margin_params":{
517
+ # "imf":{
518
+ # "long_itm":"0.2",
519
+ # "short_itm":"0.15",
520
+ # "short_otm":"0.1",
521
+ # "short_put_cap":"0.5",
522
+ # "premium_multiplier":"1"
523
+ # },
524
+ # "mmf":{
525
+ # "long_itm":"0.1",
526
+ # "short_itm":"0.075",
527
+ # "short_otm":"0.05",
528
+ # "short_put_cap":"0.5",
529
+ # "premium_multiplier":"0.5"
530
+ # }
531
+ # },
532
+ # "price_feed_id":"GVXRSBjFk6e6J3NbVPXohDJetcTjaeeuykUpbQF8UoMU",
533
+ # "oracle_ewma_factor":"0.20000046249626113",
534
+ # "max_order_size":"2",
535
+ # "max_funding_rate_change":"0.02",
536
+ # "max_tob_spread":"0.2",
537
+ # "interest_rate":"0.0001",
538
+ # "clamp_rate":"0.02",
539
+ # "option_type":"CALL",
540
+ # "strike_price":"96000",
541
+ # "funding_period_hours":"24",
542
+ # "tags":[
543
+ # ]
544
+ # }
545
+ #
546
+ assetKind = self.safe_string(market, 'asset_kind')
547
+ isOption = (assetKind == 'PERP_OPTION')
548
+ type = 'option' if (isOption) else 'swap'
549
+ isSwap = (type == 'swap')
499
550
  marketId = self.safe_string(market, 'symbol')
500
551
  quoteId = self.safe_string(market, 'quote_currency')
501
552
  baseId = self.safe_string(market, 'base_currency')
@@ -505,6 +556,13 @@ class paradex(Exchange, ImplicitAPI):
505
556
  settle = self.safe_currency_code(settleId)
506
557
  symbol = base + '/' + quote + ':' + settle
507
558
  expiry = self.safe_integer(market, 'expiry_at')
559
+ optionType = self.safe_string(market, 'option_type')
560
+ strikePrice = self.safe_string(market, 'strike_price')
561
+ if isOption:
562
+ optionTypeSuffix = 'C' if (optionType == 'CALL') else 'P'
563
+ symbol = symbol + '-' + strikePrice + '-' + optionTypeSuffix
564
+ else:
565
+ expiry = None
508
566
  takerFee = self.parse_number('0.0003')
509
567
  makerFee = self.parse_number('-0.00005')
510
568
  return self.safe_market_structure({
@@ -516,23 +574,23 @@ class paradex(Exchange, ImplicitAPI):
516
574
  'baseId': baseId,
517
575
  'quoteId': quoteId,
518
576
  'settleId': settleId,
519
- 'type': 'swap',
577
+ 'type': type,
520
578
  'spot': False,
521
579
  'margin': None,
522
- 'swap': True,
580
+ 'swap': isSwap,
523
581
  'future': False,
524
- 'option': False,
582
+ 'option': isOption,
525
583
  'active': self.safe_bool(market, 'enableTrading'),
526
584
  'contract': True,
527
585
  'linear': True,
528
- 'inverse': None,
586
+ 'inverse': False,
529
587
  'taker': takerFee,
530
588
  'maker': makerFee,
531
589
  'contractSize': self.parse_number('1'),
532
- 'expiry': None if (expiry == 0) else expiry,
590
+ 'expiry': expiry,
533
591
  'expiryDatetime': None if (expiry == 0) else self.iso8601(expiry),
534
- 'strike': None,
535
- 'optionType': None,
592
+ 'strike': self.parse_number(strikePrice),
593
+ 'optionType': self.safe_string_lower(market, 'option_type'),
536
594
  'precision': {
537
595
  'amount': self.safe_number(market, 'order_size_increment'),
538
596
  'price': self.safe_number(market, 'price_tick_size'),
@@ -333,7 +333,7 @@ class paymium(Exchange, ImplicitAPI):
333
333
  response = await self.publicGetDataCurrencyTrades(self.extend(request, params))
334
334
  return self.parse_trades(response, market, since, limit)
335
335
 
336
- async def create_deposit_address(self, code: str, params={}):
336
+ async def create_deposit_address(self, code: str, params={}) -> DepositAddress:
337
337
  """
338
338
  create a currency deposit address
339
339
 
@@ -429,6 +429,7 @@ class poloniex(Exchange, ImplicitAPI):
429
429
  'untilDays': None,
430
430
  'trigger': False,
431
431
  'trailing': False,
432
+ 'symbolRequired': False,
432
433
  },
433
434
  'fetchMyTrades': {
434
435
  'limit': 100,
@@ -2572,7 +2573,7 @@ class poloniex(Exchange, ImplicitAPI):
2572
2573
  'nonce': None,
2573
2574
  }
2574
2575
 
2575
- async def create_deposit_address(self, code: str, params={}):
2576
+ async def create_deposit_address(self, code: str, params={}) -> DepositAddress:
2576
2577
  """
2577
2578
  create a currency deposit address
2578
2579
 
@@ -1886,7 +1886,7 @@ class upbit(Exchange, ImplicitAPI):
1886
1886
  #
1887
1887
  return self.parse_deposit_address(response)
1888
1888
 
1889
- async def create_deposit_address(self, code: str, params={}):
1889
+ async def create_deposit_address(self, code: str, params={}) -> DepositAddress:
1890
1890
  """
1891
1891
 
1892
1892
  https://docs.upbit.com/reference/%EC%9E%85%EA%B8%88-%EC%A3%BC%EC%86%8C-%EC%83%9D%EC%84%B1-%EC%9A%94%EC%B2%AD
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.whitebit import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Any, Balances, BorrowInterest, Bool, Conversion, Currencies, Currency, DepositAddress, FundingHistory, Int, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFees, Transaction, TransferEntry
9
+ from ccxt.base.types import Any, Balances, BorrowInterest, Bool, Conversion, CrossBorrowRate, Currencies, Currency, DepositAddress, FundingHistory, Int, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFees, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -46,13 +46,16 @@ class whitebit(Exchange, ImplicitAPI):
46
46
  'cancelOrder': True,
47
47
  'cancelOrders': False,
48
48
  'createConvertTrade': True,
49
+ 'createDepositAddress': True,
49
50
  'createMarketBuyOrderWithCost': True,
50
51
  'createMarketOrderWithCost': False,
51
52
  'createMarketSellOrderWithCost': False,
52
53
  'createOrder': True,
54
+ 'createPostOnlyOrder': True,
53
55
  'createStopLimitOrder': True,
54
56
  'createStopMarketOrder': True,
55
57
  'createStopOrder': True,
58
+ 'createTriggerOrder': True,
56
59
  'editOrder': False,
57
60
  'fetchBalance': True,
58
61
  'fetchBorrowRateHistories': False,
@@ -61,7 +64,7 @@ class whitebit(Exchange, ImplicitAPI):
61
64
  'fetchConvertQuote': True,
62
65
  'fetchConvertTrade': False,
63
66
  'fetchConvertTradeHistory': True,
64
- 'fetchCrossBorrowRate': False,
67
+ 'fetchCrossBorrowRate': True,
65
68
  'fetchCrossBorrowRates': False,
66
69
  'fetchCurrencies': True,
67
70
  'fetchDeposit': True,
@@ -1375,6 +1378,10 @@ class whitebit(Exchange, ImplicitAPI):
1375
1378
  :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1376
1379
  :param dict [params]: extra parameters specific to the exchange API endpoint
1377
1380
  :param float [params.cost]: *market orders only* the cost of the order in units of the base currency
1381
+ :param float [params.triggerPrice]: The price at which a trigger order is triggered at
1382
+ :param bool [params.postOnly]: If True, the order will only be posted to the order book and not executed immediately
1383
+ :param str [params.clientOrderId]: a unique id for the order
1384
+ :param str [params.marginMode]: 'cross' or 'isolated', for margin trading, uses self.options.defaultMarginMode if not passed, defaults to None/None/None
1378
1385
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1379
1386
  """
1380
1387
  await self.load_markets()
@@ -2001,6 +2008,60 @@ class whitebit(Exchange, ImplicitAPI):
2001
2008
  'tag': tag,
2002
2009
  }
2003
2010
 
2011
+ async def create_deposit_address(self, code: str, params={}) -> DepositAddress:
2012
+ """
2013
+ create a currency deposit address
2014
+
2015
+ https://docs.whitebit.com/private/http-main-v4/#create-new-address-for-deposit
2016
+
2017
+ :param str code: unified currency code of the currency for the deposit address
2018
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2019
+ :param str [params.network]: the blockchain network to create a deposit address on
2020
+ :param str [params.type]: address type, available for specific currencies
2021
+ :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
2022
+ """
2023
+ await self.load_markets()
2024
+ currency = self.currency(code)
2025
+ request: dict = {
2026
+ 'ticker': currency['id'],
2027
+ }
2028
+ response = await self.v4PrivatePostMainAccountCreateNewAddress(self.extend(request, params))
2029
+ #
2030
+ # {
2031
+ # "account": {
2032
+ # "address": "GDTSOI56XNVAKJNJBLJGRNZIVOCIZJRBIDKTWSCYEYNFAZEMBLN75RMN",
2033
+ # "memo": "48565488244493"
2034
+ # },
2035
+ # "required": {
2036
+ # "maxAmount": "0",
2037
+ # "minAmount": "1",
2038
+ # "fixedFee": "0",
2039
+ # "flexFee": {
2040
+ # "maxFee": "0",
2041
+ # "minFee": "0",
2042
+ # "percent": "0"
2043
+ # }
2044
+ # }
2045
+ # }
2046
+ #
2047
+ data = self.safe_dict(response, 'account', {})
2048
+ return self.parse_deposit_address(data, currency)
2049
+
2050
+ def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
2051
+ #
2052
+ # {
2053
+ # "address": "GDTSOI56XNVAKJNJBLJGRNZIVOCIZJRBIDKTWSCYEYNFAZEMBLN75RMN",
2054
+ # "memo": "48565488244493"
2055
+ # },
2056
+ #
2057
+ return {
2058
+ 'info': depositAddress,
2059
+ 'currency': self.safe_currency_code(None, currency),
2060
+ 'network': None,
2061
+ 'address': self.safe_string(depositAddress, 'address'),
2062
+ 'tag': self.safe_string(depositAddress, 'memo'),
2063
+ }
2064
+
2004
2065
  async def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
2005
2066
  """
2006
2067
  set the level of leverage for a market
@@ -3069,6 +3130,41 @@ class whitebit(Exchange, ImplicitAPI):
3069
3130
  'takeProfitPrice': self.safe_number(tpsl, 'takeProfit'),
3070
3131
  })
3071
3132
 
3133
+ async def fetch_cross_borrow_rate(self, code: str, params={}) -> CrossBorrowRate:
3134
+ """
3135
+ fetch the rate of interest to borrow a currency for margin trading
3136
+
3137
+ https://docs.whitebit.com/private/http-main-v4/#get-plans
3138
+
3139
+ :param str code: unified currency code
3140
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3141
+ :returns dict: a `borrow rate structure <https://docs.ccxt.com/#/?id=borrow-rate-structure>`
3142
+ """
3143
+ await self.load_markets()
3144
+ currency = self.currency(code)
3145
+ request: dict = {
3146
+ 'ticker': currency['id'],
3147
+ }
3148
+ response = await self.v4PrivatePostMainAccountSmartPlans(self.extend(request, params))
3149
+ #
3150
+ #
3151
+ data = self.safe_list(response, 0, [])
3152
+ return self.parse_borrow_rate(data, currency)
3153
+
3154
+ def parse_borrow_rate(self, info, currency: Currency = None):
3155
+ #
3156
+ #
3157
+ currencyId = self.safe_string(info, 'ticker')
3158
+ percent = self.safe_string(info, 'percent')
3159
+ return {
3160
+ 'currency': self.safe_currency_code(currencyId, currency),
3161
+ 'rate': self.parse_number(Precise.string_div(percent, '100')),
3162
+ 'period': self.safe_integer(info, 'duration'),
3163
+ 'timestamp': None,
3164
+ 'datetime': None,
3165
+ 'info': info,
3166
+ }
3167
+
3072
3168
  def is_fiat(self, currency: str) -> bool:
3073
3169
  fiatCurrencies = self.safe_value(self.options, 'fiatCurrencies', [])
3074
3170
  return self.in_array(currency, fiatCurrencies)
ccxt/async_support/woo.py CHANGED
@@ -563,6 +563,7 @@ class woo(Exchange, ImplicitAPI):
563
563
  symbol = base + '/' + quote
564
564
  contractSize: Num = None
565
565
  linear: Bool = None
566
+ inverse: Bool = None
566
567
  margin = True
567
568
  contract = swap
568
569
  if contract:
@@ -572,6 +573,7 @@ class woo(Exchange, ImplicitAPI):
572
573
  symbol = base + '/' + quote + ':' + settle
573
574
  contractSize = self.parse_number('1')
574
575
  linear = True
576
+ inverse = False
575
577
  return {
576
578
  'id': marketId,
577
579
  'symbol': symbol,
@@ -590,7 +592,7 @@ class woo(Exchange, ImplicitAPI):
590
592
  'active': self.safe_string(market, 'is_trading') == '1',
591
593
  'contract': contract,
592
594
  'linear': linear,
593
- 'inverse': None,
595
+ 'inverse': inverse,
594
596
  'contractSize': contractSize,
595
597
  'expiry': None,
596
598
  'expiryDatetime': None,
@@ -548,7 +548,7 @@ class woofipro(Exchange, ImplicitAPI):
548
548
  'active': None,
549
549
  'contract': True,
550
550
  'linear': True,
551
- 'inverse': None,
551
+ 'inverse': False,
552
552
  'contractSize': self.parse_number('1'),
553
553
  'expiry': None,
554
554
  'expiryDatetime': None,
@@ -1217,7 +1217,7 @@ class yobit(Exchange, ImplicitAPI):
1217
1217
  result.append(trade)
1218
1218
  return self.filter_by_symbol_since_limit(result, market['symbol'], since, limit)
1219
1219
 
1220
- async def create_deposit_address(self, code: str, params={}):
1220
+ async def create_deposit_address(self, code: str, params={}) -> DepositAddress:
1221
1221
  """
1222
1222
 
1223
1223
  https://yobit.net/en/api
@@ -1237,6 +1237,7 @@ class yobit(Exchange, ImplicitAPI):
1237
1237
  'currency': code,
1238
1238
  'address': address,
1239
1239
  'tag': None,
1240
+ 'network': None,
1240
1241
  'info': response['info'],
1241
1242
  }
1242
1243
 
ccxt/base/errors.py CHANGED
@@ -1,3 +1,9 @@
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
+
1
7
  error_hierarchy = {
2
8
  'BaseError': {
3
9
  'ExchangeError': {
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.71'
7
+ __version__ = '4.4.73'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2921,7 +2921,8 @@ class Exchange(object):
2921
2921
  length = len(keys)
2922
2922
  if length != 0:
2923
2923
  for i in range(0, length):
2924
- network = networks[keys[i]]
2924
+ key = keys[i]
2925
+ network = networks[key]
2925
2926
  deposit = self.safe_bool(network, 'deposit')
2926
2927
  if currencyDeposit is None or deposit:
2927
2928
  currency['deposit'] = deposit
@@ -2931,6 +2932,12 @@ class Exchange(object):
2931
2932
  active = self.safe_bool(network, 'active')
2932
2933
  if currencyActive is None or active:
2933
2934
  currency['active'] = active
2935
+ # set network 'active' to False if D or W is disabled
2936
+ if self.safe_bool(network, 'active') is None:
2937
+ if deposit and withdraw:
2938
+ currency['networks'][key]['active'] = True
2939
+ elif deposit is not None and withdraw is not None:
2940
+ currency['networks'][key]['active'] = False
2934
2941
  # find lowest fee(which is more desired)
2935
2942
  fee = self.safe_string(network, 'fee')
2936
2943
  feeMain = self.safe_string(currency, 'fee')
@@ -6464,19 +6471,13 @@ class Exchange(object):
6464
6471
  return self.sort_by(result, 'id', True)
6465
6472
  return result
6466
6473
 
6467
- def remove_repeated_elements_from_array(self, input):
6474
+ def remove_repeated_elements_from_array(self, input, fallbackToTimestamp: bool = True):
6468
6475
  uniqueResult = {}
6469
6476
  for i in range(0, len(input)):
6470
6477
  entry = input[i]
6471
- id = self.safe_string(entry, 'id')
6472
- if id is not None:
6473
- if self.safe_string(uniqueResult, id) is None:
6474
- uniqueResult[id] = entry
6475
- else:
6476
- timestamp = self.safe_integer_2(entry, 'timestamp', 0)
6477
- if timestamp is not None:
6478
- if self.safe_string(uniqueResult, timestamp) is None:
6479
- uniqueResult[timestamp] = entry
6478
+ uniqValue = self.safe_string_n(entry, ['id', 'timestamp', 0]) if fallbackToTimestamp else self.safe_string(entry, 'id')
6479
+ if uniqValue is not None and not (uniqValue in uniqueResult):
6480
+ uniqueResult[uniqValue] = entry
6480
6481
  values = list(uniqueResult.values())
6481
6482
  valuesLength = len(values)
6482
6483
  if valuesLength > 0: