feat(data-source): 支持指数-ETF双轨数据获取及因子计算
- 新增使用Tushare获取A股ETF价格及净值数据的私有方法 - fetch_all方法支持接收完整代码配置,区分指数与ETF及市场类别 - 指数数据和ETF数据分别下载,ETF净值数据用于溢价率计算 - 采用A股交易日为主交易日历,非A股数据前向填充对齐 - 调整因子计算,支持指数价格计算因子,ETF价格计算收益率 - run_rotation脚本和RotationStrategy引擎适配指数-ETF配置格式 - 代码结构优化,增强多市场及加密货币处理能力
This commit is contained in:
@@ -59,22 +59,38 @@ def main():
|
||||
from datetime import datetime
|
||||
config['end_date'] = datetime.now().strftime('%Y-%m-%d')
|
||||
|
||||
# 从配置中读取 code_list 和 code_name_map
|
||||
# code_list 现在是一个字典 {代码: 名称}
|
||||
# 从配置中读取 code_list(新的配置格式:{代码: {name, etf, market}})
|
||||
code_list_config = config.get('code_list', {})
|
||||
|
||||
# 提取代码列表和名称映射
|
||||
if isinstance(code_list_config, dict):
|
||||
code_list = list(code_list_config.keys())
|
||||
code_name_map = code_list_config
|
||||
# 构建 code_name_map: {代码: 名称}
|
||||
code_name_map = {}
|
||||
for code, cfg in code_list_config.items():
|
||||
if isinstance(cfg, dict):
|
||||
code_name_map[code] = cfg.get('name', code)
|
||||
else:
|
||||
# 兼容旧格式
|
||||
code_name_map[code] = cfg
|
||||
else:
|
||||
# 兼容旧格式(列表)
|
||||
code_list = code_list_config
|
||||
code_name_map = DEFAULT_CODE_NAME_MAP
|
||||
code_list_config = {}
|
||||
|
||||
benchmark_config = config.get('benchmark', {})
|
||||
benchmark_name = benchmark_config.get('name', DEFAULT_BENCHMARK_NAME)
|
||||
|
||||
print(f"\n配置文件: {args.config}")
|
||||
print(f"候选标的: {len(code_list)} 只")
|
||||
|
||||
# 统计ETF映射情况
|
||||
etf_count = sum(1 for cfg in code_list_config.values() if isinstance(cfg, dict) and cfg.get('etf'))
|
||||
crypto_count = sum(1 for cfg in code_list_config.values() if isinstance(cfg, dict) and cfg.get('market') == 'CRYPTO')
|
||||
print(f" - ETF映射: {etf_count} 只")
|
||||
print(f" - 直接交易: {crypto_count} 只(加密货币)")
|
||||
|
||||
print(f"回测区间: {config['start_date']} ~ {config['end_date']}")
|
||||
print(f"因子类型: {config['factor_type']}")
|
||||
print(f"窗口天数: {config['n_days']}")
|
||||
@@ -82,8 +98,8 @@ def main():
|
||||
print(f"调仓周期: {config['rebalance_days']} 天")
|
||||
print(f"交易成本: {config['trade_cost']:.2%}")
|
||||
|
||||
# 更新 config 中的 code_list 为列表格式
|
||||
config['code_list'] = code_list
|
||||
# 保持 config 中的 code_list 为完整配置格式(用于引擎内部解析)
|
||||
# 不需要修改 config['code_list'],引擎会直接使用原始配置
|
||||
|
||||
# 创建策略实例
|
||||
strategy = RotationStrategy(config)
|
||||
@@ -119,6 +135,10 @@ def main():
|
||||
benchmark_name=benchmark_name,
|
||||
save_path=args.save_path,
|
||||
select_num=config["select_num"],
|
||||
code_config=code_list_config, # 传入完整配置以显示ETF映射
|
||||
index_data=strategy.index_data, # 传入指数数据
|
||||
etf_price_data=strategy.etf_data, # 传入ETF价格数据
|
||||
etf_nav_data_raw=strategy.etf_nav_data, # 传入ETF净值数据
|
||||
)
|
||||
|
||||
elapsed = time.time() - start_time
|
||||
|
||||
Reference in New Issue
Block a user