unicex 0.13.17__py3-none-any.whl → 0.16.5__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 (63) hide show
  1. unicex/__init__.py +36 -2
  2. unicex/_abc/exchange_info.py +1 -1
  3. unicex/_abc/uni_client.py +31 -1
  4. unicex/_abc/uni_websocket_manager.py +1 -1
  5. unicex/_base/client.py +7 -0
  6. unicex/_base/websocket.py +31 -9
  7. unicex/binance/adapter.py +7 -16
  8. unicex/binance/client.py +25 -25
  9. unicex/binance/uni_websocket_manager.py +6 -2
  10. unicex/bingx/__init__.py +27 -0
  11. unicex/bingx/adapter.py +284 -0
  12. unicex/bingx/client.py +521 -0
  13. unicex/bingx/exchange_info.py +22 -0
  14. unicex/bingx/uni_client.py +191 -0
  15. unicex/bingx/uni_websocket_manager.py +283 -0
  16. unicex/bingx/user_websocket.py +7 -0
  17. unicex/bingx/websocket_manager.py +118 -0
  18. unicex/bitget/adapter.py +2 -2
  19. unicex/bitget/client.py +64 -64
  20. unicex/bitget/uni_websocket_manager.py +27 -6
  21. unicex/bitget/websocket_manager.py +2 -4
  22. unicex/bybit/adapter.py +1 -0
  23. unicex/bybit/client.py +4 -4
  24. unicex/bybit/exchange_info.py +1 -1
  25. unicex/bybit/uni_websocket_manager.py +33 -4
  26. unicex/bybit/websocket_manager.py +8 -24
  27. unicex/enums.py +19 -3
  28. unicex/extra.py +37 -35
  29. unicex/gate/adapter.py +113 -0
  30. unicex/gate/client.py +9 -9
  31. unicex/gate/uni_client.py +1 -3
  32. unicex/gate/uni_websocket_manager.py +47 -9
  33. unicex/hyperliquid/adapter.py +1 -0
  34. unicex/hyperliquid/client.py +12 -12
  35. unicex/hyperliquid/uni_client.py +4 -7
  36. unicex/hyperliquid/uni_websocket_manager.py +6 -2
  37. unicex/kucoin/__init__.py +27 -0
  38. unicex/kucoin/adapter.py +181 -0
  39. unicex/kucoin/client.py +135 -0
  40. unicex/kucoin/exchange_info.py +50 -0
  41. unicex/kucoin/uni_client.py +208 -0
  42. unicex/kucoin/uni_websocket_manager.py +273 -0
  43. unicex/kucoin/user_websocket.py +7 -0
  44. unicex/kucoin/websocket_manager.py +11 -0
  45. unicex/mapper.py +62 -21
  46. unicex/mexc/adapter.py +104 -0
  47. unicex/mexc/client.py +7 -7
  48. unicex/mexc/uni_client.py +1 -3
  49. unicex/mexc/uni_websocket_manager.py +31 -9
  50. unicex/mexc/websocket_manager.py +27 -6
  51. unicex/okx/adapter.py +51 -0
  52. unicex/okx/client.py +15 -15
  53. unicex/okx/exchange_info.py +2 -2
  54. unicex/okx/uni_websocket_manager.py +50 -9
  55. unicex/okx/websocket_manager.py +119 -166
  56. unicex/types.py +14 -10
  57. unicex/utils.py +44 -1
  58. {unicex-0.13.17.dist-info → unicex-0.16.5.dist-info}/METADATA +7 -5
  59. unicex-0.16.5.dist-info/RECORD +109 -0
  60. unicex-0.13.17.dist-info/RECORD +0 -93
  61. {unicex-0.13.17.dist-info → unicex-0.16.5.dist-info}/WHEEL +0 -0
  62. {unicex-0.13.17.dist-info → unicex-0.16.5.dist-info}/licenses/LICENSE +0 -0
  63. {unicex-0.13.17.dist-info → unicex-0.16.5.dist-info}/top_level.txt +0 -0
unicex/bitget/client.py CHANGED
@@ -6,7 +6,7 @@ from typing import Any, Literal
6
6
 
7
7
  from unicex._base import BaseClient
8
8
  from unicex.exceptions import NotAuthorized
