ccxt 4.4.63__py2.py3-none-any.whl → 4.4.68__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 (60) hide show
  1. ccxt/__init__.py +5 -3
  2. ccxt/abstract/binance.py +1 -0
  3. ccxt/abstract/binancecoinm.py +1 -0
  4. ccxt/abstract/binanceus.py +1 -0
  5. ccxt/abstract/binanceusdm.py +1 -0
  6. ccxt/abstract/cryptomus.py +20 -0
  7. ccxt/abstract/derive.py +117 -0
  8. ccxt/abstract/tradeogre.py +1 -0
  9. ccxt/abstract/whitebit.py +16 -0
  10. ccxt/async_support/__init__.py +5 -3
  11. ccxt/async_support/base/exchange.py +6 -5
  12. ccxt/async_support/binance.py +8 -6
  13. ccxt/async_support/bitget.py +22 -12
  14. ccxt/async_support/bitrue.py +6 -3
  15. ccxt/async_support/bybit.py +1 -1
  16. ccxt/async_support/coinbase.py +73 -2
  17. ccxt/async_support/cryptocom.py +2 -0
  18. ccxt/async_support/cryptomus.py +1041 -0
  19. ccxt/async_support/derive.py +2530 -0
  20. ccxt/async_support/gate.py +5 -1
  21. ccxt/async_support/htx.py +19 -5
  22. ccxt/async_support/hyperliquid.py +108 -68
  23. ccxt/async_support/luno.py +113 -1
  24. ccxt/async_support/paradex.py +51 -12
  25. ccxt/async_support/tradeogre.py +132 -13
  26. ccxt/async_support/whitebit.py +276 -2
  27. ccxt/base/exchange.py +13 -4
  28. ccxt/binance.py +8 -6
  29. ccxt/bitget.py +22 -12
  30. ccxt/bitrue.py +6 -3
  31. ccxt/bybit.py +1 -1
  32. ccxt/coinbase.py +73 -2
  33. ccxt/cryptocom.py +2 -0
  34. ccxt/cryptomus.py +1041 -0
  35. ccxt/derive.py +2529 -0
  36. ccxt/gate.py +5 -1
  37. ccxt/htx.py +19 -5
  38. ccxt/hyperliquid.py +108 -68
  39. ccxt/luno.py +113 -1
  40. ccxt/paradex.py +51 -12
  41. ccxt/pro/__init__.py +3 -3
  42. ccxt/pro/bitopro.py +1 -1
  43. ccxt/pro/bybit.py +3 -2
  44. ccxt/pro/derive.py +704 -0
  45. ccxt/pro/gate.py +8 -1
  46. ccxt/pro/hyperliquid.py +3 -3
  47. ccxt/pro/vertex.py +5 -0
  48. ccxt/test/tests_async.py +36 -3
  49. ccxt/test/tests_sync.py +36 -3
  50. ccxt/tradeogre.py +132 -13
  51. ccxt/whitebit.py +276 -2
  52. {ccxt-4.4.63.dist-info → ccxt-4.4.68.dist-info}/METADATA +16 -12
  53. {ccxt-4.4.63.dist-info → ccxt-4.4.68.dist-info}/RECORD +56 -53
  54. ccxt/abstract/currencycom.py +0 -68
  55. ccxt/async_support/currencycom.py +0 -2070
  56. ccxt/currencycom.py +0 -2070
  57. ccxt/pro/currencycom.py +0 -536
  58. {ccxt-4.4.63.dist-info → ccxt-4.4.68.dist-info}/LICENSE.txt +0 -0
  59. {ccxt-4.4.63.dist-info → ccxt-4.4.68.dist-info}/WHEEL +0 -0
  60. {ccxt-4.4.63.dist-info → ccxt-4.4.68.dist-info}/top_level.txt +0 -0
ccxt/pro/gate.py CHANGED
@@ -46,6 +46,7 @@ class gate(ccxt.async_support.gate):
46
46
  'fetchOpenOrdersWs': True,
47
47
  'fetchClosedOrdersWs': True,
48
48
  'watchOrderBook': True,
49
+ 'watchBidsAsks': True,
49
50
  'watchTicker': True,
50
51
  'watchTickers': True,
51
52
  'watchTrades': True,
