hyperquant 1.37__tar.gz → 1.38__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.
Files changed (44) hide show
  1. {hyperquant-1.37 → hyperquant-1.38}/PKG-INFO +1 -1
  2. {hyperquant-1.37 → hyperquant-1.38}/pyproject.toml +1 -1
  3. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/polymarket.py +44 -0
  4. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/polymarket.py +84 -0
  5. {hyperquant-1.37 → hyperquant-1.38}/uv.lock +1 -1
  6. {hyperquant-1.37 → hyperquant-1.38}/.gitignore +0 -0
  7. {hyperquant-1.37 → hyperquant-1.38}/README.md +0 -0
  8. {hyperquant-1.37 → hyperquant-1.38}/requirements-dev.lock +0 -0
  9. {hyperquant-1.37 → hyperquant-1.38}/requirements.lock +0 -0
  10. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/__init__.py +0 -0
  11. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/auth.py +0 -0
  12. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/bitget.py +0 -0
  13. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/bitmart.py +0 -0
  14. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/coinw.py +0 -0
  15. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/deepcoin.py +0 -0
  16. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/edgex.py +0 -0
  17. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/hyperliquid.py +0 -0
  18. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/lbank.py +0 -0
  19. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/lib/edgex_sign.py +0 -0
  20. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/lib/hpstore.py +0 -0
  21. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/lib/hyper_types.py +0 -0
  22. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/lib/util.py +0 -0
  23. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/lighter.py +0 -0
  24. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/apexpro.py +0 -0
  25. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/bitget.py +0 -0
  26. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/bitmart.py +0 -0
  27. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/coinw.py +0 -0
  28. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/deepcoin.py +0 -0
  29. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/edgex.py +0 -0
  30. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/hyperliquid.py +0 -0
  31. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/lbank.py +0 -0
  32. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/lighter.py +0 -0
  33. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/ourbit.py +0 -0
  34. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/ourbit.py +0 -0
  35. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/ws.py +0 -0
  36. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/core.py +0 -0
  37. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/datavison/_util.py +0 -0
  38. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/datavison/binance.py +0 -0
  39. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/datavison/coinglass.py +0 -0
  40. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/datavison/okx.py +0 -0
  41. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/db.py +0 -0
  42. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/draw.py +0 -0
  43. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/logkit.py +0 -0
  44. {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/notikit.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperquant
3
- Version: 1.37
3
+ Version: 1.38
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 = "1.37"
3
+ version = "1.38"
4
4
  description = "A minimal yet hyper-efficient backtesting framework for quantitative trading"
5
5
  authors = [
6
6
  { name = "MissinA", email = "1421329142@qq.com" }
@@ -394,6 +394,36 @@ class _SideBook:
394
394
  except (TypeError, ValueError):
395
395
  return None
396
396
 
397
+ class Price(DataStore):
398
+ _KEYS = ["s"]
399
+
400
+ def _on_message(self, msg: dict[str, Any]) -> None:
401
+ payload = msg.get('payload') or {}
402
+ data = payload.get('data') or {}
403
+ symbol = payload.get('symbol')
404
+
405
+ if not symbol:
406
+ return
407
+
408
+ _next = self.get({'s': symbol}) or {}
409
+ _next_price = _next.get('p')
410
+ last_price = None
411
+
412
+ if data and isinstance(data, list):
413
+ last_price = data[-1].get('value')
414
+ if 'value' in payload:
415
+ last_price = payload.get('value')
416
+
417
+ if last_price is None:
418
+ return
419
+
420
+ record = {'s': symbol, 'p': last_price}
421
+ key = {'s': symbol}
422
+ if self.get(key):
423
+ self._update([record])
424
+ else:
425
+ self._insert([record])
426
+
397
427
 
398
428
  class BBO(DataStore):
399
429
  _KEYS = ["s", "S"]
@@ -612,6 +642,7 @@ class PolymarketDataStore(DataStoreCollection):
612
642
  self._create("mytrade", datastore_class=MyTrade)
613
643
  self._create("fill", datastore_class=Fill)
614
644
  self._create("trade", datastore_class=Trade)
645
+ self._create("price", datastore_class=Price)
615
646
 
616
647
  @property
617
648
  def book(self) -> Book:
@@ -762,6 +793,13 @@ class PolymarketDataStore(DataStoreCollection):
762
793
  """
763
794
 
764
795
  return self._get("trade")
796
+
797
+ @property
798
+ def price(self) -> Price:
799
+ """Price DataStore
800
+ _key: s
801
+ """
802
+ return self._get("price")
765
803
 
766
804
  @property
767
805
  def fill(self) -> Fill:
@@ -837,6 +875,12 @@ class PolymarketDataStore(DataStoreCollection):
837
875
  # 判定msg是否为list
838
876
  lst_msg = msg if isinstance(msg, list) else [msg]
839
877
  for m in lst_msg:
878
+ if m == '':
879
+ continue
880
+ topic = m.get("topic") or ""
881
+ if topic in {'crypto_prices_chainlink', 'crypto_prices'}:
882
+ self.price._on_message(m)
883
+ continue
840
884
  raw_type = m.get("event_type") or m.get("type")
841
885
  if not raw_type:
842
886
  continue
@@ -240,6 +240,89 @@ class Polymarket:
240
240
  orders = results["orders"]
241
241
  self.store.orders._on_response(orders)
242
242
 
243
+ async def sub_rts_prices(
244
+ self,
245
+ symbols: Sequence[str] | str | None = None,
246
+ *,
247
+ source: Literal["chainlink", "binance"] = "chainlink",
248
+ server_filter: bool = False,
249
+ ) -> pybotters.ws.WebSocketApp:
250
+ """Subscribe to Polymarket RTDS prices (Chainlink or Binance sources).
251
+
252
+ Parameters
253
+ ----------
254
+ symbols
255
+ Requested symbols (Chainlink prefers ``eth/usd`` format, Binance
256
+ uses ``ethusdt``).
257
+ source
258
+ Either ``"chainlink"`` (default) or ``"binance"``.
259
+ server_filter
260
+ When ``True`` the request payload includes the filter exactly as the
261
+ docs specify (e.g. ``{"symbol":"btc/usd"}``). In practice the
262
+ server sometimes stops streaming after returning the first snapshot
263
+ when filters are present, so the default behaviour is to subscribe
264
+ to the full feed and filter locally.
265
+ """
266
+
267
+ if isinstance(symbols, str):
268
+ requested = [symbols]
269
+ elif symbols:
270
+ requested = list(symbols)
271
+ else:
272
+ requested = []
273
+
274
+ target_symbols = {s.lower() for s in requested if s}
275
+
276
+ if source == "chainlink":
277
+ topic = "crypto_prices_chainlink"
278
+ sub_type = "*"
279
+ if server_filter and target_symbols:
280
+ if len(target_symbols) == 1:
281
+ filters = json.dumps({"symbol": next(iter(target_symbols))})
282
+ else:
283
+ filters = json.dumps({"symbols": sorted(target_symbols)})
284
+ else:
285
+ filters = None
286
+ else:
287
+ topic = "crypto_prices"
288
+ sub_type = "update"
289
+ filters = None
290
+ if server_filter and target_symbols:
291
+ filters = ",".join(sorted(target_symbols))
292
+
293
+ subscription: dict[str, Any] = {"topic": topic, "type": sub_type}
294
+ if filters:
295
+ subscription["filters"] = filters
296
+
297
+ payload = {
298
+ "action": "subscribe",
299
+ "subscriptions": [subscription],
300
+ }
301
+
302
+ def callback(msg, ws):
303
+ if not msg:
304
+ return
305
+ try:
306
+ data = json.loads(msg)
307
+ except json.JSONDecodeError:
308
+ return
309
+
310
+ payload = data.get("payload") or {}
311
+ symbol = str(payload.get("symbol") or "").lower()
312
+ if (not server_filter) and target_symbols and symbol and symbol not in target_symbols:
313
+ return
314
+
315
+ self.store.onmessage(data, ws)
316
+
317
+ wsapp = self.client.ws_connect(
318
+ RTS_DATA_ENDPOINT,
319
+ hdlr_str=callback,
320
+ heartbeat=5,
321
+ )
322
+
323
+ await wsapp._event.wait()
324
+ await wsapp.current_ws.send_json(payload)
325
+ return wsapp
243
326
 
244
327
 
245
328
  async def sub_books(
@@ -917,6 +1000,7 @@ class Polymarket:
917
1000
  if isinstance(fee_resp, dict):
918
1001
  return int(fee_resp.get("base_fee", 0))
919
1002
  return int(fee_resp or 0)
1003
+
920
1004
 
921
1005
  async def _signed_request_via_session(
922
1006
  self, method: str, path: str, body: Mapping[str, Any] | list[Any] | None
@@ -945,7 +945,7 @@ wheels = [
945
945
 
946
946
  [[package]]
947
947
  name = "hyperquant"
948
- version = "1.36"
948
+ version = "1.37"
949
949
  source = { editable = "." }
950
950
  dependencies = [
951
951
  { name = "aiohttp" },
File without changes
File without changes
File without changes