ccxt 4.4.73__py2.py3-none-any.whl → 4.4.75__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 (57) hide show
  1. ccxt/__init__.py +1 -5
  2. ccxt/abstract/bitmart.py +2 -0
  3. ccxt/abstract/coinlist.py +3 -0
  4. ccxt/ace.py +3 -0
  5. ccxt/alpaca.py +3 -0
  6. ccxt/ascendex.py +6 -0
  7. ccxt/async_support/__init__.py +1 -5
  8. ccxt/async_support/ace.py +3 -0
  9. ccxt/async_support/alpaca.py +3 -0
  10. ccxt/async_support/ascendex.py +6 -0
  11. ccxt/async_support/base/exchange.py +1 -1
  12. ccxt/async_support/bequant.py +1 -0
  13. ccxt/async_support/binanceusdm.py +1 -1
  14. ccxt/async_support/bit2c.py +26 -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/bithumb.py +34 -0
  19. ccxt/async_support/bitmart.py +70 -6
  20. ccxt/async_support/bitopro.py +37 -0
  21. ccxt/async_support/blofin.py +1 -1
  22. ccxt/async_support/bybit.py +10 -1
  23. ccxt/async_support/coinlist.py +86 -11
  24. ccxt/async_support/deribit.py +19 -0
  25. ccxt/async_support/gate.py +11 -7
  26. ccxt/async_support/hitbtc.py +7 -1
  27. ccxt/async_support/okx.py +28 -24
  28. ccxt/base/exchange.py +33 -14
  29. ccxt/bequant.py +1 -0
  30. ccxt/binanceusdm.py +1 -1
  31. ccxt/bit2c.py +26 -0
  32. ccxt/bitbank.py +32 -0
  33. ccxt/bitbns.py +1 -1
  34. ccxt/bitflyer.py +1 -0
  35. ccxt/bithumb.py +34 -0
  36. ccxt/bitmart.py +70 -6
  37. ccxt/bitopro.py +37 -0
  38. ccxt/blofin.py +1 -1
  39. ccxt/bybit.py +10 -1
  40. ccxt/coinlist.py +86 -11
  41. ccxt/deribit.py +19 -0
  42. ccxt/gate.py +11 -7
  43. ccxt/hitbtc.py +7 -1
  44. ccxt/okx.py +28 -24
  45. ccxt/pro/__init__.py +1 -5
  46. ccxt/pro/ascendex.py +1 -1
  47. ccxt/pro/bingx.py +9 -1
  48. ccxt/pro/bitget.py +9 -1
  49. ccxt/pro/bitmart.py +9 -1
  50. ccxt/pro/bitopro.py +5 -4
  51. {ccxt-4.4.73.dist-info → ccxt-4.4.75.dist-info}/METADATA +5 -5
  52. {ccxt-4.4.73.dist-info → ccxt-4.4.75.dist-info}/RECORD +55 -57
  53. ccxt/abstract/bitcoincom.py +0 -115
  54. ccxt/abstract/bitpanda.py +0 -23
  55. {ccxt-4.4.73.dist-info → ccxt-4.4.75.dist-info}/LICENSE.txt +0 -0
  56. {ccxt-4.4.73.dist-info → ccxt-4.4.75.dist-info}/WHEEL +0 -0
  57. {ccxt-4.4.73.dist-info → ccxt-4.4.75.dist-info}/top_level.txt +0 -0
ccxt/coinlist.py CHANGED
@@ -171,6 +171,7 @@ class coinlist(Exchange, ImplicitAPI):
171
171
  'v1/leaderboard': 1,
172
172
  'v1/affiliate/{competition_code}': 1,
173
173
  'v1/competition/{competition_id}': 1,
174
+ 'v1/symbols/{symbol}/funding': 1,
174
175
  },
175
176
  },
176
177
  'private': {
@@ -194,6 +195,7 @@ class coinlist(Exchange, ImplicitAPI):
194
195
  'v1/credits': 1, # not unified
195
196
  'v1/positions': 1,
196
197
  'v1/accounts/{trader_id}/competitions': 1,
198
+ 'v1/closedPositions': 1,
197
199
  },
198
200
  'post': {
199
201
  'v1/keys': 1, # not unified
@@ -212,6 +214,9 @@ class coinlist(Exchange, ImplicitAPI):
212
214
  'v1/orders/{order_id}': 1,
213
215
  'v1/orders/bulk': 1, # not unified
214
216
  },