@@ -1128,7 +1129,9 @@ class gate(ccxt.async_support.gate):
1128
1129
  cache = self.positions[type]
1129
1130
  for i in range(0, len(positions)):
1130
1131
  position = positions[i]
1131
- cache.append(position)
1132
+ contracts = self.safe_number(position, 'contracts', 0)
1133
+ if contracts > 0:
1134
+ cache.append(position)
1132
1135
  # don't remove the future from the .futures cache
1133
1136
  future = client.futures[messageHash]
1134
1137
  future.resolve(cache)
@@ -1892,6 +1895,10 @@ class gate(ccxt.async_support.gate):
1892
1895
  'signature': signature,
1893
1896
  'req_param': reqParams,
1894
1897
  }
1898
+ if (channel == 'spot.order_place') or (channel == 'futures.order_place'):
1899
+ payload['req_header'] = {
1900
+ 'X-Gate-Channel-Id': 'ccxt',
1901
+ }
1895
1902
  request: dict = {
1896
1903
  'id': requestId,
1897
1904
  'time': time,
ccxt/pro/hyperliquid.py CHANGED
@@ -101,7 +101,7 @@ class hyperliquid(ccxt.async_support.hyperliquid):
101
101
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
102
102
  """
103
103
  await self.load_markets()
104
- order, globalParams = self.parseCreateOrderArgs(symbol, type, side, amount, price, params)
104
+ order, globalParams = self.parseCreateEditOrderArgs(None, symbol, type, side, amount, price, params)
105
105
  orders = await self.create_orders_ws([order], globalParams)
106
106
  return orders[0]
107
107
 
@@ -109,7 +109,6 @@ class hyperliquid(ccxt.async_support.hyperliquid):
109
109
  """
110
110
  edit a trade order
111
111
 
112
- https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-an-order
113
112
  https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-multiple-orders
114
113
 
115
114
  :param str id: cancel order id
@@ -130,7 +129,8 @@ class hyperliquid(ccxt.async_support.hyperliquid):
130
129
  await self.load_markets()
131
130
  market = self.market(symbol)
132
131
  url = self.urls['api']['ws']['public']
133
- postRequest = self.edit_order_request(id, symbol, type, side, amount, price, params)
132
+ order, globalParams = self.parseCreateEditOrderArgs(id, symbol, type, side, amount, price, params)
133
+ postRequest = self.editOrdersRequest([order], globalParams)
134
134
  wrapped = self.wrap_as_post_action(postRequest)
135
135
  request = self.safe_dict(wrapped, 'request', {})
136
136
  requestId = self.safe_string(wrapped, 'requestId')
ccxt/pro/vertex.py CHANGED
@@ -55,6 +55,11 @@ class vertex(ccxt.async_support.vertex):
55
55
  },
56
56
  'ws': {
57
57
  'inflate': True,
58
+ 'options': {
59
+ 'headers': {
60
+ 'Sec-WebSocket-Extensions': 'permessage-deflate', # requires permessage-deflate extension, maybe we can set self in client implementation when self.inflateis True
61
+ },
62
+ },
58
63
  },
59
64
  },
60
65
  'streaming': {
ccxt/test/tests_async.py CHANGED
@@ -1022,8 +1022,7 @@ class testMainClass:
1022
1022
  skip_keys = exchange.safe_value(exchange_data, 'skipKeys', [])
1023
1023
  await self.test_request_statically(exchange, method, result, type, skip_keys)
1024
1024
  # reset options
1025
- # exchange.options = exchange.deepExtend (oldExchangeOptions, {});
1026
- exchange.extend_exchange_options(exchange.deep_extend(old_exchange_options, {}))
1025
+ exchange.options = exchange.convert_to_safe_dictionary(exchange.deep_extend(old_exchange_options, {}))
1027
1026
  if not is_sync():
1028
1027
  await close(exchange)
1029
1028
  return True # in c# methods that will be used with promiseAll need to return something
@@ -1147,7 +1146,7 @@ class testMainClass:
1147
1146
  # -----------------------------------------------------------------------------
1148
1147
  # --- Init of brokerId tests functions-----------------------------------------
1149
1148
  # -----------------------------------------------------------------------------
1150
- 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()]
1149
+ 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()]
1151
1150
  await asyncio.gather(*promises)
1152
1151
  success_message = '[' + self.lang + '][TEST_SUCCESS] brokerId tests passed.'
