hyperquant 1.22__py3-none-any.whl → 1.25__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.
Potentially problematic release.
This version of hyperquant might be problematic. Click here for more details.
- hyperquant/broker/lighter.py +222 -12
- hyperquant/broker/models/lighter.py +360 -0
- hyperquant/broker/ws.py +7 -0
- {hyperquant-1.22.dist-info → hyperquant-1.25.dist-info}/METADATA +1 -4
- {hyperquant-1.22.dist-info → hyperquant-1.25.dist-info}/RECORD +6 -8
- hyperquant/broker/coinup.py +0 -591
- hyperquant/broker/models/coinup.py +0 -334
- {hyperquant-1.22.dist-info → hyperquant-1.25.dist-info}/WHEEL +0 -0
|
@@ -1,334 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import asyncio
|
|
4
|
-
import json
|
|
5
|
-
import logging
|
|
6
|
-
from typing import Any, Awaitable, TYPE_CHECKING
|
|
7
|
-
import zlib
|
|
8
|
-
|
|
9
|
-
from aiohttp import ClientResponse
|
|
10
|
-
from pybotters.store import DataStore, DataStoreCollection
|
|
11
|
-
|
|
12
|
-
if TYPE_CHECKING:
|
|
13
|
-
from pybotters.typedefs import Item
|
|
14
|
-
from pybotters.ws import ClientWebSocketResponse
|
|
15
|
-
|
|
16
|
-
logger = logging.getLogger(__name__)
|
|
17
|
-
|
|
18
|
-
# {"event_rep":"","channel":"market_e_wlfiusdt_depth_step0","data":null,"tick":{"asks":[[0.1402,9864],[0.1403,23388],[0.1404,9531],[0.1405,4995],[0.1406,3074],[0.1407,18736],[0.1408,3514],[0.1409,6326],[0.141,13217],[0.1411,18253],[0.1412,12214],[0.1413,15243],[0.1414,3606],[0.1415,14894],[0.1416,7932],[0.1417,4973],[0.1418,13031],[0.1419,19793],[0.142,17093],[0.1421,19395],[0.1422,12793],[0.1423,17846],[0.1424,15320],[0.1425,13313],[0.1426,20405],[0.1427,6611],[0.1428,17688],[0.1429,16308],[0.143,10073],[0.1431,15438]],"buys":[[0.1401,9473],[0.14,17486],[0.1399,11957],[0.1398,4824],[0.1397,18447],[0.1396,16929],[0.1395,19859],[0.1394,7283],[0.1393,19609],[0.1392,13638],[0.1391,4146],[0.139,3924],[0.1389,21574],[0.1388,14692],[0.1387,13772],[0.1386,21153],[0.1385,19533],[0.1384,20164],[0.1383,2645],[0.1382,17852],[0.1381,21453],[0.138,19162],[0.1379,17365],[0.1378,9061],[0.1377,14713],[0.1376,12023],[0.1375,11245],[0.1374,9633],[0.1373,5124],[0.1372,5140]]},"ts":1761239630000,"status":"ok"}
|
|
19
|
-
|
|
20
|
-
class Book(DataStore):
|
|
21
|
-
|
|
22
|
-
_KEYS = ["s", "S", "p"]
|
|
23
|
-
|
|
24
|
-
def _init(self) -> None:
|
|
25
|
-
self.limit: int | None = None
|
|
26
|
-
|
|
27
|
-
def _on_message(self, msg: Any) -> None:
|
|
28
|
-
asks = msg["tick"]["asks"]
|
|
29
|
-
bids = msg["tick"]["buys"]
|
|
30
|
-
if self.limit is not None:
|
|
31
|
-
asks = asks[: self.limit]
|
|
32
|
-
bids = bids[: self.limit]
|
|
33
|
-
chanel = msg["channel"]
|
|
34
|
-
symbol = chanel.split("_")[2].upper()
|
|
35
|
-
symbol = symbol.replace("USDT", "-USDT")
|
|
36
|
-
asks = [
|
|
37
|
-
{"s": symbol, "S": "a", "p": float(price), "q": float(quantity)} for price, quantity in asks
|
|
38
|
-
]
|
|
39
|
-
bids = [
|
|
40
|
-
{"s": symbol, "S": "b", "p": float(price), "q": float(quantity)} for price, quantity in bids
|
|
41
|
-
]
|
|
42
|
-
self._find_and_delete({"s": symbol})
|
|
43
|
-
self._insert(asks + bids)
|
|
44
|
-
|
|
45
|
-
class Detail(DataStore):
|
|
46
|
-
|
|
47
|
-
_KEYS = ["symbol"]
|
|
48
|
-
|
|
49
|
-
def _onresponse(self, data: Any) -> None:
|
|
50
|
-
data = data.get("data", {})
|
|
51
|
-
clist = data.get("contractList", [])
|
|
52
|
-
# coinResultVo -> marginCoinPrecision 取出来
|
|
53
|
-
for c in clist:
|
|
54
|
-
p = c.get("coinResultVo", {}).get("marginCoinPrecision")
|
|
55
|
-
p = 10 ** (-p)
|
|
56
|
-
c["tick_size"] = p
|
|
57
|
-
c['TickSize'] = p # 兼容用大写开头的字段
|
|
58
|
-
self._update(clist)
|
|
59
|
-
|
|
60
|
-
class Position(DataStore):
|
|
61
|
-
|
|
62
|
-
_KEYS = ["symbol"]
|
|
63
|
-
|
|
64
|
-
def _onresponse(self, data: Any) -> None:
|
|
65
|
-
data = data.get("data", [])
|
|
66
|
-
p_list = data.get("positionList", [])
|
|
67
|
-
self._clear()
|
|
68
|
-
self._update(p_list)
|
|
69
|
-
|
|
70
|
-
class Balance(DataStore):
|
|
71
|
-
|
|
72
|
-
_KEYS = ["symbol"]
|
|
73
|
-
|
|
74
|
-
def _onresponse(self, data: Any) -> None:
|
|
75
|
-
data = data.get("data", [])
|
|
76
|
-
b_list = data.get("accountList", [])
|
|
77
|
-
self._clear()
|
|
78
|
-
self._update(b_list)
|
|
79
|
-
|
|
80
|
-
class Orders(DataStore):
|
|
81
|
-
|
|
82
|
-
_KEYS = ["orderId"]
|
|
83
|
-
|
|
84
|
-
@staticmethod
|
|
85
|
-
def _normalize(entry: dict[str, Any]) -> dict[str, Any] | None:
|
|
86
|
-
order_id = entry.get("orderId")
|
|
87
|
-
if order_id is None:
|
|
88
|
-
return None
|
|
89
|
-
normalized = dict(entry)
|
|
90
|
-
normalized["orderId"] = str(order_id)
|
|
91
|
-
return normalized
|
|
92
|
-
|
|
93
|
-
def _onresponse(self, data: Any) -> None:
|
|
94
|
-
payload: Any = data
|
|
95
|
-
if isinstance(data, dict):
|
|
96
|
-
payload = data.get("data") or data
|
|
97
|
-
if isinstance(payload, dict):
|
|
98
|
-
payload = payload.get("orderList") or payload.get("orders") or []
|
|
99
|
-
|
|
100
|
-
items: list[dict[str, Any]] = []
|
|
101
|
-
if isinstance(payload, list):
|
|
102
|
-
for entry in payload:
|
|
103
|
-
if not isinstance(entry, dict):
|
|
104
|
-
continue
|
|
105
|
-
normalized = self._normalize(entry)
|
|
106
|
-
if normalized:
|
|
107
|
-
items.append(normalized)
|
|
108
|
-
|
|
109
|
-
self._clear()
|
|
110
|
-
if items:
|
|
111
|
-
self._insert(items)
|
|
112
|
-
|
|
113
|
-
class HistoryOrders(DataStore):
|
|
114
|
-
|
|
115
|
-
_KEYS = ["orderId"]
|
|
116
|
-
|
|
117
|
-
@staticmethod
|
|
118
|
-
def _normalize(entry: dict[str, Any]) -> dict[str, Any] | None:
|
|
119
|
-
order_id = entry.get("orderId")
|
|
120
|
-
if order_id is None:
|
|
121
|
-
return None
|
|
122
|
-
normalized = dict(entry)
|
|
123
|
-
normalized["orderId"] = str(order_id)
|
|
124
|
-
return normalized
|
|
125
|
-
|
|
126
|
-
def _onresponse(self, data: Any) -> None:
|
|
127
|
-
payload: Any = data
|
|
128
|
-
if isinstance(data, dict):
|
|
129
|
-
payload = data.get("data") or data
|
|
130
|
-
if isinstance(payload, dict):
|
|
131
|
-
payload = payload.get("orderList") or payload.get("orders") or []
|
|
132
|
-
|
|
133
|
-
items: list[dict[str, Any]] = []
|
|
134
|
-
if isinstance(payload, list):
|
|
135
|
-
for entry in payload:
|
|
136
|
-
if not isinstance(entry, dict):
|
|
137
|
-
continue
|
|
138
|
-
normalized = self._normalize(entry)
|
|
139
|
-
if normalized:
|
|
140
|
-
items.append(normalized)
|
|
141
|
-
|
|
142
|
-
self._clear()
|
|
143
|
-
if items:
|
|
144
|
-
self._insert(items)
|
|
145
|
-
|
|
146
|
-
class CoinUpDataStore(DataStoreCollection):
|
|
147
|
-
def _init(self) -> None:
|
|
148
|
-
self._create("book", datastore_class=Book)
|
|
149
|
-
self._create("detail", datastore_class=Detail)
|
|
150
|
-
self._create("position", datastore_class=Position)
|
|
151
|
-
self._create("balance", datastore_class=Balance)
|
|
152
|
-
self._create("orders", datastore_class=Orders)
|
|
153
|
-
self._create("history_orders", datastore_class=HistoryOrders)
|
|
154
|
-
|
|
155
|
-
def onmessage(self, msg: Item, ws: ClientWebSocketResponse | None = None) -> None:
|
|
156
|
-
decompressed = zlib.decompress(msg, 16 + zlib.MAX_WBITS)
|
|
157
|
-
text = decompressed.decode("utf-8")
|
|
158
|
-
data = json.loads(text)
|
|
159
|
-
chanel = data.get("channel", "")
|
|
160
|
-
if 'depth' in chanel:
|
|
161
|
-
self.book._on_message(data)
|
|
162
|
-
|
|
163
|
-
def onresponse(self, data: Any) -> None:
|
|
164
|
-
pass
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
@property
|
|
168
|
-
def book(self) -> Book:
|
|
169
|
-
"""
|
|
170
|
-
.. code:: json
|
|
171
|
-
|
|
172
|
-
{
|
|
173
|
-
"s": "BTCUSDT",
|
|
174
|
-
"S": "a", # 卖单
|
|
175
|
-
"p": "95640.3",
|
|
176
|
-
"q": "0.807"
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
"""
|
|
180
|
-
return self._get("book")
|
|
181
|
-
|
|
182
|
-
@property
|
|
183
|
-
def detail(self) -> Detail:
|
|
184
|
-
"""
|
|
185
|
-
.. code:: json
|
|
186
|
-
|
|
187
|
-
{
|
|
188
|
-
"id": 117,
|
|
189
|
-
"contractName": "E-RESOLV-USDT",
|
|
190
|
-
"symbol": "RESOLV-USDT",
|
|
191
|
-
"contractType": "E",
|
|
192
|
-
"coType": "E",
|
|
193
|
-
"contractShowType": "USDT合约",
|
|
194
|
-
"deliveryKind": "0",
|
|
195
|
-
"contractSide": 1,
|
|
196
|
-
"multiplier": 22.8000000000000000,
|
|
197
|
-
"multiplierCoin": "RESOLV",
|
|
198
|
-
"marginCoin": "USDT",
|
|
199
|
-
"originalCoin": "USDT",
|
|
200
|
-
"marginRate": 1.00000000,
|
|
201
|
-
"capitalStartTime": 0,
|
|
202
|
-
"capitalFrequency": 8,
|
|
203
|
-
"settlementFrequency": 1,
|
|
204
|
-
"brokerId": 1,
|
|
205
|
-
"base": "RESOLV",
|
|
206
|
-
"quote": "USDT",
|
|
207
|
-
"coinResultVo": {
|
|
208
|
-
"symbolPricePrecision": 5,
|
|
209
|
-
"depth": [
|
|
210
|
-
"5",
|
|
211
|
-
"4",
|
|
212
|
-
"3"
|
|
213
|
-
],
|
|
214
|
-
"minOrderVolume": 1,
|
|
215
|
-
"minOrderMoney": 1,
|
|
216
|
-
"maxMarketVolume": 5000000,
|
|
217
|
-
"maxMarketMoney": 6411360,
|
|
218
|
-
"maxLimitVolume": 5000000,
|
|
219
|
-
"maxLimitMoney": 5000000.0000000000000000,
|
|
220
|
-
"priceRange": 0.3000000000,
|
|
221
|
-
"marginCoinPrecision": 4,
|
|
222
|
-
"fundsInStatus": 1,
|
|
223
|
-
"fundsOutStatus": 1
|
|
224
|
-
},
|
|
225
|
-
"sort": 100,
|
|
226
|
-
"maxLever": 75,
|
|
227
|
-
"minLever": 1,
|
|
228
|
-
"contractOtherName": "RESOLV/USDT",
|
|
229
|
-
"subSymbol": "e_resolvusdt",
|
|
230
|
-
"classification": 1,
|
|
231
|
-
"nextCapitalSettTime": 1761292800000,
|
|
232
|
-
"tick_size": 0.0001
|
|
233
|
-
}
|
|
234
|
-
"""
|
|
235
|
-
return self._get("detail")
|
|
236
|
-
|
|
237
|
-
@property
|
|
238
|
-
def position(self) -> Position:
|
|
239
|
-
"""
|
|
240
|
-
_key: symbol
|
|
241
|
-
|
|
242
|
-
.. code:: json
|
|
243
|
-
|
|
244
|
-
{
|
|
245
|
-
"id": 256538,
|
|
246
|
-
"contractId": 169,
|
|
247
|
-
"contractName": "E-WLFI-USDT",
|
|
248
|
-
"contractOtherName": "WLFI/USDT",
|
|
249
|
-
"symbol": "WLFI-USDT",
|
|
250
|
-
"positionVolume": 1.0,
|
|
251
|
-
"canCloseVolume": 1.0,
|
|
252
|
-
"closeVolume": 0.0,
|
|
253
|
-
"openAvgPrice": 0.1409,
|
|
254
|
-
"indexPrice": 0.14040034,
|
|
255
|
-
"reducePrice": -0.9769279224708908,
|
|
256
|
-
"holdAmount": 16.53718437074,
|
|
257
|
-
"marginRate": 7.852395215348719,
|
|
258
|
-
"realizedAmount": 0.0,
|
|
259
|
-
"returnRate": -0.0177310149041873,
|
|
260
|
-
"orderSide": "BUY",
|
|
261
|
-
"positionType": 1,
|
|
262
|
-
"canUseAmount": 16.11598335074,
|
|
263
|
-
"canSubMarginAmount": 0,
|
|
264
|
-
"openRealizedAmount": -0.0074949,
|
|
265
|
-
"keepRate": 0.015,
|
|
266
|
-
"maxFeeRate": 2.0E-4,
|
|
267
|
-
"unRealizedAmount": -0.0074949,
|
|
268
|
-
"leverageLevel": 5,
|
|
269
|
-
"positionBalance": 2.1060051,
|
|
270
|
-
"tradeFee": "-0.0004",
|
|
271
|
-
"capitalFee": "0",
|
|
272
|
-
"closeProfit": "0",
|
|
273
|
-
"settleProfit": "0",
|
|
274
|
-
"shareAmount": "0",
|
|
275
|
-
"historyRealizedAmount": "-0.0004227",
|
|
276
|
-
"profitRealizedAmount": "-0.0004",
|
|
277
|
-
"openAmount": 0.4227,
|
|
278
|
-
"adlLevel": 2
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
"""
|
|
282
|
-
return self._get("position")
|
|
283
|
-
|
|
284
|
-
@property
|
|
285
|
-
def balance(self) -> Balance:
|
|
286
|
-
"""
|
|
287
|
-
_key: symbol
|
|
288
|
-
|
|
289
|
-
.. code:: json
|
|
290
|
-
|
|
291
|
-
{
|
|
292
|
-
"symbol": "USDT",
|
|
293
|
-
"originalCoin": "USDT",
|
|
294
|
-
"unRealizedAmount": "-0.0074949",
|
|
295
|
-
"realizedAmount": "0",
|
|
296
|
-
"totalMargin": "16.53718437074",
|
|
297
|
-
"totalAmount": "16.53718437074",
|
|
298
|
-
"canUseAmount": 16.11598335074,
|
|
299
|
-
"availableAmount": 16.11598335074,
|
|
300
|
-
"isolateMargin": "0",
|
|
301
|
-
"walletBalance": "16.54467927074",
|
|
302
|
-
"lockAmount": "0",
|
|
303
|
-
"accountNormal": "16.54467927074",
|
|
304
|
-
"totalMarginRate": "7.8523952153487187"
|
|
305
|
-
}
|
|
306
|
-
"""
|
|
307
|
-
return self._get("balance")
|
|
308
|
-
|
|
309
|
-
@property
|
|
310
|
-
def orders(self) -> Orders:
|
|
311
|
-
"""
|
|
312
|
-
_key: orderId
|
|
313
|
-
|
|
314
|
-
.. code:: json
|
|
315
|
-
|
|
316
|
-
{
|
|
317
|
-
"orderId": "2951913499074783723",
|
|
318
|
-
"contractId": 169,
|
|
319
|
-
"side": "SELL",
|
|
320
|
-
"price": 0.15,
|
|
321
|
-
"volume": 1,
|
|
322
|
-
"status": 0
|
|
323
|
-
}
|
|
324
|
-
"""
|
|
325
|
-
return self._get("orders")
|
|
326
|
-
|
|
327
|
-
@property
|
|
328
|
-
def history_orders(self) -> HistoryOrders:
|
|
329
|
-
"""
|
|
330
|
-
_key: orderId
|
|
331
|
-
|
|
332
|
-
历史委托记录,与 ``orders`` 结构一致。
|
|
333
|
-
"""
|
|
334
|
-
return self._get("history_orders")
|
|
File without changes
|