fix(factor): 因子任务持久化到 backtest_results.db(type=factor)
此前 FactorReport 无 id,_on_done 不存 DB → 因子任务不进任务列表、重启丢失
(用户:历史任务列表看不到因子分析)。_on_done 现对 FactorReport 调
_persist_factor 存 backtest_stats(type=factor, strategy=因子名, symbol=标的池,
statistics={ic_summary, report_paths})。FactorReport 加 symbols/start/end 字段。
This commit is contained in:
@@ -54,6 +54,9 @@ class FactorReport:
|
||||
output_dir: str
|
||||
ic_summary: dict = field(default_factory=dict)
|
||||
report_paths: dict = field(default_factory=dict)
|
||||
symbols: list[str] = field(default_factory=list)
|
||||
start: str = ""
|
||||
end: str = ""
|
||||
|
||||
|
||||
def run_factor_analysis(
|
||||
@@ -371,5 +374,8 @@ def run_factor_analysis(
|
||||
factor_names=factor_names,
|
||||
output_dir=output_dir,
|
||||
ic_summary=ic_summary,
|
||||
report_paths=report_paths
|
||||
report_paths=report_paths,
|
||||
symbols=symbols,
|
||||
start=start,
|
||||
end=end,
|
||||
)
|
||||
|
||||
@@ -144,8 +144,30 @@ class Orchestrator:
|
||||
# load_result(result.id). FactorReport (no .id) falls back to None until S2.
|
||||
task.complete(result_id=getattr(result, "id", None))
|
||||
task.raw_result = result # S2: keep in-memory result (FactorReport) for ic-summary/report
|
||||
# S2: persist factor result so it appears in task list & survives restart
|
||||
if getattr(result, "ic_summary", None) and getattr(result, "factor_names", None) is not None:
|
||||
self._persist_factor(task_id, result)
|
||||
await self._notify_stage(task_id, "完成")
|
||||
|
||||
def _persist_factor(self, task_id: str, fr) -> None:
|
||||
"""Persist FactorReport to backtest_results.db (type=factor) so it shows
|
||||
in task list and survives API restart. Mirrors cta/optimize persistence."""
|
||||
from sanguo_backtest.result_store import save_result, BacktestResult
|
||||
try:
|
||||
save_result(BacktestResult(
|
||||
task_id=task_id, type="factor", status="done",
|
||||
strategy=",".join(fr.factor_names),
|
||||
symbol=",".join(getattr(fr, "symbols", []) or []),
|
||||
params={"factor_names": fr.factor_names},
|
||||
start=getattr(fr, "start", "") or "",
|
||||
end=getattr(fr, "end", "") or "",
|
||||
statistics={"ic_summary": fr.ic_summary, "report_paths": fr.report_paths},
|
||||
equity_curve=None, trades=None,
|
||||
), db_path=self.db_path)
|
||||
except Exception as e:
|
||||
import logging
|
||||
logging.getLogger(__name__).warning("persist factor %s failed: %s", task_id, e)
|
||||
|
||||
def get_status(self, task_id: str) -> TaskState | None:
|
||||
"""Get task status by ID"""
|
||||
return self.pool.get_status(task_id)
|
||||
|
||||
Reference in New Issue
Block a user