1153
1152
  dump('[INFO]' + success_message)
@@ -1642,3 +1641,37 @@ class testMainClass:
1642
1641
  if not is_sync():
1643
1642
  await close(exchange)
1644
1643
  return True
1644
+
1645
+ async def test_cryptomus(self):
1646
+ exchange = self.init_offline_exchange('cryptomus')
1647
+ request = None
1648
+ try:
1649
+ await exchange.create_order('BTC/USDT', 'limit', 'sell', 1, 20000)
1650
+ except Exception as e:
1651
+ request = json_parse(exchange.last_request_body)
1652
+ tag = 'ccxt'
1653
+ assert request['tag'] == tag, 'cryptomus - tag: ' + tag + ' not in request.'
1654
+ if not is_sync():
1655
+ await close(exchange)
1656
+ return True
1657
+
1658
+ async def test_derive(self):
1659
+ exchange = self.init_offline_exchange('derive')
1660
+ id = '0x0ad42b8e602c2d3d475ae52d678cf63d84ab2749'
1661
+ assert exchange.options['id'] == id, 'derive - id: ' + id + ' not in options'
1662
+ request = None
1663
+ try:
1664
+ params = {
1665
+ 'subaccount_id': 1234,
1666
+ 'max_fee': 10,
1667
+ 'deriveWalletAddress': '0x0ad42b8e602c2d3d475ae52d678cf63d84ab2749',
1668
+ }
1669
+ exchange.walletAddress = '0x0ad42b8e602c2d3d475ae52d678cf63d84ab2749'
1670
+ exchange.privateKey = '0x7b77bb7b20e92bbb85f2a22b330b896959229a5790e35f2f290922de3fb22ad5'
1671
+ await exchange.create_order('LBTC/USDC', 'limit', 'sell', 0.01, 3000, params)
1672
+ except Exception as e:
1673
+ request = json_parse(exchange.last_request_body)
1674
+ assert request['referral_code'] == id, 'derive - referral_code: ' + id + ' not in request.'
1675
+ if not is_sync():
1676
+ await close(exchange)
1677
+ return True
ccxt/test/tests_sync.py CHANGED
@@ -1019,8 +1019,7 @@ class testMainClass:
1019
1019
  skip_keys = exchange.safe_value(exchange_data, 'skipKeys', [])
1020
1020
  self.test_request_statically(exchange, method, result, type, skip_keys)
1021
1021
  # reset options
1022
- # exchange.options = exchange.deepExtend (oldExchangeOptions, {});
1023
- exchange.extend_exchange_options(exchange.deep_extend(old_exchange_options, {}))
1022
+ exchange.options = exchange.convert_to_safe_dictionary(exchange.deep_extend(old_exchange_options, {}))
1024
1023
  if not is_sync():
1025
1024
  close(exchange)
1026
1025
  return True # in c# methods that will be used with promiseAll need to return something
@@ -1144,7 +1143,7 @@ class testMainClass:
1144
1143
  # -----------------------------------------------------------------------------
1145
1144
  # --- Init of brokerId tests functions-----------------------------------------
1146
1145
  # -----------------------------------------------------------------------------
1147
- 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()]
1146
+ 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()]
1148
1147
  (promises)
1149
1148
  success_message = '[' + self.lang + '][TEST_SUCCESS] brokerId tests passed.'
1150
1149
  dump('[INFO]' + success_message)
@@ -1639,3 +1638,37 @@ class testMainClass:
1639
1638
  if not is_sync():
1640
1639
  close(exchange)
1641
1640
  return True
