fix(strategy): 收益计算改为使用指数数据
- 原逻辑: 优先使用ETF价格计算收益,导致回测起点被ETF最早日期限制(2011-12-09) - 新逻辑: 使用指数数据计算收益,可从2000年开始回测(8240天) - ETF数据仅用于报告显示溢价率,不参与收益计算 - 注意: 2000-2005年只有7只标的有数据,分散度不足导致净值下跌48%
This commit is contained in:
@@ -406,35 +406,25 @@ class RotationStrategy(StrategyBase):
|
|||||||
# 4. 执行回测
|
# 4. 执行回测
|
||||||
print("\n执行回测...")
|
print("\n执行回测...")
|
||||||
|
|
||||||
# 获取ETF数据和代码映射
|
# 获取指数收盘价数据(用于收益计算)
|
||||||
etf_data = data.get('etf_data')
|
index_close = data.get('index_close')
|
||||||
etf_code_map = data.get('etf_code_map', {}) # {指数代码: ETF代码}
|
|
||||||
|
|
||||||
# 计算日收益率(使用ETF价格数据,匹配原引擎逻辑)
|
# 计算日收益率(使用指数数据,可从2000年开始)
|
||||||
if etf_data is not None and not etf_data.empty:
|
# ETF数据仅用于报告显示溢价率,不参与收益计算
|
||||||
# 使用ETF价格计算收益,列名保持指数代码格式
|
if index_close is not None and not index_close.empty:
|
||||||
returns_data = {}
|
returns_df = index_close.pct_change()
|
||||||
for idx_code in valid_codes:
|
returns_df.columns = [f'日收益率_{col}' for col in returns_df.columns]
|
||||||
etf_code = etf_code_map.get(idx_code, idx_code)
|
|
||||||
if etf_code in etf_data.columns:
|
|
||||||
returns_data[f'日收益率_{idx_code}'] = etf_data[etf_code].pct_change(fill_method=None)
|
|
||||||
returns_df = pd.DataFrame(returns_data)
|
|
||||||
else:
|
else:
|
||||||
# 回退到指数收盘价数据
|
# 回退:从index_data提取收盘价
|
||||||
index_close = data.get('index_close')
|
returns_data = {}
|
||||||
if index_close is not None and not index_close.empty:
|
for code in valid_codes:
|
||||||
returns_df = index_close.pct_change()
|
if code in index_data:
|
||||||
returns_df.columns = [f'日收益率_{col}' for col in returns_df.columns]
|
df = index_data[code]
|
||||||
else:
|
returns_data[f'日收益率_{code}'] = df['close'].pct_change(fill_method=None)
|
||||||
returns_data = {}
|
returns_df = pd.DataFrame(returns_data)
|
||||||
for code in valid_codes:
|
if valid_codes:
|
||||||
if code in index_data:
|
first_code = valid_codes[0]
|
||||||
df = index_data[code]
|
returns_df.index = index_data[first_code].index
|
||||||
returns_data[f'日收益率_{code}'] = df['close'].pct_change()
|
|
||||||
returns_df = pd.DataFrame(returns_data)
|
|
||||||
if valid_codes:
|
|
||||||
first_code = valid_codes[0]
|
|
||||||
returns_df.index = index_data[first_code].index
|
|
||||||
|
|
||||||
# 确保信号和收益率数据日期对齐
|
# 确保信号和收益率数据日期对齐
|
||||||
common_dates = signals.index.intersection(returns_df.index)
|
common_dates = signals.index.intersection(returns_df.index)
|
||||||
|
|||||||
Reference in New Issue
Block a user