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.

@@ -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
- direction_code = str(entry.get("PosiDirection")) if entry.get("PosiDirection") is not None else None
277
- side = self._POS_DIRECTION_MAP.get(direction_code, direction_code)
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.7
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.9
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=Wst7mTBuUS2BQ5hZd0a8FNNs5Uc01ac9WzJpseTuyAY,7673
8
- hyperquant/broker/bitget.py,sha256=866OuWUek0xJM8qWa7Bh4GDvcwUe3JVrx5mQMv2WEJE,2616
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=dZUbi0a_Vhkp4pJ1V11X6nEM7I4HhQIVRgpSMeGcAMU,11681
13
+ hyperquant/broker/lbank.py,sha256=98M5wmSoeHwbBYMA3rh25zqLb6fQKVaEmwqALF5nOvY,22181
12
14
  hyperquant/broker/ourbit.py,sha256=NUcDSIttf-HGWzoW1uBTrGLPHlkuemMjYCm91MigTno,18228
13
- hyperquant/broker/ws.py,sha256=9Zu5JSLj-ylYEVmFmRwvZDDnVYKwb37cLHfZzA0AZGc,2200
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=swKYa7-jRoCSQxg0AUTZ7lPEhD1vxYIKm49eaIPwMxU,8961
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=ZCD1dOUMyWPT8lKDj6C6LcHEof2d0JN384McURzLA-s,18868
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.7.dist-info/METADATA,sha256=DZvCivcjbSzGsuRtDvwuaAiaG2zw61z_13guzOR2rsQ,4316
28
- hyperquant-0.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
29
- hyperquant-0.7.dist-info/RECORD,,
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,,