9
- from unicex.types import RequestMethod
9
+ from unicex.types import NumberLike, RequestMethod
10
10
  from unicex.utils import (
11
11
  dict_to_query_string,
12
12
  filter_params,
@@ -434,18 +434,18 @@ class Client(BaseClient):
434
434
  side: str,
435
435
  order_type: str,
436
436
  force: str | None = None,
437
- price: str | None = None,
438
- size: str | None = None,
437
+ price: NumberLike | None = None,
438
+ size: NumberLike | None = None,
439
439
  client_oid: str | None = None,
440
- trigger_price: str | None = None,
440
+ trigger_price: NumberLike | None = None,
441
441
  tpsl_type: str | None = None,
442
442
  request_time: str | None = None,
443
443
  receive_window: str | None = None,
444
444
  stp_mode: str | None = None,
445
- preset_take_profit_price: str | None = None,
446
- execute_take_profit_price: str | None = None,
447
- preset_stop_loss_price: str | None = None,
448
- execute_stop_loss_price: str | None = None,
445
+ preset_take_profit_price: NumberLike | None = None,
446
+ execute_take_profit_price: NumberLike | None = None,
447
+ preset_stop_loss_price: NumberLike | None = None,
448
+ execute_stop_loss_price: NumberLike | None = None,
449
449
  ) -> dict:
450
450
  """Размещение спотового ордера.
451
451
 
@@ -479,15 +479,15 @@ class Client(BaseClient):
479
479
  async def cancel_an_existing_order_and_send_a_new_order(
480
480
  self,
481
481
  symbol: str,
482
- price: str,
483
- size: str,
482
+ price: NumberLike,
483
+ size: NumberLike,
484
484
  order_id: str | None = None,
485
485
  client_oid: str | None = None,
486
486
  new_client_oid: str | None = None,
487
- preset_take_profit_price: str | None = None,
488
- execute_take_profit_price: str | None = None,
489
- preset_stop_loss_price: str | None = None,
490
- execute_stop_loss_price: str | None = None,
487
+ preset_take_profit_price: NumberLike | None = None,
488
+ execute_take_profit_price: NumberLike | None = None,
489
+ preset_stop_loss_price: NumberLike | None = None,
490
+ execute_stop_loss_price: NumberLike | None = None,
491
491
  ) -> dict:
492
492
  """Отмена существующего ордера и размещение нового.
493
493
 
@@ -716,11 +716,11 @@ class Client(BaseClient):
716
716
  self,
717
717
  symbol: str,
718
718
  side: str,
719
- trigger_price: str,
719
+ trigger_price: NumberLike,
720
720
  order_type: str,
721
- size: str | float,
721
+ size: NumberLike,
722
722
  trigger_type: str,
723
- execute_price: str | None = None,
723
+ execute_price: NumberLike | None = None,
724
724
  plan_type: str | None = None,
725
725
  client_oid: str | None = None,
726
726
  stp_mode: str | None = None,
@@ -748,12 +748,12 @@ class Client(BaseClient):
748
748
 
749
749
  async def modify_plan_order(
750
750
  self,
751
- trigger_price: str,
752
- size: str | float,
751
+ trigger_price: NumberLike,
752
+ size: NumberLike,
753
753
  order_type: str,
754
754
  order_id: str | None = None,
755
755
  client_oid: str | None = None,
756
- execute_price: str | None = None,
756
+ execute_price: NumberLike | None = None,
757
757
  ) -> dict:
758
758
  """Изменение планового ордера (trigger order).
759
759
 
@@ -950,7 +950,7 @@ class Client(BaseClient):
950
950
  self,
951
951
  from_type: str,
952
952
  to_type: str,
953
- amount: str | float,
953
+ amount: NumberLike,
954
954
  coin: str,
955
955
  symbol: str,
956
956
  client_oid: str | None = None,
@@ -992,7 +992,7 @@ class Client(BaseClient):
992
992
  self,
993
993
  from_type: str,
994
994
  to_type: str,
995
- amount: float,
995
+ amount: NumberLike,
996
996
  coin: str,
997
997
  symbol: str | None = None,
998
998
  client_oid: str | None = None,
@@ -1026,7 +1026,7 @@ class Client(BaseClient):
1026
1026
  inner_to_type: str | None = None,
1027
1027
  area_code: str | None = None,
1028
1028
  tag: str | None = None,
1029
- size: str | float | None = None,
1029
+ size: NumberLike | None = None,
1030
1030
  remark: str | None = None,
1031
1031
  client_oid: str | None = None,
1032
1032
  member_code: str | None = None,
@@ -1480,8 +1480,8 @@ class Client(BaseClient):
1480
1480
  self,
1481
1481
  symbol: str,
1482
1482
  margin_coin: str,
1483
- open_amount: float,
1484
- open_price: float,
1483
+ open_amount: NumberLike,
1484
+ open_price: NumberLike,
1485
1485
  product_type: Literal["USDT-FUTURES", "USDC-FUTURES", "COIN-FUTURES"] = "USDT-FUTURES",
1486
1486
  leverage: int | None = 20,
1487
1487
  ) -> dict:
@@ -1575,7 +1575,7 @@ class Client(BaseClient):
1575
1575
  symbol: str,
1576
1576
  margin_coin: str,
1577
1577
  hold_side: str,
1578
- amount: str,
1578
+ amount: NumberLike,
1579
1579
  product_type: Literal["USDT-FUTURES", "USDC-FUTURES", "COIN-FUTURES"] = "USDT-FUTURES",
1580
1580
  ) -> dict:
1581
1581
  """Добавить или уменьшить маржу для позиции (только для изолированной маржи).
