ccxt 4.4.93__py2.py3-none-any.whl → 4.4.95__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 (52) hide show
  1. ccxt/__init__.py +1 -1
  2. ccxt/abstract/bingx.py +3 -0
  3. ccxt/abstract/hyperliquid.py +1 -1
  4. ccxt/abstract/woo.py +59 -4
  5. ccxt/async_support/__init__.py +1 -1
  6. ccxt/async_support/base/exchange.py +1 -1
  7. ccxt/async_support/base/ws/future.py +2 -0
  8. ccxt/async_support/bingx.py +129 -92
  9. ccxt/async_support/bitget.py +1 -1
  10. ccxt/async_support/bitstamp.py +2 -0
  11. ccxt/async_support/blofin.py +6 -1
  12. ccxt/async_support/bybit.py +3 -3
  13. ccxt/async_support/coinbase.py +40 -1
  14. ccxt/async_support/coinmate.py +34 -0
  15. ccxt/async_support/coinmetro.py +15 -3
  16. ccxt/async_support/coinone.py +34 -0
  17. ccxt/async_support/coinsph.py +29 -0
  18. ccxt/async_support/gate.py +1 -1
  19. ccxt/async_support/htx.py +5 -1
  20. ccxt/async_support/hyperliquid.py +126 -33
  21. ccxt/async_support/okx.py +10 -3
  22. ccxt/async_support/wavesexchange.py +12 -2
  23. ccxt/async_support/woo.py +1251 -875
  24. ccxt/base/errors.py +0 -6
  25. ccxt/base/exchange.py +44 -22
  26. ccxt/bingx.py +129 -92
  27. ccxt/bitget.py +1 -1
  28. ccxt/bitstamp.py +2 -0
  29. ccxt/blofin.py +6 -1
  30. ccxt/bybit.py +3 -3
  31. ccxt/coinbase.py +40 -1
  32. ccxt/coinmate.py +34 -0
  33. ccxt/coinmetro.py +14 -3
  34. ccxt/coinone.py +34 -0
  35. ccxt/coinsph.py +29 -0
  36. ccxt/gate.py +1 -1
  37. ccxt/htx.py +5 -1
  38. ccxt/hyperliquid.py +126 -33
  39. ccxt/okx.py +10 -3
  40. ccxt/pro/__init__.py +1 -1
  41. ccxt/pro/hyperliquid.py +6 -6
  42. ccxt/pro/kraken.py +17 -16
  43. ccxt/pro/mexc.py +10 -10
  44. ccxt/test/tests_async.py +19 -17
  45. ccxt/test/tests_sync.py +19 -17
  46. ccxt/wavesexchange.py +12 -2
  47. ccxt/woo.py +1251 -875
  48. {ccxt-4.4.93.dist-info → ccxt-4.4.95.dist-info}/METADATA +4 -4
  49. {ccxt-4.4.93.dist-info → ccxt-4.4.95.dist-info}/RECORD +52 -52
  50. {ccxt-4.4.93.dist-info → ccxt-4.4.95.dist-info}/LICENSE.txt +0 -0
  51. {ccxt-4.4.93.dist-info → ccxt-4.4.95.dist-info}/WHEEL +0 -0
  52. {ccxt-4.4.93.dist-info → ccxt-4.4.95.dist-info}/top_level.txt +0 -0
ccxt/pro/mexc.py CHANGED
@@ -1377,14 +1377,14 @@ class mexc(ccxt.async_support.mexc):
1377
1377
  channel = 'spot@public.bookTicker.v3.api@' + market['id']
1378
1378
  url = self.urls['api']['ws']['spot']
1379
1379
  params['unsubscribed'] = True
1380
- self.watch_spot_public(channel, messageHash, params)
1380
+ await self.watch_spot_public(channel, messageHash, params)
1381
1381
  else:
1382
1382
  channel = 'unsub.ticker'
1383
1383
  requestParams: dict = {
1384
1384
  'symbol': market['id'],
1385
1385
  }
