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,232 @@
|
|
|
1
|
+
__all__ = ["WebsocketManager"]
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
from collections.abc import Awaitable, Callable, Sequence
|
|
6
|
+
from typing import Any, Literal
|
|
7
|
+
|
|
8
|
+
from unicex._base import Websocket
|
|
9
|
+
|
|
10
|
+
from .client import Client
|
|
11
|
+
|
|
12
|
+
type CallbackType = Callable[[Any], Awaitable[None]]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class WebsocketManager:
|
|
16
|
+
"""Менеджер асинхронных вебсокетов для Bitget."""
|
|
17
|
+
|
|
18
|
+
_URL: str = "wss://ws.bitget.com/v2/ws/public"
|
|
19
|
+
"""Базовый URL для вебсокета."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, client: Client | None = None, **ws_kwargs: Any) -> None:
|
|
22
|
+
"""Инициализирует менеджер вебсокетов для Bitget.
|
|
23
|
+
|
|
24
|
+
Параметры:
|
|
25
|
+
client (`Client | None`): Клиент для выполнения запросов. Нужен, чтобы открыть приватные вебсокеты.
|
|
26
|
+
ws_kwargs (`dict[str, Any]`): Дополнительные аргументы, котоыре прокидываются в `Websocket`.
|
|
27
|
+
"""
|
|
28
|
+
self.client = client
|
|
29
|
+
self._ws_kwargs = {"ping_message": "ping", **ws_kwargs}
|
|
30
|
+
|
|
31
|
+
def _generate_subscription_message(
|
|
32
|
+
self,
|
|
33
|
+
topic: str,
|
|
34
|
+
market_type: Literal["SPOT", "USDT-FUTURES"],
|
|
35
|
+
symbol: str | None = None,
|
|
36
|
+
symbols: Sequence[str] | None = None,
|
|
37
|
+
) -> list[str]:
|
|
38
|
+
"""Сформировать сообщение для подписки на вебсокет.
|
|
39
|
+
|
|
40
|
+
Параметры:
|
|
41
|
+
topic (`str`): Канал подписки (например: "ticker", "candle1m", "depth").
|
|
42
|
+
market_type (`"SPOT" | "USDT-FUTURES"`): Тип рынка для подписки.
|
|
43
|
+
symbol (`str | None`): Торговая пара. Нельзя использовать одновременно с `symbols`.
|
|
44
|
+
symbols (`Sequence[str] | None`): Список торговых пар. Нельзя использовать одновременно с `symbol`.
|
|
45
|
+
|
|
46
|
+
Возвращает:
|
|
47
|
+
`str`: JSON-строка с сообщением для подписки на вебсокет.
|
|
48
|
+
"""
|
|
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")
|
|
53
|
+
|
|
54
|
+
tickers = [symbol] if symbol else symbols
|
|
55
|
+
streams: list[dict] = [
|
|
56
|
+
{
|
|
57
|
+
"instType": market_type,
|
|
58
|
+
"channel": topic,
|
|
59
|
+
"instId": ticker.upper(),
|
|
60
|
+
}
|
|
61
|
+
for ticker in tickers # type: ignore
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
return [json.dumps({"op": "subscribe", "args": streams})]
|
|
65
|
+
|
|
66
|
+
def trade(
|
|
67
|
+
self,
|
|
68
|
+
callback: CallbackType,
|
|
69
|
+
market_type: Literal["SPOT", "USDT-FUTURES"],
|
|
70
|
+
symbol: str | None = None,
|
|
71
|
+
symbols: Sequence[str] | None = None,
|
|
72
|
+
) -> Websocket:
|
|
73
|
+
"""Создает вебсокет для получения сделок.
|
|
74
|
+
|
|
75
|
+
https://www.bitget.com/api-doc/spot/websocket/public/Trades-Channel
|
|
76
|
+
|
|
77
|
+
Параметры:
|
|
78
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
79
|
+
market_type (`Literal["SPOT", "USDT-FUTURES"]`): Тип рынка.
|
|
80
|
+
symbol (`str | None`): Один символ для подписки.
|
|
81
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
82
|
+
|
|
83
|
+
Возвращает:
|
|
84
|
+
`Websocket`: Объект для управления вебсокет соединением.
|
|
85
|
+
"""
|
|
86
|
+
subsription_messages = self._generate_subscription_message(
|
|
87
|
+
topic="trade",
|
|
88
|
+
market_type=market_type,
|
|
89
|
+
symbol=symbol,
|
|
90
|
+
symbols=symbols,
|
|
91
|
+
)
|
|
92
|
+
return Websocket(
|
|
93
|
+
callback=callback,
|
|
94
|
+
url=self._URL,
|
|
95
|
+
subscription_messages=subsription_messages,
|
|
96
|
+
**self._ws_kwargs,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
def ticker(
|
|
100
|
+
self,
|
|
101
|
+
callback: CallbackType,
|
|
102
|
+
market_type: Literal["SPOT", "USDT-FUTURES"],
|
|
103
|
+
symbol: str | None = None,
|
|
104
|
+
symbols: Sequence[str] | None = None,
|
|
105
|
+
) -> Websocket:
|
|
106
|
+
"""Создает вебсокет для получения тикеров.
|
|
107
|
+
|
|
108
|
+
https://www.bitget.com/api-doc/spot/websocket/public/Tickers-Channel
|
|
109
|
+
|
|
110
|
+
Параметры:
|
|
111
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
112
|
+
market_type (`Literal["SPOT", "USDT-FUTURES"]`): Тип рынка.
|
|
113
|
+
symbol (`str | None`): Один символ для подписки.
|
|
114
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
115
|
+
|
|
116
|
+
Возвращает:
|
|
117
|
+
`Websocket`: Объект для управления вебсокет соединением.
|
|
118
|
+
"""
|
|
119
|
+
subscription_messages = self._generate_subscription_message(
|
|
120
|
+
topic="ticker",
|
|
121
|
+
market_type=market_type,
|
|
122
|
+
symbol=symbol,
|
|
123
|
+
symbols=symbols,
|
|
124
|
+
)
|
|
125
|
+
return Websocket(
|
|
126
|
+
callback=callback,
|
|
127
|
+
url=self._URL,
|
|
128
|
+
subscription_messages=subscription_messages,
|
|
129
|
+
**self._ws_kwargs,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
def candlestick(
|
|
133
|
+
self,
|
|
134
|
+
callback: CallbackType,
|
|
135
|
+
market_type: Literal["SPOT", "USDT-FUTURES"],
|
|
136
|
+
interval: str,
|
|
137
|
+
symbol: str | None = None,
|
|
138
|
+
symbols: Sequence[str] | None = None,
|
|
139
|
+
) -> Websocket:
|
|
140
|
+
"""Создает вебсокет для получения данных свечей (candlestick).
|
|
141
|
+
|
|
142
|
+
https://www.bitget.com/api-doc/spot/websocket/public/Candlesticks-Channel
|
|
143
|
+
|
|
144
|
+
Параметры:
|
|
145
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
146
|
+
market_type (`Literal["SPOT", "USDT-FUTURES"]`): Тип рынка.
|
|
147
|
+
interval (`str`): Интервал свечи, например "1m", "1H", "1Dutc".
|
|
148
|
+
symbol (`str | None`): Один символ для подписки.
|
|
149
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
150
|
+
|
|
151
|
+
Возвращает:
|
|
152
|
+
`Websocket`: Объект для управления вебсокет соединением.
|
|
153
|
+
"""
|
|
154
|
+
topic = f"candle{interval}"
|
|
155
|
+
subscription_messages = self._generate_subscription_message(
|
|
156
|
+
topic=topic,
|
|
157
|
+
market_type=market_type,
|
|
158
|
+
symbol=symbol,
|
|
159
|
+
symbols=symbols,
|
|
160
|
+
)
|
|
161
|
+
return Websocket(
|
|
162
|
+
callback=callback,
|
|
163
|
+
url=self._URL,
|
|
164
|
+
subscription_messages=subscription_messages,
|
|
165
|
+
**self._ws_kwargs,
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
def depth(
|
|
169
|
+
self,
|
|
170
|
+
callback: CallbackType,
|
|
171
|
+
market_type: Literal["SPOT", "USDT-FUTURES"],
|
|
172
|
+
depth_type: str = "books",
|
|
173
|
+
symbol: str | None = None,
|
|
174
|
+
symbols: Sequence[str] | None = None,
|
|
175
|
+
) -> Websocket:
|
|
176
|
+
"""Создает вебсокет для получения данных глубины рынка (order book).
|
|
177
|
+
|
|
178
|
+
https://www.bitget.com/api-doc/spot/websocket/public/Depth-Channel
|
|
179
|
+
|
|
180
|
+
Параметры:
|
|
181
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
182
|
+
market_type (`Literal["SPOT", "USDT-FUTURES"]`): Тип рынка.
|
|
183
|
+
depth_type (`str`): Тип глубины: "books", "books1", "books5", "books15".
|
|
184
|
+
symbol (`str | None`): Один символ для подписки.
|
|
185
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
186
|
+
|
|
187
|
+
Возвращает:
|
|
188
|
+
`Websocket`: Объект для управления вебсокет соединением.
|
|
189
|
+
"""
|
|
190
|
+
subscription_messages = self._generate_subscription_message(
|
|
191
|
+
topic=depth_type,
|
|
192
|
+
market_type=market_type,
|
|
193
|
+
symbol=symbol,
|
|
194
|
+
symbols=symbols,
|
|
195
|
+
)
|
|
196
|
+
return Websocket(
|
|
197
|
+
callback=callback,
|
|
198
|
+
url=self._URL,
|
|
199
|
+
subscription_messages=subscription_messages,
|
|
200
|
+
**self._ws_kwargs,
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def auction(
|
|
204
|
+
self,
|
|
205
|
+
callback: CallbackType,
|
|
206
|
+
symbol: str | None = None,
|
|
207
|
+
symbols: Sequence[str] | None = None,
|
|
208
|
+
) -> Websocket:
|
|
209
|
+
"""Создает вебсокет для получения информации о Call Auction.
|
|
210
|
+
|
|
211
|
+
https://www.bitget.com/api-doc/spot/websocket/public/Auction-Channel
|
|
212
|
+
|
|
213
|
+
Параметры:
|
|
214
|
+
callback (`CallbackType`): Асинхронная функция обратного вызова для обработки сообщений.
|
|
215
|
+
symbol (`str | None`): Один символ для подписки.
|
|
216
|
+
symbols (`Sequence[str] | None`): Список символов для мультиплекс‑подключения.
|
|
217
|
+
|
|
218
|
+
Возвращает:
|
|
219
|
+
`Websocket`: Объект для управления вебсокет соединением.
|
|
220
|
+
"""
|
|
221
|
+
subscription_messages = self._generate_subscription_message(
|
|
222
|
+
topic="auction",
|
|
223
|
+
market_type="SPOT",
|
|
224
|
+
symbol=symbol,
|
|
225
|
+
symbols=symbols,
|
|
226
|
+
)
|
|
227
|
+
return Websocket(
|
|
228
|
+
callback=callback,
|
|
229
|
+
url=self._URL,
|
|
230
|
+
subscription_messages=subscription_messages,
|
|
231
|
+
**self._ws_kwargs,
|
|
232
|
+
)
|
unicex/bybit/__init__.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Пакет, содержащий реализации клиентов и менеджеров для работы с биржей Bybit."""
|
|
2
|
+
|
|
3
|
+
__all__ = [
|
|
4
|
+
"Client",
|
|
5
|
+
"UniClient",
|
|
6
|
+
"UserWebsocket",
|
|
7
|
+
"WebsocketManager",
|
|
8
|
+
"UniWebsocketManager",
|
|
9
|
+
"ExchangeInfo",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
from .client import Client
|
|
13
|
+
from .exchange_info import ExchangeInfo
|
|
14
|
+
from .uni_client import UniClient
|
|
15
|
+
from .uni_websocket_manager import UniWebsocketManager
|
|
16
|
+
from .user_websocket import UserWebsocket
|
|
17
|
+
from .websocket_manager import WebsocketManager
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
async def load_exchange_info() -> None:
|
|
21
|
+
"""Загружает информацию о бирже Bybit."""
|
|
22
|
+
await ExchangeInfo.load_exchange_info()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
async def start_exchange_info(parse_interval_seconds: int = 60 * 60) -> None:
|
|
26
|
+
"""Запускает процесс обновления информации о бирже Bybit."""
|
|
27
|
+
await ExchangeInfo.start(parse_interval_seconds)
|
unicex/bybit/adapter.py
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
__all__ = ["Adapter"]
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from unicex.types import (
|
|
6
|
+
KlineDict,
|
|
7
|
+
LiquidationDict,
|
|
8
|
+
OpenInterestDict,
|
|
9
|
+
OpenInterestItem,
|
|
10
|
+
TickerDailyDict,
|
|
11
|
+
TickerDailyItem,
|
|
12
|
+
TradeDict,
|
|
13
|
+
)
|
|
14
|
+
from unicex.utils import catch_adapter_errors, decorate_all_methods
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@decorate_all_methods(catch_adapter_errors)
|
|
18
|
+
class Adapter:
|
|
19
|
+
"""Адаптер для унификации данных с Bybit API."""
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def tickers(raw_data: dict, only_usdt: bool) -> list[str]:
|
|
23
|
+
"""Преобразует сырой ответ, в котором содержатся данные о тикерах в список тикеров.
|
|
24
|
+
|
|
25
|
+
Параметры:
|
|
26
|
+
raw_data (dict): Сырой ответ с биржи.
|
|
27
|
+
only_usdt (bool): Флаг, указывающий, нужно ли включать только тикеры в паре к USDT.
|
|
28
|
+
|
|
29
|
+
Возвращает:
|
|
30
|
+
list[str]: Список тикеров.
|
|
31
|
+
"""
|
|
32
|
+
return [
|
|
33
|
+
item["symbol"]
|
|
34
|
+
for item in raw_data["result"]["list"]
|
|
35
|
+
if item["symbol"].endswith("USDT") or not only_usdt
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
@staticmethod
|
|
39
|
+
def ticker_24hr(raw_data: dict) -> TickerDailyDict:
|
|
40
|
+
"""Преобразует сырой ответ, в котором содержатся данные о тикере за последние 24 часа в унифицированный формат.
|
|
41
|
+
|
|
42
|
+
Параметры:
|
|
43
|
+
raw_data (dict): Сырой ответ с биржи.
|
|
44
|
+
|
|
45
|
+
Возвращает:
|
|
46
|
+
TickerDailyDict: Словарь, где ключ - тикер, а значение - статистика за последние 24 часа.
|
|
47
|
+
"""
|
|
48
|
+
return {
|
|
49
|
+
item["symbol"]: TickerDailyItem(
|
|
50
|
+
p=round(float(item["price24hPcnt"]) * 100, 2),
|
|
51
|
+
v=float(item["volume24h"]),
|
|
52
|
+
q=float(item["turnover24h"]),
|
|
53
|
+
)
|
|
54
|
+
for item in raw_data["result"]["list"]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def open_interest(raw_data: dict) -> OpenInterestDict:
|
|
59
|
+
"""Преобразует сырой ответ, в котором содержатся данные об открытом интересе, в унифицированный формат.
|
|
60
|
+
|
|
61
|
+
Параметры:
|
|
62
|
+
raw_data (dict): Сырой ответ с биржи.
|
|
63
|
+
|
|
64
|
+
Возвращает:
|
|
65
|
+
OpenInterestDict: Словарь, где ключ - тикер, а значение - агрегированные данные открытого интереса.
|
|
66
|
+
"""
|
|
67
|
+
return {
|
|
68
|
+
item["symbol"]: OpenInterestItem(
|
|
69
|
+
t=raw_data["time"],
|
|
70
|
+
v=float(item["openInterest"]),
|
|
71
|
+
)
|
|
72
|
+
for item in raw_data["result"]["list"]
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@staticmethod
|
|
76
|
+
def funding_rate(raw_data: dict) -> dict[str, float]:
|
|
77
|
+
"""Преобразует сырой ответ, в котором содержатся данные о ставках финансирования, в унифицированный формат.
|
|
78
|
+
|
|
79
|
+
Параметры:
|
|
80
|
+
raw_data (dict): Сырой ответ с биржи.
|
|
81
|
+
|
|
82
|
+
Возвращает:
|
|
83
|
+
dict[str, float]: Словарь, где ключ - тикер, а значение - ставка финансирования.
|
|
84
|
+
"""
|
|
85
|
+
return {
|
|
86
|
+
item["symbol"]: float(item["fundingRate"]) * 100
|
|
87
|
+
for item in raw_data["result"]["list"]
|
|
88
|
+
if item["fundingRate"]
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@staticmethod
|
|
92
|
+
def last_price(raw_data: dict) -> dict[str, float]:
|
|
93
|
+
"""Преобразует сырой ответ, в котором содержатся данные о последней цене, в унифицированный формат.
|
|
94
|
+
|
|
95
|
+
Параметры:
|
|
96
|
+
raw_data (dict): Сырой ответ с биржи.
|
|
97
|
+
|
|
98
|
+
Возвращает:
|
|
99
|
+
dict[str, float]: Словарь, где ключ - тикер, а значение - последняя цена.
|
|
100
|
+
"""
|
|
101
|
+
return {item["symbol"]: float(item["lastPrice"]) for item in raw_data["result"]["list"]}
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
def klines(raw_data: dict) -> list[KlineDict]:
|
|
105
|
+
"""Преобразует сырой ответ, в котором содержатся данные о свечах, в унифицированный формат.
|
|
106
|
+
|
|
107
|
+
Параметры:
|
|
108
|
+
raw_data (dict): Сырой ответ с биржи.
|
|
109
|
+
|
|
110
|
+
Возвращает:
|
|
111
|
+
list[KlineDict]: Список словарей, где каждый словарь содержит данные о свече.
|
|
112
|
+
"""
|
|
113
|
+
return [
|
|
114
|
+
KlineDict(
|
|
115
|
+
s=raw_data["result"]["symbol"],
|
|
116
|
+
t=int(kline[0]),
|
|
117
|
+
o=float(kline[1]),
|
|
118
|
+
h=float(kline[2]),
|
|
119
|
+
l=float(kline[3]),
|
|
120
|
+
c=float(kline[4]),
|
|
121
|
+
v=float(kline[5]),
|
|
122
|
+
q=float(kline[6]),
|
|
123
|
+
T=None,
|
|
124
|
+
x=None,
|
|
125
|
+
)
|
|
126
|
+
for kline in sorted(
|
|
127
|
+
raw_data["result"]["list"],
|
|
128
|
+
key=lambda x: int(x[0]),
|
|
129
|
+
)
|
|
130
|
+
]
|
|
131
|
+
|
|
132
|
+
@staticmethod
|
|
133
|
+
def Klines_message(raw_msg: Any) -> list[KlineDict]:
|
|
134
|
+
"""Преобразует вебсокет-сообщение с данными о свечах в унифицированный формат.
|
|
135
|
+
|
|
136
|
+
Параметры:
|
|
137
|
+
raw_msg (`Any`): Сырое сообщение из вебсокета Bybit.
|
|
138
|
+
|
|
139
|
+
Возвращает:
|
|
140
|
+
`list[KlineDict]`: Список свечей в унифицированном формате.
|
|
141
|
+
"""
|
|
142
|
+
symbol = raw_msg["topic"].split(".")[-1]
|
|
143
|
+
return [
|
|
144
|
+
KlineDict(
|
|
145
|
+
s=symbol,
|
|
146
|
+
t=kline["start"],
|
|
147
|
+
o=float(kline["open"]),
|
|
148
|
+
h=float(kline["high"]),
|
|
149
|
+
l=float(kline["low"]),
|
|
150
|
+
c=float(kline["close"]),
|
|
151
|
+
v=float(kline["volume"]),
|
|
152
|
+
q=float(kline["turnover"]),
|
|
153
|
+
T=kline["end"],
|
|
154
|
+
x=kline["confirm"],
|
|
155
|
+
)
|
|
156
|
+
for kline in sorted(
|
|
157
|
+
raw_msg["data"],
|
|
158
|
+
key=lambda x: int(x["start"]),
|
|
159
|
+
)
|
|
160
|
+
]
|
|
161
|
+
|
|
162
|
+
@staticmethod
|
|
163
|
+
def trades_message(raw_msg: Any) -> list[TradeDict]:
|
|
164
|
+
"""Преобразует вебсокет-сообщение с данными о сделках в унифицированный формат.
|
|
165
|
+
|
|
166
|
+
Параметры:
|
|
167
|
+
raw_msg (`Any`): Сырое сообщение из вебсокета Bybit.
|
|
168
|
+
|
|
169
|
+
Возвращает:
|
|
170
|
+
`list[TradeDict]`: Список сделок в унифицированном формате.
|
|
171
|
+
"""
|
|
172
|
+
return [
|
|
173
|
+
TradeDict(
|
|
174
|
+
t=trade["T"],
|
|
175
|
+
s=trade["s"],
|
|
176
|
+
S=trade["S"].upper(),
|
|
177
|
+
p=float(trade["p"]),
|
|
178
|
+
v=float(trade["v"]),
|
|
179
|
+
)
|
|
180
|
+
for trade in sorted(
|
|
181
|
+
raw_msg["data"],
|
|
182
|
+
key=lambda x: int(x["T"]),
|
|
183
|
+
)
|
|
184
|
+
]
|
|
185
|
+
|
|
186
|
+
@staticmethod
|
|
187
|
+
def liquidations_message(raw_msg: Any) -> list[LiquidationDict]:
|
|
188
|
+
"""Преобразует вебсокет-сообщение с данными о ликвидациях в унифицированный формат.
|
|
189
|
+
|
|
190
|
+
Параметры:
|
|
191
|
+
raw_msg (`Any`): Сырое сообщение из вебсокета Bybit.
|
|
192
|
+
|
|
193
|
+
Возвращает:
|
|
194
|
+
`list[LiquidationDict]`: Список ликвидаций в унифицированном формате.
|
|
195
|
+
"""
|
|
196
|
+
return [
|
|
197
|
+
LiquidationDict(
|
|
198
|
+
t=liquidation["T"],
|
|
199
|
+
s=liquidation["s"],
|
|
200
|
+
S=liquidation["S"].upper(),
|
|
201
|
+
v=float(liquidation["v"]),
|
|
202
|
+
p=float(liquidation["p"]),
|
|
203
|
+
)
|
|
204
|
+
for liquidation in sorted(
|
|
205
|
+
raw_msg["data"],
|
|
206
|
+
key=lambda x: int(x["T"]),
|
|
207
|
+
)
|
|
208
|
+
]
|