feat(api): paper positions/pending 端点(实走监控用,Phase 3c Live页后端基础)

This commit is contained in:
2026-07-09 22:33:35 +08:00
parent 193064c953
commit 252deb5ec7
2 changed files with 74 additions and 0 deletions
+21
View File
@@ -115,6 +115,27 @@ def get_strategies(aid: int):
return list_strategy_summary(_db_path["path"], aid) return list_strategy_summary(_db_path["path"], aid)
@router.get("/paper/{aid}/positions", dependencies=[Depends(verify_token)])
def get_positions(aid: int):
"""当前持仓快照(实走监控,Phase 3c)。{symbol:{volume,frozen,avg_price}} → list。"""
from sanguo_trader.persistence import load_positions
pos = load_positions(_db_path["path"], aid, "account")
return [
{"symbol": sym, "volume": p["volume"], "frozen": p.get("frozen", 0),
"avg_price": p["avg_price"]}
for sym, p in pos.items()
]
@router.get("/paper/{aid}/pending", dependencies=[Depends(verify_token)])
def get_pending(aid: int):
"""跨日 pending 订单(实走监控,Phase 3c)。"""
from sanguo_trader.persistence import load_pending_orders
return load_pending_orders(_db_path["path"], aid)
class _DataSourceWrapper: class _DataSourceWrapper:
"""包装 iter_bars/fetch_day 给 PaperEngine/live_orchestrator。""" """包装 iter_bars/fetch_day 给 PaperEngine/live_orchestrator。"""
+53
View File
@@ -90,3 +90,56 @@ def test_strategy_summary_aggregation(tmp_path):
assert summary["s1"]["filled"] == 2 assert summary["s1"]["filled"] == 2
assert summary["s1"]["rejected"] == 1 assert summary["s1"]["rejected"] == 1
assert summary["s2"]["filled"] == 1 assert summary["s2"]["filled"] == 1
def test_positions_endpoint(tmp_path):
"""Phase 3c:当前持仓快照({symbol:{volume,frozen,avg_price}} → list)。"""
from sanguo_trader.persistence import save_positions
c, token = _client(tmp_path)
db = os.path.join(str(tmp_path), "p.db")
aid = c.post(
"/api/v1/paper/create",
json={"symbols": ["600000"],
"strategies": [{"name": "S", "symbol": "600000"}],
"start": "2024-01-01", "end": "2024-06-30"},
headers=_auth(token),
).json()["account_id"]
save_positions(db, aid, "account",
{"600000": {"volume": 100, "frozen": 0, "avg_price": 10.5}},
"2024-01-15")
resp = c.get(f"/api/v1/paper/{aid}/positions", headers=_auth(token))
assert resp.status_code == 200
data = resp.json()
assert len(data) == 1
assert data[0]["symbol"] == "600000"
assert data[0]["volume"] == 100
assert data[0]["frozen"] == 0
assert data[0]["avg_price"] == 10.5
def test_pending_endpoint(tmp_path):
"""Phase 3c:跨日 pending 订单(C-S3)。"""
from sanguo_trader.persistence import save_pending_orders
c, token = _client(tmp_path)
db = os.path.join(str(tmp_path), "p.db")
aid = c.post(
"/api/v1/paper/create",
json={"symbols": ["600000"],
"strategies": [{"name": "S", "symbol": "600000"}],
"start": "2024-01-01", "end": "2024-06-30"},
headers=_auth(token),
).json()["account_id"]
save_pending_orders(db, aid, [
{"strategy_id": "s1", "symbol": "600000", "side": "buy",
"price": 10.0, "volume": 100, "is_market": True,
"match_session": "next_open", "listing_days": 0},
])
resp = c.get(f"/api/v1/paper/{aid}/pending", headers=_auth(token))
assert resp.status_code == 200
data = resp.json()
assert len(data) == 1
assert data[0]["symbol"] == "600000"
assert data[0]["side"] == "buy"
assert data[0]["is_market"] is True