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: ["symbol", "side", "px"]
26
- - symbol: 交易对符号
27
- - side: 买卖方向 (A: ask卖出, B: bid买入)
28
- - px: 价格
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 = ["symbol", "side", "i"]
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[:5]
47
- bids = bids[:5]
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({"symbol": symbol})
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
- "symbol": symbol,
65
- "side": side_id,
66
- "px": str(price),
67
- "sz": str(size),
68
- "count": count,
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(self) -> dict[str, list[Item]]:
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="side",
104
- item_asc_key="A", # asks 升序
105
- item_desc_key="B", # bids 降序
106
- sort_key="px",
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
- "px": order.get("price"),
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
- "deal_vol": order.get("dealVol"),
155
- "deal_avg_px": order.get("dealAvgPrice"),
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
- "position_id": position.get("positionId"),
229
- "symbol": position.get("symbol"),
230
- "side": "short" if position.get("positionType") == 2 else "long",
231
- "open_type": position.get("openType"),
232
- "state": position.get("state"),
233
- "hold_vol": position.get("holdVol"),
234
- "frozen_vol": position.get("frozenVol"),
235
- "close_vol": position.get("closeVol"),
236
- "hold_avg_price": position.get("holdAvgPriceFullyScale"),
237
- "open_avg_price": position.get("openAvgPriceFullyScale"),
238
- "close_avg_price": str(position.get("closeAvgPrice")),
239
- "liquidate_price": str(position.get("liquidatePrice")),
240
- "oim": position.get("oim"),
241
- "im": position.get("im"),
242
- "hold_fee": position.get("holdFee"),
243
- "realised": position.get("realised"),
244
- "leverage": position.get("leverage"),
245
- "margin_ratio": position.get("marginRatio"),
246
- "create_ts": position.get("createTime"),
247
- "update_ts": position.get("updateTime"),
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: ("symbol", "side", "px")
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
- "symbol": "BTC_USDT", # 交易对
430
- "side": "A", # 卖出方向
431
- "px": "110152.5", # 价格
432
- "sz": "53539", # 数量
433
- "count": 1 # 订单数量
434
- "i" 0 # 价格档位索引
435
- },
436
- {
437
- "symbol": "BTC_USDT", # 交易对
438
- "side": "B", # 买入方向
439
- "px": "110152.4", # 价格
440
- "sz": "76311", # 数量
441
- "count": 1 # 订单数量
442
- "i" 0 # 价格档位索引
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 state in (2, 3):
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
- if state == 4:
727
- item["state"] = "canceled"
728
- self._update([item])
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.51
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=iEI8qTNpyesB_w67SrKXeGoB9JllovBeJKI0EZFYew4,20631
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=rFJEFwzTravStHsB0kEwP5YhI2EQsn79Vv7aEiCIWLc,41585
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.51.dist-info/METADATA,sha256=ZB9iF5hWyPtdDsqc3jcekGUswYvKSmJgsfEN6OqI37k,4317
20
- hyperquant-0.51.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
21
- hyperquant-0.51.dist-info/RECORD,,
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,,