217
+ 'put': {
218
+ 'v1/accounts/{trader_id}/alias': 1,
219
+ },
215
220
  'delete': {
216
221
  'v1/keys/{key}': 1, # not unified
217
222
  'v1/orders': 1,
@@ -501,7 +506,7 @@ class coinlist(Exchange, ImplicitAPI):
501
506
  # {
502
507
  # "symbols": [
503
508
  # {
504
- # "symbol": "CQT-USDT",
509
+ # "symbol": "CQT-USDT", # spot
505
510
  # "base_currency": "CQT",
506
511
  # "is_trader_geofenced": False,
507
512
  # "list_time": "2021-06-15T00:00:00.000Z",
@@ -526,6 +531,62 @@ class coinlist(Exchange, ImplicitAPI):
526
531
  return self.parse_markets(markets)
527
532
 
528
533
  def parse_market(self, market: dict) -> Market:
534
+ # perp
535
+ # {
536
+ # "symbol":"BTC-PERP",
537
+ # "base_currency":"BTC",
538
+ # "is_trader_geofenced":false,
539
+ # "expiry_name":null,
540
+ # "expiry_time":null,
541
+ # "list_time":"2024-09-16T00:00:00.000Z",
542
+ # "type":"perp-swap",
543
+ # "series_code":"BTC",
544
+ # "long_name":"Bitcoin",
545
+ # "asset_class":"CRYPTO",
546
+ # "minimum_price_increment":"0.01",
547
+ # "minimum_size_increment":"0.0001",
548
+ # "quote_currency":"USDT",
549
+ # "multiplier":"1",
550
+ # "contract_frequency":"FGHJKMNQUVXZ",
551
+ # "index_code":".BTC-USDT",
552
+ # "price_band_threshold_market":"0.05",
553
+ # "price_band_threshold_limit":"0.25",
554
+ # "maintenance_initial_ratio":"0.500000000000000000",
555
+ # "liquidation_initial_ratio":"0.500000000000000000",
556
+ # "last_price":"75881.36000000",
557
+ # "fair_price":"76256.00000000",
558
+ # "index_price":"77609.90000000",
559
+ # "mark_price":"76237.75000000",
560
+ # "mark_price_dollarizer":"0.99950000",
561
+ # "funding_interval":{
562
+ # "hours":"8"
563
+ # },
564
+ # "funding_rate_index_code":".BTC-USDT-FR8H",
565
+ # "initial_margin_base":"0.200000000000000000",
566
+ # "initial_margin_per_contract":"0.160000000000000000",
567
+ # "position_limit":"5.0000"
568
+ # }
569
+ # spot
570
+ # {
571
+ # "symbol": "CQT-USDT", # spot
572
+ # "base_currency": "CQT",
573
+ # "is_trader_geofenced": False,
574
+ # "list_time": "2021-06-15T00:00:00.000Z",
575
+ # "type": "spot",
576
+ # "series_code": "CQT-USDT-SPOT",
577
+ # "long_name": "Covalent",
578
+ # "asset_class": "CRYPTO",
579
+ # "minimum_price_increment": "0.0001",
580
+ # "minimum_size_increment": "0.0001",
581
+ # "quote_currency": "USDT",
582
+ # "index_code": null,
583
+ # "price_band_threshold_market": "0.05",
584
+ # "price_band_threshold_limit": "0.25",
585
+ # "last_price": "0.12160000",
586
+ # "fair_price": "0.12300000",
587
+ # "index_price": null
588
+ # }
589
+ isSwap = self.safe_string(market, 'type') == 'perp-swap'
529
590
  id = self.safe_string(market, 'symbol')
530
591
  baseId = self.safe_string(market, 'base_currency')
531
592
  quoteId = self.safe_string(market, 'quote_currency')
@@ -534,26 +595,40 @@ class coinlist(Exchange, ImplicitAPI):
534
595
  amountPrecision = self.safe_string(market, 'minimum_size_increment')
535
596
  pricePrecision = self.safe_string(market, 'minimum_price_increment')
536
597
  created = self.safe_string(market, 'list_time')
598
+ settledId = None
599
+ settled = None
600
+ linear = None
601
+ inverse = None
602
+ contractSize = None
603
+ symbol = base + '/' + quote
604
+ if isSwap:
605
+ contractSize = self.parse_number('1')
606
+ linear = True
607
+ inverse = False
608
+ settledId = quoteId
609
+ settled = quote
610
+ symbol = symbol + ':' + quote
611
+ type = 'swap' if isSwap else 'spot'
537
612
  return {
538
613
  'id': id,
539
- 'symbol': base + '/' + quote,
614
+ 'symbol': symbol,
540
615
  'base': base,
541
616
  'quote': quote,
542
- 'settle': None,
617
+ 'settle': settled,
543
618
  'baseId': baseId,
544
619
  'quoteId': quoteId,
545
- 'settleId': None,
546
- 'type': 'spot',
547
- 'spot': True,
620
+ 'settleId': settledId,
621
+ 'type': type,
622
+ 'spot': not isSwap,
548
623
  'margin': False,
549
- 'swap': False,
624
+ 'swap': isSwap,
550
625
  'future': False,
551
626
  'option': False,
552
627
  'active': True,
553
- 'contract': False,
554
- 'linear': None,
555
- 'inverse': None,
556
- 'contractSize': None,
628
+ 'contract': isSwap,
629
+ 'linear': linear,
630
+ 'inverse': inverse,
631
+ 'contractSize': contractSize,
557
632
  'expiry': None,
558
633
  'expiryDatetime': None,
559
634
  'strike': None,
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/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': {
@@ -1823,31 +1824,31 @@ class okx(Exchange, ImplicitAPI):
1823
1824
  chainsLength = len(chains)
1824
1825
  for j in range(0, chainsLength):
1825
1826
  chain = chains[j]
1826
- networkId = self.safe_string(chain, 'chain') # USDT-BEP20, USDT-Avalance-C, etc
1827
- if networkId is not None:
1828
- idParts = networkId.split('-')
1829
- parts = self.array_slice(idParts, 1)
1830
- chainPart = '-'.join(parts)
1831
- networkCode = self.network_id_to_code(chainPart, currency['code'])
1832
- networks[networkCode] = {
1833
- 'id': networkId,
1834
- 'network': networkCode,
1835
- 'active': None,
1836
- 'deposit': self.safe_bool(chain, 'canDep'),
1837
- 'withdraw': self.safe_bool(chain, 'canWd'),
1838
- 'fee': self.safe_number(chain, 'fee'),
1839
- 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'wdTickSz'))),
1840
- 'limits': {
1841
- 'withdraw': {
1842
- 'min': self.safe_number(chain, 'minWd'),
1843
- 'max': self.safe_number(chain, 'maxWd'),
1844
- },
1845
- },
1846
- 'info': chain,
1847
- }
1848
- else:
1849
- # only happens for FIAT currency
1827
+ # allow empty string for rare fiat-currencies, e.g. TRY
1828
+ networkId = self.safe_string(chain, 'chain', '') # USDT-BEP20, USDT-Avalance-C, etc
1829
+ if networkId == '':
1830
+ # only happens for fiat 'TRY' currency
1850
1831
  type = 'fiat'
