ccxt 4.3.20__py2.py3-none-any.whl → 4.3.21__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.

Potentially problematic release.


This version of ccxt might be problematic. Click here for more details.

ccxt/exmo.py CHANGED
@@ -270,7 +270,7 @@ class exmo(Exchange, ImplicitAPI):
270
270
  margin['amount'] = amount
271
271
  return margin
272
272
 
273
- def parse_margin_modification(self, data, market: Market = None) -> MarginModification:
273
+ def parse_margin_modification(self, data: dict, market: Market = None) -> MarginModification:
274
274
  #
275
275
  # {}
276
276
  #
ccxt/gate.py CHANGED
@@ -5678,7 +5678,7 @@ class gate(Exchange, ImplicitAPI):
5678
5678
  raise NotSupported(self.id + ' modifyMarginHelper() not support self market type')
5679
5679
  return self.parse_margin_modification(response, market)
5680
5680
 
5681
- def parse_margin_modification(self, data, market: Market = None) -> MarginModification:
5681
+ def parse_margin_modification(self, data: dict, market: Market = None) -> MarginModification:
5682
5682
  #
5683
5683
  # {
5684
5684
  # "value": "11.9257",
ccxt/hitbtc.py CHANGED
@@ -3057,7 +3057,7 @@ class hitbtc(Exchange, ImplicitAPI):
3057
3057
  'type': type,
3058
3058
  })
3059
3059
 
3060
- def parse_margin_modification(self, data, market: Market = None) -> MarginModification:
3060
+ def parse_margin_modification(self, data: dict, market: Market = None) -> MarginModification:
3061
3061
  #
3062
3062
  # addMargin/reduceMargin
3063
3063
  #
ccxt/hyperliquid.py CHANGED
@@ -1544,14 +1544,17 @@ class hyperliquid(Exchange, ImplicitAPI):
1544
1544
  :param int [limit]: the maximum number of open orders structures to retrieve
1545
1545
  :param dict [params]: extra parameters specific to the exchange API endpoint
1546
1546
  :param str [params.user]: user address, will default to self.walletAddress if not provided
