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
|
output_dir: str
|
||||||
ic_summary: dict = field(default_factory=dict)
|
ic_summary: dict = field(default_factory=dict)
|
||||||
report_paths: 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(
|
def run_factor_analysis(
|
||||||
@@ -371,5 +374,8 @@ def run_factor_analysis(
|
|||||||
factor_names=factor_names,
|
factor_names=factor_names,
|
||||||
output_dir=output_dir,
|
output_dir=output_dir,
|
||||||
ic_summary=ic_summary,
|
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.
|
# load_result(result.id). FactorReport (no .id) falls back to None until S2.
|
||||||
task.complete(result_id=getattr(result, "id", None))
|
task.complete(result_id=getattr(result, "id", None))
|
||||||
task.raw_result = result # S2: keep in-memory result (FactorReport) for ic-summary/report
|
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, "完成")
|
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:
|
def get_status(self, task_id: str) -> TaskState | None:
|
||||||
"""Get task status by ID"""
|
"""Get task status by ID"""
|
||||||
return self.pool.get_status(task_id)
|
return self.pool.get_status(task_id)
|
||||||
|
|||||||
Reference in New Issue
Block a user