@@ -1637,7 +1637,7 @@ class Client(BaseClient):
1637
1637
  async def futures_union_convert(
1638
1638
  self,
1639
1639
  coin: str,
1640
- amount: str,
1640
+ amount: NumberLike,
1641
1641
  ) -> dict:
1642
1642
  """Конвертация активов в режиме объединенной маржи.
1643
1643
 
@@ -1826,19 +1826,19 @@ class Client(BaseClient):
1826
1826
  symbol: str,
1827
1827
  margin_mode: str,
1828
1828
  margin_coin: str,
1829
- size: str,
1829
+ size: NumberLike,
1830
1830
  side: str,
1831
1831
  order_type: str,
1832
1832
  product_type: Literal["USDT-FUTURES", "USDC-FUTURES", "COIN-FUTURES"] = "USDT-FUTURES",
1833
- price: str | None = None,
1833
+ price: NumberLike | None = None,
1834
1834
  trade_side: str | None = None,
1835
1835
  force: str | None = "gtc",
1836
1836
  client_oid: str | None = None,
1837
1837
  reduce_only: str | None = "NO",
1838
- preset_stop_surplus_price: str | None = None,
1839
- preset_stop_loss_price: str | None = None,
1840
- preset_stop_surplus_execute_price: str | None = None,
1841
- preset_stop_loss_execute_price: str | None = None,
1838
+ preset_stop_surplus_price: NumberLike | None = None,
1839
+ preset_stop_loss_price: NumberLike | None = None,
1840
+ preset_stop_surplus_execute_price: NumberLike | None = None,
1841
+ preset_stop_loss_execute_price: NumberLike | None = None,
1842
1842
  stp_mode: str | None = "none",
1843
1843
  ) -> dict:
1844
1844
  """Разместить ордер на фьючерсном рынке.
@@ -1875,7 +1875,7 @@ class Client(BaseClient):
1875
1875
  margin_coin: str,
1876
1876
  side: str,
1877
1877
  product_type: Literal["USDT-FUTURES", "USDC-FUTURES", "COIN-FUTURES"] = "USDT-FUTURES",
1878
- size: str | None = None,
1878
+ size: NumberLike | None = None,
1879
1879
  trade_side: str | None = None,
1880
1880
  client_oid: str | None = None,
1881
1881
  ) -> dict:
@@ -1929,10 +1929,10 @@ class Client(BaseClient):
1929
1929
  product_type: Literal["USDT-FUTURES", "USDC-FUTURES", "COIN-FUTURES"] = "USDT-FUTURES",
1930
1930
  order_id: str | None = None,
1931
1931
  client_oid: str | None = None,
1932
- new_size: str | None = None,
1933
- new_price: str | None = None,
1934
- new_preset_stop_surplus_price: str | None = None,
1935
- new_preset_stop_loss_price: str | None = None,
1932
+ new_size: NumberLike | None = None,
1933
+ new_price: NumberLike | None = None,
1934
+ new_preset_stop_surplus_price: NumberLike | None = None,
1935
+ new_preset_stop_loss_price: NumberLike | None = None,
1936
1936
  ) -> dict:
