# FlaskAPIFetcher 交易日历 API 集成 ## 更新日期 2024-04-16 --- ## 变更概述 将 `FlaskAPIFetcher.get_trading_calendar()` 从临时的 pandas BDay 实现升级为通过 API 获取准确交易日历。 --- ## 变更详情 ### 变更前(临时实现) ```python def get_trading_calendar(self, market: str = 'A') -> pd.Index: """使用 pandas BDay 生成近似日历""" if market == 'A': calendar = pd.bdate_range(start='2020-01-01', end='2025-12-31') # 手动移除节假日(不完整) holidays = ['2024-02-10', '2024-02-11', ...] calendar = calendar[~calendar.isin(pd.to_datetime(holidays))] return calendar elif market == 'US': return pd.bdate_range(start='2020-01-01', end='2025-12-31') ``` **问题**: - ❌ 使用 `bdate_range` 生成近似日历 - ❌ 节假日列表不完整 - ❌ 不支持动态日期范围 - ❌ 可能包含非交易日 --- ### 变更后(API 实现) ```python def get_trading_calendar( self, market: str = 'A', start: str = None, end: str = None ) -> pd.Index: """通过 API 获取准确交易日历""" # 默认日期范围 if start is None: start = '2020-01-01' if end is None: end = '2025-12-31' # 调用 API 获取准确日历 calendar = self._source.get_trading_calendar( market=market, start_date=start, end_date=end ) if calendar is None: raise ValueError( f"交易日历获取失败: market={market}, {start} ~ {end}" ) return calendar ``` **优势**: - ✅ 通过 API 获取准确日历 - ✅ 包含所有节假日处理 - ✅ 支持动态日期范围 - ✅ API 失败时抛出异常(不静默降级) --- ## API 端点 ### 请求 ``` GET /api/v1/trading-calendar 参数: - market: 市场代码 ('A', 'US', 'HK') - start: 开始日期 (YYYY-MM-DD) - end: 结束日期 (YYYY-MM-DD) ``` ### 响应 ```json { "market": "A", "exchange": "SSE", "trading_dates": ["2024-01-02", "2024-01-03", ...], "count": 242 } ``` --- ## 使用示例 ### 基础使用 ```python from framework_v2.shared.data import FlaskAPIFetcher fetcher = FlaskAPIFetcher() # 获取 A 股 2024 年交易日历 calendar = fetcher.get_trading_calendar( market='A', start='2024-01-01', end='2024-12-31' ) print(f"A 股交易日: {len(calendar)} 天") # 242 天 ``` ### 在数据对齐中使用 ```python from framework_v2.shared.data import FlaskAPIFetcher, CrossMarketAligner fetcher = FlaskAPIFetcher() # 1. 获取数据 data = fetcher.fetch_indices(["^IXIC"], "2024-01-01", "2024-12-31") # 2. 获取准确交易日历 calendar = fetcher.get_trading_calendar( market='A', start='2024-01-01', end='2024-12-31' ) # 3. 创建对齐器 aligner = CrossMarketAligner(target_calendar=calendar) # 4. 对齐收益率 returns = aligner.align_returns(data["^IXIC"]["close"], code="^IXIC") ``` --- ## 测试验证 ### 端到端测试结果 ``` 阶段 3: 数据对齐(到 A 股日历) ====================================================================== [3.1] 获取 A 股交易日历(通过 API)... ✓ A (SSE): 484 个交易日 (2023-01-03 ~ 2024-12-31) A 股交易日: 484 天 日期范围: 2023-01-03 00:00:00 ~ 2024-12-31 00:00:00 [3.2] 对齐因子到 A 股日历... 对齐 ^IXIC 因子... 对齐后天数: 484 填充天数: 18 (3.7%) NaN 数量: 15 对齐 399006.SZ 因子... 对齐后天数: 484 填充天数: 0 (0.0%) NaN 数量: 19 [3.3] 对齐收益率到 A 股日历... 对齐 ^IXIC 收益率... 对齐后天数: 484 收益率范围: -3.6391% ~ 4.4159% NaN 数量: 0 零收益率天数: 18 (休市日) ✅ 对齐 399006.SZ 收益率... 对齐后天数: 484 收益率范围: -10.5941% ~ 17.2494% NaN 数量: 0 零收益率天数: 0 (休市日) ✅ ✓ 阶段 3 通过 ``` ### 关键验证 | 验证项 | 预期 | 实际 | 状态 | |--------|------|------|------| | API 调用成功 | 是 | 是 | ✅ | | 返回天数准确 | 484 天 | 484 天 | ✅ | | 纳指休市日 | 18 天 | 18 天 | ✅ | | 创业板休市日 | 0 天 | 0 天 | ✅ | | 收益率 NaN | 0 | 0 | ✅ | --- ## 影响分析 ### 正面影响 1. **准确性提升**: 从近似日历 → 准确日历 2. **维护成本降低**: 无需手动维护节假日列表 3. **多市场支持**: A 股、美股、港股统一 API 4. **动态日期范围**: 支持任意日期范围查询 ### 无破坏性变更 - ✅ 方法签名向后兼容(新增可选参数 `start`, `end`) - ✅ 返回类型兼容(`pd.DatetimeIndex` 是 `pd.Index` 的子类) - ✅ 现有代码无需修改 --- ## 相关文件 | 文件 | 变更 | |------|------| | `framework_v2/shared/data/flask_api_fetcher.py` | 更新 `get_trading_calendar()` 实现 | | `framework_v2/tests/test_end_to_end.py` | 更新测试使用 API 日历 | | `framework_v2/FLASK_API_FETCHER_GUIDE.md` | 更新文档 | | `framework_v2/FLASK_API_FETCHER_ARCHITECTURE.md` | 更新架构说明 | | `datasource/flask_api_source.py` | 底层 API 调用(已存在) | --- ## 版本历史 - **2024-04-16**: API 交易日历集成 - 替换临时 pandas BDay 实现 - 调用 `/api/v1/trading-calendar` 端点 - 支持动态日期范围 - 端到端测试通过 - **2024-04-15**: 初始版本 - 临时实现(pandas BDay + 手动节假日) - 固定日期范围(2020-2025)