1386
1386
  url = self.urls['api']['ws']['swap']
1387
- self.watch_swap_public(channel, messageHash, requestParams, params)
1387
+ await self.watch_swap_public(channel, messageHash, requestParams, params)
1388
1388
  client = self.client(url)
1389
1389
  self.handle_unsubscriptions(client, [messageHash])
1390
1390
  return None
@@ -1435,7 +1435,7 @@ class mexc(ccxt.async_support.mexc):
1435
1435
  request['params'] = {}
1436
1436
  messageHashes.append('unsubscribe:ticker')
1437
1437
  client = self.client(url)
1438
- self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
1438
+ await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
1439
1439
  self.handle_unsubscriptions(client, messageHashes)
1440
1440
  return None
1441
1441
 
@@ -1469,7 +1469,7 @@ class mexc(ccxt.async_support.mexc):
1469
1469
  'params': topics,
1470
1470
  }
1471
1471
  client = self.client(url)
1472
- self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
1472
+ await self.watch_multiple(url, messageHashes, self.extend(request, params), messageHashes)
1473
1473
  self.handle_unsubscriptions(client, messageHashes)
1474
1474
  return None
1475
1475
 
@@ -1493,7 +1493,7 @@ class mexc(ccxt.async_support.mexc):
1493
1493
  url = self.urls['api']['ws']['spot']
1494
1494
  channel = 'spot@public.kline.v3.api@' + market['id'] + '@' + timeframeId
1495
1495
  params['unsubscribed'] = True
1496
- self.watch_spot_public(channel, messageHash, params)
1496
+ await self.watch_spot_public(channel, messageHash, params)
1497
1497
  else:
1498
1498
  url = self.urls['api']['ws']['swap']
1499
1499
  channel = 'unsub.kline'
@@ -1501,7 +1501,7 @@ class mexc(ccxt.async_support.mexc):
1501
1501
  'symbol': market['id'],
1502
1502
  'interval': timeframeId,
1503
1503
  }
1504
- self.watch_swap_public(channel, messageHash, requestParams, params)
1504
+ await self.watch_swap_public(channel, messageHash, requestParams, params)
1505
1505
  client = self.client(url)
1506
1506
  self.handle_unsubscriptions(client, [messageHash])
1507
1507
  return None
@@ -1522,14 +1522,14 @@ class mexc(ccxt.async_support.mexc):
1522
1522
  url = self.urls['api']['ws']['spot']
1523
1523
  channel = 'spot@public.increase.depth.v3.api@' + market['id']
1524
1524
  params['unsubscribed'] = True
1525
- self.watch_spot_public(channel, messageHash, params)
1525
+ await self.watch_spot_public(channel, messageHash, params)
1526
1526
  else:
1527
1527
  url = self.urls['api']['ws']['swap']
1528
1528
  channel = 'unsub.depth'
1529
1529
  requestParams: dict = {
1530
1530
  'symbol': market['id'],
1531
1531
  }
1532
- self.watch_swap_public(channel, messageHash, requestParams, params)
1532
+ await self.watch_swap_public(channel, messageHash, requestParams, params)
1533
1533
  client = self.client(url)
1534
1534
  self.handle_unsubscriptions(client, [messageHash])
1535
1535
  return None
@@ -1551,14 +1551,14 @@ class mexc(ccxt.async_support.mexc):
1551
1551
  url = self.urls['api']['ws']['spot']
1552
1552
  channel = 'spot@public.deals.v3.api@' + market['id']
1553
1553
  params['unsubscribed'] = True
1554
- self.watch_spot_public(channel, messageHash, params)
1554
+ await self.watch_spot_public(channel, messageHash, params)
1555
1555
  else:
1556
1556
  url = self.urls['api']['ws']['swap']
1557
1557
  channel = 'unsub.deal'
1558
1558
  requestParams: dict = {
1559
1559
  'symbol': market['id'],
1560
1560
  }