1937
1937
  """Модифицировать существующий ордер: цену, размер и/или TP/SL.
1938
1938
 
@@ -2212,12 +2212,12 @@ class Client(BaseClient):
2212
2212
  margin_coin: str,
2213
2213
  symbol: str,
2214
2214
  plan_type: str,
2215
- trigger_price: str,
2215
+ trigger_price: NumberLike,
2216
2216
  hold_side: str,
2217
- size: str,
2217
+ size: NumberLike,
2218
2218
  product_type: Literal["USDT-FUTURES", "USDC-FUTURES", "COIN-FUTURES"] = "USDT-FUTURES",
2219
2219
  trigger_type: str | None = None,
2220
- execute_price: str | None = None,
2220
+ execute_price: NumberLike | None = None,
2221
2221
  range_rate: str | None = None,
2222
2222
  client_oid: str | None = None,
2223
2223
  stp_mode: str | None = None,
@@ -2251,14 +2251,14 @@ class Client(BaseClient):
2251
2251
  symbol: str,
2252
2252
  hold_side: str,
2253
2253
  product_type: Literal["USDT-FUTURES", "USDC-FUTURES", "COIN-FUTURES"] = "USDT-FUTURES",
2254
- stop_surplus_trigger_price: str | None = None,
2255
- stop_surplus_size: str | None = None,
2254
+ stop_surplus_trigger_price: NumberLike | None = None,
2255
+ stop_surplus_size: NumberLike | None = None,
2256
2256
  stop_surplus_trigger_type: str | None = None,
2257
- stop_surplus_execute_price: str | None = None,
2258
- stop_loss_trigger_price: str | None = None,
2259
- stop_loss_size: str | None = None,
2257
+ stop_surplus_execute_price: NumberLike | None = None,
2258
+ stop_loss_trigger_price: NumberLike | None = None,
2259
+ stop_loss_size: NumberLike | None = None,
2260
2260
  stop_loss_trigger_type: str | None = None,
2261
- stop_loss_execute_price: str | None = None,
2261
+ stop_loss_execute_price: NumberLike | None = None,
2262
2262
  stp_mode: str | None = None,
2263
2263
  stop_surplus_client_oid: str | None = None,
2264
2264
  stop_loss_client_oid: str | None = None,
@@ -2295,22 +2295,22 @@ class Client(BaseClient):
2295
2295
  symbol: str,
2296
2296
  margin_mode: str,
2297
2297
  margin_coin: str,
2298
- size: str,
2298
+ size: NumberLike,
2299
2299
  side: str,
2300
2300
  order_type: str,
2301
- trigger_price: str,
2301
+ trigger_price: NumberLike,
2302
2302
  trigger_type: str,
2303
2303
  product_type: Literal["USDT-FUTURES", "USDC-FUTURES", "COIN-FUTURES"] = "USDT-FUTURES",
2304
2304
  trade_side: str | None = None,
2305
- price: str | None = None,
2305
+ price: NumberLike | None = None,
2306
2306
  callback_ratio: str | None = None,
2307
2307
  client_oid: str | None = None,
2308
2308
  reduce_only: str | None = None,
2309
- stop_surplus_trigger_price: str | None = None,
2310
- stop_surplus_execute_price: str | None = None,
2309
+ stop_surplus_trigger_price: NumberLike | None = None,
2310
+ stop_surplus_execute_price: NumberLike | None = None,
2311
2311
  stop_surplus_trigger_type: str | None = None,
2312
- stop_loss_trigger_price: str | None = None,
2313
- stop_loss_execute_price: str | None = None,
2312
+ stop_loss_trigger_price: NumberLike | None = None,
2313
+ stop_loss_execute_price: NumberLike | None = None,
2314
2314
  stop_loss_trigger_type: str | None = None,
2315
2315
  stp_mode: str | None = None,
2316
2316
  ) -> dict:
@@ -2351,13 +2351,13 @@ class Client(BaseClient):
2351
2351
  self,
2352
2352
  margin_coin: str,
2353
2353
  symbol: str,
2354
- trigger_price: str,
2355
- size: str,
2354
+ trigger_price: NumberLike,
2355
+ size: NumberLike,
2356
2356
  product_type: Literal["USDT-FUTURES", "USDC-FUTURES", "COIN-FUTURES"] = "USDT-FUTURES",
2357
2357
  order_id: str | None = None,
2358
2358
  client_oid: str | None = None,
2359
2359
  trigger_type: str | None = None,
2360
- execute_price: str | None = None,
2360
+ execute_price: NumberLike | None = None,
2361
2361
  range_rate: str | None = None,
2362
2362
  ) -> dict:
2363
2363
  """Изменить TP/SL ордер.
@@ -2386,16 +2386,16 @@ class Client(BaseClient):
2386
2386
  product_type: Literal["USDT-FUTURES", "USDC-FUTURES", "COIN-FUTURES"] = "USDT-FUTURES",
2387
2387
  order_id: str | None = None,
2388
2388
  client_oid: str | None = None,
