PanWatch 交易日历与时区设计:A股休市日 AI 为什么不会瞎跑
【免费下载链接】PanWatchPanWatch — AI stock monitoring for A-shares, HK & US markets, powered by TradingAgents. Portfolio insights, real-time alerts & automated reports.|盯盘侠:覆盖 A股/港股/美股的 AI 盯盘、持仓分析、实时提醒与自动报告。项目地址: https://gitcode.com/GitHub_Trending/pa/PanWatch
PanWatch 是一款覆盖A股、港股、美股的 AI 盯盘工具:它负责持仓分析、实时提醒和自动报告。但一个容易被忽略的问题——AI 定时任务如何知道今天到底开不开市——直接决定了它会不会在你国庆假期还发一堆无效通知。这篇文章带你看懂 PanWatch 的交易日历与时区设计:为什么盘前计划、日终摘要、模拟盘扫描在 A股休市日会自动"熄屏",而交易日又绝不会漏跑。
一个定时任务引发的"事故"
想象你配置了一个每天 09:00 执行的盘前计划任务。如果它只看"星期几",那周六周日能拦住;但 A股有法定节假日——国庆、春节、清明——全是工作日却休市。
对 AI 盯盘系统来说,休市日瞎跑有三宗罪:
- 💸白白消耗 Token:让大模型分析一份根本不会变化的行情
- 📢打扰用户:假期里推送一堆"今日盘前计划",没人看也失去信任
- 🌐跨市场误判:北京时间的周一 9 点,美股其实还在凌晨,按服务器本地时间判断必然错
PanWatch 的答案是把"时间判断"拆成两层,分别由不同模块负责。
交易日历:回答"这一天开不开市"
核心逻辑在 trading_calendar.py 中,对外只暴露两个函数:
is_trading_day(market, d):某个市场在某一天是否开市(默认查该市场时区的"今天")any_market_trading_day(d):CN/HK/US任一市场在交易即返回 True
A股:用权威日历,含法定节假日
A股节假日安排每年不同,靠"猜"是没用的。PanWatch 通过 akshare 拉取新浪交易日历(tool_trade_date_hist_sina),缓存为内存中的日期集合,启动预热 + 每日凌晨刷新(见 context_scheduler.py 中的日历刷新任务)。
判断顺序是精心安排的:
- 先判周末——零依赖、永远准确,三个市场统一拦截
- 再查 A股日历——日历已加载且查询日期在覆盖区间内,按法定节假日精确判断
- 其余情况——港美股、日历缺失、日期超出覆盖范围,降级为只判周末
降级哲学:宁可多发,不能漏发
模块顶部的注释写得很直白:
拿不到日历时退回「只判周末」—— 宁可多发一条通知,也不能把交易日误判为休市。少发一条是遗憾,漏发一整天是事故。
同时它对"没有日历源"保持诚实:港股/美股没有等价的公开节假日日历,就只判周末,不假装支持节假日。日期超出日历覆盖范围(比如跨年没刷新)也会安全降级,而不是直接报错。
时区设计:用"市场当地时间"做判断
第二个常见坑是时区。PanWatch 的做法是:每个市场自带时区和交易时段定义,判断时一律先换算到市场当地时间。
市场定义集中在 models.py:
| 市场 | 时区 | 交易时段 |
|---|---|---|
| A股 | Asia/Shanghai | 09:30–11:30,13:00–15:00 |
| 港股 | Asia/Hong_Kong | 09:30–12:00,13:00–16:00 |
| 美股 | America/New_York | 09:30–16:00 |
MarketDef.is_trading_time()的判断流程是:
- 把时间换算到该市场时区
- 先问交易日历:非交易日(周末/A股节假日)一律 False
- 再看当前时刻是否落在任一交易时段内
注意一个巧妙的设计:日历判断和时段判断是互补的,不能混用。盘前计划、日终摘要这类任务本身就发生在交易时段之外,如果只判断"是否在交易时段",它们会被永久拦死、永远不执行;所以必须用"是不是交易日"来守卫(这也是 trading_calendar.py 文件开头注释强调的重点)。
系统自身的时区则统一由 timezone.py 管理:默认Asia/Shanghai,可通过环境变量TZ覆盖,避免硬编码。
实战:定时任务如何被"拦截"
三层守卫分别拦截不同类型的任务:
① 逐只股票执行的任务——看交易时段agent_scheduler.py 在单只执行模式下,每只股票先问market_def.is_trading_time(),非交易时段直接跳过,日志记录"跳过(非交易时段)"。
② 盘前/日终类任务——看交易日历_paper_trading_scheduler.py 的盘前计划(每天 09:00)和日终摘要,执行前都先调any_market_trading_day():周末或 A股节假日直接跳过,一条通知都不发。
③ 高频扫描任务——全市场休市即停模拟盘扫描每 60 秒跑一次,但只要 CN/HK/US全部不在交易时段,本轮扫描直接跳过——"行情不动,扫了也白扫"。
边界处理:这套设计如何"诚实降级"
| 场景 | 行为 |
|---|---|
| 日历拉取失败 | 降级为只判周末,交易日照常跑,只是漏拦节假日(宁可多发) |
| 港美股节假日 | 无日历源,只判周末,不假装精确 |
| 日期超出日历覆盖范围(跨年) | 降级只判周末,并记 debug 日志 |
| 服务器与用户时区不同 | 判断统一换算到市场当地时间,不受影响 |
小结:把"什么时候该干活"交给日历
PanWatch 的这套设计可以总结成三句话:
- 日历管"哪天",时段管"几点"——两个问题分开判断,互不干扰
- 一切以市场当地时间为准——A股看上海、港股看香港、美股看纽约
- 降级永远朝"多发"方向——少发一条是遗憾,漏发一整天是事故
想深入了解实现细节,可以从这几个入口读起:
- 交易日历核心:src/platform/scheduling/trading_calendar.py
- 市场与时段定义:src/platform/marketdata/models.py
- Agent 调度守卫:src/modules/automation/agent_scheduler.py
- 模拟盘盘前/日终任务:src/modules/paper_trading/paper_trading_scheduler.py
- 日历刷新任务:src/modules/research/context_scheduler.py
- 相关单元测试:tests/test_trading_calendar.py
【免费下载链接】PanWatchPanWatch — AI stock monitoring for A-shares, HK & US markets, powered by TradingAgents. Portfolio insights, real-time alerts & automated reports.|盯盘侠:覆盖 A股/港股/美股的 AI 盯盘、持仓分析、实时提醒与自动报告。项目地址: https://gitcode.com/GitHub_Trending/pa/PanWatch
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考