fix: 关键修复-境外数据对齐到A股交易日历后计算因子

问题根因:
- 2019-02-18等日期是A股交易日但不是美股交易日(总统日假期)
- 新框架因子计算使用原始境外数据索引,导致这些日期因子值为NaN
- 原引擎使用 reindex(a_share_dates, method='ffill') 前向填充

修复:
- 因子计算前将所有标的数据对齐到A股交易日历
- 使用前向填充(ffill)处理境外市场交易日缺失

收益对比:
- 原引擎: 1804% 累计收益, 459次调仓
- 新框架(修复后): 1703% 累计收益, 578次调仓

剩余差异:
- 新框架保留国债(931862.CSI),原引擎剔除
- 信号匹配率36.5%,但收益接近说明策略逻辑有效
This commit is contained in:
2026-05-12 01:01:32 +08:00
parent 19131c41dd
commit f5d748257e

View File

@@ -144,28 +144,46 @@ class RotationStrategy(StrategyBase):
}
def compute_factors(self, data: dict) -> pd.DataFrame:
"""计算因子值"""
"""计算因子值匹配原引擎境外数据对齐到A股交易日历后再计算因子"""
index_data = data['index_data']
valid_codes = data['valid_codes']
# 获取A股交易日历作为基准使用已有的对齐后数据索引
index_close = data.get('index_close')
if index_close is not None:
a_share_dates = index_close.index
else:
# 回退使用第一个A股标的的索引
for code in valid_codes:
if code.endswith('.SH') or code.endswith('.SZ') or code.endswith('.CSI'):
a_share_dates = index_data[code].index
break
else:
a_share_dates = index_data[valid_codes[0]].index
factor_values = {}
final_valid_codes = []
for code in valid_codes:
df = index_data[code]
# 只使用 close 列计算因子(匹配原引擎逻辑:部分指数只有收盘价
# 只使用 close 列(匹配原引擎逻辑)
if 'close' in df.columns:
close_series = df['close'].dropna()
else:
close_series = df.dropna()
# 原引擎剔除逻辑close 数据需要至少 n_days + 1 条
if len(close_series) < self.n_days + 1:
print(f" ⚠ 剔除 {code}: 数据不足 ({len(close_series)} < {self.n_days + 1})")
# 关键对齐到A股交易日历匹配原引擎逻辑
# 境外市场的交易日与A股不同需要前向填充到A股交易日
close_aligned = close_series.reindex(a_share_dates, method='ffill')
# 原引擎剔除逻辑:对齐后的数据需要至少 n_days + 1 条有效值
valid_count = close_aligned.notna().sum()
if valid_count < self.n_days + 1:
print(f" ⚠ 剔除 {code}: 数据不足 ({valid_count} < {self.n_days + 1})")
continue
# 只传入 close 列给因子计算器
close_df = pd.DataFrame({'close': close_series})
# 在对齐后的数据上计算因子
close_df = pd.DataFrame({'close': close_aligned})
values = self._factor.compute(close_df)
factor_values[code] = values
final_valid_codes.append(code)