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.
- unicex/__init__.py +36 -2
- unicex/_abc/exchange_info.py +1 -1
- unicex/_abc/uni_client.py +31 -1
- unicex/_abc/uni_websocket_manager.py +1 -1
- unicex/_base/client.py +7 -0
- unicex/_base/websocket.py +31 -9
- unicex/binance/adapter.py +7 -16
- unicex/binance/client.py +25 -25
- unicex/binance/uni_websocket_manager.py +6 -2
- unicex/bingx/__init__.py +27 -0
- unicex/bingx/adapter.py +284 -0
- unicex/bingx/client.py +521 -0
- unicex/bingx/exchange_info.py +22 -0
- unicex/bingx/uni_client.py +191 -0
- unicex/bingx/uni_websocket_manager.py +283 -0
- unicex/bingx/user_websocket.py +7 -0
- unicex/bingx/websocket_manager.py +118 -0
- unicex/bitget/adapter.py +2 -2
- unicex/bitget/client.py +64 -64
- unicex/bitget/uni_websocket_manager.py +27 -6
- unicex/bitget/websocket_manager.py +2 -4
- unicex/bybit/adapter.py +1 -0
- unicex/bybit/client.py +4 -4
- unicex/bybit/exchange_info.py +1 -1
- unicex/bybit/uni_websocket_manager.py +33 -4
- unicex/bybit/websocket_manager.py +8 -24
- unicex/enums.py +19 -3
- unicex/extra.py +37 -35
- unicex/gate/adapter.py +113 -0
- unicex/gate/client.py +9 -9
- unicex/gate/uni_client.py +1 -3
- unicex/gate/uni_websocket_manager.py +47 -9
- unicex/hyperliquid/adapter.py +1 -0
- unicex/hyperliquid/client.py +12 -12
- unicex/hyperliquid/uni_client.py +4 -7
- unicex/hyperliquid/uni_websocket_manager.py +6 -2
- unicex/kucoin/__init__.py +27 -0
- unicex/kucoin/adapter.py +181 -0
- unicex/kucoin/client.py +135 -0
- unicex/kucoin/exchange_info.py +50 -0
- unicex/kucoin/uni_client.py +208 -0
- unicex/kucoin/uni_websocket_manager.py +273 -0
- unicex/kucoin/user_websocket.py +7 -0
- unicex/kucoin/websocket_manager.py +11 -0
- unicex/mapper.py +62 -21
- unicex/mexc/adapter.py +104 -0
- unicex/mexc/client.py +7 -7
- unicex/mexc/uni_client.py +1 -3
- unicex/mexc/uni_websocket_manager.py +31 -9
- unicex/mexc/websocket_manager.py +27 -6
- unicex/okx/adapter.py +51 -0
- unicex/okx/client.py +15 -15
- unicex/okx/exchange_info.py +2 -2
- unicex/okx/uni_websocket_manager.py +50 -9
- unicex/okx/websocket_manager.py +119 -166
- unicex/types.py +14 -10
- unicex/utils.py +44 -1
- {unicex-0.13.17.dist-info → unicex-0.16.5.dist-info}/METADATA +7 -5
- unicex-0.16.5.dist-info/RECORD +109 -0
- unicex-0.13.17.dist-info/RECORD +0 -93
- {unicex-0.13.17.dist-info → unicex-0.16.5.dist-info}/WHEEL +0 -0
- {unicex-0.13.17.dist-info → unicex-0.16.5.dist-info}/licenses/LICENSE +0 -0
- {unicex-0.13.17.dist-info → unicex-0.16.5.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
__all__ = ["IUniWebsocketManager"]
|
|
2
|
+
|
|
3
|
+
from collections.abc import Awaitable, Callable, Sequence
|
|
4
|
+
from typing import Any, overload
|
|
5
|
+
|
|
6
|
+
from unicex._abc import IUniWebsocketManager
|
|
7
|
+
from unicex._base import Websocket
|
|
8
|
+
from unicex.enums import Timeframe
|
|
9
|
+
from unicex.types import LoggerLike
|
|
10
|
+
|
|
11
|
+
from .adapter import Adapter
|
|
12
|
+
from .client import Client
|
|
13
|
+
from .uni_client import UniClient
|
|
14
|
+
from .websocket_manager import WebsocketManager
|
|
15
|
+
|
|
16
|
+
type CallbackType = Callable[[Any], Awaitable[None]]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class UniWebsocketManager(IUniWebsocketManager):
|
|
20
|
+
"""Реализация менеджера асинхронных унифицированных вебсокетов."""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
client: Client | UniClient | None = None,
|
|
25
|
+
logger: LoggerLike | None = None,
|
|
26
|
+
**ws_kwargs: Any,
|
|
27
|
+
) -> None:
|
|
28
|
+
"""Инициализирует унифицированный менеджер вебсокетов.
|
|
29
|
+
|
|
30
|
+
Параметры:
|
|
31
|
+
client (`Client | UniClient | None`): Клиент Kucoin или унифицированный клиент. Нужен для подключения к приватным топикам.
|
|
32
|
+
logger (`LoggerLike | None`): Логгер для записи логов.
|
|
33
|
+
ws_kwargs (`dict[str, Any]`): Дополнительные параметры инициализации, которые будут переданы WebsocketManager/Websocket.
|
|
34
|
+
"""
|
|
35
|
+
super().__init__(client=client, logger=logger)
|
|
36
|
+
self._websocket_manager = WebsocketManager(self._client, **ws_kwargs) # type: ignore
|
|
37
|
+
self._adapter = Adapter()
|
|
38
|
+
|
|
39
|
+
@overload
|
|
40
|
+
def klines(
|
|
41
|
+
self,
|
|
42
|
+
callback: CallbackType,
|
|
43
|
+
timeframe: Timeframe,
|
|
44
|
+
*,
|
|
45
|
+
symbol: str,
|
|
46
|
+
symbols: None = None,
|
|
47
|
+
) -> Websocket: ...
|
|
48
|
+
|
|
49
|
+
@overload
|
|
50
|
+
def klines(
|
|
51
|
+
self,
|
|
52
|
+
callback: CallbackType,
|
|
53
|
+
timeframe: Timeframe,
|
|
54
|
+
*,
|
|
55
|
+
symbol: None = None,
|
|
56
|
+
symbols: Sequence[str],
|
|
57
|
+
) -> Websocket: ...
|
|
58
|
+
|
|
59
|
+
def klines(
|
|
60
|
+
self,
|
|
61
|
+
callback: CallbackType,
|
|
62
|
+
timeframe: Timeframe,
|
|
63
|
+
symbol: str | None = None,
|
|
64
|
+
symbols: Sequence[str] | None = None,
|
|
65
|
+
) -> Websocket:
|
|
66
|
+
"""Открывает стрим свечей (spot) с унификацией сообщений.
|
|
67
|
+
|
|
68
|
+
Параметры:
|
|
69
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
70
|
+
timeframe (`Timeframe`): Временной интервал свечей.
|
|
71
|
+
symbol (`str | None`): Один символ для подписки.
|
|
72
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
73
|
+
|
|
74
|
+
Должен быть указан либо `symbol`, либо `symbols`.
|
|
75
|
+
|
|
76
|
+
Возвращает:
|
|
77
|
+
`Websocket`: Экземпляр вебсокета для управления соединением.
|
|
78
|
+
"""
|
|
79
|
+
raise NotImplementedError()
|
|
80
|
+
|
|
81
|
+
@overload
|
|
82
|
+
def futures_klines(
|
|
83
|
+
self,
|
|
84
|
+
callback: CallbackType,
|
|
85
|
+
timeframe: Timeframe,
|
|
86
|
+
*,
|
|
87
|
+
symbol: str,
|
|
88
|
+
symbols: None = None,
|
|
89
|
+
) -> Websocket: ...
|
|
90
|
+
|
|
91
|
+
@overload
|
|
92
|
+
def futures_klines(
|
|
93
|
+
self,
|
|
94
|
+
callback: CallbackType,
|
|
95
|
+
timeframe: Timeframe,
|
|
96
|
+
*,
|
|
97
|
+
symbol: None = None,
|
|
98
|
+
symbols: Sequence[str],
|
|
99
|
+
) -> Websocket: ...
|
|
100
|
+
|
|
101
|
+
def futures_klines(
|
|
102
|
+
self,
|
|
103
|
+
callback: CallbackType,
|
|
104
|
+
timeframe: Timeframe,
|
|
105
|
+
symbol: str | None = None,
|
|
106
|
+
symbols: Sequence[str] | None = None,
|
|
107
|
+
) -> Websocket:
|
|
108
|
+
"""Открывает стрим свечей (futures) с унификацией сообщений.
|
|
109
|
+
|
|
110
|
+
Параметры:
|
|
111
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
112
|
+
timeframe (`Timeframe`): Временной интервал свечей.
|
|
113
|
+
symbol (`str | None`): Один символ для подписки.
|
|
114
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
115
|
+
|
|
116
|
+
Должен быть указан либо `symbol`, либо `symbols`.
|
|
117
|
+
|
|
118
|
+
Возвращает:
|
|
119
|
+
`Websocket`: Экземпляр вебсокета.
|
|
120
|
+
"""
|
|
121
|
+
raise NotImplementedError()
|
|
122
|
+
|
|
123
|
+
@overload
|
|
124
|
+
def trades(
|
|
125
|
+
self,
|
|
126
|
+
callback: CallbackType,
|
|
127
|
+
*,
|
|
128
|
+
symbol: str,
|
|
129
|
+
symbols: None = None,
|
|
130
|
+
) -> Websocket: ...
|
|
131
|
+
|
|
132
|
+
@overload
|
|
133
|
+
def trades(
|
|
134
|
+
self,
|
|
135
|
+
callback: CallbackType,
|
|
136
|
+
*,
|
|
137
|
+
symbol: None = None,
|
|
138
|
+
symbols: Sequence[str],
|
|
139
|
+
) -> Websocket: ...
|
|
140
|
+
|
|
141
|
+
def trades(
|
|
142
|
+
self,
|
|
143
|
+
callback: CallbackType,
|
|
144
|
+
symbol: str | None = None,
|
|
145
|
+
symbols: Sequence[str] | None = None,
|
|
146
|
+
) -> Websocket:
|
|
147
|
+
"""Открывает стрим сделок (spot) с унификацией сообщений.
|
|
148
|
+
|
|
149
|
+
Параметры:
|
|
150
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
151
|
+
symbol (`str | None`): Один символ для подписки.
|
|
152
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
153
|
+
|
|
154
|
+
Должен быть указан либо `symbol`, либо `symbols`.
|
|
155
|
+
|
|
156
|
+
Возвращает:
|
|
157
|
+
`Websocket`: Экземпляр вебсокета.
|
|
158
|
+
"""
|
|
159
|
+
raise NotImplementedError()
|
|
160
|
+
|
|
161
|
+
@overload
|
|
162
|
+
def aggtrades(
|
|
163
|
+
self,
|
|
164
|
+
callback: CallbackType,
|
|
165
|
+
*,
|
|
166
|
+
symbol: str,
|
|
167
|
+
symbols: None = None,
|
|
168
|
+
) -> Websocket: ...
|
|
169
|
+
|
|
170
|
+
@overload
|
|
171
|
+
def aggtrades(
|
|
172
|
+
self,
|
|
173
|
+
callback: CallbackType,
|
|
174
|
+
*,
|
|
175
|
+
symbol: None = None,
|
|
176
|
+
symbols: Sequence[str],
|
|
177
|
+
) -> Websocket: ...
|
|
178
|
+
|
|
179
|
+
def aggtrades(
|
|
180
|
+
self,
|
|
181
|
+
callback: CallbackType,
|
|
182
|
+
symbol: str | None = None,
|
|
183
|
+
symbols: Sequence[str] | None = None,
|
|
184
|
+
) -> Websocket:
|
|
185
|
+
"""Открывает стрим агрегированных сделок (spot) с унификацией сообщений.
|
|
186
|
+
|
|
187
|
+
Параметры:
|
|
188
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
189
|
+
symbol (`str | None`): Один символ для подписки.
|
|
190
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
191
|
+
|
|
192
|
+
Должен быть указан либо `symbol`, либо `symbols`.
|
|
193
|
+
|
|
194
|
+
Возвращает:
|
|
195
|
+
`Websocket`: Экземпляр вебсокета.
|
|
196
|
+
"""
|
|
197
|
+
raise NotImplementedError()
|
|
198
|
+
|
|
199
|
+
@overload
|
|
200
|
+
def futures_trades(
|
|
201
|
+
self,
|
|
202
|
+
callback: CallbackType,
|
|
203
|
+
*,
|
|
204
|
+
symbol: str,
|
|
205
|
+
symbols: None = None,
|
|
206
|
+
) -> Websocket: ...
|
|
207
|
+
|
|
208
|
+
@overload
|
|
209
|
+
def futures_trades(
|
|
210
|
+
self,
|
|
211
|
+
callback: CallbackType,
|
|
212
|
+
*,
|
|
213
|
+
symbol: None = None,
|
|
214
|
+
symbols: Sequence[str],
|
|
215
|
+
) -> Websocket: ...
|
|
216
|
+
|
|
217
|
+
def futures_trades(
|
|
218
|
+
self,
|
|
219
|
+
callback: CallbackType,
|
|
220
|
+
symbol: str | None = None,
|
|
221
|
+
symbols: Sequence[str] | None = None,
|
|
222
|
+
) -> Websocket:
|
|
223
|
+
"""Открывает стрим сделок (futures) с унификацией сообщений.
|
|
224
|
+
|
|
225
|
+
Параметры:
|
|
226
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
227
|
+
symbol (`str | None`): Один символ для подписки.
|
|
228
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
229
|
+
|
|
230
|
+
Должен быть указан либо `symbol`, либо `symbols`.
|
|
231
|
+
|
|
232
|
+
Возвращает:
|
|
233
|
+
`Websocket`: Экземпляр вебсокета.
|
|
234
|
+
"""
|
|
235
|
+
raise NotImplementedError()
|
|
236
|
+
|
|
237
|
+
@overload
|
|
238
|
+
def futures_aggtrades(
|
|
239
|
+
self,
|
|
240
|
+
callback: CallbackType,
|
|
241
|
+
*,
|
|
242
|
+
symbol: str,
|
|
243
|
+
symbols: None = None,
|
|
244
|
+
) -> Websocket: ...
|
|
245
|
+
|
|
246
|
+
@overload
|
|
247
|
+
def futures_aggtrades(
|
|
248
|
+
self,
|
|
249
|
+
callback: CallbackType,
|
|
250
|
+
*,
|
|
251
|
+
symbol: None = None,
|
|
252
|
+
symbols: Sequence[str],
|
|
253
|
+
) -> Websocket: ...
|
|
254
|
+
|
|
255
|
+
def futures_aggtrades(
|
|
256
|
+
self,
|
|
257
|
+
callback: CallbackType,
|
|
258
|
+
symbol: str | None = None,
|
|
259
|
+
symbols: Sequence[str] | None = None,
|
|
260
|
+
) -> Websocket:
|
|
261
|
+
"""Открывает стрим агрегированных сделок (futures) с унификацией сообщений.
|
|
262
|
+
|
|
263
|
+
Параметры:
|
|
264
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
265
|
+
symbol (`str | None`): Один символ для подписки.
|
|
266
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
267
|
+
|
|
268
|
+
Должен быть указан либо `symbol`, либо `symbols`.
|
|
269
|
+
|
|
270
|
+
Возвращает:
|
|
271
|
+
`Websocket`: Экземпляр вебсокета.
|
|
272
|
+
"""
|
|
273
|
+
raise NotImplementedError()
|
unicex/mapper.py
CHANGED
|
@@ -6,31 +6,66 @@ __all__ = [
|
|
|
6
6
|
"get_exchange_info",
|
|
7
7
|
]
|
|
8
8
|
|
|
9
|
+
# ruff: noqa
|
|
9
10
|
|
|
10
11
|
from ._abc import IExchangeInfo, IUniClient, IUniWebsocketManager
|
|
11
|
-
from .binance import ExchangeInfo as BinanceExchangeInfo
|
|
12
|
-
from .binance import UniClient as BinanceUniClient
|
|
13
|
-
from .binance import UniWebsocketManager as BinanceUniWebsocketManager
|
|
14
|
-
from .bitget import ExchangeInfo as BitgetExchangeInfo
|
|
15
|
-
from .bitget import UniClient as BitgetUniClient
|
|
16
|
-
from .bitget import UniWebsocketManager as BitgetUniWebsocketManager
|
|
17
|
-
from .bybit import ExchangeInfo as BybitExchangeInfo
|
|
18
|
-
from .bybit import UniClient as BybitUniClient
|
|
19
|
-
from .bybit import UniWebsocketManager as BybitUniWebsocketManager
|
|
20
12
|
from .enums import Exchange
|
|
21
13
|
from .exceptions import NotSupported
|
|
22
|
-
|
|
23
|
-
from .
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
from .
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
14
|
+
|
|
15
|
+
from .binance import (
|
|
16
|
+
UniClient as BinanceUniClient,
|
|
17
|
+
UniWebsocketManager as BinanceUniWebsocketManager,
|
|
18
|
+
ExchangeInfo as BinanceExchangeInfo,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
from .bitget import (
|
|
22
|
+
UniClient as BitgetUniClient,
|
|
23
|
+
UniWebsocketManager as BitgetUniWebsocketManager,
|
|
24
|
+
ExchangeInfo as BitgetExchangeInfo,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
from .bybit import (
|
|
28
|
+
UniClient as BybitUniClient,
|
|
29
|
+
UniWebsocketManager as BybitUniWebsocketManager,
|
|
30
|
+
ExchangeInfo as BybitExchangeInfo,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
from .gate import (
|
|
34
|
+
UniClient as GateioUniClient,
|
|
35
|
+
UniWebsocketManager as GateioUniWebsocketManager,
|
|
36
|
+
ExchangeInfo as GateioExchangeInfo,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
from .hyperliquid import (
|
|
40
|
+
UniClient as HyperliquidUniClient,
|
|
41
|
+
UniWebsocketManager as HyperliquidUniWebsocketManager,
|
|
42
|
+
ExchangeInfo as HyperliquidExchangeInfo,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
from .mexc import (
|
|
46
|
+
UniClient as MexcUniClient,
|
|
47
|
+
UniWebsocketManager as MexcUniWebsocketManager,
|
|
48
|
+
ExchangeInfo as MexcExchangeInfo,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
from .okx import (
|
|
52
|
+
UniClient as OkxUniClient,
|
|
53
|
+
UniWebsocketManager as OkxUniWebsocketManager,
|
|
54
|
+
ExchangeInfo as OkxExchangeInfo,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
from .kucoin import (
|
|
58
|
+
UniClient as KucoinUniClient,
|
|
59
|
+
UniWebsocketManager as KucoinUniWebsocketManager,
|
|
60
|
+
ExchangeInfo as KucoinExchangeInfo,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
from .bingx import (
|
|
64
|
+
UniClient as BingXUniClient,
|
|
65
|
+
UniWebsocketManager as BingXUniWebsocketManager,
|
|
66
|
+
ExchangeInfo as BingXExchangeInfo,
|
|
67
|
+
)
|
|
68
|
+
|
|
34
69
|
|
|
35
70
|
_UNI_CLIENT_MAPPER: dict[Exchange, type[IUniClient]] = {
|
|
36
71
|
Exchange.BINANCE: BinanceUniClient,
|
|
@@ -40,6 +75,8 @@ _UNI_CLIENT_MAPPER: dict[Exchange, type[IUniClient]] = {
|
|
|
40
75
|
Exchange.HYPERLIQUID: HyperliquidUniClient,
|
|
41
76
|
Exchange.MEXC: MexcUniClient,
|
|
42
77
|
Exchange.OKX: OkxUniClient,
|
|
78
|
+
Exchange.KUCOIN: KucoinUniClient,
|
|
79
|
+
Exchange.BINGX: BingXUniClient,
|
|
43
80
|
}
|
|
44
81
|
"""Маппер, который связывает биржу и реализацию унифицированного клиента."""
|
|
45
82
|
|
|
@@ -51,6 +88,8 @@ _UNI_WS_MANAGER_MAPPER: dict[Exchange, type[IUniWebsocketManager]] = {
|
|
|
51
88
|
Exchange.HYPERLIQUID: HyperliquidUniWebsocketManager,
|
|
52
89
|
Exchange.MEXC: MexcUniWebsocketManager,
|
|
53
90
|
Exchange.OKX: OkxUniWebsocketManager,
|
|
91
|
+
Exchange.KUCOIN: KucoinUniWebsocketManager,
|
|
92
|
+
Exchange.BINGX: BingXUniWebsocketManager,
|
|
54
93
|
}
|
|
55
94
|
"""Маппер, который связывает биржу и реализацию унифицированного вебсокет-менеджера."""
|
|
56
95
|
|
|
@@ -62,6 +101,8 @@ _EXCHANGE_INFO_MAPPER: dict[Exchange, type[IExchangeInfo]] = {
|
|
|
62
101
|
Exchange.HYPERLIQUID: HyperliquidExchangeInfo,
|
|
63
102
|
Exchange.MEXC: MexcExchangeInfo,
|
|
64
103
|
Exchange.OKX: OkxExchangeInfo,
|
|
104
|
+
Exchange.KUCOIN: KucoinExchangeInfo,
|
|
105
|
+
Exchange.BINGX: BingXExchangeInfo,
|
|
65
106
|
}
|
|
66
107
|
"""Маппер, который связывает биржу и реализацию сборщика информации о тикерах на бирже."""
|
|
67
108
|
|
unicex/mexc/adapter.py
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
__all__ = ["Adapter"]
|
|
2
2
|
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
3
5
|
from unicex.types import (
|
|
4
6
|
KlineDict,
|
|
5
7
|
OpenInterestDict,
|
|
6
8
|
OpenInterestItem,
|
|
7
9
|
TickerDailyDict,
|
|
8
10
|
TickerDailyItem,
|
|
11
|
+
TradeDict,
|
|
9
12
|
)
|
|
10
13
|
from unicex.utils import catch_adapter_errors, decorate_all_methods
|
|
11
14
|
|
|
@@ -127,6 +130,7 @@ class Adapter:
|
|
|
127
130
|
result[symbol] = OpenInterestItem(
|
|
128
131
|
t=item["timestamp"],
|
|
129
132
|
v=float(item["holdVol"]) * Adapter._get_contract_size(symbol),
|
|
133
|
+
u="coins",
|
|
130
134
|
)
|
|
131
135
|
return result
|
|
132
136
|
|
|
@@ -230,6 +234,106 @@ class Adapter:
|
|
|
230
234
|
|
|
231
235
|
return sorted(klines, key=lambda kline_item: kline_item["t"])
|
|
232
236
|
|
|
237
|
+
@staticmethod
|
|
238
|
+
def klines_message(raw_msg: Any) -> list[KlineDict]:
|
|
239
|
+
"""Преобразует вебсокет-сообщение со свечами в унифицированный формат.
|
|
240
|
+
|
|
241
|
+
Параметры:
|
|
242
|
+
raw_msg (Any): Сырое сообщение с вебсокета.
|
|
243
|
+
|
|
244
|
+
Возвращает:
|
|
245
|
+
list[KlineDict]: Список свечей в унифицированном формате.
|
|
246
|
+
"""
|
|
247
|
+
kline = raw_msg["publicSpotKline"]
|
|
248
|
+
return [
|
|
249
|
+
KlineDict(
|
|
250
|
+
s=raw_msg["symbol"],
|
|
251
|
+
t=int(kline["windowStart"]) * 1000,
|
|
252
|
+
o=float(kline["openingPrice"]),
|
|
253
|
+
h=float(kline["highestPrice"]),
|
|
254
|
+
l=float(kline["lowestPrice"]),
|
|
255
|
+
c=float(kline["closingPrice"]),
|
|
256
|
+
v=float(kline["volume"]),
|
|
257
|
+
T=int(kline["windowEnd"]) * 1000,
|
|
258
|
+
x=None,
|
|
259
|
+
q=float(kline["amount"]),
|
|
260
|
+
)
|
|
261
|
+
]
|
|
262
|
+
|
|
263
|
+
@staticmethod
|
|
264
|
+
def futures_klines_message(raw_msg: Any) -> list[KlineDict]:
|
|
265
|
+
"""Преобразует вебсокет-сообщение со свечами в унифицированный формат.
|
|
266
|
+
|
|
267
|
+
Параметры:
|
|
268
|
+
raw_msg (Any): Сырое сообщение с вебсокета.
|
|
269
|
+
|
|
270
|
+
Возвращает:
|
|
271
|
+
list[KlineDict]: Список свечей в унифицированном формате.
|
|
272
|
+
"""
|
|
273
|
+
data = raw_msg["data"]
|
|
274
|
+
return [
|
|
275
|
+
KlineDict(
|
|
276
|
+
s=data["symbol"],
|
|
277
|
+
t=data["t"] * 1000,
|
|
278
|
+
o=data["o"],
|
|
279
|
+
h=data["h"],
|
|
280
|
+
l=data["l"],
|
|
281
|
+
c=data["c"],
|
|
282
|
+
v=data["q"], # Контракты
|
|
283
|
+
q=data["a"],
|
|
284
|
+
T=None,
|
|
285
|
+
x=None,
|
|
286
|
+
)
|
|
287
|
+
]
|
|
288
|
+
|
|
289
|
+
@staticmethod
|
|
290
|
+
def trades_message(raw_msg: Any) -> list[TradeDict]:
|
|
291
|
+
"""Преобразует вебсокет-сообщение со сделками в унифицированный формат.
|
|
292
|
+
|
|
293
|
+
Параметры:
|
|
294
|
+
raw_msg (Any): Сырое сообщение с вебсокета.
|
|
295
|
+
|
|
296
|
+
Возвращает:
|
|
297
|
+
list[TradeDict]: Список сделок в унифицированном формате.
|
|
298
|
+
"""
|
|
299
|
+
return [
|
|
300
|
+
TradeDict(
|
|
301
|
+
t=trade["time"],
|
|
302
|
+
s=raw_msg["symbol"],
|
|
303
|
+
S="BUY" if trade["tradeType"] == 1 else "SELL",
|
|
304
|
+
p=float(trade["price"]),
|
|
305
|
+
v=float(trade["quantity"]),
|
|
306
|
+
)
|
|
307
|
+
for trade in sorted(
|
|
308
|
+
raw_msg["publicAggreDeals"]["deals"],
|
|
309
|
+
key=lambda item: item["time"],
|
|
310
|
+
)
|
|
311
|
+
]
|
|
312
|
+
|
|
313
|
+
@staticmethod
|
|
314
|
+
def futures_trades_message(raw_msg: Any) -> list[TradeDict]:
|
|
315
|
+
"""Преобразует вебсокет-сообщение со сделками в унифицированный формат.
|
|
316
|
+
|
|
317
|
+
Параметры:
|
|
318
|
+
raw_msg (Any): Сырое сообщение с вебсокета.
|
|
319
|
+
|
|
320
|
+
Возвращает:
|
|
321
|
+
list[TradeDict]: Список сделок в унифицированном формате.
|
|
322
|
+
"""
|
|
323
|
+
return [
|
|
324
|
+
TradeDict(
|
|
325
|
+
t=item["t"],
|
|
326
|
+
s=raw_msg["symbol"],
|
|
327
|
+
S="BUY" if item["T"] == 1 else "SELL",
|
|
328
|
+
p=item["p"],
|
|
329
|
+
v=item["v"] * Adapter._get_contract_size(raw_msg["symbol"]),
|
|
330
|
+
)
|
|
331
|
+
for item in sorted(
|
|
332
|
+
raw_msg["data"],
|
|
333
|
+
key=lambda item: item["t"],
|
|
334
|
+
)
|
|
335
|
+
]
|
|
336
|
+
|
|
233
337
|
@staticmethod
|
|
234
338
|
def _get_contract_size(symbol: str) -> float:
|
|
235
339
|
"""Возвращает размер контракта для указанного символа тикера."""
|
unicex/mexc/client.py
CHANGED
|
@@ -6,7 +6,7 @@ from typing import Any
|
|
|
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 dict_to_query_string, filter_params, generate_hmac_sha256_signature
|
|
11
11
|
|
|
12
12
|
|
|
@@ -289,9 +289,9 @@ class Client(BaseClient):
|
|
|
289
289
|
symbol: str,
|
|
290
290
|
side: str,
|
|
291
291
|
type: str,
|
|
292
|
-
quantity:
|
|
293
|
-
quote_order_quantity:
|
|
294
|
-
price:
|
|
292
|
+
quantity: NumberLike | None = None,
|
|
293
|
+
quote_order_quantity: NumberLike | None = None,
|
|
294
|
+
price: NumberLike | None = None,
|
|
295
295
|
new_client_order_id: str | None = None,
|
|
296
296
|
stp_mode: str | None = None,
|
|
297
297
|
) -> dict:
|
|
@@ -319,9 +319,9 @@ class Client(BaseClient):
|
|
|
319
319
|
symbol: str,
|
|
320
320
|
side: str,
|
|
321
321
|
type: str,
|
|
322
|
-
quantity:
|
|
323
|
-
quote_order_quantity:
|
|
324
|
-
price:
|
|
322
|
+
quantity: NumberLike | None = None,
|
|
323
|
+
quote_order_quantity: NumberLike | None = None,
|
|
324
|
+
price: NumberLike | None = None,
|
|
325
325
|
new_client_order_id: str | None = None,
|
|
326
326
|
stp_mode: str | None = None,
|
|
327
327
|
) -> dict:
|
unicex/mexc/uni_client.py
CHANGED
|
@@ -180,9 +180,7 @@ class UniClient(IUniClient[Client]):
|
|
|
180
180
|
"""
|
|
181
181
|
raw_data = await self._client.futures_ticker()
|
|
182
182
|
adapted_data = Adapter.funding_rate(raw_data=raw_data) # type: ignore[reportArgumentType]
|
|
183
|
-
if symbol
|
|
184
|
-
return adapted_data[symbol]
|
|
185
|
-
return adapted_data
|
|
183
|
+
return adapted_data[symbol] if symbol else adapted_data
|
|
186
184
|
|
|
187
185
|
@overload
|
|
188
186
|
async def open_interest(self, symbol: str) -> OpenInterestItem: ...
|
|
@@ -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
|
"""Реализация менеджера асинхронных унифицированных вебсокетов."""
|
|
21
21
|
|
|
22
22
|
def __init__(
|
|
23
|
-
self,
|
|
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`): Клиент Mexc или унифицированный клиент. Нужен для подключения к приватным топикам.
|
|
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,15 @@ class UniWebsocketManager(IUniWebsocketManager):
|
|
|
72
76
|
Возвращает:
|
|
73
77
|
`Websocket`: Экземпляр вебсокета для управления соединением.
|
|
74
78
|
"""
|
|
75
|
-
|
|
79
|
+
wrapper = self._make_wrapper(self._adapter.klines_message, callback)
|
|
80
|
+
return self._websocket_manager.klines(
|
|
81
|
+
callback=wrapper,
|
|
82
|
+
symbol=symbol,
|
|
83
|
+
symbols=symbols,
|
|
84
|
+
interval=timeframe.to_exchange_format(
|
|
85
|
+
Exchange.MEXC, MarketType.FUTURES
|
|
86
|
+
), # Тут фьючерсный интервал, потому что для вебсокета MEXC решили что сделают так (идиоты)
|
|
87
|
+
)
|
|
76
88
|
|
|
77
89
|
@overload
|
|
78
90
|
def futures_klines(
|
|
@@ -114,7 +126,13 @@ class UniWebsocketManager(IUniWebsocketManager):
|
|
|
114
126
|
Возвращает:
|
|
115
127
|
`Websocket`: Экземпляр вебсокета.
|
|
116
128
|
"""
|
|
117
|
-
|
|
129
|
+
wrapper = self._make_wrapper(self._adapter.futures_klines_message, callback)
|
|
130
|
+
return self._websocket_manager.futures_kline(
|
|
131
|
+
callback=wrapper,
|
|
132
|
+
symbol=symbol,
|
|
133
|
+
symbols=symbols,
|
|
134
|
+
interval=timeframe.to_exchange_format(Exchange.MEXC, MarketType.FUTURES),
|
|
135
|
+
)
|
|
118
136
|
|
|
119
137
|
@overload
|
|
120
138
|
def trades(
|
|
@@ -152,7 +170,8 @@ class UniWebsocketManager(IUniWebsocketManager):
|
|
|
152
170
|
Возвращает:
|
|
153
171
|
`Websocket`: Экземпляр вебсокета.
|
|
154
172
|
"""
|
|
155
|
-
|
|
173
|
+
wrapper = self._make_wrapper(self._adapter.trades_message, callback)
|
|
174
|
+
return self._websocket_manager.trade(callback=wrapper, symbol=symbol, symbols=symbols)
|
|
156
175
|
|
|
157
176
|
@overload
|
|
158
177
|
def aggtrades(
|
|
@@ -190,7 +209,7 @@ class UniWebsocketManager(IUniWebsocketManager):
|
|
|
190
209
|
Возвращает:
|
|
191
210
|
`Websocket`: Экземпляр вебсокета.
|
|
192
211
|
"""
|
|
193
|
-
|
|
212
|
+
return self.trades(callback=callback, symbol=symbol, symbols=symbols) # type: ignore[reportCallIssue]
|
|
194
213
|
|
|
195
214
|
@overload
|
|
196
215
|
def futures_trades(
|
|
@@ -228,7 +247,10 @@ class UniWebsocketManager(IUniWebsocketManager):
|
|
|
228
247
|
Возвращает:
|
|
229
248
|
`Websocket`: Экземпляр вебсокета.
|
|
230
249
|
"""
|
|
231
|
-
|
|
250
|
+
wrapper = self._make_wrapper(self._adapter.futures_trades_message, callback)
|
|
251
|
+
return self._websocket_manager.futures_trade(
|
|
252
|
+
callback=wrapper, symbol=symbol, symbols=symbols
|
|
253
|
+
)
|
|
232
254
|
|
|
233
255
|
@overload
|
|
234
256
|
def futures_aggtrades(
|
|
@@ -266,4 +288,4 @@ class UniWebsocketManager(IUniWebsocketManager):
|
|
|
266
288
|
Возвращает:
|
|
267
289
|
`Websocket`: Экземпляр вебсокета.
|
|
268
290
|
"""
|
|
269
|
-
|
|
291
|
+
return self.futures_trades(callback=callback, symbol=symbol, symbols=symbols) # type: ignore[reportCallIssue]
|