feat(s3): 历史任务 + 参数优化端到端跑通

- result_store.load_result_by_task_id + orchestrator.get_result DB 兜底(历史回看)
- GET /task 列表、GET /task/{id}/optimization-results
- Task.raw_result 存优化结果 list(内存)
- cta_optimizer 修同款 bug(interval d / capital 1M / vnpy DB SETTINGS)
- get_status 返回 error_msg(str 守卫)
- 前端 优化页(网格输入+轮询+结果表)、历史页(任务列表+回看)、侧栏子菜单
- 修 5 个旧 test_routes 回归;73 tests passed
- 冒烟:历史 3 任务 + 优化 9 组合
This commit is contained in:
2026-07-07 06:35:54 +08:00
parent 212ad6426d
commit 54fc1b656f
11 changed files with 386 additions and 14 deletions
+42 -2
View File
@@ -120,7 +120,7 @@ def get_status(task_id: str):
"task_id": task_id,
"status": s.value if hasattr(s, "value") else str(s),
"stage": stage or "",
"error_msg": task.error_msg if task else None,
"error_msg": task.error_msg if (task and isinstance(task.error_msg, str)) else None,
}
@@ -266,4 +266,44 @@ def factor_report(task_id: str, factor: str, token: str = Query(...)):
path = paths.get(factor)
if not path or not os.path.exists(path):
raise HTTPException(status_code=404, detail=f"report for {factor} not found")
return FileResponse(path)
return FileResponse(path)
# ===== History + Optimization endpoints (S3) =====
@router.get("/task", dependencies=[Depends(verify_token)])
def list_tasks(type: str | None = None, status: str | None = None):
"""List historical tasks (from the results DB)."""
from sanguo_backtest.result_store import list_results
orch = get_orchestrator()
items = []
for r in list_results(type_filter=type, db_path=orch.db_path):
if status and r.status != status:
continue
items.append({
"id": r.id,
"task_id": r.task_id,
"type": r.type,
"status": r.status,
"strategy": r.strategy,
"symbol": r.symbol,
"start": r.start,
"end": r.end,
})
items.reverse() # newest first
return {"tasks": items}
@router.get("/task/{task_id}/optimization-results", dependencies=[Depends(verify_token)])
def optimization_results(task_id: str):
"""Optimization results: list of {params, statistics} per parameter combo."""
raw = get_orchestrator().get_raw_result(task_id)
if raw is None:
raise HTTPException(status_code=404, detail="optimization results not ready")
rows = []
for r in (raw if isinstance(raw, list) else [raw]):
rows.append({
"params": getattr(r, "params", {}),
"statistics": getattr(r, "statistics", {}),
})
return {"task_id": task_id, "results": rows}