feat(api): paper positions/pending 端点(实走监控用,Phase 3c Live页后端基础)
This commit is contained in:
@@ -115,6 +115,27 @@ def get_strategies(aid: int):
|
||||
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:
|
||||
"""包装 iter_bars/fetch_day 给 PaperEngine/live_orchestrator。"""
|
||||
|
||||
|
||||
@@ -90,3 +90,56 @@ def test_strategy_summary_aggregation(tmp_path):
|
||||
assert summary["s1"]["filled"] == 2
|
||||
assert summary["s1"]["rejected"] == 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
|
||||
|
||||
Reference in New Issue
Block a user