feat(report): 策略KPI数据统一来源,避免重复计算

修改内容:
1. strategies/rotation/report.py
   - 新增保存策略KPI到JSON文件的功能
   - 保存指标:累计收益、年化收益、夏普比率、最大回撤、Calmar比率、日胜率
   - 同时保存基准指标和回测区间信息
   - 输出路径: results/report_metrics.json

2. visualization/report_generator/generate_report.py
   - 加载策略KPI JSON文件(优先)
   - 直接使用轮动策略输出的指标,不再重复计算
   - 保留备用计算逻辑(JSON不存在时)
   - 确保HTML报告与轮动策略结果完全一致

效果:
- KPI指标统一从轮动策略回测结果获取
- 避免重复计算导致的数据不一致
- 数据来源清晰可追溯
- HTML报告指标与终端输出完全一致
This commit is contained in:
2026-05-08 22:25:22 +08:00
parent 5c87bea4fc
commit 861e590441
2 changed files with 87 additions and 1 deletions

View File

@@ -133,6 +133,37 @@ def generate_performance_report(
etf_nav_data_raw=etf_nav_data_raw,
)
# 保存整体策略KPI到JSON文件
import json
metrics_dict = {
"策略": {
"累计收益": float(s_total_return),
"年化收益(自然日)": float(s_cagr_nat),
"年化收益(交易日)": float(s_cagr_trd),
"夏普比率": float(s_sharpe),
"最大回撤": float(s_max_dd),
"Calmar比率": float(s_calmar),
"日胜率": float(s_win_rate),
"回测区间": {
"开始": strategy_nav.index.min().strftime("%Y-%m-%d"),
"结束": strategy_nav.index.max().strftime("%Y-%m-%d"),
"交易天数": len(strategy_nav)
}
},
"基准": {
"累计收益": float(b_total_return),
"年化收益(自然日)": float(b_cagr_nat),
"夏普比率": float(b_sharpe),
"最大回撤": float(b_max_dd),
"名称": benchmark_name
}
}
metrics_path = f"{save_path}_metrics.json"
with open(metrics_path, 'w', encoding='utf-8') as f:
json.dump(metrics_dict, f, indent=2, ensure_ascii=False)
print(f"策略指标已保存: {metrics_path}")
# 返回指标字典
return {
"累计收益": s_total_return,