From baeeb13c3472d33fec9751ca87bf2495e7b92621 Mon Sep 17 00:00:00 2001 From: aszerW Date: Fri, 8 May 2026 23:07:08 +0800 Subject: [PATCH] =?UTF-8?q?fix(engine):=20=E4=BF=AE=E5=A4=8D=E5=87=80?= =?UTF-8?q?=E5=80=BC=E8=B5=B7=E7=82=B9=E5=BD=92=E4=B8=80=E5=8C=96=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=8C=E7=A1=AE=E4=BF=9D=E5=87=80=E5=80=BC=E4=BB=8E?= =?UTF-8?q?1.0=E5=BC=80=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题分析: 1. 策略净值起点原为1.0051,不是标准的1.0 2. 根本原因:日收益率在factor_data中已计算好,第一行包含前一天价格变化 3. cumprod()从第一行开始,导致起点不是1.0 4. 累计收益计算错误: - 原计算方式:净值终点-1 = 1822.83% - 正确收益:净值终点/起点 = 1813.07% - 差异约10% 修复内容: - strategies/rotation/engine.py - 策略净值归一化:净值 = cumprod() / cumprod().iloc[0] - 基准净值归一化:同样处理确保起点=1.0 - 消除第一行日收益率包含的前一天收益影响 修复效果: - 策略净值起点:从1.0051 → 1.0000 ✅ - 基准净值起点:从1.0072 → 1.0000 ✅ - 策略累计收益:从1822.83% → 1813.07% ✅ - 基准累计收益:从48.21% → 47.15% ✅ 影响: - HTML报告中净值曲线起点标准化为1.0 - KPI指标中的累计收益计算正确 - 与其他回测系统的净值展示方式一致 --- strategies/rotation/engine.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/strategies/rotation/engine.py b/strategies/rotation/engine.py index 82144fb..6d21de5 100644 --- a/strategies/rotation/engine.py +++ b/strategies/rotation/engine.py @@ -286,8 +286,10 @@ class RotationStrategy(BacktestStrategy): result["换手率"] = turnover_list result["轮动策略日收益率"] -= result["换手率"] * trade_cost - # 计算净值 + # 计算净值 - 强制起点为1.0 result["轮动策略净值"] = (1 + result["轮动策略日收益率"]).cumprod() + # 归一化:确保净值起点为1.0(消除第一行日收益率包含的前一天收益) + result["轮动策略净值"] = result["轮动策略净值"] / result["轮动策略净值"].iloc[0] # 各ETF单独净值 - 使用第一个有效价格作为基准 for code in self.valid_codes: @@ -317,6 +319,8 @@ class RotationStrategy(BacktestStrategy): result["基准日收益率"] = bench_ret.reindex(result.index, fill_value=0) result["基准净值"] = (1 + result["基准日收益率"]).cumprod() + # 归一化:确保基准净值起点为1.0 + result["基准净值"] = result["基准净值"] / result["基准净值"].iloc[0] self.backtest_result = result