1561
- self.watch_swap_public(channel, messageHash, requestParams, params)
1561
+ await self.watch_swap_public(channel, messageHash, requestParams, params)
1562
1562
  client = self.client(url)
1563
1563
  self.handle_unsubscriptions(client, [messageHash])
1564
1564
  return None
ccxt/test/tests_async.py CHANGED
@@ -622,7 +622,7 @@ class testMainClass:
622
622
  def check_constructor(self, exchange):
623
623
  # todo: this might be moved in base tests later
624
624
  if exchange.id == 'binance':
625
- assert exchange.hostname is None, 'binance.com hostname should be empty'
625
+ assert exchange.hostname is None or exchange.hostname == '', 'binance.com hostname should be empty'
626
626
  assert exchange.urls['api']['public'] == 'https://api.binance.com/api/v3', 'https://api.binance.com/api/v3 does not match: ' + exchange.urls['api']['public']
627
627
  assert ('lending/union/account' in exchange.api['sapi']['get']), 'SAPI should contain the endpoint lending/union/account, ' + json_stringify(exchange.api['sapi']['get'])
628
628
  elif exchange.id == 'binanceus':
@@ -1173,7 +1173,7 @@ class testMainClass:
1173
1173
  # -----------------------------------------------------------------------------
1174
1174
  # --- Init of brokerId tests functions-----------------------------------------
1175
1175
  # -----------------------------------------------------------------------------
1176
- promises = [self.test_binance(), self.test_okx(), self.test_cryptocom(), self.test_bybit(), self.test_kucoin(), self.test_kucoinfutures(), self.test_bitget(), self.test_mexc(), self.test_htx(), self.test_woo(), self.test_bitmart(), self.test_coinex(), self.test_bingx(), self.test_phemex(), self.test_blofin(), self.test_hyperliquid(), self.test_coinbaseinternational(), self.test_coinbase_advanced(), self.test_woofi_pro(), self.test_oxfun(), self.test_xt(), self.test_vertex(), self.test_paradex(), self.test_hashkey(), self.test_coincatch(), self.test_defx(), self.test_cryptomus(), self.test_derive(), self.test_mode_trade()]
1176
+ promises = [self.test_binance(), self.test_okx(), self.test_cryptocom(), self.test_bybit(), self.test_kucoin(), self.test_kucoinfutures(), self.test_bitget(), self.test_mexc(), self.test_htx(), self.test_woo(), self.test_bitmart(), self.test_coinex(), self.test_bingx(), self.test_phemex(), self.test_blofin(), self.test_coinbaseinternational(), self.test_coinbase_advanced(), self.test_woofi_pro(), self.test_oxfun(), self.test_xt(), self.test_vertex(), self.test_paradex(), self.test_hashkey(), self.test_coincatch(), self.test_defx(), self.test_cryptomus(), self.test_derive(), self.test_mode_trade()]
1177
1177
  await asyncio.gather(*promises)
1178
1178
  success_message = '[' + self.lang + '][TEST_SUCCESS] brokerId tests passed.'
1179
1179
  dump('[INFO]' + success_message)
@@ -1395,7 +1395,7 @@ class testMainClass:
1395
1395
  try:
1396
1396
  await exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1397
1397
  except Exception as e:
1398
- spot_order_request = self.urlencoded_to_dict(exchange.last_request_body)
1398
+ spot_order_request = json_parse(exchange.last_request_body)
1399
1399
  broker_id = spot_order_request['broker_id']
1400
1400
  id_string = str(id)
1401
1401
  assert broker_id.startswith(id_string), 'woo - broker_id: ' + broker_id + ' does not start with id: ' + id_string
@@ -1489,20 +1489,22 @@ class testMainClass:
1489
1489
  await close(exchange)
1490
1490
  return True
1491
1491
 