1832
+ idParts = networkId.split('-')
1833
+ parts = self.array_slice(idParts, 1)
1834
+ chainPart = '-'.join(parts)
1835
+ networkCode = self.network_id_to_code(chainPart, currency['code'])
1836
+ networks[networkCode] = {
1837
+ 'id': networkId,
1838
+ 'network': networkCode,
1839
+ 'active': None,
1840
+ 'deposit': self.safe_bool(chain, 'canDep'),
1841
+ 'withdraw': self.safe_bool(chain, 'canWd'),
1842
+ 'fee': self.safe_number(chain, 'fee'),
1843
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'wdTickSz'))),
1844
+ 'limits': {
1845
+ 'withdraw': {
1846
+ 'min': self.safe_number(chain, 'minWd'),
1847
+ 'max': self.safe_number(chain, 'maxWd'),
1848
+ },
1849
+ },
1850
+ 'info': chain,
1851
+ }
1851
1852
  firstChain = self.safe_dict(chains, 0, {})
1852
1853
  result[code] = self.safe_currency_structure({
1853
1854
  'info': chains,
@@ -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.73'
7
+ __version__ = '4.4.75'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
@@ -20,14 +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
24
  from ccxt.pro.bitget import bitget # noqa: F401
26
25
  from ccxt.pro.bithumb import bithumb # noqa: F401
27
26
  from ccxt.pro.bitmart import bitmart # noqa: F401
28
27
  from ccxt.pro.bitmex import bitmex # noqa: F401
29
28
  from ccxt.pro.bitopro import bitopro # noqa: F401
30
- from ccxt.pro.bitpanda import bitpanda # noqa: F401
31
29
  from ccxt.pro.bitrue import bitrue # noqa: F401
32
30
  from ccxt.pro.bitstamp import bitstamp # noqa: F401
33
31
  from ccxt.pro.bitvavo import bitvavo # noqa: F401
@@ -94,14 +92,12 @@ exchanges = [
94
92
  'binanceus',
95
93
  'binanceusdm',
96
94
  'bingx',
97
- 'bitcoincom',
98
95
  'bitfinex',
99
96
  'bitget',
100
97
  'bithumb',
101
98
  'bitmart',
102
99
  'bitmex',
103
100
  'bitopro',
104
- 'bitpanda',
105
101
  'bitrue',
106
102
  'bitstamp',
107
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
  #
ccxt/pro/bitget.py CHANGED
@@ -77,6 +77,9 @@ class bitget(ccxt.async_support.bitget):
77
77
  'watchOrderBook': {
78
78
  'checksum': True,
79
79
  },
80
+ 'watchTrades': {
81
+ 'ignoreDuplicates': True,
82
+ },
80
83
  },
81
84
  'streaming': {
82
85
  'ping': self.ping,
@@ -767,7 +770,12 @@ class bitget(ccxt.async_support.bitget):
767
770
  first = self.safe_value(trades, 0)
768
771
  tradeSymbol = self.safe_string(first, 'symbol')
769
772
  limit = trades.getLimit(tradeSymbol, limit)
770
- return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
773
+ result = self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
774
+ if self.handle_option('watchTrades', 'ignoreDuplicates', True):
775
+ filtered = self.remove_repeated_trades_from_array(result)
776
+ filtered = self.sort_by(filtered, 'timestamp')
777
+ return filtered
778
+ return result
771
779
 
772
780
  async def un_watch_trades(self, symbol: str, params={}) -> Any:
773
781
  """
ccxt/pro/bitmart.py CHANGED
@@ -71,6 +71,9 @@ class bitmart(ccxt.async_support.bitmart):
71
71
  'watchOrderBookForSymbols': {
72
72
  'depth': 'depth/increase100',
73
73
  },
74
+ 'watchTrades': {
75
+ 'ignoreDuplicates': True,
76
+ },
74
77
  'ws': {
75
78
  'inflate': True,
76
79
  },
@@ -299,7 +302,12 @@ class bitmart(ccxt.async_support.bitmart):
299
302
  first = self.safe_dict(trades, 0)
300
303
  tradeSymbol = self.safe_string(first, 'symbol')
301
304
  limit = trades.getLimit(tradeSymbol, limit)
302
- return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
305
+ result = self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
306
+ if self.handle_option('watchTrades', 'ignoreDuplicates', True):
307
+ filtered = self.remove_repeated_trades_from_array(result)
308
+ filtered = self.sort_by(filtered, 'timestamp')
309
+ return filtered
310
+ return result
303
311
 
304
312
  def get_params_for_multiple_sub(self, methodName: str, symbols: List[str], limit: Int = None, params={}):
305
313
  symbols = self.market_symbols(symbols, None, False, True)
ccxt/pro/bitopro.py CHANGED
@@ -343,15 +343,16 @@ class bitopro(ccxt.async_support.bitopro):
343
343
  # }
344
344
  #
345
345
  marketId = self.safe_string(message, 'pair')
346
- market = self.safe_market(marketId, None, '_')
346
+ # market-ids are lowercase in REST API and uppercase in WS API
347
+ market = self.safe_market(marketId.lower(), None, '_')
347
348
  symbol = market['symbol']
348
349
  event = self.safe_string(message, 'event')
349
350
  messageHash = event + ':' + symbol
350
- result = self.parse_ticker(message)
351
+ result = self.parse_ticker(message, market)
352
+ result['symbol'] = self.safe_string(market, 'symbol') # symbol returned from REST's parseTicker is distorted for WS, so re-set it from market object
351
353
  timestamp = self.safe_integer(message, 'timestamp')
352
- datetime = self.safe_string(message, 'datetime')
353
354
  result['timestamp'] = timestamp
354
- result['datetime'] = datetime
355
+ result['datetime'] = self.iso8601(timestamp) # we shouldn't set "datetime" string provided by server, values are obviously wrong offset from UTC
355
356
  self.tickers[symbol] = result
356
357
  client.resolve(result, messageHash)
357
358
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ccxt
3
- Version: 4.4.73
3
+ Version: 4.4.75
4
4
  Summary: A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges
5
5
  Home-page: https://ccxt.com
6
6
  Author: Igor Kroitor
@@ -49,7 +49,7 @@ Requires-Dist: mypy==1.6.1; extra == "type"
49
49
 
50
50
  # CCXT – CryptoCurrency eXchange Trading Library
51
51
 
52
- [![NPM Downloads](https://img.shields.io/npm/dy/ccxt.svg)](https://www.npmjs.com/package/ccxt) [![npm](https://img.shields.io/npm/v/ccxt.svg)](https://npmjs.com/package/ccxt) [![PyPI](https://img.shields.io/pypi/v/ccxt.svg)](https://pypi.python.org/pypi/ccxt) [![NuGet version](https://img.shields.io/nuget/v/ccxt)](https://www.nuget.org/packages/ccxt) [![GoDoc](https://pkg.go.dev/badge/github.com/ccxt/ccxt/go/v4?utm_source=godoc)](https://godoc.org/github.com/ccxt/ccxt/go/v4) [![Discord](https://img.shields.io/discord/690203284119617602?logo=discord&logoColor=white)](https://discord.gg/ccxt) [![Supported Exchanges](https://img.shields.io/badge/exchanges-109-blue.svg)](https://github.com/ccxt/ccxt/wiki/Exchange-Markets) [![Follow CCXT at x.com](https://img.shields.io/twitter/follow/ccxt_official.svg?style=social&label=CCXT)](https://x.com/ccxt_official)
52
+ [![NPM Downloads](https://img.shields.io/npm/dy/ccxt.svg)](https://www.npmjs.com/package/ccxt) [![npm](https://img.shields.io/npm/v/ccxt.svg)](https://npmjs.com/package/ccxt) [![PyPI](https://img.shields.io/pypi/v/ccxt.svg)](https://pypi.python.org/pypi/ccxt) [![NuGet version](https://img.shields.io/nuget/v/ccxt)](https://www.nuget.org/packages/ccxt) [![GoDoc](https://pkg.go.dev/badge/github.com/ccxt/ccxt/go/v4?utm_source=godoc)](https://godoc.org/github.com/ccxt/ccxt/go/v4) [![Discord](https://img.shields.io/discord/690203284119617602?logo=discord&logoColor=white)](https://discord.gg/ccxt) [![Supported Exchanges](https://img.shields.io/badge/exchanges-107-blue.svg)](https://github.com/ccxt/ccxt/wiki/Exchange-Markets) [![Follow CCXT at x.com](https://img.shields.io/twitter/follow/ccxt_official.svg?style=social&label=CCXT)](https://x.com/ccxt_official)
53
53
 
54
54
  A `JavaScript` / `Python` / `PHP` / `C#` / `Go` library for cryptocurrency trading and e-commerce with support for many bitcoin/ether/altcoin exchange markets and merchant APIs.
55
55
 
@@ -275,13 +275,13 @@ console.log(version, Object.keys(exchanges));
275
275
 
276
276
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
277
277
 
278
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.73/dist/ccxt.browser.min.js
279
- * unpkg: https://unpkg.com/ccxt@4.4.73/dist/ccxt.browser.min.js
278
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.4.75/dist/ccxt.browser.min.js
279
+ * unpkg: https://unpkg.com/ccxt@4.4.75/dist/ccxt.browser.min.js
280
280
 
281
281
  CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
282
282
 
283
283
  ```HTML
284
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.4.73/dist/ccxt.browser.min.js"></script>
284
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.4.75/dist/ccxt.browser.min.js"></script>
285
285
  ```
286
286
 
287
287
  Creates a global `ccxt` object: