unicex 0.16.7__py3-none-any.whl → 0.17.1__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 CHANGED
@@ -100,6 +100,7 @@ __all__ = [
100
100
 
101
101
  # abstract & base
102
102
  import asyncio
103
+ from typing import Awaitable
103
104
  from ._abc import IUniClient, IUniWebsocketManager
104
105
  from ._base import BaseClient, Websocket
105
106
 
@@ -204,9 +205,9 @@ from .bingx import (
204
205
  )
205
206
 
206
207
 
207
- async def load_exchanges_info() -> None:
208
+ async def load_exchanges_info() -> list:
208
209
  """Единожды загружает информацию о тикерах на всех биржах."""
209
- await asyncio.gather(
210
+ return await asyncio.gather(
210
211
  BinanceExchangeInfo.load_exchange_info(),
211
212
  BitgetExchangeInfo.load_exchange_info(),
212
213
  BybitExchangeInfo.load_exchange_info(),
@@ -219,9 +220,9 @@ async def load_exchanges_info() -> None:
219
220
  )
220
221
 
221
222
 
222
- async def start_exchanges_info(parse_interval_seconds: int = 60 * 60) -> None:
223
+ async def start_exchanges_info(parse_interval_seconds: int = 60 * 60) -> Awaitable:
223
224
  """Запускает цикл обновления информации о тикерах на всех биржах."""
224
- asyncio.gather(
225
+ return asyncio.gather(
225
226
  BinanceExchangeInfo.start(parse_interval_seconds),
226
227
  BitgetExchangeInfo.start(parse_interval_seconds),
227
228
  BybitExchangeInfo.start(parse_interval_seconds),
@@ -0,0 +1,27 @@
1
+ """Пакет, содержащий реализации клиентов и менеджеров для работы с биржей Aster."""
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
+ """Загружает информацию о бирже Aster."""
22
+ await ExchangeInfo.load_exchange_info()
23
+
24
+
25
+ async def start_exchange_info(parse_interval_seconds: int = 60 * 60) -> None:
26
+ """Запускает процесс обновления информации о бирже Aster."""
27
+ await ExchangeInfo.start(parse_interval_seconds)
@@ -0,0 +1,173 @@
1
+ __all__ = ["Adapter"]
2
+
3
+ from typing import Any
4
+
5
+ from unicex.types import (
6
+ KlineDict,
7
+ OpenInterestDict,
8
+ OpenInterestItem,
9
+ TickerDailyDict,
10
+ TickerDailyItem,
11
+ TradeDict,
12
+ )
13
+ from unicex.utils import catch_adapter_errors, decorate_all_methods, get_timestamp
14
+
15
+
16
+ @decorate_all_methods(catch_adapter_errors)
17
+ class Adapter:
18
+ """Адаптер для унификации данных с Aster API."""
19
+
20
+ @staticmethod
21
+ def tickers(raw_data: list[dict], only_usdt: bool) -> list[str]:
22
+ """Преобразует сырой ответ, в котором содержатся данные о тикерах в список тикеров.
23
+
24
+ Параметры:
25
+ raw_data (list[dict]): Сырой ответ с биржи.
26
+ only_usdt (bool): Флаг, указывающий, нужно ли включать только тикеры в паре к USDT.
27
+
28
+ Возвращает:
29
+ list[str]: Список тикеров.
30
+ """
31
+ return [
32
+ item["symbol"] for item in raw_data if item["symbol"].endswith("USDT") or not only_usdt
33
+ ]
34
+
35
+ @staticmethod
36
+ def ticker_24hr(raw_data: list[dict]) -> TickerDailyDict:
37
+ """Преобразует сырой ответ, в котором содержатся данные о тикере за последние 24 часа в унифицированный формат.
38
+
39
+ Параметры:
40
+ raw_data (list[dict]): Сырой ответ с биржи.
41
+
42
+ Возвращает:
43
+ TickerDailyDict: Словарь, где ключ - тикер, а значение - статистика за последние 24 часа.
44
+ """
45
+ return {
46
+ item["symbol"]: TickerDailyItem(
47
+ p=float(item["priceChangePercent"]),
48
+ q=float(item["quoteVolume"]),
49
+ v=float(item["volume"]),
50
+ )
51
+ for item in raw_data
52
+ }
53
+
54
+ @staticmethod
55
+ def last_price(raw_data: list[dict]) -> dict[str, float]:
56
+ """Преобразует сырой ответ с ценами тикеров в унифицированный формат.
57
+
58
+ Параметры:
59
+ raw_data (list[dict]): Сырой ответ с биржи.
60
+
61
+ Возвращает:
62
+ dict[str, float]: Словарь, где ключ - тикер, а значение - последняя цена.
63
+ """
64
+ return {item["symbol"]: float(item["price"]) for item in raw_data}
65
+
66
+ @staticmethod
67
+ def klines(raw_data: list[list], symbol: str) -> list[KlineDict]:
68
+ """Преобразует сырой ответ, в котором содержатся данные о свечах, в унифицированный формат.
69
+
70
+ Параметры:
71
+ raw_data (list[list]): Сырой ответ с биржи.
72
+ symbol (str): Символ тикера.
73
+
74
+ Возвращает:
75
+ list[KlineDict]: Список свечей.
76
+ """
77
+ return [
78
+ KlineDict(
79
+ s=symbol,
80
+ t=kline[0],
81
+ o=float(kline[1]),
82
+ h=float(kline[2]),
83
+ l=float(kline[3]),
84
+ c=float(kline[4]),
85
+ v=float(kline[5]),
86
+ q=float(kline[7]),
87
+ T=kline[6],
88
+ x=None,
89
+ )
90
+ for kline in sorted(raw_data, key=lambda x: int(x[0]))
91
+ ]
92
+
93
+ @staticmethod
94
+ def funding_rate(raw_data: list[dict]) -> dict[str, float]:
95
+ """Преобразует сырой ответ, в котором содержатся данные о ставках финансирования, в унифицированный формат.
96
+
97
+ Параметры:
98
+ raw_data (list[dict]): Сырой ответ с биржи.
99
+
100
+ Возвращает:
101
+ dict[str, float]: Словарь, где ключ - тикер, а значение - ставка финансирования.
102
+ """
103
+ return {item["symbol"]: float(item["lastFundingRate"]) * 100 for item in raw_data}
104
+
105
+ @staticmethod
106
+ def open_interest(raw_data: dict) -> OpenInterestDict:
107
+ """Преобразует сырой ответ, в котором содержатся данные об открытом интересе, в унифицированный формат.
108
+
109
+ Параметры:
110
+ raw_data (dict): Сырой ответ с биржи.
111
+
112
+ Возвращает:
113
+ OpenInterestDict: Словарь, где ключ - тикер, а значение - открытый интерес в USDT.
114
+ """
115
+ # В ответе нет времени, поэтому используем текущее.
116
+ timestamp = get_timestamp()
117
+ return {
118
+ item["symbol"]: OpenInterestItem(
119
+ t=timestamp,
120
+ v=float(item["openInterest"]),
121
+ u="usd",
122
+ )
123
+ for item in raw_data.get("data", [])
124
+ }
125
+
126
+ @staticmethod
127
+ def Klines_message(raw_msg: Any) -> list[KlineDict]:
128
+ """Преобразует сырое сообщение с вебсокета, в котором содержится информация о
129
+ свече/свечах в унифицированный вид.
130
+
131
+ Параметры:
132
+ raw_msg (Any): Сырое сообщение с вебсокета.
133
+
134
+ Возвращает:
135
+ list[KlineDict]: Список словарей, где каждый словарь содержит данные о свече.
136
+ """
137
+ kline = raw_msg.get("data", raw_msg)["k"] # Чтобы корректно обрабатывать multiplex стримы
138
+ return [
139
+ KlineDict(
140
+ s=kline["s"],
141
+ t=kline["t"],
142
+ o=float(kline["o"]),
143
+ h=float(kline["h"]),
144
+ l=float(kline["l"]),
145
+ c=float(kline["c"]),
146
+ v=float(kline["v"]),
147
+ q=float(kline["q"]),
148
+ T=kline["T"],
149
+ x=kline["x"],
150
+ )
151
+ ]
152
+
153
+ @staticmethod
154
+ def trades_message(raw_msg: Any) -> list[TradeDict]:
155
+ """Преобразует сырое сообщение с вебсокета, в котором содержится информация о
156
+ сделке/сделках в унифицированный вид.
157
+
158
+ Параметры:
159
+ raw_msg (Any): Сырое сообщение с вебсокета.
160
+
161
+ Возвращает:
162
+ list[TradeDict]: Список словарей, где каждый словарь содержит данные о сделке.
163
+ """
164
+ data = raw_msg.get("data", raw_msg) # Чтобы корректно обрабатывать multiplex стримы
165
+ return [
166
+ TradeDict(
167
+ t=data["T"],
168
+ s=data["s"],
169
+ S="SELL" if data["m"] else "BUY",
170
+ p=float(data["p"]),
171
+ v=float(data["q"]),
172
+ )
173
+ ]