hyperquant 0.48__tar.gz → 0.49__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-0.48 → hyperquant-0.49}/PKG-INFO +1 -1
- {hyperquant-0.48 → hyperquant-0.49}/pyproject.toml +1 -1
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/broker/ourbit.py +1 -1
- hyperquant-0.49/tests/test_order_sync.py +88 -0
- hyperquant-0.49/tests/test_store.py +16 -0
- {hyperquant-0.48 → hyperquant-0.49/tests}/tmp.py +1 -1
- {hyperquant-0.48 → hyperquant-0.49}/uv.lock +1 -1
- {hyperquant-0.48 → hyperquant-0.49}/.gitignore +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/.python-version +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/README.md +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/apis.json +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/data/alpine_smoke.log +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/data/logs/notikit.log +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/pub.sh +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/requirements-dev.lock +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/requirements.lock +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/__init__.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/broker/auth.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/broker/hyperliquid.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/broker/lib/hpstore.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/broker/lib/hyper_types.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/broker/models/hyperliquid.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/broker/models/ourbit.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/broker/ws.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/core.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/datavison/_util.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/datavison/binance.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/datavison/coinglass.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/datavison/okx.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/db.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/draw.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/logkit.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49}/src/hyperquant/notikit.py +0 -0
- {hyperquant-0.48 → hyperquant-0.49/tests}/test.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: hyperquant
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.49
|
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
|
@@ -518,7 +518,7 @@ class OurbitSpot:
|
|
518
518
|
|
519
519
|
# 确定API端点
|
520
520
|
url = f'{self.api_url}/api/platform/spot/{"v4/order/place" if order_type == "market" else "order/place"}'
|
521
|
-
print(f"Placing {symbol}: {data}")
|
521
|
+
# print(f"Placing {symbol}: {data}")
|
522
522
|
# 发送请求
|
523
523
|
res = await self.client.fetch("POST", url, json=data)
|
524
524
|
|
@@ -0,0 +1,88 @@
|
|
1
|
+
import asyncio
|
2
|
+
from hyperquant.broker.ourbit import OurbitSpot
|
3
|
+
import pybotters
|
4
|
+
|
5
|
+
|
6
|
+
# 等待指定 oid 的最终 delete,超时抛 TimeoutError
|
7
|
+
async def wait_delete(stream: pybotters.StoreStream, oid: str, seconds: float):
|
8
|
+
async with asyncio.timeout(seconds):
|
9
|
+
while True:
|
10
|
+
change = await stream.__anext__()
|
11
|
+
if change.operation == "delete" and change.data.get("order_id") == oid:
|
12
|
+
return change.data # 内含 state / avg_price / deal_quantity 等累计字段
|
13
|
+
|
14
|
+
|
15
|
+
async def order_sync(
|
16
|
+
ob: OurbitSpot,
|
17
|
+
symbol: str = "SOL_USDT",
|
18
|
+
side: str = "buy",
|
19
|
+
order_type: str = "market", # "market" / "limit"
|
20
|
+
usdt_amount: float | None = None, # 市价可填
|
21
|
+
quantity: float | None = None, # 市价可填
|
22
|
+
price: float | None = None, # 限价必填
|
23
|
+
window_sec: float = 2.0, # 主等待窗口(限价可设为 5.0)
|
24
|
+
grace_sec: float = 1.0, # 撤单后宽限
|
25
|
+
):
|
26
|
+
with ob.store.orders.watch() as stream:
|
27
|
+
# 下单(只保留最简两种入参形态)
|
28
|
+
try:
|
29
|
+
oid = await ob.place_order(
|
30
|
+
symbol,
|
31
|
+
side,
|
32
|
+
order_type=order_type,
|
33
|
+
usdt_amount=usdt_amount,
|
34
|
+
quantity=quantity,
|
35
|
+
price=price,
|
36
|
+
)
|
37
|
+
except Exception as e:
|
38
|
+
return {"symbol": symbol, "state": "error", "error": str(e)}
|
39
|
+
|
40
|
+
# 步骤1:主窗口内等待这单的最终 delete
|
41
|
+
try:
|
42
|
+
return await wait_delete(stream, oid, window_sec)
|
43
|
+
except TimeoutError:
|
44
|
+
# 步骤2:到点撤单(市价通常用不到;限价才有意义)
|
45
|
+
try:
|
46
|
+
await ob.cancel_order(oid)
|
47
|
+
except Exception:
|
48
|
+
pass
|
49
|
+
# 固定宽限内再等“迟到”的最终 delete
|
50
|
+
try:
|
51
|
+
return await wait_delete(stream, oid, grace_sec)
|
52
|
+
except TimeoutError:
|
53
|
+
return {"order_id": oid, "symbol": symbol, "state": "timeout"}
|
54
|
+
|
55
|
+
|
56
|
+
async def main():
|
57
|
+
async with pybotters.Client(
|
58
|
+
apis={
|
59
|
+
"ourbit": [
|
60
|
+
"WEB3bf088f8b2f2fae07592fe1a6240e2d798100a9cb2a91f8fda1056b6865ab3ee"
|
61
|
+
]
|
62
|
+
}
|
63
|
+
) as client:
|
64
|
+
ob = OurbitSpot(client)
|
65
|
+
await ob.__aenter__()
|
66
|
+
await ob.sub_personal() # 私有频道
|
67
|
+
ob.store.book.limit = 3
|
68
|
+
await ob.sub_orderbook(["SOL_USDT"]) # 订单簿频道
|
69
|
+
# # 示例:市价
|
70
|
+
# result = await order_sync( ob, symbol="SOL_USDT", side="buy", order_type="limit", quantity=0.04, price=200, window_sec=2)
|
71
|
+
# print(result)
|
72
|
+
while True:
|
73
|
+
asks = ob.store.book.find({'s': 'SOL_USDT', 'S': 'a'})
|
74
|
+
bids = ob.store.book.find({'s': 'SOL_USDT', 'S': 'b'})
|
75
|
+
if asks and bids:
|
76
|
+
best_ask = float(asks[1]['p'])
|
77
|
+
best_bid = float(bids[1]['p'])
|
78
|
+
|
79
|
+
result = await order_sync( ob, symbol="SOL_USDT", side="buy", order_type="limit", quantity=0.04, price=best_bid, window_sec=1)
|
80
|
+
print(result)
|
81
|
+
await asyncio.sleep(5)
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
if __name__ == "__main__":
|
87
|
+
asyncio.run(main())
|
88
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import asyncio
|
2
|
+
import pybotters
|
3
|
+
|
4
|
+
|
5
|
+
async def main():
|
6
|
+
ds = pybotters.store.DataStore(keys=["id"])
|
7
|
+
loop = asyncio.get_running_loop()
|
8
|
+
|
9
|
+
wait_task = loop.create_task(ds.wait())
|
10
|
+
loop.call_soon(
|
11
|
+
ds._insert, [{"id": 1, "val": 1}, {"id": 2, "val": 2}, {"id": 3, "val": 3}]
|
12
|
+
)
|
13
|
+
await asyncio.wait_for(wait_task, timeout=5.0)
|
14
|
+
|
15
|
+
ds._insert, [{"id": 1, "val": 1}, {"id": 2, "val": 2}, {"id": 3, "val": 3}]
|
16
|
+
|
@@ -164,7 +164,7 @@ async def close_spot():
|
|
164
164
|
ob_spot = OurbitSpot(client)
|
165
165
|
await ob_spot.__aenter__()
|
166
166
|
await ob_spot.update('balance')
|
167
|
-
|
167
|
+
print(ob_spot.store.balance.find())
|
168
168
|
# await ob_spot.place_order('FLOKI_USDT', 'sell', order_type='market', quantity=216574)
|
169
169
|
for b in ob_spot.store.balance.find():
|
170
170
|
if b['currency'] != 'USDT':
|
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
|