fix(strategy): 修复收益率计算交易日不对齐问题
问题: 指数数据使用各市场原始交易日,直接pct_change导致大量NaN 修复: 先在原始交易日历计算收益率,再用ffill对齐到A股日历 效果: 收益从44.55%恢复到11961.88%(年化15.7%,26年周期)
This commit is contained in:
@@ -406,25 +406,25 @@ class RotationStrategy(StrategyBase):
|
|||||||
# 4. 执行回测
|
# 4. 执行回测
|
||||||
print("\n执行回测...")
|
print("\n执行回测...")
|
||||||
|
|
||||||
# 获取指数收盘价数据(用于收益计算)
|
# 获取A股交易日历(从因子数据索引)
|
||||||
index_close = data.get('index_close')
|
a_share_dates = signals.index
|
||||||
|
|
||||||
# 计算日收益率(使用指数数据,可从2000年开始)
|
# 计算日收益率:先在原始交易日历计算,再对齐到A股日历
|
||||||
# ETF数据仅用于报告显示溢价率,不参与收益计算
|
# 关键:与因子计算逻辑一致,避免交易日不对齐导致收益率NaN
|
||||||
if index_close is not None and not index_close.empty:
|
returns_data = {}
|
||||||
returns_df = index_close.pct_change()
|
for code in valid_codes:
|
||||||
returns_df.columns = [f'日收益率_{col}' for col in returns_df.columns]
|
if code in index_data:
|
||||||
else:
|
df = index_data[code]
|
||||||
# 回退:从index_data提取收盘价
|
# 提取原始收盘价序列
|
||||||
returns_data = {}
|
if 'close' in df.columns:
|
||||||
for code in valid_codes:
|
close_series = df['close'].dropna()
|
||||||
if code in index_data:
|
# 先在原始交易日历计算收益率
|
||||||
df = index_data[code]
|
returns_series = close_series.pct_change(fill_method=None)
|
||||||
returns_data[f'日收益率_{code}'] = df['close'].pct_change(fill_method=None)
|
# 然后对齐到A股交易日历(用ffill填充非共同交易日)
|
||||||
returns_df = pd.DataFrame(returns_data)
|
returns_aligned = returns_series.reindex(a_share_dates, method='ffill')
|
||||||
if valid_codes:
|
returns_data[f'日收益率_{code}'] = returns_aligned
|
||||||
first_code = valid_codes[0]
|
|
||||||
returns_df.index = index_data[first_code].index
|
returns_df = pd.DataFrame(returns_data)
|
||||||
|
|
||||||
# 确保信号和收益率数据日期对齐
|
# 确保信号和收益率数据日期对齐
|
||||||
common_dates = signals.index.intersection(returns_df.index)
|
common_dates = signals.index.intersection(returns_df.index)
|
||||||
|
|||||||
Reference in New Issue
Block a user