Date 模块设计决策
目录
1. 设计目标
1.1 核心目标
Date 模块旨在为量化交易系统提供:
- 精确性:时间戳和日期计算零误差
- 可靠性:交易日历与交易所同步
- 易用性:简洁的函数接口
- 性能:高效的批量处理能力
1.2 非目标
- 不提供历史行情复权功能(由数据层处理)
- 不提供时间序列索引(由DataFrame处理)
- 不提供时区转换的完整支持(仅默认北京时间)
2. 架构决策
2.1 分离 timestamp 和 trade 模块
决策:将时间戳处理和交易日算法分离为两个独立子模块
原因:
- 职责分离:timestamp 处理通用时间转换,trade 处理业务相关的交易日计算
- 依赖分离:timestamp 仅依赖标准库和numpy,trade 依赖 pandas 和业务常量
- 可维护性:两个领域独立演进,互不影响
权衡:
- 跨模块调用稍显繁琐(如需要同时导入)
- 但避免了单一模块过大
2.2 预加载交易日数据
决策:使用 trade_dates_data.py 预生成完整的 TRADE_DATE_SSE 列表
替代方案考虑:
| 方案 | 优点 | 缺点 |
|---|---|---|
| 预生成列表 | O(1)查询、无网络依赖 | 占用内存、需手动更新 |
| 实时API查询 | 数据实时 | 依赖网络、有延迟 |
| 算法计算 | 零存储 | 无法处理复杂节假日 |
最终选择:预生成列表,平衡查询性能和实现复杂度
2.3 函数命名规范
决策:采用 util_ 前缀统一命名
原因:
- 避免与标准库命名冲突
- 明确标识为工具函数
- 保持与原 FQData 的一致性
3. 性能决策
3.1 二分查找优化
决策:util_get_real_date() 使用 bisect.bisect_left() 实现 O(log n) 查找
python
pos = bisect.bisect_left(trade_list, date_str)原因:
- 交易日列表长度随年份增长(已超过9000条)
- 线性搜索 O(n) 在频繁调用时成为瓶颈
- 二分查找 O(log n) 性能提升显著
权衡:
- trade_date_sse 必须有序(预生成列表保证)
- 代码复杂度略有增加
3.2 util_if_trade 的 O(1) 查询
决策:使用 in 操作符直接查询列表
python
return normalized in trade_date_sse原因:
- Python 列表的
in操作在短列表上性能优秀 - 预加载数据保证列表在内存中
- 避免函数调用开销
注意:当 trade_date_sse 列表非常大时,可考虑转换为 set 优化:
python
trade_date_set = set(trade_date_sse) # O(1) 但增加内存3.3 时间戳自动精度识别
决策:util_stamp2datetime() 自动识别多种时间戳精度
python
try:
return datetime.fromtimestamp(timestamp)
except OSError:
try:
return datetime.fromtimestamp(timestamp / 1000) # 毫秒
...原因:
- 不同数据源使用不同精度的时间戳
- 自动识别避免用户手动转换
- 向后兼容各种历史数据格式
4. 兼容性决策
4.1 迁移自 FQData
决策:保持函数签名和命名与原 FQData.QAUtil.QADate 一致
原因:
- 减少现有代码的迁移成本
- 降低用户学习成本
- 保持 FQBase 的"即插即用"特性
实现:
- 复制原有函数逻辑
- 更新模块路径导入
- 保持
__all__导出列表一致
4.2 多种日期格式支持
决策:util_format_date2str() 支持多种输入格式
python
def util_format_date2str(cursor_date):
# 支持: str, int, datetime, datetime.date, pd.Timestamp原因:
- 量化数据源格式不统一
- 用户代码中日期格式各异
- 统一格式化简化数据处理流程
4.3 默认北京时间
决策:所有时间转换默认使用北京时间(UTC+8)
python
QATZInfo_CN = 'Asia/Shanghai'
local_tz = timezone(timedelta(hours=8))原因:
- 中国量化交易主要市场为A股和国内期货
- 避免时区混淆导致的交易事故
- 简化国内交易系统的开发
注意:跨境外市场数据需显式处理时区
5. 市场支持决策
5.1 A股支持
决策:内置上证所交易日历 trade_date_sse
范围:1990-12-19(上证成立)至今
维护:每年初更新,重大节假日调整后同步
5.2 期货支持
决策:util_if_tradetime() 支持国内期货交易时间
覆盖品种:
- 商品期货(9:00-10:15, 10:30-11:30, 13:30-15:00)
- 金融期货 IH/IF/IC(9:30-11:30, 13:00-15:00)
- 国债期货 T/TF(9:15-11:30, 13:00-15:15)
夜盘支持:
- AU/AG/SC(贵金属/原油):21:00-02:30
- CU/AL/ZN/PB/SN/NI(基本金属):21:00-01:00
- RU/RB/HC/BU/FU/SP(黑色/化工):21:00-23:00
5.3 市场类型常量
决策:使用 MARKET_TYPE 枚举区分市场
python
from FQBase.Config.business.constants import MARKET_TYPE
MARKET_TYPE.STOCK_CN # A股
MARKET_TYPE.FUTURE_CN # 国内期货原因:
- 避免字符串硬编码
- IDE 自动补全支持
- 类型检查支持
6. 未来演进方向
6.1 可能的变化
| 变化 | 触发条件 |
|---|---|
| 交易所改用T+0交易 | 政策重大调整 |
| 增加港股/美股支持 | 业务国际化 |
| 引入缓存机制 | 性能瓶颈显现 |
| 时间序列索引 | 复杂时间框架需求 |
6.2 不纳入的设计
以下功能不属于 Date 模块职责:
- K线合成(如1分钟转5分钟)
- 复权数据处理
- 财务日历(非交易日历)
- 国际节假日支持