1492
- async def test_hyperliquid(self):
1493
- exchange = self.init_offline_exchange('hyperliquid')
1494
- id = '1'
1495
- request = None
1496
- try:
1497
- await exchange.create_order('SOL/USDC:USDC', 'limit', 'buy', 1, 100)
1498
- except Exception as e:
1499
- request = json_parse(exchange.last_request_body)
1500
- broker_id = str((request['action']['brokerCode']))
1501
- assert broker_id == id, 'hyperliquid - brokerId: ' + broker_id + ' does not start with id: ' + id
1502
- if not is_sync():
1503
- await close(exchange)
1504
- return True
1505
-
1492
+ # async testHyperliquid () {
1493
+ # const exchange = this.initOfflineExchange ('hyperliquid');
1494
+ # const id = '1';
1495
+ # let request = undefined;
1496
+ # try {
1497
+ # await exchange.createOrder ('SOL/USDC:USDC', 'limit', 'buy', 1, 100);
1498
+ # } catch (e) {
1499
+ # request = jsonParse (exchange.last_request_body);
1500
+ # }
1501
+ # const brokerId = (request['action']['brokerCode']).toString ();
1502
+ # assert (brokerId === id, 'hyperliquid - brokerId: ' + brokerId + ' does not start with id: ' + id);
1503
+ # if (!isSync ()) {
1504
+ # await close (exchange);
1505
+ # }
1506
+ # return true;
1507
+ # }
1506
1508
  async def test_coinbaseinternational(self):
1507
1509
  exchange = self.init_offline_exchange('coinbaseinternational')
1508
1510
  exchange.options['portfolio'] = 'random'
ccxt/test/tests_sync.py CHANGED
@@ -619,7 +619,7 @@ class testMainClass:
619
619
  def check_constructor(self, exchange):
620
620
  # todo: this might be moved in base tests later
621
621
  if exchange.id == 'binance':
622
- assert exchange.hostname is None, 'binance.com hostname should be empty'
622
+ assert exchange.hostname is None or exchange.hostname == '', 'binance.com hostname should be empty'
623
623
  assert exchange.urls['api']['public'] == 'https://api.binance.com/api/v3', 'https://api.binance.com/api/v3 does not match: ' + exchange.urls['api']['public']
624
624
  assert ('lending/union/account' in exchange.api['sapi']['get']), 'SAPI should contain the endpoint lending/union/account, ' + json_stringify(exchange.api['sapi']['get'])
625
625
  elif exchange.id == 'binanceus':
@@ -1170,7 +1170,7 @@ class testMainClass:
1170
1170
  # -----------------------------------------------------------------------------
1171
1171
  # --- Init of brokerId tests functions-----------------------------------------
1172
1172
  # -----------------------------------------------------------------------------
1173
- promises = [self.test_binance(), self.test_okx(), self.test_cryptocom(), self.test_bybit(), self.test_kucoin(), self.test_kucoinfutures(), self.test_bitget(), self.test_mexc(), self.test_htx(), self.test_woo(), self.test_bitmart(), self.test_coinex(), self.test_bingx(), self.test_phemex(), self.test_blofin(), self.test_hyperliquid(), self.test_coinbaseinternational(), self.test_coinbase_advanced(), self.test_woofi_pro(), self.test_oxfun(), self.test_xt(), self.test_vertex(), self.test_paradex(), self.test_hashkey(), self.test_coincatch(), self.test_defx(), self.test_cryptomus(), self.test_derive(), self.test_mode_trade()]
1173
+ promises = [self.test_binance(), self.test_okx(), self.test_cryptocom(), self.test_bybit(), self.test_kucoin(), self.test_kucoinfutures(), self.test_bitget(), self.test_mexc(), self.test_htx(), self.test_woo(), self.test_bitmart(), self.test_coinex(), self.test_bingx(), self.test_phemex(), self.test_blofin(), self.test_coinbaseinternational(), self.test_coinbase_advanced(), self.test_woofi_pro(), self.test_oxfun(), self.test_xt(), self.test_vertex(), self.test_paradex(), self.test_hashkey(), self.test_coincatch(), self.test_defx(), self.test_cryptomus(), self.test_derive(), self.test_mode_trade()]
1174
1174
  (promises)
