hyperquant 0.7__py3-none-any.whl → 0.9__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/auth.py +74 -1
- hyperquant/broker/bitget.py +245 -35
- hyperquant/broker/coinup.py +556 -0
- hyperquant/broker/coinw.py +487 -0
- hyperquant/broker/lbank.py +312 -5
- hyperquant/broker/models/bitget.py +84 -8
- hyperquant/broker/models/coinup.py +290 -0
- hyperquant/broker/models/coinw.py +724 -0
- hyperquant/broker/models/lbank.py +16 -6
- hyperquant/broker/ws.py +53 -4
- {hyperquant-0.7.dist-info → hyperquant-0.9.dist-info}/METADATA +4 -2
- {hyperquant-0.7.dist-info → hyperquant-0.9.dist-info}/RECORD +13 -9
- {hyperquant-0.7.dist-info → hyperquant-0.9.dist-info}/WHEEL +0 -0
|
@@ -184,7 +184,8 @@ class Orders(DataStore):
|
|
|
184
184
|
"side": direction,
|
|
185
185
|
"offset": offset_flag,
|
|
186
186
|
"order_type": order_kind,
|
|
187
|
-
"price": entry.get("Price"),
|
|
187
|
+
"price": entry.get('TradePrice') or entry.get("Price"),
|
|
188
|
+
"order_price": entry.get("OrderPrice") or entry.get('Price'),
|
|
188
189
|
"quantity": entry.get("Volume"),
|
|
189
190
|
"filled": entry.get("VolumeTraded"),
|
|
190
191
|
"remaining": entry.get("VolumeRemain"),
|
|
@@ -270,14 +271,20 @@ class Position(DataStore):
|
|
|
270
271
|
if not entry:
|
|
271
272
|
return None
|
|
272
273
|
position_id = entry.get("PositionID")
|
|
274
|
+
bus_id = entry.get("BusinessNo")
|
|
273
275
|
if not position_id:
|
|
274
276
|
return None
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
side =
|
|
278
|
-
|
|
277
|
+
|
|
278
|
+
q = float(entry.get("Position", 0))
|
|
279
|
+
side = "net"
|
|
280
|
+
if q > 0:
|
|
281
|
+
side = "long"
|
|
282
|
+
elif q < 0:
|
|
283
|
+
side = "short"
|
|
284
|
+
|
|
279
285
|
return {
|
|
280
286
|
"position_id": position_id,
|
|
287
|
+
"bus_id": bus_id,
|
|
281
288
|
"symbol": entry.get("InstrumentID"),
|
|
282
289
|
"side": side,
|
|
283
290
|
"quantity": entry.get("Position"),
|
|
@@ -291,6 +298,7 @@ class Position(DataStore):
|
|
|
291
298
|
"realized_pnl": entry.get("CloseProfit"),
|
|
292
299
|
"update_time": entry.get("UpdateTime"),
|
|
293
300
|
"insert_time": entry.get("InsertTime"),
|
|
301
|
+
"begin_time": entry.get("BeginTime")
|
|
294
302
|
}
|
|
295
303
|
|
|
296
304
|
def _onresponse(self, data: dict[str, Any] | None) -> None:
|
|
@@ -472,6 +480,7 @@ class LbankDataStore(DataStoreCollection):
|
|
|
472
480
|
[
|
|
473
481
|
{
|
|
474
482
|
"position_id": <仓位ID>,
|
|
483
|
+
"bus_id": <订单ID覆盖>,
|
|
475
484
|
"symbol": <合约ID>,
|
|
476
485
|
"side": "long" / "short" / "net",
|
|
477
486
|
"quantity": <持仓数量>,
|
|
@@ -484,7 +493,8 @@ class LbankDataStore(DataStoreCollection):
|
|
|
484
493
|
"unrealized_pnl": <未实现盈亏>,
|
|
485
494
|
"realized_pnl": <已实现盈亏>,
|
|
486
495
|
"update_time": <更新时间>,
|
|
487
|
-
"insert_time":
|
|
496
|
+
"insert_time": <插入时间>,
|
|
497
|
+
"begin_time": <持仓开始时间>
|
|
488
498
|
},
|
|
489
499
|
...
|
|
490
500
|
]
|
hyperquant/broker/ws.py
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
import base64
|
|
3
2
|
import time
|
|
4
3
|
from typing import Any
|
|
5
4
|
|
|
6
5
|
import pybotters
|
|
6
|
+
from aiohttp import WSMsgType
|
|
7
7
|
from pybotters.ws import ClientWebSocketResponse, logger
|
|
8
|
-
from pybotters.auth import Hosts
|
|
9
|
-
import urllib
|
|
10
|
-
import yarl
|
|
11
8
|
|
|
12
9
|
|
|
13
10
|
class Heartbeat:
|
|
@@ -34,11 +31,18 @@ class Heartbeat:
|
|
|
34
31
|
while not ws.closed:
|
|
35
32
|
await ws.send_str('ping')
|
|
36
33
|
await asyncio.sleep(6)
|
|
34
|
+
|
|
35
|
+
@staticmethod
|
|
36
|
+
async def coinw(ws: ClientWebSocketResponse):
|
|
37
|
+
while not ws.closed:
|
|
38
|
+
await ws.send_json({"event": "ping"})
|
|
39
|
+
await asyncio.sleep(3.0)
|
|
37
40
|
|
|
38
41
|
pybotters.ws.HeartbeatHosts.items['futures.ourbit.com'] = Heartbeat.ourbit
|
|
39
42
|
pybotters.ws.HeartbeatHosts.items['www.ourbit.com'] = Heartbeat.ourbit_spot
|
|
40
43
|
pybotters.ws.HeartbeatHosts.items['quote.edgex.exchange'] = Heartbeat.edgex
|
|
41
44
|
pybotters.ws.HeartbeatHosts.items['uuws.rerrkvifj.com'] = Heartbeat.lbank
|
|
45
|
+
pybotters.ws.HeartbeatHosts.items['ws.futurescw.com'] = Heartbeat.coinw
|
|
42
46
|
|
|
43
47
|
class WssAuth:
|
|
44
48
|
@staticmethod
|
|
@@ -63,4 +67,49 @@ class WssAuth:
|
|
|
63
67
|
else:
|
|
64
68
|
logger.warning(f"WebSocket login failed: {data}")
|
|
65
69
|
|
|
70
|
+
@staticmethod
|
|
71
|
+
async def coinw(ws: ClientWebSocketResponse):
|
|
72
|
+
creds = ws._response._session.__dict__["_apis"].get(
|
|
73
|
+
pybotters.ws.AuthHosts.items[ws._response.url.host].name
|
|
74
|
+
)
|
|
75
|
+
if not creds:
|
|
76
|
+
raise RuntimeError("CoinW credentials are required for websocket login.")
|
|
77
|
+
if isinstance(creds, dict):
|
|
78
|
+
raise RuntimeError("CoinW credentials must be a sequence, not a dict.")
|
|
79
|
+
if len(creds) < 1:
|
|
80
|
+
raise RuntimeError("CoinW credentials are incomplete.")
|
|
81
|
+
|
|
82
|
+
api_key = creds[0]
|
|
83
|
+
secret = creds[1] if len(creds) > 1 else ""
|
|
84
|
+
|
|
85
|
+
await ws.send_json(
|
|
86
|
+
{
|
|
87
|
+
"event": "login",
|
|
88
|
+
"params": {
|
|
89
|
+
"api_key": api_key,
|
|
90
|
+
"passphrase": secret.decode(),
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
async for msg in ws:
|
|
96
|
+
if msg.type != WSMsgType.TEXT:
|
|
97
|
+
continue
|
|
98
|
+
try:
|
|
99
|
+
data:dict = msg.json()
|
|
100
|
+
except Exception: # pragma: no cover - defensive
|
|
101
|
+
continue
|
|
102
|
+
|
|
103
|
+
channel = data.get("channel")
|
|
104
|
+
event_type = data.get("type")
|
|
105
|
+
if channel == "login" or event_type == "login":
|
|
106
|
+
result = data.get("data", {}).get("result")
|
|
107
|
+
if result is not True:
|
|
108
|
+
raise RuntimeError(f"CoinW WebSocket login failed: {data}")
|
|
109
|
+
break
|
|
110
|
+
if data.get("event") == "pong":
|
|
111
|
+
# ignore heartbeat responses while waiting
|
|
112
|
+
continue
|
|
113
|
+
|
|
66
114
|
pybotters.ws.AuthHosts.items['futures.ourbit.com'] = pybotters.auth.Item("ourbit", WssAuth.ourbit)
|
|
115
|
+
pybotters.ws.AuthHosts.items['ws.futurescw.com'] = pybotters.auth.Item("coinw", WssAuth.coinw)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hyperquant
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9
|
|
4
4
|
Summary: A minimal yet hyper-efficient backtesting framework for quantitative trading
|
|
5
5
|
Project-URL: Homepage, https://github.com/yourusername/hyperquant
|
|
6
6
|
Project-URL: Issues, https://github.com/yourusername/hyperquant/issues
|
|
@@ -12,15 +12,17 @@ Classifier: Intended Audience :: Developers
|
|
|
12
12
|
Classifier: License :: OSI Approved :: MIT License
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
14
|
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
15
|
-
Requires-Python: >=3.
|
|
15
|
+
Requires-Python: >=3.11
|
|
16
16
|
Requires-Dist: aiohttp>=3.10.4
|
|
17
17
|
Requires-Dist: colorama>=0.4.6
|
|
18
18
|
Requires-Dist: cryptography>=44.0.2
|
|
19
|
+
Requires-Dist: curl-cffi>=0.13.0
|
|
19
20
|
Requires-Dist: duckdb>=1.2.2
|
|
20
21
|
Requires-Dist: numpy>=1.21.0
|
|
21
22
|
Requires-Dist: pandas>=2.2.3
|
|
22
23
|
Requires-Dist: pybotters>=1.9.1
|
|
23
24
|
Requires-Dist: pyecharts>=2.0.8
|
|
25
|
+
Requires-Dist: rnet==3.0.0rc10
|
|
24
26
|
Description-Content-Type: text/markdown
|
|
25
27
|
|
|
26
28
|
# minquant
|
|
@@ -4,26 +4,30 @@ hyperquant/db.py,sha256=i2TjkCbmH4Uxo7UTDvOYBfy973gLcGexdzuT_YcSeIE,6678
|
|
|
4
4
|
hyperquant/draw.py,sha256=up_lQ3pHeVLoNOyh9vPjgNwjD0M-6_IetSGviQUgjhY,54624
|
|
5
5
|
hyperquant/logkit.py,sha256=nUo7nx5eONvK39GOhWwS41zNRL756P2J7-5xGzwXnTY,8462
|
|
6
6
|
hyperquant/notikit.py,sha256=x5yAZ_tAvLQRXcRbcg-VabCaN45LUhvlTZnUqkIqfAA,3596
|
|
7
|
-
hyperquant/broker/auth.py,sha256=
|
|
8
|
-
hyperquant/broker/bitget.py,sha256=
|
|
7
|
+
hyperquant/broker/auth.py,sha256=xNZEQP0LRRV9BkT2uXBJ-vFfeahUnRVq1bjIT6YbQu8,10089
|
|
8
|
+
hyperquant/broker/bitget.py,sha256=X_S0LKZ7FZAEb6oEMr1vdGP1fondzK74BhmNTpRDSEA,9488
|
|
9
|
+
hyperquant/broker/coinup.py,sha256=Ag0si2ODnrERaB_PDj9oidBkUu7JeorfHPG7fRsbblg,19217
|
|
10
|
+
hyperquant/broker/coinw.py,sha256=SnJU0vASh77rfcpMGWaIfTblQSjQk3vjlW_4juYdbcs,17214
|
|
9
11
|
hyperquant/broker/edgex.py,sha256=TqUO2KRPLN_UaxvtLL6HnA9dAQXC1sGxOfqTHd6W5k8,18378
|
|
10
12
|
hyperquant/broker/hyperliquid.py,sha256=7MxbI9OyIBcImDelPJu-8Nd53WXjxPB5TwE6gsjHbto,23252
|
|
11
|
-
hyperquant/broker/lbank.py,sha256=
|
|
13
|
+
hyperquant/broker/lbank.py,sha256=98M5wmSoeHwbBYMA3rh25zqLb6fQKVaEmwqALF5nOvY,22181
|
|
12
14
|
hyperquant/broker/ourbit.py,sha256=NUcDSIttf-HGWzoW1uBTrGLPHlkuemMjYCm91MigTno,18228
|
|
13
|
-
hyperquant/broker/ws.py,sha256=
|
|
15
|
+
hyperquant/broker/ws.py,sha256=NS71Do-62mtVrGcyNE-AtHJkDecsSxdz_KU1yNBr_BQ,4079
|
|
14
16
|
hyperquant/broker/lib/edgex_sign.py,sha256=lLUCmY8HHRLfLKyGrlTJYaBlSHPsIMWg3EZnQJKcmyk,95785
|
|
15
17
|
hyperquant/broker/lib/hpstore.py,sha256=LnLK2zmnwVvhEbLzYI-jz_SfYpO1Dv2u2cJaRAb84D8,8296
|
|
16
18
|
hyperquant/broker/lib/hyper_types.py,sha256=HqjjzjUekldjEeVn6hxiWA8nevAViC2xHADOzDz9qyw,991
|
|
17
19
|
hyperquant/broker/lib/util.py,sha256=iMU1qF0CHj5zzlIMEQGwjz-qtEVosEe7slXOCuB7Rcw,566
|
|
18
|
-
hyperquant/broker/models/bitget.py,sha256=
|
|
20
|
+
hyperquant/broker/models/bitget.py,sha256=0RwDY75KrJb-c-oYoMxbqxWfsILe-n_Npojz4UFUq7c,11389
|
|
21
|
+
hyperquant/broker/models/coinup.py,sha256=W34WpbcnKz6JjfDMf8yC7JV_teCFcQR_5WvmyWCmPsQ,9803
|
|
22
|
+
hyperquant/broker/models/coinw.py,sha256=LvLMVP7i-qkkTK1ubw8eBkMK2RQmFoKPxdKqmC4IToY,22157
|
|
19
23
|
hyperquant/broker/models/edgex.py,sha256=vPAkceal44cjTYKQ_0BoNAskOpmkno_Yo1KxgMLPc6Y,33954
|
|
20
24
|
hyperquant/broker/models/hyperliquid.py,sha256=c4r5739ibZfnk69RxPjQl902AVuUOwT8RNvKsMtwXBY,9459
|
|
21
|
-
hyperquant/broker/models/lbank.py,sha256=
|
|
25
|
+
hyperquant/broker/models/lbank.py,sha256=vHkNKxIMzpoC_EwcZnEOPOupizF92yGWi9GKxvYYFUQ,19181
|
|
22
26
|
hyperquant/broker/models/ourbit.py,sha256=xMcbuCEXd3XOpPBq0RYF2zpTFNnxPtuNJZCexMZVZ1k,41965
|
|
23
27
|
hyperquant/datavison/_util.py,sha256=92qk4vO856RqycO0YqEIHJlEg-W9XKapDVqAMxe6rbw,533
|
|
24
28
|
hyperquant/datavison/binance.py,sha256=3yNKTqvt_vUQcxzeX4ocMsI5k6Q6gLZrvgXxAEad6Kc,5001
|
|
25
29
|
hyperquant/datavison/coinglass.py,sha256=PEjdjISP9QUKD_xzXNzhJ9WFDTlkBrRQlVL-5pxD5mo,10482
|
|
26
30
|
hyperquant/datavison/okx.py,sha256=yg8WrdQ7wgWHNAInIgsWPM47N3Wkfr253169IPAycAY,6898
|
|
27
|
-
hyperquant-0.
|
|
28
|
-
hyperquant-0.
|
|
29
|
-
hyperquant-0.
|
|
31
|
+
hyperquant-0.9.dist-info/METADATA,sha256=VFXXWiKJ4_NZhv48TUkYGp9_P1zkRdou-7hKi07qMLw,4381
|
|
32
|
+
hyperquant-0.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
33
|
+
hyperquant-0.9.dist-info/RECORD,,
|
|
File without changes
|