fix(rotation): 修复ETF数据获取逻辑,分别获取指数raw和ETF hfq数据
问题:之前统一使用fetch_indices(adj='raw')导致ETF未使用后复权价格 修复: - 在GlobalRotationStrategy中覆盖get_data()方法 - 指数数据:调用fetch_indices(adj='raw')获取原始价格 - ETF数据:调用fetch_etf(adj='hfq')获取后复权价格 - 确保指数信号计算和ETF收益计算使用正确的数据源 影响:回测将正确反映ETF的真实收益(包含分红再投资)
This commit is contained in:
@@ -115,6 +115,68 @@ class GlobalRotationStrategy(StrategyBase):
|
||||
|
||||
return list(codes)
|
||||
|
||||
def get_data(self) -> Dict[str, pd.DataFrame]:
|
||||
"""
|
||||
获取数据(分别获取指数和 ETF,使用不同的复权方式)
|
||||
|
||||
指数数据:使用 raw(原始价格)用于信号计算
|
||||
ETF 数据:使用 hfq(后复权价格)用于收益计算
|
||||
|
||||
Returns:
|
||||
数据字典 {code: DataFrame}
|
||||
"""
|
||||
if self._data_fetcher is None:
|
||||
self._data_fetcher = self._create_data_fetcher()
|
||||
|
||||
# 获取信号→交易映射
|
||||
signal_to_trade = self.config.asset_pools.get_signal_to_trade_mapping()
|
||||
|
||||
# 处理 end_date 为 None 的情况(使用今天)
|
||||
from datetime import date
|
||||
start = self.config.backtest.start_date
|
||||
end = self.config.backtest.end_date
|
||||
if end is None:
|
||||
end = date.today().strftime('%Y-%m-%d')
|
||||
|
||||
data = {}
|
||||
|
||||
# 1. 获取指数数据(信号标的,使用 raw)
|
||||
signal_codes = set(self.config.asset_pools.get_signal_codes())
|
||||
if self.use_dynamic_threshold and self.bond_code:
|
||||
signal_codes.add(self.bond_code)
|
||||
|
||||
if signal_codes:
|
||||
print(f"\n[数据] 获取 {len(signal_codes)} 只指数数据(adj='raw')...")
|
||||
try:
|
||||
index_data = self._data_fetcher.fetch_indices(
|
||||
codes=list(signal_codes),
|
||||
start=start,
|
||||
end=end,
|
||||
adj='raw' # 指数使用原始价格
|
||||
)
|
||||
data.update(index_data)
|
||||
print(f" ✓ 指数数据: {len(index_data)} 只")
|
||||
except Exception as e:
|
||||
print(f" ✗ 指数数据获取失败: {e}")
|
||||
|
||||
# 2. 获取 ETF 数据(交易标的,使用 hfq)
|
||||
trade_codes = list(set(signal_to_trade.values()))
|
||||
if trade_codes:
|
||||
print(f"\n[数据] 获取 {len(trade_codes)} 只 ETF 数据(adj='hfq')...")
|
||||
try:
|
||||
etf_data = self._data_fetcher.fetch_etf(
|
||||
codes=trade_codes,
|
||||
start=start,
|
||||
end=end,
|
||||
adj='hfq' # ETF 使用后复权价格
|
||||
)
|
||||
data.update(etf_data)
|
||||
print(f" ✓ ETF 数据: {len(etf_data)} 只")
|
||||
except Exception as e:
|
||||
print(f" ✗ ETF 数据获取失败: {e}")
|
||||
|
||||
return data
|
||||
|
||||
def compute_factors(self, data: Dict[str, pd.DataFrame]) -> Dict[str, pd.Series]:
|
||||
"""
|
||||
计算动量因子(只使用信号标的的数据)
|
||||
|
||||
Reference in New Issue
Block a user