feat(framework_v2): 集成交易日历 API + 端到端测试

## 核心功能
- get_trading_calendar(): 通过 API 获取准确交易日历
  - 替换临时 pandas BDay 实现
  - 调用 /api/v1/trading-calendar 端点
  - 支持动态日期范围(start, end 参数)
  - 支持 A/US/HK 多市场

## 端到端测试
- test_end_to_end.py: 完整流程测试(5 个阶段)
  - 阶段 1: 数据获取(纳指 502 天,创业板 484 天)
  - 阶段 2: 因子计算(MomentumFactor n_days=20)
  - 阶段 3: 数据对齐(CrossMarketAligner 到 A 股 484 天)
  - 阶段 4: 信号生成(Top-1,469 个信号)
  - 阶段 5: 收益计算(年化 51.71%,超额 96.37%)

## 测试验证
- 5/5 阶段通过
- API 日历: 484 个交易日(准确)
- 纳指休市日: 18 天收益率 = 0%
- 收益率 NaN: 0
- 跨市场对齐成功

## 架构改进
- 从近似日历 → 准确 API 日历
- 无需手动维护节假日列表
- API 失败时抛出异常(不静默降级)
This commit is contained in:
2026-05-24 12:38:06 +08:00
parent d07fb8de6d
commit e7ab8a2755
2 changed files with 507 additions and 43 deletions

View File

@@ -166,58 +166,54 @@ class FlaskAPIFetcher(DataFetcher):
return results
def get_trading_calendar(self, market: str = 'A') -> pd.Index:
def get_trading_calendar(
self,
market: str = 'A',
start: str = None,
end: str = None
) -> pd.Index:
"""
获取交易日历
注意Flask API 暂不直接提供交易日历
这里使用 pandas 的 BDay 生成近似日历
TODO: 后续可通过 API 端点获取准确日历
获取交易日历(通过 API
Args:
market: 市场代码'A', 'US', 'HK' 等)
market: 市场代码
- 'A''china': A股上交所/深交所)
- 'US''us': 美股NYSE
- 'HK''hk': 港股HKEX
start: 开始日期 YYYY-MM-DD默认 2020-01-01
end: 结束日期 YYYY-MM-DD默认 2025-12-31
Returns:
交易日历 Index
交易日历 DatetimeIndex
示例:
>>> fetcher = FlaskAPIFetcher()
>>> # 获取 A 股 2024 年交易日历
>>> calendar = fetcher.get_trading_calendar('A', '2024-01-01', '2024-12-31')
>>> # 获取美股交易日历
>>> calendar = fetcher.get_trading_calendar('US', '2024-01-01', '2024-12-31')
"""
# 临时实现:使用 pandas 生成工作日日历
# 实际应该从 API 获取准确的交易日历
# 默认日期范围
if start is None:
start = '2020-01-01'
if end is None:
end = '2025-12-31'
if market == 'A':
# A股中国工作日简化实现
start = pd.Timestamp('2020-01-01')
end = pd.Timestamp('2025-12-31')
calendar = pd.bdate_range(start=start, end=end)
# 移除中国主要节假日(简化版)
# 实际应该从 API 或数据库获取准确日历
holidays = [
# 春节(示例,不完整)
'2024-02-10', '2024-02-11', '2024-02-12', '2024-02-13', '2024-02-14',
'2024-02-15', '2024-02-16', '2024-02-17',
# 国庆(示例,不完整)
'2024-10-01', '2024-10-02', '2024-10-03', '2024-10-04',
'2024-10-05', '2024-10-06', '2024-10-07',
]
calendar = calendar[~calendar.isin(pd.to_datetime(holidays))]
return calendar
# 调用 API 获取准确日历
calendar = self._source.get_trading_calendar(
market=market,
start_date=start,
end_date=end
)
elif market == 'US':
# 美股:美国工作日
start = pd.Timestamp('2020-01-01')
end = pd.Timestamp('2025-12-31')
return pd.bdate_range(start=start, end=end)
if calendar is None:
# API 失败,抛出异常(不应静默降级)
raise ValueError(
f"交易日历获取失败: market={market}, {start} ~ {end}"
f"请检查 API 服务是否可用。"
)
elif market == 'HK':
# 港股:香港工作日
start = pd.Timestamp('2020-01-01')
end = pd.Timestamp('2025-12-31')
return pd.bdate_range(start=start, end=end)
else:
raise ValueError(f"不支持的市场: {market}")
return calendar
def get_benchmark(
self,