3. 交易日历的生成与维护

交易日历是交易系统的“时间基准表”。它决定了某一天是否开市、属于哪个交易日、结算日如何顺延、节假日如何回补。时钟同步解决“现在几点”,而交易日历解决“今天算不算交易日、算哪一天”。两者共同构成 Session 管理的时间语义基础。本节聚焦交易日历的生成规则、数据来源与更新维护流程。

一、核心原理:交易日历不是简单节假日表

很多初学者把交易日历理解为“节假日列表”,这是最常见的认知偏差。真正的交易日历至少包含四类信息:

  • 自然日序列:连续的日历日期,作为主键骨架。
  • 交易日标志:该自然日是否为交易日(is_trading_day)。
  • 归属交易日:夜盘、跨零点交易时段归属到哪个交易日(trading_day)。
  • 阶段与顺延规则:如 T+1 结算、节假日顺延、临时休市。

以国内期货夜盘为例,周五 21:00 至次日凌晨 02:30 的交易,其自然日跨周五和周六,但归属交易日通常是下周一(若周一为交易日)。因此交易日历必须显式记录“归属交易日”映射,而不能靠日期加减推算。

关键结论:交易日历 = 自然日骨架 + 交易日标志 + 归属交易日映射 + 顺延规则。缺少归属映射的日历,在夜盘和跨节场景必然出错。

二、数据源:权威来源与工程化选择

交易日历的数据源可分为三类,工程上通常组合使用:

数据源类型典型来源优点风险
交易所官方公告上交所、深交所、中金所、大商所等权威、准确格式不统一、需人工整理
行情/柜台接口CTP、恒生、券商柜台与交易系统一致依赖接口可用性
第三方日历库交易所日历包、开源财经库开箱即用更新滞后、覆盖不全

推荐策略:以交易所公告为最终权威,第三方库作为初始种子和交叉校验,柜台接口用于运行时兜底。任何单一来源都不足以支撑生产级日历。

三、生成流程:从年度公告到可查询日历

交易日历的生成通常按年度进行,流程如下:

  1. 采集:抓取或录入各交易所下一年度休市安排公告。
  2. 解析:将公告文本解析为结构化记录(日期、休市类型、备注)。
  3. 展开:以自然日为骨架,逐日标注 is_trading_day。
  4. 映射:根据夜盘规则,计算每个自然日对应的 trading_day。
  5. 校验:检查连续性、节假日顺延、跨年边界。
  6. 入库:写入日历表,供交易、结算、风控查询。

下面是一个简化的日历表结构与生成伪代码:

CREATE TABLE trading_calendar (
  cal_date        DATE PRIMARY KEY,
  is_trading_day  BOOLEAN NOT NULL,
  trading_day     DATE NOT NULL,
  exchange        VARCHAR(16) NOT NULL,
  session_type    VARCHAR(16),
  remark          VARCHAR(128)
);

# 生成逻辑(伪代码)
for d in natural_days(year):
    is_td = d not in holidays and d.weekday() < 5
    td = resolve_trading_day(d, is_td, night_session_rule)
    insert(cal_date=d, is_trading_day=is_td, trading_day=td)

四、更新流程:年度、临时与运行时

交易日历的更新分为三个层次,节奏和风险各不相同:

  • 年度更新:每年末交易所发布次年安排,提前生成并冻结。
  • 临时更新:台风、疫情、系统故障等导致临时休市或调整。
  • 运行时更新:交易系统启动或每日初始化时加载最新日历。
建议做法:年度日历提前 1 个月生成并进入“预发布”状态,经双人复核后冻结;临时变更走独立审批通道,并记录变更日志与影响范围。
常见事故:临时休市公告发布后,仅更新了行情系统,未同步更新结算与风控系统,导致结算日错位、资金划拨异常。日历更新必须全链路一致。

五、案例与复盘:一次夜盘归属错误

某系统在国庆节前最后一个交易日(9 月 30 日,周二)的夜盘,将 21:00 后的交易归属为 10 月 1 日。由于 10 月 1 日至 7 日休市,系统在 10 月 8 日开盘时无法找到对应交易日,导致订单被拒绝、持仓对账失败。

复盘发现:日历生成时仅按“自然日 + 1”推算归属交易日,未考虑节假日顺延。修复方式是引入归属交易日映射表,并在生成阶段显式处理跨节场景。该案例说明,交易日历的生成规则必须覆盖夜盘、节假日和跨年三类边界。

交易日历生成与维护:数据源 → 规则 → 日历 → 消费 数据源 交易所公告 柜台接口 / 第三方库 生成规则 交易日标志 归属交易日映射 日历表 cal_date / trading_day is_trading_day 消费方 交易 / 结算 风控 / 行情 更新流程 年度更新(提前生成 → 双人复核 → 冻结) | 临时更新(审批 → 全链路同步 → 变更日志) | 运行时更新(启动加载 → 每日校验) 误区:只维护节假日 忽略夜盘归属与顺延 校验:连续性 + 边界 跨年、跨节、夜盘 目标:全链路一致 交易、结算、风控同源

六、维护要点与检查清单

为保证交易日历长期可靠,建议建立以下维护机制:

  • 每年 Q4 启动次年日历生成,预留复核与冻结窗口。
  • 日历表按交易所维度存储,避免多市场混用。
  • 所有消费方统一从日历服务读取,禁止各自硬编码节假日。
  • 每日开盘前执行日历自检:当日 trading_day 是否存在、是否连续。
  • 临时变更必须记录操作人、时间、影响范围与回滚方案。

交易日历的生成与维护,本质是把交易所规则转化为系统可查询、可校验、可追溯的时间数据。规则清晰、数据源权威、更新流程闭环,才能让 Session 管理在夜盘、节假日和跨年场景下保持正确。