1641
+
1642
+ def test_cryptomus(self):
1643
+ exchange = self.init_offline_exchange('cryptomus')
1644
+ request = None
1645
+ try:
1646
+ exchange.create_order('BTC/USDT', 'limit', 'sell', 1, 20000)
1647
+ except Exception as e:
1648
+ request = json_parse(exchange.last_request_body)
1649
+ tag = 'ccxt'
1650
+ assert request['tag'] == tag, 'cryptomus - tag: ' + tag + ' not in request.'
1651
+ if not is_sync():
1652
+ close(exchange)
1653
+ return True
1654
+
1655
+ def test_derive(self):
1656
+ exchange = self.init_offline_exchange('derive')
1657
+ id = '0x0ad42b8e602c2d3d475ae52d678cf63d84ab2749'
1658
+ assert exchange.options['id'] == id, 'derive - id: ' + id + ' not in options'
1659
+ request = None
1660
+ try:
1661
+ params = {
1662
+ 'subaccount_id': 1234,
1663
+ 'max_fee': 10,
1664
+ 'deriveWalletAddress': '0x0ad42b8e602c2d3d475ae52d678cf63d84ab2749',
1665
+ }
1666
+ exchange.walletAddress = '0x0ad42b8e602c2d3d475ae52d678cf63d84ab2749'
1667
+ exchange.privateKey = '0x7b77bb7b20e92bbb85f2a22b330b896959229a5790e35f2f290922de3fb22ad5'
1668
+ exchange.create_order('LBTC/USDC', 'limit', 'sell', 0.01, 3000, params)
1669
+ except Exception as e:
1670
+ request = json_parse(exchange.last_request_body)
1671
+ assert request['referral_code'] == id, 'derive - referral_code: ' + id + ' not in request.'
1672
+ if not is_sync():
1673
+ close(exchange)
1674
+ return True
ccxt/tradeogre.py CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.tradeogre import ImplicitAPI
8
- from ccxt.base.types import Any, IndexType, Int, Market, Num, Order, OrderSide, OrderType, Str, Ticker
8
+ from ccxt.base.types import Any, IndexType, Int, Market, Num, Order, OrderSide, OrderType, Str, Strings, Ticker, Tickers
9
9
  from typing import List
10
10
  from ccxt.base.errors import ExchangeError
11
11
  from ccxt.base.errors import AuthenticationError
@@ -74,7 +74,7 @@ class tradeogre(Exchange, ImplicitAPI):
74
74
  'fetchMarkets': True,
75
75
  'fetchMarkOHLCV': False,
76
76
  'fetchMyTrades': False,
77
- 'fetchOHLCV': False,
77
+ 'fetchOHLCV': True,
78
78
  'fetchOpenInterest': False,
79
79
  'fetchOpenInterestHistory': False,
80
80
  'fetchOpenOrders': True,
@@ -92,7 +92,7 @@ class tradeogre(Exchange, ImplicitAPI):
92
92
  'fetchPositionsRisk': False,
93
93
  'fetchPremiumIndexOHLCV': False,
94
94
  'fetchTicker': True,
95
- 'fetchTickers': False,
95
+ 'fetchTickers': True,
96
96
  'fetchTrades': True,
97
97
  'fetchTradingLimits': False,
98
98
  'fetchTransactionFee': False,
@@ -134,6 +134,7 @@ class tradeogre(Exchange, ImplicitAPI):
134
134
  'orders/{market}': 1,
135
135
  'ticker/{market}': 1,
136
136
  'history/{market}': 1,
137
+ 'chart/{interval}/{market}': 1,
137
138
  },
138
139
  },
139
140
  'private': {
@@ -162,6 +163,14 @@ class tradeogre(Exchange, ImplicitAPI):
162
163
  'Order not found': BadRequest,
163
164
  },
164
165
  },
166
+ 'timeframes': {
167
+ '1m': '1m',
168
+ '15m': '15m',
169
+ '1h': '1h',
170
+ '4h': '4h',
171
+ '1d': '1d',
172
+ '1w': '1w',
173
+ },
165
174
  'options': {
166
175
  },
