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.
- {hyperquant-0.83 → hyperquant-0.85}/PKG-INFO +1 -1
- {hyperquant-0.83 → hyperquant-0.85}/pyproject.toml +1 -1
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/coinw.py +7 -1
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/models/coinw.py +79 -0
- {hyperquant-0.83 → hyperquant-0.85}/tests/test_coinw.py +8 -7
- {hyperquant-0.83 → hyperquant-0.85}/uv.lock +1 -1
- {hyperquant-0.83 → hyperquant-0.85}/.gitignore +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/.python-version +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/README.md +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/apis.json +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/data/alpine_smoke.log +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/data/logs/notikit.log +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/data/logs/test_order_sync.log +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/data/records_swap.csv +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/data/records_swapc.csv +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/doc/lbank.md +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/pub.sh +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/requirements-dev.lock +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/requirements.lock +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/__init__.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/auth.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/bitget.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/edgex.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/hyperliquid.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/lbank.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/lib/edgex_sign.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/lib/hpstore.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/lib/hyper_types.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/lib/util.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/models/bitget.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/models/edgex.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/models/hyperliquid.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/models/lbank.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/models/ourbit.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/ourbit.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/broker/ws.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/core.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/datavison/_util.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/datavison/binance.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/datavison/coinglass.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/datavison/okx.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/db.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/draw.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/logkit.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/src/hyperquant/notikit.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/tests/test_bitget.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/tests/test_draw.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/tests/test_edgex.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/tests/test_lbank.py +0 -0
- {hyperquant-0.83 → hyperquant-0.85}/tests/test_ourbit.py +0 -0
- {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.
|
|
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
|
|
@@ -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 =
|
|
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
|
|
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
|
-
|
|
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(
|
|
212
|
+
asyncio.run(test_update())
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|