1547
+ :param str [params.method]: 'openOrders' or 'frontendOpenOrders' default is 'frontendOpenOrders'
1547
1548
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1548
1549
  """
1549
1550
  userAddress = None
1550
1551
  userAddress, params = self.handle_public_address('fetchOpenOrders', params)
1552
+ method = None
1553
+ method, params = self.handle_option_and_params(params, 'fetchOpenOrders', 'method', 'frontendOpenOrders')
1551
1554
  self.load_markets()
1552
1555
  market = self.safe_market(symbol)
1553
1556
  request = {
1554
- 'type': 'openOrders',
1557
+ 'type': method,
1555
1558
  'user': userAddress,
1556
1559
  }
1557
1560
  response = self.publicPostInfo(self.extend(request, params))
@@ -1725,6 +1728,25 @@ class hyperliquid(Exchange, ImplicitAPI):
1725
1728
  # "oid":6195281425
1726
1729
  # }
1727
1730
  # }
1731
+ # frontendOrder
1732
+ # {
1733
+ # "children": [],
1734
+ # "cloid": null,
1735
+ # "coin": "BLUR",
1736
+ # "isPositionTpsl": False,
1737
+ # "isTrigger": True,
1738
+ # "limitPx": "0.5",
1739
+ # "oid": 8670487141,
1740
+ # "orderType": "Stop Limit",
1741
+ # "origSz": "20.0",
1742
+ # "reduceOnly": False,
1743
+ # "side": "B",
1744
+ # "sz": "20.0",
1745
+ # "tif": null,
1746
+ # "timestamp": 1715523663687,
1747
+ # "triggerCondition": "Price above 0.6",
1748
+ # "triggerPx": "0.6"
1749
+ # }
1728
1750
  #
1729
1751
  entry = self.safe_dict_n(order, ['order', 'resting', 'filled'])
1730
1752
  if entry is None:
@@ -1755,7 +1777,7 @@ class hyperliquid(Exchange, ImplicitAPI):
1755
1777
  'lastTradeTimestamp': None,
1756
1778
  'lastUpdateTimestamp': None,
1757
1779
  'symbol': symbol,
1758
- 'type': self.safe_string_lower(entry, 'orderType'),
1780
+ 'type': self.parse_order_type(self.safe_string_lower(entry, 'orderType')),
1759
1781
  'timeInForce': self.safe_string_upper(entry, 'tif'),
1760
1782
  'postOnly': None,
1761
1783
  'reduceOnly': self.safe_bool(entry, 'reduceOnly'),
@@ -2190,7 +2212,7 @@ class hyperliquid(Exchange, ImplicitAPI):
2190
2212
  'code': self.safe_string(response, 'status'),
2191
2213
  })
2192
2214
 
2193
- def parse_margin_modification(self, data, market: Market = None) -> MarginModification:
2215
+ def parse_margin_modification(self, data: dict, market: Market = None) -> MarginModification:
2194
2216
  #
2195
2217
  # {
2196
2218
  # 'type': 'default'
ccxt/okx.py CHANGED
@@ -269,6 +269,9 @@ class okx(Exchange, ImplicitAPI):
269
269
  'sprd/books': 1 / 2,
270
270
  'sprd/ticker': 1,
271
271
  'sprd/public-trades': 1 / 5,
272
+ 'market/sprd-ticker': 2,
273
+ 'market/sprd-candles': 2,
274
+ 'market/sprd-history-candles': 2,
272
275
  'tradingBot/grid/ai-param': 1,
273
276
  'tradingBot/grid/min-investment': 1,
274
277
  'tradingBot/public/rsi-back-testing': 1,
@@ -6235,7 +6238,7 @@ class okx(Exchange, ImplicitAPI):
6235
6238
  'status': 'ok' if (errorCode == '0') else 'failed',
6236
6239
  })
6237
6240
 
6238
- def parse_margin_modification(self, data, market: Market = None) -> MarginModification:
6241
+ def parse_margin_modification(self, data: dict, market: Market = None) -> MarginModification:
6239
6242
  #
6240
6243
  # addMargin/reduceMargin
6241
6244
  #
ccxt/phemex.py CHANGED
@@ -3790,7 +3790,7 @@ class phemex(Exchange, ImplicitAPI):
3790
3790
  }
3791
3791
  return self.safe_string(statuses, status, status)
3792
3792
 
3793
- def parse_margin_modification(self, data, market: Market = None) -> MarginModification:
3793
+ def parse_margin_modification(self, data: dict, market: Market = None) -> MarginModification:
3794
3794
  #
3795
3795
  # {
3796
3796
  # "code": 0,
ccxt/pro/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # ----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.20'
7
+ __version__ = '4.3.21'
8
8
 
9
9
  # ----------------------------------------------------------------------------
10
10
 
ccxt/pro/kucoinfutures.py CHANGED
@@ -4,7 +4,7 @@
4
4
  # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
5
 
6
6
  import ccxt.async_support
7
- from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById
7
+ from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheByTimestamp
8
8
  from ccxt.base.types import Balances, Int, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
9
9
  from ccxt.async_support.base.ws.client import Client
10
10
  from typing import List
@@ -22,6 +22,7 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
22
22
  'watchTickers': True,
23
23
  'watchBidsAsks': True,
24
24
  'watchTrades': True,
25
+ 'watchOHLCV': True,
25
26
  'watchOrderBook': True,
26
27
  'watchOrders': True,
27
28
  'watchBalance': True,
@@ -32,6 +33,21 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
32
33
  'watchOrderBookForSymbols': True,
33
34
  },
34
35
  'options': {
36
+ 'timeframes': {
37
+ '1m': '1min',
38
+ '3m': '1min',
39
+ '5m': '5min',
40
+ '15m': '15min',
41
+ '30m': '30min',
42
+ '1h': '1hour',
43
+ '2h': '2hour',
44
+ '4h': '4hour',
45
+ '8h': '8hour',
46
+ '12h': '12hour',
47
+ '1d': '1day',
48
+ '1w': '1week',
49
+ '1M': '1month',
50
+ },
35
51
  'accountsByType': {
36
52
  'swap': 'future',
37
53
  'cross': 'margin',
@@ -540,6 +556,77 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
540
556
  client.resolve(trades, messageHash)
541
557
  return message
542
558
 
559
+ async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
560
+ """
561
+ :see: https://www.kucoin.com/docs/websocket/futures-trading/public-channels/klines
562
+ watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
563
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
564
+ :param str timeframe: the length of time each candle represents
565
+ :param int [since]: timestamp in ms of the earliest candle to fetch
566
+ :param int [limit]: the maximum amount of candles to fetch
567
+ :param dict [params]: extra parameters specific to the exchange API endpoint
568
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
569
+ """
570
+ await self.load_markets()
571
+ symbol = self.symbol(symbol)
572
+ url = await self.negotiate(False)
573
+ marketId = self.market_id(symbol)
574
+ timeframes = self.safe_dict(self.options, 'timeframes')
575
+ timeframeId = self.safe_string(timeframes, timeframe, timeframe)
576
+ topic = '/contractMarket/limitCandle:' + marketId + '_' + timeframeId
577
+ messageHash = 'ohlcv::' + symbol + '_' + timeframe
578
+ ohlcv = await self.subscribe(url, messageHash, topic, None, params)
579
+ if self.newUpdates:
580
+ limit = ohlcv.getLimit(symbol, limit)
581
+ return self.filter_by_since_limit(ohlcv, since, limit, 0, True)
582
+
583
+ def handle_ohlcv(self, client: Client, message):
584
+ #
585
+ # {
586
+ # "topic":"/contractMarket/limitCandle:LTCUSDTM_1min",
587
+ # "type":"message",
588
+ # "data":{
589
+ # "symbol":"LTCUSDTM",
590
+ # "candles":[
591
+ # "1715470980",
592
+ # "81.38",
593
+ # "81.38",
594
+ # "81.38",
595
+ # "81.38",
596
+ # "61.0",
597
+ # "61"
598
+ # ],
599
+ # "time":1715470994801
600
+ # },
601
+ # "subject":"candle.stick"
602
+ # }
603
+ #
604
+ topic = self.safe_string(message, 'topic')
605
+ parts = topic.split('_')
606
+ timeframeId = self.safe_string(parts, 1)
607
+ data = self.safe_dict(message, 'data')
608
+ timeframes = self.safe_dict(self.options, 'timeframes')
609
+ timeframe = self.find_timeframe(timeframeId, timeframes)
610
+ marketId = self.safe_string(data, 'symbol')
611
+ symbol = self.safe_symbol(marketId)
612
+ messageHash = 'ohlcv::' + symbol + '_' + timeframe
613
+ ohlcv = self.safe_list(data, 'candles')
614
+ parsed = [
615
+ self.safe_integer(ohlcv, 0),
616
+ self.safe_number(ohlcv, 1),
617
+ self.safe_number(ohlcv, 2),
618
+ self.safe_number(ohlcv, 3),
619
+ self.safe_number(ohlcv, 4),
620
+ self.safe_number(ohlcv, 6), # Note value 5 is incorrect and will be fixed in subsequent versions of kucoin
621
+ ]
622
+ self.ohlcvs[symbol] = self.safe_dict(self.ohlcvs, symbol, {})
623
+ if not (timeframe in self.ohlcvs[symbol]):
624
+ limit = self.safe_integer(self.options, 'OHLCVLimit', 1000)
625
+ self.ohlcvs[symbol][timeframe] = ArrayCacheByTimestamp(limit)
626
+ stored = self.ohlcvs[symbol][timeframe]
627
+ stored.append(parsed)
628
+ client.resolve(stored, messageHash)
629
+
543
630
  async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
544
631
  """