167
176
  'features': {
@@ -335,18 +344,72 @@ class tradeogre(Exchange, ImplicitAPI):
335
344
  #
336
345
  return self.parse_ticker(response, market)
337
346
 
347
+ def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
348
+ """
349
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
350
+ :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
351
+ :param dict [params]: extra parameters specific to the exchange API endpoint
352
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
353
+ """
354
+ self.load_markets()
355
+ symbols = self.market_symbols(symbols)
356
+ request: dict = {}
357
+ response = self.publicGetMarkets(self.extend(request, params))
358
+ #
359
+ # [
360
+ # {
361
+ # "AAVE-USDT": {
362
+ # "initialprice": "177.20325711",
363
+ # "price": "177.20325711",
364
+ # "high": "177.20325711",
365
+ # "low": "177.20325711",
366
+ # "volume": "0.00000000",
367
+ # "bid": "160.72768581",
368
+ # "ask": "348.99999999",
369
+ # "basename": "Aave"
370
+ # }
371
+ # },
372
+ # ...
373
+ # ]
374
+ #
375
+ result: dict = {}
376
+ for i in range(0, len(response)):
377
+ entry = response[i]
378
+ marketIdArray = list(entry.keys())
379
+ marketId = self.safe_string(marketIdArray, 0)
380
+ market = self.safe_market(marketId)
381
+ data = entry[marketId]
382
+ ticker = self.parse_ticker(data, market)
383
+ symbol = ticker['symbol']
384
+ result[symbol] = ticker
385
+ return self.filter_by_array_tickers(result, 'symbol', symbols)
386
+
338
387
  def parse_ticker(self, ticker, market: Market = None):
339
388
  #
340
- # {
341
- # "success":true,
342
- # "initialprice":"0.02502002",
343
- # "price":"0.02500000",
344
- # "high":"0.03102001",
345
- # "low":"0.02500000",
346
- # "volume":"0.15549958",
347
- # "bid":"0.02420000",
348
- # "ask":"0.02625000"
349
- # }
389
+ # fetchTicker:
390
+ # {
391
+ # "success":true,
392
+ # "initialprice":"0.02502002",
393
+ # "price":"0.02500000",
394
+ # "high":"0.03102001",
395
+ # "low":"0.02500000",
396
+ # "volume":"0.15549958",
397
+ # "bid":"0.02420000",
398
+ # "ask":"0.02625000"
399
+ # }
400
+ #
401
+ # fetchTickers:
402
+ # {
403
+ # "initialprice": "177.20325711",
404
+ # "price": "177.20325711",
405
+ # "high": "177.20325711",
406
+ # "low": "177.20325711",
407
+ # "volume": "0.00000000",
408
+ # "bid": "160.72768581",
409
+ # "ask": "348.99999999",
410
+ # "basename": "Aave"
411
+ # },
412
+ # ...
350
413
  #
351
414
  return self.safe_ticker({
352
415
  'symbol': self.safe_string(market, 'symbol'),
@@ -371,6 +434,62 @@ class tradeogre(Exchange, ImplicitAPI):
371
434
  'info': ticker,
372
435
  }, market)
373
436
 
437
+ def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
438
+ """
439
+ fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
440
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
441
+ :param str timeframe: the length of time each candle represents
442
+ :param int [since]: timestamp in ms of the earliest candle to fetch
443
+ :param int [limit]: the maximum amount of candles to fetch
444
+ :param dict [params]: extra parameters specific to the exchange API endpoint
445
+ :param int [params.until]: timestamp of the latest candle in ms
446
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
447
+ """
448
+ self.load_markets()
449
+ market = self.market(symbol)
450
+ request: dict = {
451
+ 'market': market['id'],
452
+ 'interval': self.safe_string(self.timeframes, timeframe, timeframe),
453
+ }
454
+ until = self.safe_integer(params, 'until')
455
+ if until is not None:
456
+ params = self.omit(params, 'until')
457
+ request['timestamp'] = until
458
+ response = self.publicGetChartIntervalMarket(self.extend(request, params))
459
+ #
460
+ # [
461
+ # [
462
+ # 1729130040,
463
+ # 67581.47235999,
464
+ # 67581.47235999,
465
+ # 67338.01,
466
+ # 67338.01,
467
+ # 6.72168016
468
+ # ],
469
+ # ]
470
+ #
471
+ return self.parse_ohlcvs(response, market, timeframe, since, limit)
472
+
473
+ def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
474
+ #
475
+ # [
476
+ # 1729130040,
477
+ # 67581.47235999,
478
+ # 67581.47235999,
479
+ # 67338.01,
480
+ # 67338.01,
481
+ # 6.72168016
482
+ # ]
483
+ #
484
+ return [
485
+ self.safe_timestamp(ohlcv, 0),
486
+ self.safe_number(ohlcv, 1),
487
+ self.safe_number(ohlcv, 3),
488
+ self.safe_number(ohlcv, 4),
489
+ self.safe_number(ohlcv, 2),
490
+ self.safe_number(ohlcv, 5),
491
+ ]
492
+
374
493
  def fetch_order_book(self, symbol: str, limit: Int = None, params={}):
375
494
  """
376
495
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data