unicex 0.13.17__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.
- unicex/__init__.py +200 -0
- unicex/_abc/__init__.py +11 -0
- unicex/_abc/exchange_info.py +216 -0
- unicex/_abc/uni_client.py +329 -0
- unicex/_abc/uni_websocket_manager.py +294 -0
- unicex/_base/__init__.py +9 -0
- unicex/_base/client.py +214 -0
- unicex/_base/websocket.py +261 -0
- unicex/binance/__init__.py +27 -0
- unicex/binance/adapter.py +202 -0
- unicex/binance/client.py +1577 -0
- unicex/binance/exchange_info.py +62 -0
- unicex/binance/uni_client.py +188 -0
- unicex/binance/uni_websocket_manager.py +166 -0
- unicex/binance/user_websocket.py +186 -0
- unicex/binance/websocket_manager.py +912 -0
- unicex/bitget/__init__.py +27 -0
- unicex/bitget/adapter.py +188 -0
- unicex/bitget/client.py +2514 -0
- unicex/bitget/exchange_info.py +48 -0
- unicex/bitget/uni_client.py +198 -0
- unicex/bitget/uni_websocket_manager.py +275 -0
- unicex/bitget/user_websocket.py +7 -0
- unicex/bitget/websocket_manager.py +232 -0
- unicex/bybit/__init__.py +27 -0
- unicex/bybit/adapter.py +208 -0
- unicex/bybit/client.py +1876 -0
- unicex/bybit/exchange_info.py +53 -0
- unicex/bybit/uni_client.py +200 -0
- unicex/bybit/uni_websocket_manager.py +291 -0
- unicex/bybit/user_websocket.py +7 -0
- unicex/bybit/websocket_manager.py +339 -0
- unicex/enums.py +273 -0
- unicex/exceptions.py +64 -0
- unicex/extra.py +335 -0
- unicex/gate/__init__.py +27 -0
- unicex/gate/adapter.py +178 -0
- unicex/gate/client.py +1667 -0
- unicex/gate/exchange_info.py +55 -0
- unicex/gate/uni_client.py +214 -0
- unicex/gate/uni_websocket_manager.py +269 -0
- unicex/gate/user_websocket.py +7 -0
- unicex/gate/websocket_manager.py +513 -0
- unicex/hyperliquid/__init__.py +27 -0
- unicex/hyperliquid/adapter.py +261 -0
- unicex/hyperliquid/client.py +2315 -0
- unicex/hyperliquid/exchange_info.py +119 -0
- unicex/hyperliquid/uni_client.py +325 -0
- unicex/hyperliquid/uni_websocket_manager.py +269 -0
- unicex/hyperliquid/user_websocket.py +7 -0
- unicex/hyperliquid/websocket_manager.py +393 -0
- unicex/mapper.py +111 -0
- unicex/mexc/__init__.py +27 -0
- unicex/mexc/_spot_ws_proto/PrivateAccountV3Api_pb2.py +38 -0
- unicex/mexc/_spot_ws_proto/PrivateDealsV3Api_pb2.py +38 -0
- unicex/mexc/_spot_ws_proto/PrivateOrdersV3Api_pb2.py +38 -0
- unicex/mexc/_spot_ws_proto/PublicAggreBookTickerV3Api_pb2.py +38 -0
- unicex/mexc/_spot_ws_proto/PublicAggreDealsV3Api_pb2.py +40 -0
- unicex/mexc/_spot_ws_proto/PublicAggreDepthsV3Api_pb2.py +40 -0
- unicex/mexc/_spot_ws_proto/PublicBookTickerBatchV3Api_pb2.py +38 -0
- unicex/mexc/_spot_ws_proto/PublicBookTickerV3Api_pb2.py +38 -0
- unicex/mexc/_spot_ws_proto/PublicDealsV3Api_pb2.py +40 -0
- unicex/mexc/_spot_ws_proto/PublicFuture_pb2.py +103 -0
- unicex/mexc/_spot_ws_proto/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
- unicex/mexc/_spot_ws_proto/PublicIncreaseDepthsV3Api_pb2.py +40 -0
- unicex/mexc/_spot_ws_proto/PublicLimitDepthsV3Api_pb2.py +40 -0
- unicex/mexc/_spot_ws_proto/PublicMiniTickerV3Api_pb2.py +38 -0
- unicex/mexc/_spot_ws_proto/PublicMiniTickersV3Api_pb2.py +38 -0
- unicex/mexc/_spot_ws_proto/PublicSpotKlineV3Api_pb2.py +38 -0
- unicex/mexc/_spot_ws_proto/PushDataV3ApiWrapper_pb2.py +38 -0
- unicex/mexc/_spot_ws_proto/__init__.py +335 -0
- unicex/mexc/adapter.py +239 -0
- unicex/mexc/client.py +846 -0
- unicex/mexc/exchange_info.py +47 -0
- unicex/mexc/uni_client.py +211 -0
- unicex/mexc/uni_websocket_manager.py +269 -0
- unicex/mexc/user_websocket.py +7 -0
- unicex/mexc/websocket_manager.py +456 -0
- unicex/okx/__init__.py +27 -0
- unicex/okx/adapter.py +150 -0
- unicex/okx/client.py +2864 -0
- unicex/okx/exchange_info.py +47 -0
- unicex/okx/uni_client.py +202 -0
- unicex/okx/uni_websocket_manager.py +269 -0
- unicex/okx/user_websocket.py +7 -0
- unicex/okx/websocket_manager.py +743 -0
- unicex/types.py +164 -0
- unicex/utils.py +218 -0
- unicex-0.13.17.dist-info/METADATA +243 -0
- unicex-0.13.17.dist-info/RECORD +93 -0
- unicex-0.13.17.dist-info/WHEEL +5 -0
- unicex-0.13.17.dist-info/licenses/LICENSE +28 -0
- unicex-0.13.17.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
__all__ = ["IUniClient"]
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from typing import Generic, Self, TypeVar, overload
|
|
5
|
+
|
|
6
|
+
import aiohttp
|
|
7
|
+
|
|
8
|
+
from unicex._base import BaseClient
|
|
9
|
+
from unicex.enums import Timeframe
|
|
10
|
+
from unicex.types import KlineDict, LoggerLike, OpenInterestDict, OpenInterestItem, TickerDailyDict
|
|
11
|
+
from unicex.utils import batched_list
|
|
12
|
+
|
|
13
|
+
TClient = TypeVar("TClient", bound="BaseClient")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class IUniClient(ABC, Generic[TClient]):
|
|
17
|
+
"""Интерфейс для реализации асинхронного унифицированного клиента."""
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
session: aiohttp.ClientSession,
|
|
22
|
+
api_key: str | None = None,
|
|
23
|
+
api_secret: str | None = None,
|
|
24
|
+
api_passphrase: str | None = None,
|
|
25
|
+
logger: LoggerLike | None = None,
|
|
26
|
+
max_retries: int = 3,
|
|
27
|
+
retry_delay: int | float = 0.1,
|
|
28
|
+
proxies: list[str] | None = None,
|
|
29
|
+
timeout: int = 10,
|
|
30
|
+
) -> None:
|
|
31
|
+
"""Инициализация клиента.
|
|
32
|
+
|
|
33
|
+
Параметры:
|
|
34
|
+
api_key (`str | None`): Ключ API для аутентификации.
|
|
35
|
+
api_secret (`str | None`): Секретный ключ API для аутентификации.
|
|
36
|
+
api_passphrase (`str | None`): Пароль API для аутентификации (Bitget).
|
|
37
|
+
session (`aiohttp.ClientSession`): Сессия для выполнения HTTP-запросов.
|
|
38
|
+
logger (`LoggerLike | None`): Логгер для вывода информации.
|
|
39
|
+
max_retries (`int`): Максимальное количество повторных попыток запроса.
|
|
40
|
+
retry_delay (`int | float`): Задержка между повторными попытками.
|
|
41
|
+
proxies (`list[str] | None`): Список HTTP(S) прокси для циклического использования.
|
|
42
|
+
timeout (`int`): Максимальное время ожидания ответа от сервера.
|
|
43
|
+
"""
|
|
44
|
+
self._client: TClient = self._client_cls(
|
|
45
|
+
api_key=api_key,
|
|
46
|
+
api_secret=api_secret,
|
|
47
|
+
api_passphrase=api_passphrase,
|
|
48
|
+
session=session,
|
|
49
|
+
logger=logger,
|
|
50
|
+
max_retries=max_retries,
|
|
51
|
+
retry_delay=retry_delay,
|
|
52
|
+
proxies=proxies,
|
|
53
|
+
timeout=timeout,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
async def create(
|
|
58
|
+
cls,
|
|
59
|
+
api_key: str | None = None,
|
|
60
|
+
api_secret: str | None = None,
|
|
61
|
+
api_passphrase: str | None = None,
|
|
62
|
+
session: aiohttp.ClientSession | None = None,
|
|
63
|
+
logger: LoggerLike | None = None,
|
|
64
|
+
max_retries: int = 3,
|
|
65
|
+
retry_delay: int | float = 0.1,
|
|
66
|
+
proxies: list[str] | None = None,
|
|
67
|
+
timeout: int = 10,
|
|
68
|
+
) -> Self:
|
|
69
|
+
"""Создает инстанцию клиента.
|
|
70
|
+
Создать клиент можно и через __init__, но в таком случае session: `aiohttp.ClientSession` - обязательный параметр.
|
|
71
|
+
|
|
72
|
+
Параметры:
|
|
73
|
+
api_key (`str | None`): Ключ API для аутентификации.
|
|
74
|
+
api_secret (`str | None`): Секретный ключ API для аутентификации.
|
|
75
|
+
api_passphrase (`str | None`): Пароль API для аутентификации (Bitget).
|
|
76
|
+
session (`aiohttp.ClientSession | None`): Сессия для выполнения HTTP-запросов.
|
|
77
|
+
logger (`LoggerLike | None`): Логгер для вывода информации.
|
|
78
|
+
max_retries (`int`): Максимальное количество повторных попыток запроса.
|
|
79
|
+
retry_delay (`int | float`): Задержка между повторными попытками.
|
|
80
|
+
proxies (`list[str] | None`): Список HTTP(S) прокси для циклического использования.
|
|
81
|
+
timeout (`int`): Максимальное время ожидания ответа от сервера.
|
|
82
|
+
|
|
83
|
+
Возвращает:
|
|
84
|
+
`IUniClient`: Созданный экземпляр клиента.
|
|
85
|
+
"""
|
|
86
|
+
return cls(
|
|
87
|
+
session=session or aiohttp.ClientSession(),
|
|
88
|
+
api_key=api_key,
|
|
89
|
+
api_secret=api_secret,
|
|
90
|
+
api_passphrase=api_passphrase,
|
|
91
|
+
logger=logger,
|
|
92
|
+
max_retries=max_retries,
|
|
93
|
+
retry_delay=retry_delay,
|
|
94
|
+
proxies=proxies,
|
|
95
|
+
timeout=timeout,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
@classmethod
|
|
99
|
+
def from_client(cls, client: TClient) -> Self:
|
|
100
|
+
"""Создает UniClient из уже существующего Client.
|
|
101
|
+
|
|
102
|
+
Параметры:
|
|
103
|
+
client (`TClient`): Экземпляр Client.
|
|
104
|
+
|
|
105
|
+
Возвращает:
|
|
106
|
+
`Self`: Созданный экземпляр клиента.
|
|
107
|
+
"""
|
|
108
|
+
instance = cls.__new__(cls) # создаем пустой объект без вызова __init__
|
|
109
|
+
instance._client = client
|
|
110
|
+
return instance
|
|
111
|
+
|
|
112
|
+
def is_authorized(self) -> bool:
|
|
113
|
+
"""Проверяет, наличие апи ключей в инстансе клиента.
|
|
114
|
+
|
|
115
|
+
Возвращает:
|
|
116
|
+
`bool`: True, если апи ключи присутствуют, иначе False.
|
|
117
|
+
"""
|
|
118
|
+
return self._client.is_authorized()
|
|
119
|
+
|
|
120
|
+
async def close_connection(self) -> None:
|
|
121
|
+
"""Закрывает сессию клиента."""
|
|
122
|
+
await self._client.close_connection()
|
|
123
|
+
|
|
124
|
+
async def __aenter__(self) -> Self:
|
|
125
|
+
"""Вход в асинхронный контекст."""
|
|
126
|
+
return self
|
|
127
|
+
|
|
128
|
+
async def __aexit__(self, *_) -> None:
|
|
129
|
+
"""Выход из асинхронного контекста."""
|
|
130
|
+
await self.close_connection()
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def client(self) -> TClient:
|
|
134
|
+
"""Возвращает клиент биржи.
|
|
135
|
+
|
|
136
|
+
Возвращает:
|
|
137
|
+
`TClient`: Клиент биржи.
|
|
138
|
+
"""
|
|
139
|
+
return self._client
|
|
140
|
+
|
|
141
|
+
@property
|
|
142
|
+
@abstractmethod
|
|
143
|
+
def _client_cls(self) -> type[TClient]:
|
|
144
|
+
"""Возвращает класс клиента для конкретной биржи.
|
|
145
|
+
|
|
146
|
+
Возвращает:
|
|
147
|
+
`type[TClient]`: Класс клиента.
|
|
148
|
+
"""
|
|
149
|
+
...
|
|
150
|
+
|
|
151
|
+
@abstractmethod
|
|
152
|
+
async def tickers(self, only_usdt: bool = True) -> list[str]:
|
|
153
|
+
"""Возвращает список тикеров.
|
|
154
|
+
|
|
155
|
+
Параметры:
|
|
156
|
+
only_usdt (`bool`): Если True, возвращает только тикеры в паре к USDT.
|
|
157
|
+
|
|
158
|
+
Возвращает:
|
|
159
|
+
`list[str]`: Список тикеров.
|
|
160
|
+
"""
|
|
161
|
+
...
|
|
162
|
+
|
|
163
|
+
async def tickers_batched(
|
|
164
|
+
self, only_usdt: bool = True, batch_size: int = 20
|
|
165
|
+
) -> list[list[str]]:
|
|
166
|
+
"""Возвращает список тикеров в чанках.
|
|
167
|
+
|
|
168
|
+
Параметры:
|
|
169
|
+
only_usdt (`bool`): Если True, возвращает только тикеры в паре к USDT.
|
|
170
|
+
batch_size (`int`): Размер чанка.
|
|
171
|
+
|
|
172
|
+
Возвращает:
|
|
173
|
+
`list[list[str]]`: Список тикеров в чанках.
|
|
174
|
+
"""
|
|
175
|
+
tickers = await self.tickers(only_usdt)
|
|
176
|
+
return batched_list(tickers, batch_size)
|
|
177
|
+
|
|
178
|
+
@abstractmethod
|
|
179
|
+
async def futures_tickers(self, only_usdt: bool = True) -> list[str]:
|
|
180
|
+
"""Возвращает список тикеров.
|
|
181
|
+
|
|
182
|
+
Параметры:
|
|
183
|
+
only_usdt (`bool`): Если True, возвращает только тикеры в паре к USDT.
|
|
184
|
+
|
|
185
|
+
Возвращает:
|
|
186
|
+
`list[str]`: Список тикеров.
|
|
187
|
+
"""
|
|
188
|
+
...
|
|
189
|
+
|
|
190
|
+
async def futures_tickers_batched(
|
|
191
|
+
self, only_usdt: bool = True, batch_size: int = 20
|
|
192
|
+
) -> list[list[str]]:
|
|
193
|
+
"""Возвращает список тикеров в чанках.
|
|
194
|
+
|
|
195
|
+
Параметры:
|
|
196
|
+
only_usdt (`bool`): Если True, возвращает только тикеры в паре к USDT.
|
|
197
|
+
batch_size (`int`): Размер чанка.
|
|
198
|
+
|
|
199
|
+
Возвращает:
|
|
200
|
+
`list[list[str]]`: Список тикеров в чанках.
|
|
201
|
+
"""
|
|
202
|
+
tickers = await self.futures_tickers(only_usdt)
|
|
203
|
+
return batched_list(tickers, batch_size)
|
|
204
|
+
|
|
205
|
+
@abstractmethod
|
|
206
|
+
async def last_price(self) -> dict[str, float]:
|
|
207
|
+
"""Возвращает последнюю цену для каждого тикера.
|
|
208
|
+
|
|
209
|
+
Возвращает:
|
|
210
|
+
`dict[str, float]`: Словарь с последними ценами для каждого тикера.
|
|
211
|
+
"""
|
|
212
|
+
...
|
|
213
|
+
|
|
214
|
+
@abstractmethod
|
|
215
|
+
async def futures_last_price(self) -> dict[str, float]:
|
|
216
|
+
"""Возвращает последнюю цену для каждого тикера.
|
|
217
|
+
|
|
218
|
+
Возвращает:
|
|
219
|
+
`dict[str, float]`: Словарь с последними ценами для каждого тикера.
|
|
220
|
+
"""
|
|
221
|
+
...
|
|
222
|
+
|
|
223
|
+
@abstractmethod
|
|
224
|
+
async def ticker_24hr(self) -> TickerDailyDict:
|
|
225
|
+
"""Возвращает статистику за последние 24 часа для каждого тикера.
|
|
226
|
+
|
|
227
|
+
Возвращает:
|
|
228
|
+
`TickerDailyDict`: Словарь с статистикой за последние 24 часа для каждого тикера.
|
|
229
|
+
"""
|
|
230
|
+
...
|
|
231
|
+
|
|
232
|
+
@abstractmethod
|
|
233
|
+
async def futures_ticker_24hr(self) -> TickerDailyDict:
|
|
234
|
+
"""Возвращает статистику за последние 24 часа для каждого тикера.
|
|
235
|
+
|
|
236
|
+
Возвращает:
|
|
237
|
+
`TickerDailyDict`: Словарь с статистикой за последние 24 часа для каждого тикера.
|
|
238
|
+
"""
|
|
239
|
+
...
|
|
240
|
+
|
|
241
|
+
@abstractmethod
|
|
242
|
+
async def klines(
|
|
243
|
+
self,
|
|
244
|
+
symbol: str,
|
|
245
|
+
interval: Timeframe | str,
|
|
246
|
+
limit: int | None = None,
|
|
247
|
+
start_time: int | None = None,
|
|
248
|
+
end_time: int | None = None,
|
|
249
|
+
) -> list[KlineDict]:
|
|
250
|
+
"""Возвращает список свечей.
|
|
251
|
+
|
|
252
|
+
Параметры:
|
|
253
|
+
symbol (`str`): Название тикера.
|
|
254
|
+
interval (`Timeframe`): Таймфрейм свечей.
|
|
255
|
+
limit (`int`): Количество свечей.
|
|
256
|
+
start_time (`int`): Время начала периода в миллисекундах.
|
|
257
|
+
end_time (`int`): Время окончания периода в миллисекундах.
|
|
258
|
+
|
|
259
|
+
Возвращает:
|
|
260
|
+
`list[KlineDict]`: Список свечей.
|
|
261
|
+
"""
|
|
262
|
+
...
|
|
263
|
+
|
|
264
|
+
@abstractmethod
|
|
265
|
+
async def futures_klines(
|
|
266
|
+
self,
|
|
267
|
+
symbol: str,
|
|
268
|
+
interval: Timeframe | str,
|
|
269
|
+
limit: int | None = None,
|
|
270
|
+
start_time: int | None = None,
|
|
271
|
+
end_time: int | None = None,
|
|
272
|
+
) -> list[KlineDict]:
|
|
273
|
+
"""Возвращает список свечей.
|
|
274
|
+
|
|
275
|
+
Параметры:
|
|
276
|
+
symbol (`str`): Название тикера.
|
|
277
|
+
interval (`Timeframe`): Таймфрейм свечей.
|
|
278
|
+
limit (`int`): Количество свечей.
|
|
279
|
+
start_time (`int`): Время начала периода в миллисекундах.
|
|
280
|
+
end_time (`int`): Время окончания периода в миллисекундах.
|
|
281
|
+
|
|
282
|
+
Возвращает:
|
|
283
|
+
`list[KlineDict]`: Список свечей.
|
|
284
|
+
"""
|
|
285
|
+
...
|
|
286
|
+
|
|
287
|
+
@overload
|
|
288
|
+
async def funding_rate(self, symbol: str) -> float: ...
|
|
289
|
+
|
|
290
|
+
@overload
|
|
291
|
+
async def funding_rate(self, symbol: None) -> dict[str, float]: ...
|
|
292
|
+
|
|
293
|
+
@overload
|
|
294
|
+
async def funding_rate(self) -> dict[str, float]: ...
|
|
295
|
+
|
|
296
|
+
@abstractmethod
|
|
297
|
+
async def funding_rate(self, symbol: str | None = None) -> dict[str, float] | float:
|
|
298
|
+
"""Возвращает ставку финансирования для тикера или всех тикеров, если тикер не указан.
|
|
299
|
+
|
|
300
|
+
Параметры:
|
|
301
|
+
symbol (`str | None`): Название тикера (Опционально).
|
|
302
|
+
|
|
303
|
+
Возвращает:
|
|
304
|
+
`dict[str, float] | float`: Ставка финансирования для тикера или словарь со ставками для всех тикеров.
|
|
305
|
+
"""
|
|
306
|
+
...
|
|
307
|
+
|
|
308
|
+
@overload
|
|
309
|
+
async def open_interest(self, symbol: str) -> OpenInterestItem: ...
|
|
310
|
+
|
|
311
|
+
@overload
|
|
312
|
+
async def open_interest(self, symbol: None) -> OpenInterestDict: ...
|
|
313
|
+
|
|
314
|
+
@overload
|
|
315
|
+
async def open_interest(self) -> OpenInterestDict: ...
|
|
316
|
+
|
|
317
|
+
@abstractmethod
|
|
318
|
+
async def open_interest(self, symbol: str | None = None) -> OpenInterestItem | OpenInterestDict:
|
|
319
|
+
"""Возвращает объем открытого интереса для тикера или всех тикеров, если тикер не указан.
|
|
320
|
+
|
|
321
|
+
Параметры:
|
|
322
|
+
symbol (`str | None`): Название тикера (Опционально, но обязателен для следующих бирж: BINANCE).
|
|
323
|
+
|
|
324
|
+
Возвращает:
|
|
325
|
+
`OpenInterestItem | OpenInterestDict`: Если тикер передан - словарь со временем и объемом
|
|
326
|
+
открытого интереса в монетах. Если нет передан - то словарь, в котором ключ - тикер,
|
|
327
|
+
а значение - словарь с временем и объемом открытого интереса в монетах.
|
|
328
|
+
"""
|
|
329
|
+
...
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
__all__ = ["IUniWebsocketManager"]
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from collections.abc import Awaitable, Callable, Sequence
|
|
5
|
+
from typing import Any, overload
|
|
6
|
+
|
|
7
|
+
from loguru import logger as _logger
|
|
8
|
+
|
|
9
|
+
from unicex._base import BaseClient, Websocket
|
|
10
|
+
from unicex.enums import Timeframe
|
|
11
|
+
from unicex.types import LoggerLike
|
|
12
|
+
|
|
13
|
+
from .uni_client import IUniClient
|
|
14
|
+
|
|
15
|
+
type CallbackType = Callable[[Any], Awaitable[None]]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class IUniWebsocketManager(ABC):
|
|
19
|
+
"""Интерфейс менеджера асинхронных унифицированных вебсокетов."""
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self, client: BaseClient | IUniClient | None = None, logger: LoggerLike | None = None
|
|
23
|
+
) -> None:
|
|
24
|
+
"""Инициализирует унифицированный менеджер вебсокетов.
|
|
25
|
+
|
|
26
|
+
Параметры:
|
|
27
|
+
client (`BaseClient | IUniClient | None`): Клиент или унифицированный клиент. Нужен для подключения к приватным топикам.
|
|
28
|
+
logger (`LoggerLike | None`): Логгер для записи логов.
|
|
29
|
+
"""
|
|
30
|
+
if isinstance(client, IUniClient):
|
|
31
|
+
client = client.client
|
|
32
|
+
self._client = client
|
|
33
|
+
self._logger = logger or _logger
|
|
34
|
+
|
|
35
|
+
def _make_wrapper(
|
|
36
|
+
self, adapter_func: Callable[[dict], Any], callback: CallbackType
|
|
37
|
+
) -> CallbackType:
|
|
38
|
+
"""Создает обертку над callback, применяя адаптер к сырым сообщениям."""
|
|
39
|
+
|
|
40
|
+
async def _wrapper(raw_msg: dict) -> None:
|
|
41
|
+
try:
|
|
42
|
+
adapted = adapter_func(raw_msg)
|
|
43
|
+
except Exception as e:
|
|
44
|
+
self._logger.warning(f"Failed to adapt message: {e}")
|
|
45
|
+
return
|
|
46
|
+
if isinstance(adapted, list):
|
|
47
|
+
for item in adapted:
|
|
48
|
+
await callback(item)
|
|
49
|
+
else:
|
|
50
|
+
await callback(adapted)
|
|
51
|
+
|
|
52
|
+
return _wrapper
|
|
53
|
+
|
|
54
|
+
@overload
|
|
55
|
+
def klines(
|
|
56
|
+
self,
|
|
57
|
+
callback: CallbackType,
|
|
58
|
+
timeframe: Timeframe,
|
|
59
|
+
*,
|
|
60
|
+
symbol: str,
|
|
61
|
+
symbols: None = None,
|
|
62
|
+
) -> Websocket: ...
|
|
63
|
+
|
|
64
|
+
@overload
|
|
65
|
+
def klines(
|
|
66
|
+
self,
|
|
67
|
+
callback: CallbackType,
|
|
68
|
+
timeframe: Timeframe,
|
|
69
|
+
*,
|
|
70
|
+
symbol: None = None,
|
|
71
|
+
symbols: Sequence[str],
|
|
72
|
+
) -> Websocket: ...
|
|
73
|
+
|
|
74
|
+
@abstractmethod
|
|
75
|
+
def klines(
|
|
76
|
+
self,
|
|
77
|
+
callback: CallbackType,
|
|
78
|
+
timeframe: Timeframe,
|
|
79
|
+
symbol: str | None = None,
|
|
80
|
+
symbols: Sequence[str] | None = None,
|
|
81
|
+
) -> Websocket:
|
|
82
|
+
"""Открывает стрим свечей (spot) с унификацией сообщений.
|
|
83
|
+
|
|
84
|
+
Параметры:
|
|
85
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
86
|
+
timeframe (`Timeframe`): Временной интервал свечей.
|
|
87
|
+
symbol (`str | None`): Один символ для подписки.
|
|
88
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
89
|
+
|
|
90
|
+
Должен быть указан либо `symbol`, либо `symbols`.
|
|
91
|
+
|
|
92
|
+
Возвращает:
|
|
93
|
+
`Websocket`: Экземпляр вебсокета для управления соединением.
|
|
94
|
+
"""
|
|
95
|
+
...
|
|
96
|
+
|
|
97
|
+
@overload
|
|
98
|
+
def futures_klines(
|
|
99
|
+
self,
|
|
100
|
+
callback: CallbackType,
|
|
101
|
+
timeframe: Timeframe,
|
|
102
|
+
*,
|
|
103
|
+
symbol: str,
|
|
104
|
+
symbols: None = None,
|
|
105
|
+
) -> Websocket: ...
|
|
106
|
+
|
|
107
|
+
@overload
|
|
108
|
+
def futures_klines(
|
|
109
|
+
self,
|
|
110
|
+
callback: CallbackType,
|
|
111
|
+
timeframe: Timeframe,
|
|
112
|
+
*,
|
|
113
|
+
symbol: None = None,
|
|
114
|
+
symbols: Sequence[str],
|
|
115
|
+
) -> Websocket: ...
|
|
116
|
+
|
|
117
|
+
@abstractmethod
|
|
118
|
+
def futures_klines(
|
|
119
|
+
self,
|
|
120
|
+
callback: CallbackType,
|
|
121
|
+
timeframe: Timeframe,
|
|
122
|
+
symbol: str | None = None,
|
|
123
|
+
symbols: Sequence[str] | None = None,
|
|
124
|
+
) -> Websocket:
|
|
125
|
+
"""Открывает стрим свечей (futures) с унификацией сообщений.
|
|
126
|
+
|
|
127
|
+
Параметры:
|
|
128
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
129
|
+
timeframe (`Timeframe`): Временной интервал свечей.
|
|
130
|
+
symbol (`str | None`): Один символ для подписки.
|
|
131
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
132
|
+
|
|
133
|
+
Должен быть указан либо `symbol`, либо `symbols`.
|
|
134
|
+
|
|
135
|
+
Возвращает:
|
|
136
|
+
`Websocket`: Экземпляр вебсокета.
|
|
137
|
+
"""
|
|
138
|
+
...
|
|
139
|
+
|
|
140
|
+
@overload
|
|
141
|
+
def trades(
|
|
142
|
+
self,
|
|
143
|
+
callback: CallbackType,
|
|
144
|
+
*,
|
|
145
|
+
symbol: str,
|
|
146
|
+
symbols: None = None,
|
|
147
|
+
) -> Websocket: ...
|
|
148
|
+
|
|
149
|
+
@overload
|
|
150
|
+
def trades(
|
|
151
|
+
self,
|
|
152
|
+
callback: CallbackType,
|
|
153
|
+
*,
|
|
154
|
+
symbol: None = None,
|
|
155
|
+
symbols: Sequence[str],
|
|
156
|
+
) -> Websocket: ...
|
|
157
|
+
|
|
158
|
+
@abstractmethod
|
|
159
|
+
def trades(
|
|
160
|
+
self,
|
|
161
|
+
callback: CallbackType,
|
|
162
|
+
symbol: str | None = None,
|
|
163
|
+
symbols: Sequence[str] | None = None,
|
|
164
|
+
) -> Websocket:
|
|
165
|
+
"""Открывает стрим сделок (spot) с унификацией сообщений.
|
|
166
|
+
|
|
167
|
+
Параметры:
|
|
168
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
169
|
+
symbol (`str | None`): Один символ для подписки.
|
|
170
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
171
|
+
|
|
172
|
+
Должен быть указан либо `symbol`, либо `symbols`.
|
|
173
|
+
|
|
174
|
+
Возвращает:
|
|
175
|
+
`Websocket`: Экземпляр вебсокета.
|
|
176
|
+
"""
|
|
177
|
+
...
|
|
178
|
+
|
|
179
|
+
@overload
|
|
180
|
+
def aggtrades(
|
|
181
|
+
self,
|
|
182
|
+
callback: CallbackType,
|
|
183
|
+
*,
|
|
184
|
+
symbol: str,
|
|
185
|
+
symbols: None = None,
|
|
186
|
+
) -> Websocket: ...
|
|
187
|
+
|
|
188
|
+
@overload
|
|
189
|
+
def aggtrades(
|
|
190
|
+
self,
|
|
191
|
+
callback: CallbackType,
|
|
192
|
+
*,
|
|
193
|
+
symbol: None = None,
|
|
194
|
+
symbols: Sequence[str],
|
|
195
|
+
) -> Websocket: ...
|
|
196
|
+
|
|
197
|
+
@abstractmethod
|
|
198
|
+
def aggtrades(
|
|
199
|
+
self,
|
|
200
|
+
callback: CallbackType,
|
|
201
|
+
symbol: str | None = None,
|
|
202
|
+
symbols: Sequence[str] | None = None,
|
|
203
|
+
) -> Websocket:
|
|
204
|
+
"""Открывает стрим агрегированных сделок (spot) с унификацией сообщений.
|
|
205
|
+
|
|
206
|
+
Параметры:
|
|
207
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
208
|
+
symbol (`str | None`): Один символ для подписки.
|
|
209
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
210
|
+
|
|
211
|
+
Должен быть указан либо `symbol`, либо `symbols`.
|
|
212
|
+
|
|
213
|
+
Возвращает:
|
|
214
|
+
`Websocket`: Экземпляр вебсокета.
|
|
215
|
+
"""
|
|
216
|
+
...
|
|
217
|
+
|
|
218
|
+
@overload
|
|
219
|
+
def futures_trades(
|
|
220
|
+
self,
|
|
221
|
+
callback: CallbackType,
|
|
222
|
+
*,
|
|
223
|
+
symbol: str,
|
|
224
|
+
symbols: None = None,
|
|
225
|
+
) -> Websocket: ...
|
|
226
|
+
|
|
227
|
+
@overload
|
|
228
|
+
def futures_trades(
|
|
229
|
+
self,
|
|
230
|
+
callback: CallbackType,
|
|
231
|
+
*,
|
|
232
|
+
symbol: None = None,
|
|
233
|
+
symbols: Sequence[str],
|
|
234
|
+
) -> Websocket: ...
|
|
235
|
+
|
|
236
|
+
@abstractmethod
|
|
237
|
+
def futures_trades(
|
|
238
|
+
self,
|
|
239
|
+
callback: CallbackType,
|
|
240
|
+
symbol: str | None = None,
|
|
241
|
+
symbols: Sequence[str] | None = None,
|
|
242
|
+
) -> Websocket:
|
|
243
|
+
"""Открывает стрим сделок (futures) с унификацией сообщений.
|
|
244
|
+
|
|
245
|
+
Параметры:
|
|
246
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
247
|
+
symbol (`str | None`): Один символ для подписки.
|
|
248
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
249
|
+
|
|
250
|
+
Должен быть указан либо `symbol`, либо `symbols`.
|
|
251
|
+
|
|
252
|
+
Возвращает:
|
|
253
|
+
`Websocket`: Экземпляр вебсокета.
|
|
254
|
+
"""
|
|
255
|
+
...
|
|
256
|
+
|
|
257
|
+
@overload
|
|
258
|
+
def futures_aggtrades(
|
|
259
|
+
self,
|
|
260
|
+
callback: CallbackType,
|
|
261
|
+
*,
|
|
262
|
+
symbol: str,
|
|
263
|
+
symbols: None = None,
|
|
264
|
+
) -> Websocket: ...
|
|
265
|
+
|
|
266
|
+
@overload
|
|
267
|
+
def futures_aggtrades(
|
|
268
|
+
self,
|
|
269
|
+
callback: CallbackType,
|
|
270
|
+
*,
|
|
271
|
+
symbol: None = None,
|
|
272
|
+
symbols: Sequence[str],
|
|
273
|
+
) -> Websocket: ...
|
|
274
|
+
|
|
275
|
+
@abstractmethod
|
|
276
|
+
def futures_aggtrades(
|
|
277
|
+
self,
|
|
278
|
+
callback: CallbackType,
|
|
279
|
+
symbol: str | None = None,
|
|
280
|
+
symbols: Sequence[str] | None = None,
|
|
281
|
+
) -> Websocket:
|
|
282
|
+
"""Открывает стрим агрегированных сделок (futures) с унификацией сообщений.
|
|
283
|
+
|
|
284
|
+
Параметры:
|
|
285
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
286
|
+
symbol (`str | None`): Один символ для подписки.
|
|
287
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
288
|
+
|
|
289
|
+
Должен быть указан либо `symbol`, либо `symbols`.
|
|
290
|
+
|
|
291
|
+
Возвращает:
|
|
292
|
+
`Websocket`: Экземпляр вебсокета.
|
|
293
|
+
"""
|
|
294
|
+
...
|