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.
- {hyperquant-1.37 → hyperquant-1.38}/PKG-INFO +1 -1
- {hyperquant-1.37 → hyperquant-1.38}/pyproject.toml +1 -1
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/polymarket.py +44 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/polymarket.py +84 -0
- {hyperquant-1.37 → hyperquant-1.38}/uv.lock +1 -1
- {hyperquant-1.37 → hyperquant-1.38}/.gitignore +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/README.md +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/requirements-dev.lock +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/requirements.lock +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/__init__.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/auth.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/bitget.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/bitmart.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/coinw.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/deepcoin.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/edgex.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/hyperliquid.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/lbank.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/lib/edgex_sign.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/lib/hpstore.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/lib/hyper_types.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/lib/util.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/lighter.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/apexpro.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/bitget.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/bitmart.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/coinw.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/deepcoin.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/edgex.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/hyperliquid.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/lbank.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/lighter.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/models/ourbit.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/ourbit.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/broker/ws.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/core.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/datavison/_util.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/datavison/binance.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/datavison/coinglass.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/datavison/okx.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/db.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/draw.py +0 -0
- {hyperquant-1.37 → hyperquant-1.38}/src/hyperquant/logkit.py +0 -0
- {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.
|
|
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
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|