2389
- new_size: str | None = None,
2390
- new_price: str | None = None,
2389
+ new_size: NumberLike | None = None,
2390
+ new_price: NumberLike | None = None,
2391
2391
  new_callback_ratio: str | None = None,
2392
- new_trigger_price: str | None = None,
2392
+ new_trigger_price: NumberLike | None = None,
2393
2393
  new_trigger_type: str | None = None,
2394
- new_stop_surplus_trigger_price: str | None = None,
2395
- new_stop_surplus_execute_price: str | None = None,
2394
+ new_stop_surplus_trigger_price: NumberLike | None = None,
2395
+ new_stop_surplus_execute_price: NumberLike | None = None,
2396
2396
  new_stop_surplus_trigger_type: str | None = None,
2397
- new_stop_loss_trigger_price: str | None = None,
2398
- new_stop_loss_execute_price: str | None = None,
2397
+ new_stop_loss_trigger_price: NumberLike | None = None,
2398
+ new_stop_loss_execute_price: NumberLike | None = None,
2399
2399
  new_stop_loss_trigger_type: str | None = None,
2400
2400
  ) -> dict:
2401
2401
  """Изменить триггерный или трейлинг ордер, включая TP/SL.
@@ -5,7 +5,7 @@ from typing import Any, overload
5
5
 
6
6
  from unicex._abc import IUniWebsocketManager
7
7
  from unicex._base import Websocket
8
- from unicex.enums import Timeframe
8
+ from unicex.enums import Exchange, MarketType, Timeframe
9
9
  from unicex.types import LoggerLike
10
10
 
11
11
  from .adapter import Adapter
@@ -20,16 +20,20 @@ class UniWebsocketManager(IUniWebsocketManager):
20
20
  """Реализация менеджера асинхронных унифицированных вебсокетов для биржи Bitget."""
21
21
 
22
22
  def __init__(
23
- self, client: Client | UniClient | None = None, logger: LoggerLike | None = None
23
+ self,
24
+ client: Client | UniClient | None = None,
25
+ logger: LoggerLike | None = None,
26
+ **ws_kwargs: Any,
24
27
  ) -> None:
25
28
  """Инициализирует унифицированный менеджер вебсокетов.
26
29
 
27
30
  Параметры:
28
31
  client (`Client | UniClient | None`): Клиент Bitget или унифицированный клиент. Нужен для подключения к приватным топикам.
29
32
  logger (`LoggerLike | None`): Логгер для записи логов.
33
+ ws_kwargs (`dict[str, Any]`): Дополнительные параметры инициализации, которые будут переданы WebsocketManager/Websocket.
30
34
  """
31
35
  super().__init__(client=client, logger=logger)
32
- self._websocket_manager = WebsocketManager(self._client) # type: ignore
36
+ self._websocket_manager = WebsocketManager(self._client, **ws_kwargs) # type: ignore
33
37
  self._adapter = Adapter()
34
38
 
35
39
  @overload
@@ -72,7 +76,17 @@ class UniWebsocketManager(IUniWebsocketManager):
72
76
  Возвращает:
73
77
  `Websocket`: Экземпляр вебсокета для управления соединением.
74
78
  """
75
- raise NotImplementedError()
79
+ wrapper = self._make_wrapper(self._adapter.klines_message, callback)
80
+ return self._websocket_manager.candlestick(
81
+ callback=wrapper,
82
+ market_type="SPOT",
83
+ symbol=symbol,
84
+ symbols=symbols,
85
+ interval=timeframe.to_exchange_format(
86
+ Exchange.BITGET,
87
+ MarketType.FUTURES, # Тут пришлось поставить Futures, потому что:
88
+ ), # кто бы мог подумать, что у Bitget на споте для вебсокетов и HTTP запросов совершенно разные перечисления. Тупые ублюдки.
89
+ )
76
90
 
77
91
  @overload