545
632
  watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
@@ -923,6 +1010,7 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
923
1010
  methods = {
924
1011
  'level2': self.handle_order_book,
925
1012
  'ticker': self.handle_ticker,
1013
+ 'candle.stick': self.handle_ohlcv,
926
1014
  'tickerV2': self.handle_bid_ask,
927
1015
  'availableBalance.change': self.handle_balance,
928
1016
  'match': self.handle_trade,
ccxt/pro/woo.py CHANGED
@@ -531,6 +531,16 @@ class woo(ccxt.async_support.woo):
531
531
  request = self.extend(subscribe, message)
532
532
  return await self.watch(url, messageHash, request, messageHash, subscribe)
533
533
 
534
+ async def watch_private_multiple(self, messageHashes, message, params={}):
535
+ await self.authenticate(params)
536
+ url = self.urls['api']['ws']['private'] + '/' + self.uid
537
+ requestId = self.request_id(url)
538
+ subscribe = {
539
+ 'id': requestId,
540
+ }
541
+ request = self.extend(subscribe, message)
542
+ return await self.watch_multiple(url, messageHashes, request, messageHashes, subscribe)
543
+
534
544
  async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
535
545
  """
536
546
  :see: https://docs.woo.org/#executionreport
@@ -540,10 +550,13 @@ class woo(ccxt.async_support.woo):
540
550
  :param int [since]: the earliest time in ms to fetch orders for
541
551
  :param int [limit]: the maximum number of order structures to retrieve
542
552
  :param dict [params]: extra parameters specific to the exchange API endpoint
553
+ :param bool [params.trigger]: True if trigger order
543
554
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
544
555
  """
545
556
  await self.load_markets()
546
- topic = 'executionreport'
557
+ trigger = self.safe_bool_2(params, 'stop', 'trigger', False)
558
+ topic = 'algoexecutionreportv2' if (trigger) else 'executionreport'
559
+ params = self.omit(params, ['stop', 'trigger'])
547
560
  messageHash = topic
548
561
  if symbol is not None:
549
562
  market = self.market(symbol)
@@ -562,15 +575,19 @@ class woo(ccxt.async_support.woo):
562
575
  async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
563
576
  """
564
577
  :see: https://docs.woo.org/#executionreport
578
+ :see: https://docs.woo.org/#algoexecutionreportv2
565
579
  watches information on multiple trades made by the user
566
580
  :param str symbol: unified market symbol of the market orders were made in
567
581
  :param int [since]: the earliest time in ms to fetch orders for
568
582
  :param int [limit]: the maximum number of order structures to retrieve
569
583
  :param dict [params]: extra parameters specific to the exchange API endpoint
584
+ :param bool [params.trigger]: True if trigger order
570
585
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
571
586
  """
572
587
  await self.load_markets()
573
- topic = 'executionreport'
588
+ trigger = self.safe_bool_2(params, 'stop', 'trigger', False)
589
+ topic = 'algoexecutionreportv2' if (trigger) else 'executionreport'
590
+ params = self.omit(params, ['stop', 'trigger'])
574
591
  messageHash = 'myTrades'
575
592
  if symbol is not None:
576
593
  market = self.market(symbol)
@@ -692,14 +709,24 @@ class woo(ccxt.async_support.woo):
692
709
  # }
693
710
  # }
694
711
  #
695
- order = self.safe_dict(message, 'data')
696
- tradeId = self.safe_string(order, 'tradeId')
697
- if (tradeId is not None) and (tradeId != '0'):
698
- self.handle_my_trade(client, order)
699
- self.handle_order(client, order)
712
+ topic = self.safe_string(message, 'topic')
713
+ data = self.safe_value(message, 'data')
714
+ if isinstance(data, list):
715
+ # algoexecutionreportv2
716
+ for i in range(0, len(data)):
717
+ order = data[i]
718
+ tradeId = self.omit_zero(self.safe_string(data, 'tradeId'))
719
+ if tradeId is not None:
720
+ self.handle_my_trade(client, order)
721
+ self.handle_order(client, order, topic)
722
+ else:
723
+ # executionreport
724
+ tradeId = self.omit_zero(self.safe_string(data, 'tradeId'))
725
+ if tradeId is not None:
726
+ self.handle_my_trade(client, data)
727
+ self.handle_order(client, data, topic)
700
728
 
701
- def handle_order(self, client: Client, message):
702
- topic = 'executionreport'
729
+ def handle_order(self, client: Client, message, topic):
703
730
  parsed = self.parse_ws_order(message)
704
731
  symbol = self.safe_string(parsed, 'symbol')
705
732
  orderId = self.safe_string(parsed, 'id')
@@ -776,11 +803,14 @@ class woo(ccxt.async_support.woo):
776
803
  :returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
777
804
  """
778
805
  await self.load_markets()
779
- messageHash = ''
806
+ messageHashes = []
780
807
  symbols = self.market_symbols(symbols)
781
808
  if not self.is_empty(symbols):
782
- messageHash = '::' + ','.join(symbols)
783
- messageHash = 'positions' + messageHash
809
+ for i in range(0, len(symbols)):
810
+ symbol = symbols[i]
811
+ messageHashes.append('positions::' + symbol)
812
+ else:
813
+ messageHashes.append('positions')
784
814
  url = self.urls['api']['ws']['private'] + '/' + self.uid
785
815
  client = self.client(url)
786
816
  self.set_positions_cache(client, symbols)
@@ -793,7 +823,7 @@ class woo(ccxt.async_support.woo):
793
823
  'event': 'subscribe',
794
824
  'topic': 'position',
795
825
  }
796
- newPositions = await self.watch_private(messageHash, request, params)
826
+ newPositions = await self.watch_private_multiple(messageHashes, request, params)
797
827
  if self.newUpdates:
798
828
  return newPositions
799
829
  return self.filter_by_symbols_since_limit(self.positions, symbols, since, limit, True)
@@ -862,15 +892,8 @@ class woo(ccxt.async_support.woo):
862
892
  position = self.parse_position(rawPosition, market)
863
893
  newPositions.append(position)
864
894
  cache.append(position)
865
- messageHashes = self.find_message_hashes(client, 'positions::')
866
- for i in range(0, len(messageHashes)):
867
- messageHash = messageHashes[i]
868
- parts = messageHash.split('::')
869
- symbolsString = parts[1]
870
- symbols = symbolsString.split(',')
871
- positions = self.filter_by_array(newPositions, 'symbol', symbols, False)
872
- if not self.is_empty(positions):
873
- client.resolve(positions, messageHash)
895
+ messageHash = 'positions::' + market['symbol']
896
+ client.resolve(position, messageHash)
874
897
  client.resolve(newPositions, 'positions')
875
898
 
876
899
  async def watch_balance(self, params={}) -> Balances:
@@ -978,6 +1001,7 @@ class woo(ccxt.async_support.woo):
978
1001
  'kline': self.handle_ohlcv,
979
1002
  'auth': self.handle_auth,
980
1003
  'executionreport': self.handle_order_update,
1004
+ 'algoexecutionreportv2': self.handle_order_update,
981
1005
  'trade': self.handle_trade,
982
1006
  'balance': self.handle_balance,
983
1007
  'position': self.handle_positions,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ccxt
3
- Version: 4.3.20
3
+ Version: 4.3.21
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
@@ -264,13 +264,13 @@ console.log(version, Object.keys(exchanges));
264
264
 
265
265
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
266
266
 
267
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.20/dist/ccxt.browser.js
268
- * unpkg: https://unpkg.com/ccxt@4.3.20/dist/ccxt.browser.js
267
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.3.21/dist/ccxt.browser.js
268
+ * unpkg: https://unpkg.com/ccxt@4.3.21/dist/ccxt.browser.js
269
269
 
270
270
  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.
271
271
 
272
272
  ```HTML
273
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.20/dist/ccxt.browser.js"></script>
273
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.3.21/dist/ccxt.browser.js"></script>
274
274
  ```
275
275
 
276
276
  Creates a global `ccxt` object: