hyperquant 0.51__py3-none-any.whl → 0.53__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.
@@ -22,19 +22,20 @@ class Book(DataStore):
|
|
22
22
|
Channel: push.depth.step
|
23
23
|
|
24
24
|
用于存储和管理订单簿深度数据,包含买卖盘的价格和数量信息
|
25
|
-
Keys: ["
|
26
|
-
-
|
27
|
-
-
|
28
|
-
-
|
25
|
+
Keys: ["s", "S", "p"]
|
26
|
+
- s: 交易对符号
|
27
|
+
- S: 买卖方向 (A: ask卖出, B: bid买入)
|
28
|
+
- p: 价格
|
29
29
|
|
30
30
|
|
31
31
|
"""
|
32
32
|
|
33
|
-
_KEYS = ["
|
33
|
+
_KEYS = ["s", "S", "p"]
|
34
34
|
|
35
35
|
def _init(self) -> None:
|
36
36
|
# super().__init__()
|
37
37
|
self._time: int | None = None
|
38
|
+
self.limit = 1
|
38
39
|
|
39
40
|
def _on_message(self, msg: dict[str, Any]) -> None:
|
40
41
|
|
@@ -43,15 +44,15 @@ class Book(DataStore):
|
|
43
44
|
asks = data.get("asks", [])
|
44
45
|
bids = data.get("bids", [])
|
45
46
|
# 提速 默认 5当前
|
46
|
-
asks = asks[:
|
47
|
-
bids = bids[:
|
47
|
+
asks = asks[:self.limit]
|
48
|
+
bids = bids[:self.limit]
|
48
49
|
|
49
50
|
timestamp = data.get("ct") # 使用服务器时间
|
50
51
|
|
51
52
|
data_to_insert: list[Item] = []
|
52
53
|
|
53
54
|
# 先删除旧的订单簿数据
|
54
|
-
self._find_and_delete({"
|
55
|
+
self._find_and_delete({"s": symbol})
|
55
56
|
|
56
57
|
# 处理买卖盘数据
|
57
58
|
for side_id, levels in (("B", bids), ("A", asks)):
|
@@ -61,11 +62,11 @@ class Book(DataStore):
|
|
61
62
|
price, size, count = level[0:3]
|
62
63
|
data_to_insert.append(
|
63
64
|
{
|
64
|
-
"
|
65
|
-
"
|
66
|
-
"
|
67
|
-
"
|
68
|
-
"
|
65
|
+
"s": symbol,
|
66
|
+
"S": side_id,
|
67
|
+
"p": str(price),
|
68
|
+
"q": str(size),
|
69
|
+
"ct": count,
|
69
70
|
"i": i
|
70
71
|
}
|
71
72
|
)
|
@@ -80,30 +81,17 @@ class Book(DataStore):
|
|
80
81
|
return self._time
|
81
82
|
|
82
83
|
@property
|
83
|
-
def sorted(
|
84
|
-
|
85
|
-
|
86
|
-
Returns:
|
87
|
-
返回按价格排序的买卖盘数据,卖盘升序,买盘降序
|
88
|
-
|
89
|
-
.. code-block:: python
|
84
|
+
def sorted(
|
85
|
+
self, query: Item | None = None, limit: int | None = None
|
86
|
+
) -> dict[str, list[Item]]:
|
90
87
|
|
91
|
-
{
|
92
|
-
"asks": [
|
93
|
-
{"symbol": "BTC_USDT", "side": "A", "px": "110152.5", "sz": "53539", "count": 1},
|
94
|
-
{"symbol": "BTC_USDT", "side": "A", "px": "110152.6", "sz": "95513", "count": 2}
|
95
|
-
],
|
96
|
-
"bids": [
|
97
|
-
{"symbol": "BTC_USDT", "side": "B", "px": "110152.4", "sz": "76311", "count": 1},
|
98
|
-
{"symbol": "BTC_USDT", "side": "B", "px": "110152.3", "sz": "104688", "count": 2}
|
99
|
-
]
|
100
|
-
}
|
101
|
-
"""
|
102
88
|
return self._sorted(
|
103
|
-
item_key="
|
104
|
-
item_asc_key="
|
105
|
-
item_desc_key="
|
106
|
-
sort_key="
|
89
|
+
item_key="S",
|
90
|
+
item_asc_key="a", # asks 升序
|
91
|
+
item_desc_key="b", # bids 降序
|
92
|
+
sort_key="p",
|
93
|
+
query=query,
|
94
|
+
limit=limit,
|
107
95
|
)
|
108
96
|
|
109
97
|
|
@@ -147,14 +135,17 @@ class Orders(DataStore):
|
|
147
135
|
return {
|
148
136
|
"order_id": order.get("orderId"),
|
149
137
|
"symbol": order.get("symbol"),
|
150
|
-
"
|
138
|
+
"price": order.get("price"),
|
151
139
|
"vol": order.get("vol"),
|
152
140
|
"lev": order.get("leverage"),
|
153
141
|
"side": "buy" if order.get("side") == 1 else "sell",
|
154
|
-
"
|
155
|
-
"
|
142
|
+
"deal_quantity": order.get("dealVol"),
|
143
|
+
"avg_price": order.get("dealAvgPrice"),
|
156
144
|
"create_ts": order.get("createTime"),
|
157
145
|
"update_ts": order.get("updateTime"),
|
146
|
+
"fee": order.get("makerFee"),
|
147
|
+
"profit": order.get("profit"),
|
148
|
+
"used_margin": order.get("usedMargin"),
|
158
149
|
"state": "open"
|
159
150
|
}
|
160
151
|
|
@@ -192,6 +183,13 @@ class Orders(DataStore):
|
|
192
183
|
self._find_and_delete({
|
193
184
|
"order_id": order.get("order_id")
|
194
185
|
})
|
186
|
+
else:
|
187
|
+
order = self._fmt(data)
|
188
|
+
order["state"] = "unknown"
|
189
|
+
self._update([order])
|
190
|
+
self._find_and_delete({
|
191
|
+
"order_id": order.get("order_id")
|
192
|
+
})
|
195
193
|
|
196
194
|
class Detail(DataStore):
|
197
195
|
_KEYS = ["symbol"]
|
@@ -225,27 +223,27 @@ class Position(DataStore):
|
|
225
223
|
|
226
224
|
def _fmt(self, position:dict):
|
227
225
|
return {
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
226
|
+
"position_id": position.get("positionId"),
|
227
|
+
"symbol": position.get("symbol"),
|
228
|
+
"side": "short" if position.get("positionType") == 2 else "long",
|
229
|
+
"open_type": position.get("openType"),
|
230
|
+
"state": position.get("state"),
|
231
|
+
"hold_vol": position.get("holdVol"),
|
232
|
+
"frozen_vol": position.get("frozenVol"),
|
233
|
+
"close_vol": position.get("closeVol"),
|
234
|
+
"hold_avg_price": position.get("holdAvgPriceFullyScale"),
|
235
|
+
"open_avg_price": position.get("openAvgPriceFullyScale"),
|
236
|
+
"close_avg_price": str(position.get("closeAvgPrice")),
|
237
|
+
"liquidate_price": str(position.get("liquidatePrice")),
|
238
|
+
"oim": position.get("oim"),
|
239
|
+
"im": position.get("im"),
|
240
|
+
"hold_fee": position.get("holdFee"),
|
241
|
+
"realised": position.get("realised"),
|
242
|
+
"leverage": position.get("leverage"),
|
243
|
+
"margin_ratio": position.get("marginRatio"),
|
244
|
+
"create_ts": position.get("createTime"),
|
245
|
+
"update_ts": position.get("updateTime"),
|
246
|
+
}
|
249
247
|
|
250
248
|
def _onresponse(self, data: dict[str, Any]):
|
251
249
|
positions = data.get("data", [])
|
@@ -415,32 +413,37 @@ class OurbitSwapDataStore(DataStoreCollection):
|
|
415
413
|
@property
|
416
414
|
def book(self) -> Book:
|
417
415
|
"""订单簿深度数据流
|
418
|
-
|
416
|
+
|
417
|
+
提供实时订单簿深度数据,包含买卖双方价格和数量信息
|
418
|
+
|
419
419
|
Data type: Mutable
|
420
|
-
|
421
|
-
Keys: ("
|
420
|
+
|
421
|
+
Keys: ("s", "S", "p")
|
422
|
+
- s: 交易对符号,如 "BTC_USDT"
|
423
|
+
- S: 买卖方向,"A" 表示卖单(ask),"B" 表示买单(bid)
|
424
|
+
- p: 价格
|
422
425
|
|
423
426
|
Data structure:
|
424
427
|
|
425
428
|
.. code:: python
|
426
429
|
|
427
430
|
[
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
431
|
+
{
|
432
|
+
"s": "BTC_USDT", # 交易对符号
|
433
|
+
"S": "A", # 卖单方向(ask)
|
434
|
+
"p": "110152.5", # 价格
|
435
|
+
"q": "53539", # 数量
|
436
|
+
"ct": 1, # 该价格的订单数量
|
437
|
+
"i": 0 # 价格档位索引(从0开始)
|
438
|
+
},
|
439
|
+
{
|
440
|
+
"s": "BTC_USDT", # 交易对符号
|
441
|
+
"S": "B", # 买单方向(bid)
|
442
|
+
"p": "110152.4", # 价格
|
443
|
+
"q": "76311", # 数量
|
444
|
+
"ct": 1, # 该价格的订单数量
|
445
|
+
"i": 0 # 价格档位索引(从0开始)
|
446
|
+
}
|
444
447
|
]
|
445
448
|
"""
|
446
449
|
return self._get("book", Book)
|
@@ -639,7 +642,6 @@ class SpotOrders(DataStore):
|
|
639
642
|
}
|
640
643
|
|
641
644
|
|
642
|
-
|
643
645
|
def _onresponse(self, data: dict[str, Any]):
|
644
646
|
orders = (data.get("data") or {}).get("resultList", [])
|
645
647
|
items = [self._fmt(order) for order in orders]
|
@@ -669,14 +671,10 @@ class SpotOrders(DataStore):
|
|
669
671
|
|
670
672
|
state = d.get("status")
|
671
673
|
|
672
|
-
|
673
|
-
if state == 1:
|
674
|
-
item["state"] = "open"
|
675
|
-
self._insert([item])
|
676
|
-
return
|
674
|
+
|
677
675
|
|
678
676
|
# 成交片段(部分/完全)
|
679
|
-
if
|
677
|
+
if d.get("singleDealPrice"):
|
680
678
|
# 单片段信息(可能多次推送;需做增量累计 + 去重)
|
681
679
|
single_id = d.get("singleDealId")
|
682
680
|
single_px = d.get("singleDealPrice")
|
@@ -713,26 +711,38 @@ class SpotOrders(DataStore):
|
|
713
711
|
})
|
714
712
|
|
715
713
|
# 状态文本:2=filled(整单), 3=partially_filled
|
716
|
-
item["state"] = "filled" if state == 2 else "partially_filled"
|
714
|
+
# item["state"] = "filled" if state == 2 else "partially_filled"
|
715
|
+
if state == 2:
|
716
|
+
item["state"] = "filled"
|
717
|
+
elif state == 3:
|
718
|
+
item["state"] = "partially_filled"
|
719
|
+
else:
|
720
|
+
item["state"] = "unknown_"+str(state)
|
717
721
|
|
718
722
|
self._update([item])
|
719
723
|
|
720
|
-
# 整单成交 → 删除
|
721
|
-
if state == 2:
|
724
|
+
# 整单成交 或者 部分取消 → 删除
|
725
|
+
if state == 2 or 'unknown' in item["state"]:
|
722
726
|
self._find_and_delete({"order_id": d.get("id")})
|
723
727
|
return
|
728
|
+
else:
|
729
|
+
# 新建 / 已挂出
|
730
|
+
if state == 1:
|
731
|
+
item["state"] = "open"
|
732
|
+
self._insert([item])
|
733
|
+
return
|
734
|
+
|
735
|
+
elif state == 4:
|
736
|
+
item["state"] = "canceled"
|
737
|
+
self._update([item])
|
738
|
+
self._find_and_delete({"order_id": d.get("id")})
|
739
|
+
return
|
740
|
+
else:
|
724
741
|
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
self._find_and_delete({"order_id": d.get("id")})
|
730
|
-
return
|
731
|
-
|
732
|
-
# 未知状态:更新后删除,避免脏数据残留
|
733
|
-
item["state"] = "unknown"
|
734
|
-
self._update([item])
|
735
|
-
self._find_and_delete({"order_id": d.get("id")})
|
742
|
+
# 未知状态:更新后删除,避免脏数据残留
|
743
|
+
item["state"] = "unknown_"+str(state)
|
744
|
+
self._update([item])
|
745
|
+
self._find_and_delete({"order_id": d.get("id")})
|
736
746
|
|
737
747
|
|
738
748
|
|
@@ -764,7 +774,7 @@ class SpotBook(DataStore):
|
|
764
774
|
# items.sort(key=lambda x: x.get("fv", 0)) # 按 fromVersion 排序
|
765
775
|
# self._find_and_delete({"s": symbol})
|
766
776
|
|
767
|
-
#
|
777
|
+
# 应为我们先连接的ws, 所以可能有缓存需要去处理
|
768
778
|
items = [item for item in self.cache if item.get("s") == symbol]
|
769
779
|
items.sort(key=lambda x: x.get("fv", 0)) # 按 fromVersion 排序
|
770
780
|
self.cache = [item for item in self.cache if item.get("s") != symbol]
|
hyperquant/core.py
CHANGED
@@ -335,6 +335,9 @@ class Exchange(ExchangeBase):
|
|
335
335
|
self.account[symbol]['realised_profit'] += profit
|
336
336
|
self.account[symbol]['amount'] -= -direction * cover_amount
|
337
337
|
trade['pos'] = profit # 记录盈亏
|
338
|
+
|
339
|
+
trade['pos_rate'] = -direction * (price / self.account[symbol]['hold_price'] - 1) if self.account[symbol]['hold_price'] != 0 else 0
|
340
|
+
|
338
341
|
self.account[symbol]['hold_price'] = 0 if self.account[symbol]['amount'] == 0 else self.account[symbol]['hold_price']
|
339
342
|
|
340
343
|
if open_amount > 0:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: hyperquant
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.53
|
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
|
@@ -1,5 +1,5 @@
|
|
1
1
|
hyperquant/__init__.py,sha256=UpjiX4LS5jmrBc2kE8RiLR02eCfD8JDQrR1q8zkLNcQ,161
|
2
|
-
hyperquant/core.py,sha256=
|
2
|
+
hyperquant/core.py,sha256=RzRFbyImqzBiaA-9lQzvxPfxwcOvScdABZviS4y0kqM,20783
|
3
3
|
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
|
@@ -11,11 +11,11 @@ hyperquant/broker/ws.py,sha256=umRzxwCaZaRIgIq4YY-AuA0wCXFT0uOBmQbIXFY8CK0,1555
|
|
11
11
|
hyperquant/broker/lib/hpstore.py,sha256=LnLK2zmnwVvhEbLzYI-jz_SfYpO1Dv2u2cJaRAb84D8,8296
|
12
12
|
hyperquant/broker/lib/hyper_types.py,sha256=HqjjzjUekldjEeVn6hxiWA8nevAViC2xHADOzDz9qyw,991
|
13
13
|
hyperquant/broker/models/hyperliquid.py,sha256=c4r5739ibZfnk69RxPjQl902AVuUOwT8RNvKsMtwXBY,9459
|
14
|
-
hyperquant/broker/models/ourbit.py,sha256=
|
14
|
+
hyperquant/broker/models/ourbit.py,sha256=D-kDlmPNhly61yc6Ot-c1phmVBY_pJ2kWAaEkvRQWBo,41799
|
15
15
|
hyperquant/datavison/_util.py,sha256=92qk4vO856RqycO0YqEIHJlEg-W9XKapDVqAMxe6rbw,533
|
16
16
|
hyperquant/datavison/binance.py,sha256=3yNKTqvt_vUQcxzeX4ocMsI5k6Q6gLZrvgXxAEad6Kc,5001
|
17
17
|
hyperquant/datavison/coinglass.py,sha256=PEjdjISP9QUKD_xzXNzhJ9WFDTlkBrRQlVL-5pxD5mo,10482
|
18
18
|
hyperquant/datavison/okx.py,sha256=yg8WrdQ7wgWHNAInIgsWPM47N3Wkfr253169IPAycAY,6898
|
19
|
-
hyperquant-0.
|
20
|
-
hyperquant-0.
|
21
|
-
hyperquant-0.
|
19
|
+
hyperquant-0.53.dist-info/METADATA,sha256=Rmgye1BvHPDXfLEvKW7XB-fvdFDM0SLR2vjR8lVoE80,4317
|
20
|
+
hyperquant-0.53.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
21
|
+
hyperquant-0.53.dist-info/RECORD,,
|
File without changes
|