78
92
  def futures_klines(
@@ -114,7 +128,14 @@ class UniWebsocketManager(IUniWebsocketManager):
114
128
  Возвращает:
115
129
  `Websocket`: Экземпляр вебсокета.
116
130
  """
117
- raise NotImplementedError()
131
+ wrapper = self._make_wrapper(self._adapter.klines_message, callback)
132
+ return self._websocket_manager.candlestick(
133
+ callback=wrapper,
134
+ market_type="USDT-FUTURES",
135
+ symbol=symbol,
136
+ symbols=symbols,
137
+ interval=timeframe.to_exchange_format(Exchange.BITGET, MarketType.FUTURES),
138
+ )
118
139
 
119
140
  @overload
120
141
  def trades(
@@ -272,4 +293,4 @@ class UniWebsocketManager(IUniWebsocketManager):
272
293
  Возвращает:
273
294
  `Websocket`: Экземпляр вебсокета.
274
295
  """
275
- raise NotImplementedError()
296
+ return self.futures_trades(callback=callback, symbol=symbol, symbols=symbols) # type: ignore[reportCallIssue]
@@ -6,6 +6,7 @@ from collections.abc import Awaitable, Callable, Sequence
6
6
  from typing import Any, Literal
7
7
 
8
8
  from unicex._base import Websocket
9
+ from unicex.utils import validate_single_symbol_args
9
10
 
10
11
  from .client import Client
11
12
 
@@ -46,10 +47,7 @@ class WebsocketManager:
46
47
  Возвращает:
47
48
  `str`: JSON-строка с сообщением для подписки на вебсокет.
48
49
  """
49
- if symbol and symbols:
50
- raise ValueError("Parameters symbol and symbols cannot be used together")
51
- if not (symbol or symbols):
52
- raise ValueError("Either symbol or symbols must be provided")
50
+ validate_single_symbol_args(symbol, symbols)
53
51
 
54
52
  tickers = [symbol] if symbol else symbols
55
53
  streams: list[dict] = [
unicex/bybit/adapter.py CHANGED
@@ -68,6 +68,7 @@ class Adapter:
68
68
  item["symbol"]: OpenInterestItem(
69
69
  t=raw_data["time"],
70
70
  v=float(item["openInterest"]),
71
+ u="coins",
71
72
  )
72
73
  for item in raw_data["result"]["list"]
73
74
  }
unicex/bybit/client.py CHANGED
@@ -610,7 +610,7 @@ class Client(BaseClient):
610
610
  close_on_trigger: bool | None = None,
611
611
  smp_type: str | None = None,
612
612
  mmp: bool | None = None,
613
- tpsl_mode: str | None = None,
613
+ tpsl_mode: Literal["Full", "Partial"] | None = None,
614
614
  tp_limit_price: str | None = None,
615
615
  sl_limit_price: str | None = None,
616
616
  tp_order_type: str | None = None,
@@ -666,7 +666,7 @@ class Client(BaseClient):
666
666
  trigger_price: str | None = None,
667
667
  qty: str | None = None,
668
668
  price: str | None = None,
669
- tpsl_mode: str | None = None,
669
+ tpsl_mode: Literal["Full", "Partial"] | None = None,
670
670
  take_profit: str | None = None,
671
671
  stop_loss: str | None = None,
672
672
  tp_trigger_by: str | None = None,
@@ -959,7 +959,7 @@ class Client(BaseClient):
959
959
  close_on_trigger: bool | None = None,
960
960
  smp_type: str | None = None,
961
961
  mmp: bool | None = None,
962
- tpsl_mode: str | None = None,
962
+ tpsl_mode: Literal["Full", "Partial"] | None = None,
963
963
  tp_limit_price: str | None = None,
964
964
  sl_limit_price: str | None = None,
965
965
  tp_order_type: str | None = None,
@@ -1098,7 +1098,7 @@ class Client(BaseClient):
1098
1098
  self,
1099
1099
  category: Literal["linear", "inverse"],
1100
1100
  symbol: str,
1101
- tpsl_mode: str,
1101
+ tpsl_mode: Literal["Full", "Partial"],
1102
1102
  position_idx: int,
1103
1103
  take_profit: str | None = None,
1104
1104
  stop_loss: str | None = None,
@@ -17,7 +17,7 @@ class ExchangeInfo(IExchangeInfo):
17
17
  @classmethod
18
18
  async def _load_spot_exchange_info(cls, session: aiohttp.ClientSession) -> None:
19
19
  """Загружает информацию о бирже для спотового рынка."""
20
- exchange_info = await Client(session).instruments_info("spot")
20
+ exchange_info = await Client(session).instruments_info("spot", limit=1000)
21
21
  tickers_info: dict[str, TickerInfoItem] = {}
22
22
  for symbol_info in exchange_info["result"]["list"]:
23
23
  tickers_info[symbol_info["symbol"]] = TickerInfoItem(
@@ -20,16 +20,20 @@ class UniWebsocketManager(IUniWebsocketManager):
20
20
  """Реализация менеджера асинхронных унифицированных вебсокетов."""
21
21
 
22
22
  def __init__(
23
- self, client: Client | UniClient | None = None, logger: LoggerLike | None = None
23
+ self,
24
+ client: Client | UniClient | None = None,
25
+ logger: LoggerLike | None = None,
26
+ **ws_kwargs: Any,
24
27
  ) -> None:
25
28
  """Инициализирует унифицированный менеджер вебсокетов.
26
29
 
27
30
  Параметры:
28
31
  client (`Client | UniClient | None`): Клиент Bybit или унифицированный клиент. Нужен для подключения к приватным топикам.
29
32
  logger (`LoggerLike | None`): Логгер для записи логов.
33
+ ws_kwargs (`dict[str, Any]`): Дополнительные параметры инициализации, которые будут переданы WebsocketManager/Websocket.
30
34
  """
31
35
  super().__init__(client=client, logger=logger)
32
- self._websocket_manager = WebsocketManager(self._client) # type: ignore
36
+ self._websocket_manager = WebsocketManager(self._client, **ws_kwargs) # type: ignore
33
37
  self._adapter = Adapter()
34
38
 
35
39
  @overload
@@ -207,7 +211,7 @@ class UniWebsocketManager(IUniWebsocketManager):
207
211
  Возвращает:
208
212
  `Websocket`: Экземпляр вебсокета.
209
213
  """
210
- raise NotImplementedError()
214
+ return self.trades(callback=callback, symbol=symbol, symbols=symbols) # type: ignore
211
215
 
212
216
  @overload
213
217
  def futures_trades(
@@ -288,4 +292,29 @@ class UniWebsocketManager(IUniWebsocketManager):
288
292
  Возвращает:
289
293
  `Websocket`: Экземпляр вебсокета.
290
294
  """
291
- raise NotImplementedError()
295
+ return self.futures_trades(callback=callback, symbol=symbol, symbols=symbols) # type: ignore
296
+
297
+ def liquidations(
298
+ self,
299
+ callback: CallbackType,
300
+ symbol: str | None = None,
301
+ symbols: Sequence[str] | None = None,
302
+ ) -> Websocket:
303
+ """Открывает стрим ликвидаций (futures) с унификацией сообщений.
304
+
305
+ Параметры:
306
+ callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
307
+ symbol (`str | None`): Один символ для подписки.
308
+ symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
309
+
310
+ Должен быть указан либо `symbol`, либо `symbols`.
311
+
312
+ Возвращает:
313
+ `Websocket`: Экземпляр вебсокета.
314
+ """
315
+ return self._websocket_manager.all_liquidation(
316
+ callback=self._make_wrapper(self._adapter.liquidations_message, callback),
317
+ category="linear",
318
+ symbol=symbol,
319
+ symbols=symbols,
320
+ )
@@ -6,6 +6,7 @@ from collections.abc import Awaitable, Callable, Sequence
6
6
  from typing import Any, Literal
7
7
 
8
8
  from unicex._base import Websocket
9
+ from unicex.utils import validate_single_symbol_args
9
10
 
10
11
  from .client import Client
11
12
 
@@ -108,10 +109,7 @@ class WebsocketManager:
108
109
  Возвращает:
109
110
  `Websocket`: Объект для управления вебсокет соединением.
110
111
  """
111
- if symbol and symbols:
112
- raise ValueError("Parameters symbol and symbols cannot be used together")
113
- if not (symbol or symbols):
114
- raise ValueError("Either symbol or symbols must be provided")
112
+ validate_single_symbol_args(symbol, symbols)
115
113
 
116
114
  tickers = [symbol] if symbol else symbols
117
115
  topics = [f"orderbook.{depth}.{ticker.upper()}" for ticker in tickers] # type: ignore
@@ -152,10 +150,7 @@ class WebsocketManager:
152
150
  Возвращает:
153
151
  `Websocket`: Объект для управления вебсокет соединением.
154
152
  """
155
- if symbol and symbols:
156
- raise ValueError("Parameters symbol and symbols cannot be used together")
157
- if not (symbol or symbols):
158
- raise ValueError("Either symbol or symbols must be provided")
153
+ validate_single_symbol_args(symbol, symbols)
159
154
 
160
155
  tickers = [symbol] if symbol else symbols
161
156
  topics = [f"kline.{interval}.{ticker.upper()}" for ticker in tickers] # type: ignore
@@ -192,10 +187,7 @@ class WebsocketManager:
192
187
  Возвращает:
193
188
  `Websocket`: Объект для управления вебсокет соединением.
194
189
  """
195
- if symbol and symbols:
196
- raise ValueError("Parameters symbol and symbols cannot be used together")
197
- if not (symbol or symbols):
198
- raise ValueError("Either symbol or symbols must be provided")
190
+ validate_single_symbol_args(symbol, symbols)
199
191
 
200
192
  tickers = [symbol] if symbol else symbols
201
193
  topics = [f"publicTrade.{ticker.upper()}" for ticker in tickers] # type: ignore
@@ -232,10 +224,7 @@ class WebsocketManager:
232
224
  Возвращает:
233
225
  `Websocket`: Объект для управления вебсокет соединением.
234
226
  """
235
- if symbol and symbols:
236
- raise ValueError("Parameters symbol and symbols cannot be used together")
237
- if not (symbol or symbols):
238
- raise ValueError("Either symbol or symbols must be provided")
227
+ validate_single_symbol_args(symbol, symbols)
239
228
 
240
229
  tickers = [symbol] if symbol else symbols
241
230
  topics = [f"tickers.{ticker.upper()}" for ticker in tickers] # type: ignore
@@ -280,10 +269,7 @@ class WebsocketManager:
280
269
  stacklevel=2,
281
270
  )
282
271
 
283
- if symbol and symbols:
284
- raise ValueError("Parameters symbol and symbols cannot be used together")
285
- if not (symbol or symbols):
286
- raise ValueError("Either symbol or symbols must be provided")
272
+ validate_single_symbol_args(symbol, symbols)
287
273
 
288
274
  tickers = [symbol] if symbol else symbols
289
275
  topics = [f"liquidation.{ticker.upper()}" for ticker in tickers] # type: ignore
@@ -320,10 +306,7 @@ class WebsocketManager:
320
306
  Возвращает:
321
307
  `Websocket`: Объект для управления вебсокет соединением.
322
308
  """
323
- if symbol and symbols:
324
- raise ValueError("Parameters symbol and symbols cannot be used together")
325
- if not (symbol or symbols):
326
- raise ValueError("Either symbol or symbols must be provided")
309
+ validate_single_symbol_args(symbol, symbols)
327
310
 
328
311
  tickers = [symbol] if symbol else symbols
329
312
  topics = [f"allLiquidation.{ticker.upper()}" for ticker in tickers] # type: ignore
@@ -335,5 +318,6 @@ class WebsocketManager:
335
318
  callback=callback,
336
319
  url=url,
337
320
  subscription_messages=subscription_messages,
321
+ no_message_reconnect_timeout=60 * 10,
338
322
  **self._ws_kwargs,
339
323
  )
unicex/enums.py CHANGED
@@ -26,14 +26,13 @@ class Exchange(StrEnum):
26
26
 
27
27
  BINANCE = "BINANCE"
28
28
  BITGET = "BITGET"
29
- BITUNIX = "BITUNIX"
30
29
  BYBIT = "BYBIT"
31
30
  GATE = "GATE"
32
31
  HYPERLIQUID = "HYPERLIQUID"
33
- KCEX = "KCEX"
34
32
  MEXC = "MEXC"
35
33
  OKX = "OKX"
36
- XT = "XT"
34
+ KUCOIN = "KUCOIN"
35
+ BINGX = "BINGX"
37
36
 
38
37
  def __add__(self, market_type: "MarketType") -> tuple["Exchange", "MarketType"]:
39
38
  """Возвращает кортеж из биржи и типа рынка."""
@@ -178,6 +177,23 @@ class Timeframe(StrEnum):
178
177
  Timeframe.WEEK_1: "Week1",
179
178
  Timeframe.MONTH_1: "Month1",
180
179
  },
180
+ Exchange.KUCOIN: {
181
+ Timeframe.MIN_1: "1min",
182
+ Timeframe.MIN_3: "3min",
183
+ Timeframe.MIN_5: "5min",
184
+ Timeframe.MIN_15: "15min",
185
+ Timeframe.MIN_30: "30min",
186
+ Timeframe.HOUR_1: "1hour",
187
+ Timeframe.HOUR_2: "2hour",
188
+ Timeframe.HOUR_4: "4hour",
189
+ Timeframe.HOUR_6: "6hour",
190
+ Timeframe.HOUR_8: "8hour",
191
+ Timeframe.HOUR_12: "12hour",
192
+ Timeframe.DAY_1: "1day",
193
+ Timeframe.DAY_3: "3day",
194
+ Timeframe.WEEK_1: "1week",
195
+ Timeframe.MONTH_1: "1month",
196
+ },
181
197
  Exchange.OKX: {
182
198
  Timeframe.MIN_1: "1m",
183
199
  Timeframe.MIN_3: "3m",