1175
1175
  success_message = '[' + self.lang + '][TEST_SUCCESS] brokerId tests passed.'
1176
1176
  dump('[INFO]' + success_message)
@@ -1392,7 +1392,7 @@ class testMainClass:
1392
1392
  try:
1393
1393
  exchange.create_order('BTC/USDT', 'limit', 'buy', 1, 20000)
1394
1394
  except Exception as e:
1395
- spot_order_request = self.urlencoded_to_dict(exchange.last_request_body)
1395
+ spot_order_request = json_parse(exchange.last_request_body)
1396
1396
  broker_id = spot_order_request['broker_id']
1397
1397
  id_string = str(id)
1398
1398
  assert broker_id.startswith(id_string), 'woo - broker_id: ' + broker_id + ' does not start with id: ' + id_string
@@ -1486,20 +1486,22 @@ class testMainClass:
1486
1486
  close(exchange)
1487
1487
  return True
1488
1488
 
1489
- def test_hyperliquid(self):
1490
- exchange = self.init_offline_exchange('hyperliquid')
1491
- id = '1'
1492
- request = None
1493
- try:
1494
- exchange.create_order('SOL/USDC:USDC', 'limit', 'buy', 1, 100)
1495
- except Exception as e:
1496
- request = json_parse(exchange.last_request_body)
1497
- broker_id = str((request['action']['brokerCode']))
1498
- assert broker_id == id, 'hyperliquid - brokerId: ' + broker_id + ' does not start with id: ' + id
1499
- if not is_sync():
1500
- close(exchange)
1501
- return True
1502
-
1489
+ # testHyperliquid () {
1490
+ # const exchange = this.initOfflineExchange ('hyperliquid');
1491
+ # const id = '1';
1492
+ # let request = undefined;
1493
+ # try {
1494
+ # exchange.createOrder ('SOL/USDC:USDC', 'limit', 'buy', 1, 100);
1495
+ # } catch (e) {
1496
+ # request = jsonParse (exchange.last_request_body);
1497
+ # }
1498
+ # const brokerId = (request['action']['brokerCode']).toString ();
1499
+ # assert (brokerId === id, 'hyperliquid - brokerId: ' + brokerId + ' does not start with id: ' + id);
1500
+ # if (!isSync ()) {
1501
+ # close (exchange);
1502
+ # }
1503
+ # return true;
1504
+ # }
1503
1505
  def test_coinbaseinternational(self):
1504
1506
  exchange = self.init_offline_exchange('coinbaseinternational')
1505
1507
  exchange.options['portfolio'] = 'random'
ccxt/wavesexchange.py CHANGED
@@ -2214,11 +2214,21 @@ class wavesexchange(Exchange, ImplicitAPI):
2214
2214
  order1 = self.safe_value(data, 'order1')
2215
2215
  order2 = self.safe_value(data, 'order2')
2216
2216
  order = None
2217
- # order2 arrived after order1
2217
+ # at first, detect if response is from `fetch_my_trades`
2218
2218
  if self.safe_string(order1, 'senderPublicKey') == self.apiKey:
2219
2219
  order = order1
2220
- else:
2220
+ elif self.safe_string(order2, 'senderPublicKey') == self.apiKey:
2221
2221
  order = order2
2222
+ else:
2223
+ # response is from `fetch_trades`, so find only taker order
2224
+ date1 = self.safe_string(order1, 'timestamp')
2225
+ date2 = self.safe_string(order2, 'timestamp')
2226
+ ts1 = self.parse8601(date1)
2227
+ ts2 = self.parse8601(date2)
2228
+ if ts1 > ts2:
2229
+ order = order1
2230
+ else:
2231
+ order = order2
2222
2232
  symbol = None
2223
2233
  assetPair = self.safe_value(order, 'assetPair')
2224
2234
  if assetPair is not None: