hyperquant 0.83__tar.gz → 0.85__tar.gz

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.

Files changed (51) hide show
  1. {hyperquant-0.83 → hyperquant-0.85}/PKG-INFO +1 -1
  2. {hyperquant-0.83 → hyperquant-0.85}/pyproject.toml +1 -1
  3. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/coinw.py +7 -1
  4. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/models/coinw.py +79 -0
  5. {hyperquant-0.83 → hyperquant-0.85}/tests/test_coinw.py +8 -7
  6. {hyperquant-0.83 → hyperquant-0.85}/uv.lock +1 -1
  7. {hyperquant-0.83 → hyperquant-0.85}/.gitignore +0 -0
  8. {hyperquant-0.83 → hyperquant-0.85}/.python-version +0 -0
  9. {hyperquant-0.83 → hyperquant-0.85}/README.md +0 -0
  10. {hyperquant-0.83 → hyperquant-0.85}/apis.json +0 -0
  11. {hyperquant-0.83 → hyperquant-0.85}/data/alpine_smoke.log +0 -0
  12. {hyperquant-0.83 → hyperquant-0.85}/data/logs/notikit.log +0 -0
  13. {hyperquant-0.83 → hyperquant-0.85}/data/logs/test_order_sync.log +0 -0
  14. {hyperquant-0.83 → hyperquant-0.85}/data/records_swap.csv +0 -0
  15. {hyperquant-0.83 → hyperquant-0.85}/data/records_swapc.csv +0 -0
  16. {hyperquant-0.83 → hyperquant-0.85}/doc/lbank.md +0 -0
  17. {hyperquant-0.83 → hyperquant-0.85}/pub.sh +0 -0
  18. {hyperquant-0.83 → hyperquant-0.85}/requirements-dev.lock +0 -0
  19. {hyperquant-0.83 → hyperquant-0.85}/requirements.lock +0 -0
  20. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/__init__.py +0 -0
  21. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/auth.py +0 -0
  22. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/bitget.py +0 -0
  23. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/edgex.py +0 -0
  24. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/hyperliquid.py +0 -0
  25. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/lbank.py +0 -0
  26. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/lib/edgex_sign.py +0 -0
  27. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/lib/hpstore.py +0 -0
  28. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/lib/hyper_types.py +0 -0
  29. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/lib/util.py +0 -0
  30. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/models/bitget.py +0 -0
  31. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/models/edgex.py +0 -0
  32. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/models/hyperliquid.py +0 -0
  33. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/models/lbank.py +0 -0
  34. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/models/ourbit.py +0 -0
  35. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/ourbit.py +0 -0
  36. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/ws.py +0 -0
  37. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/core.py +0 -0
  38. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/datavison/_util.py +0 -0
  39. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/datavison/binance.py +0 -0
  40. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/datavison/coinglass.py +0 -0
  41. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/datavison/okx.py +0 -0
  42. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/db.py +0 -0
  43. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/draw.py +0 -0
  44. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/logkit.py +0 -0
  45. {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/notikit.py +0 -0
  46. {hyperquant-0.83 → hyperquant-0.85}/tests/test_bitget.py +0 -0
  47. {hyperquant-0.83 → hyperquant-0.85}/tests/test_draw.py +0 -0
  48. {hyperquant-0.83 → hyperquant-0.85}/tests/test_edgex.py +0 -0
  49. {hyperquant-0.83 → hyperquant-0.85}/tests/test_lbank.py +0 -0
  50. {hyperquant-0.83 → hyperquant-0.85}/tests/test_ourbit.py +0 -0
  51. {hyperquant-0.83 → hyperquant-0.85}/tests/tmp.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperquant
3
- Version: 0.83
3
+ Version: 0.85
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,6 +1,6 @@
1
1
  [project]
2
2
  name = "hyperquant"
3
- version = "0.83"
3
+ version = "0.85"
4
4
  description = "A minimal yet hyper-efficient backtesting framework for quantitative trading"
5
5
  authors = [
6
6
  { name = "MissinA", email = "1421329142@qq.com" }
@@ -52,6 +52,7 @@ class Coinw:
52
52
  self,
53
53
  update_type: Literal[
54
54
  "detail",
55
+ "ticker",
55
56
  "orders",
56
57
  "position",
57
58
  "balance",
@@ -67,6 +68,7 @@ class Coinw:
67
68
  """刷新本地缓存,使用 CoinW REST API。
68
69
 
69
70
  - detail: ``GET /v1/perpum/instruments`` (公共)
71
+ - ticker: ``GET /v1/perpumPublic/tickers`` (公共)
70
72
  - orders: ``GET /v1/perpum/orders/open`` (私有,需要 ``instrument``)
71
73
  - position: ``GET /v1/perpum/positions`` (私有,需要 ``instrument``)
72
74
  - balance: ``GET /v1/perpum/account/getUserAssets`` (私有)
@@ -75,6 +77,7 @@ class Coinw:
75
77
  requests: list[Any] = []
76
78
 
77
79
  include_detail = update_type in {"detail", "all"}
80
+ include_ticker = update_type in {"ticker", "all"}
78
81
  include_orders = update_type in {"orders", "all"}
79
82
  include_position = update_type in {"position", "all"}
80
83
  include_balance = update_type in {"balance", "all"}
@@ -82,6 +85,9 @@ class Coinw:
82
85
  if include_detail:
83
86
  requests.append(self.client.get(f"{self.rest_api}/v1/perpum/instruments"))
84
87
 
88
+ if include_ticker:
89
+ requests.append(self.client.get(f"{self.rest_api}/v1/perpumPublic/tickers"))
90
+
85
91
  if include_orders:
86
92
  if not instrument:
87
93
  raise ValueError("instrument is required when updating orders")
@@ -299,7 +305,7 @@ class Coinw:
299
305
  self,
300
306
  pair_codes: Sequence[str] | str,
301
307
  *,
302
- depth_limit: int | None = None,
308
+ depth_limit: int | None = 1,
303
309
  biz: str = "futures",
304
310
  ) -> pybotters.ws.WebSocketApp:
305
311
  """订阅 ``type=depth`` 订单簿数据,批量控制发送频率。"""
@@ -142,6 +142,55 @@ class Detail(DataStore):
142
142
  self._insert(items)
143
143
 
144
144
 
145
+ class Ticker(DataStore):
146
+ """CoinW 24h 交易摘要数据存储。
147
+
148
+ 文档: https://www.coinw.com/api-doc/futures-trading/market/get-last-trade-summary-of-all-instruments
149
+ """
150
+
151
+ _KEYS = ["name"]
152
+
153
+ @staticmethod
154
+ def _normalize(entry: dict[str, Any]) -> dict[str, Any] | None:
155
+ instrument = entry.get("instrument") or entry.get("symbol") or entry.get("pairCode")
156
+ if not instrument:
157
+ return None
158
+ normalized = dict(entry)
159
+ normalized["instrument"] = str(instrument).upper()
160
+ return normalized
161
+
162
+ def _onresponse(self, data: Any) -> None:
163
+ if isinstance(data, dict):
164
+ entries = data.get("data") or []
165
+ else:
166
+ entries = data
167
+
168
+ self._update(entries)
169
+
170
+ def _on_message(self, msg: dict[str, Any]) -> None:
171
+ data = msg.get("data")
172
+ entries: list[dict[str, Any]] = []
173
+ if isinstance(data, list):
174
+ entries = data
175
+ elif isinstance(data, dict):
176
+ entries = data.get("data") or data.get("tickers") or []
177
+
178
+ items: list[dict[str, Any]] = []
179
+ for entry in entries:
180
+ if not isinstance(entry, dict):
181
+ continue
182
+ normalized = self._normalize(entry)
183
+ if normalized:
184
+ items.append(normalized)
185
+
186
+ if not items:
187
+ return
188
+
189
+ instruments = [{"instrument": item["instrument"]} for item in items]
190
+ self._delete(instruments)
191
+ self._insert(items)
192
+
193
+
145
194
  class Orders(DataStore):
146
195
  """CoinW 当前订单数据存储。"""
147
196
 
@@ -386,6 +435,7 @@ class CoinwFuturesDataStore(DataStoreCollection):
386
435
  def _init(self) -> None:
387
436
  self._create("book", datastore_class=Book)
388
437
  self._create("detail", datastore_class=Detail)
438
+ self._create("ticker", datastore_class=Ticker)
389
439
  self._create("orders", datastore_class=Orders)
390
440
  self._create("position", datastore_class=Position)
391
441
  self._create("balance", datastore_class=Balance)
@@ -400,6 +450,8 @@ class CoinwFuturesDataStore(DataStoreCollection):
400
450
  self.position._on_message(msg)
401
451
  elif msg_type == "assets":
402
452
  self.balance._on_message(msg)
453
+ elif msg_type == "ticker":
454
+ self.ticker._on_message(msg)
403
455
 
404
456
  async def initialize(self, *aws: Awaitable[aiohttp.ClientResponse]) -> None:
405
457
  for fut in asyncio.as_completed(aws):
@@ -407,6 +459,8 @@ class CoinwFuturesDataStore(DataStoreCollection):
407
459
  data = await res.json()
408
460
  if res.url.path == "/v1/perpum/instruments":
409
461
  self.detail._onresponse(data)
462
+ elif res.url.path == "/v1/perpumPublic/tickers":
463
+ self.ticker._onresponse(data)
410
464
  elif res.url.path == "/v1/perpum/orders/open":
411
465
  self.orders._onresponse(data)
412
466
  elif res.url.path == "/v1/perpum/positions":
@@ -512,6 +566,31 @@ class CoinwFuturesDataStore(DataStoreCollection):
512
566
 
513
567
  return self._get("detail", Detail)
514
568
 
569
+ @property
570
+ def ticker(self) -> Ticker:
571
+ """24小时交易摘要数据流。
572
+
573
+ .. code:: json
574
+
575
+ {
576
+ 'fair_price': 97072.4,
577
+ 'max_leverage': 125,
578
+ 'total_volume': 0.003,
579
+ 'price_coin': 'btc',
580
+ 'contract_id': 1,
581
+ 'base_coin': 'btc',
582
+ 'high': 98001.5,
583
+ 'rise_fall_rate': 0.012275,
584
+ 'low': 95371.4,
585
+ 'name': 'BTCUSDT',
586
+ 'contract_size': 0.001,
587
+ 'quote_coin': 'usdt',
588
+ 'last_price': 97072.4
589
+ }
590
+
591
+ """
592
+ return self._get("ticker", Ticker)
593
+
515
594
  @property
516
595
  def orders(self) -> Orders:
517
596
  """当前订单数据流。
@@ -7,15 +7,16 @@ import pybotters
7
7
  from hyperquant.broker.coinw import Coinw
8
8
 
9
9
 
10
- async def test_detail() -> None:
10
+ async def test_update() -> None:
11
11
  """Fetch instrument metadata via REST."""
12
12
  async with pybotters.Client() as client:
13
13
  async with Coinw(client) as cw:
14
- detail = cw.store.detail.find({
15
- 'symbol': 'SOL_USDT'
16
- })
17
- print(detail)
18
-
14
+ # detail = cw.store.detail.find({
15
+ # 'symbol': 'SOL_USDT'
16
+ # })
17
+ # print(detail)
18
+ await cw.update('ticker')
19
+ print(cw.store.ticker.find())
19
20
 
20
21
 
21
22
  async def test_update_private() -> None:
@@ -208,4 +209,4 @@ async def test_order_sync_polling() -> None:
208
209
 
209
210
 
210
211
  if __name__ == "__main__":
211
- asyncio.run(test_order_sync_polling())
212
+ asyncio.run(test_update())
@@ -662,7 +662,7 @@ wheels = [
662
662
 
663
663
  [[package]]
664
664
  name = "hyperquant"
665
- version = "0.82"
665
+ version = "0.84"
666
666
  source = { editable = "." }
667
667
  dependencies = [
668
668
  { name = "aiohttp" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes