Files
ai-exchange/docs/AI_ICT_Session_Generator_Spec_v1.md
2026-04-24 13:39:01 +08:00

11 KiB
Raw Permalink Blame History

AI ICT Session Generator 规格说明 v1

1. 文档目标

本文档定义 market session generator 的输入、时间规则、切分逻辑、计算方法、完整性检查和落库输出,用于指导 market_sessions 相关开发实现。

目标:

  • 统一时区与交易日边界
  • 生成稳定、可重复的 session segmentation
  • 计算 session high / low / midpoint
  • 识别数据缺失与异常情况
  • 结果结构化输出到 market_sessions

适用范围:AI ICT 项目第一阶段 MVP。

关联文档:

  1. AI_ICT_总体设计文档_v1.md
  2. AI_ICT_PostgreSQL_Schema_v1.md
  3. AI_ICT_MVP_规则规格书_v1.md
  4. AI_ICT_开发路线图_v1.md
  5. AI_ICT_执行检查清单_v1.md

2. 设计目标与边界

2.1 目标

session generator 负责把标准化 candles 按固定会话切分,生成后续规则与执行依赖的 session 数据。

输出必须支持:

  • session high
  • session low
  • midpoint
  • session 状态
  • 完整性元数据
  • 后续 rule-engine 的 session pivot 查询

2.2 不负责的内容

第一版 session generator 不负责:

  • 自动判断 bias
  • 自动判断 sweep / MSS / FVG
  • 直接产生交易信号
  • 直接生成 execution permission 最终结论

这些能力由后续 rule-engine / signal-service 基于 market_sessions 再加工。


3. 输入与输出

3.1 输入

最小输入:

  • instrument_id
  • symbol
  • timezone config
  • 标准化 candles
  • 指定 session_date 或待重算的日期范围

candles 最低要求字段:

  • instrument_id
  • timeframe
  • ts_open
  • ts_close
  • open
  • high
  • low
  • close

3.2 输出

输出到 market_sessions 表,字段遵循已有 schema:

  • instrument_id
  • session_date
  • timezone
  • session_code
  • start_ts
  • end_ts
  • high
  • low
  • midpoint
  • status
  • meta

4. 时间与时区规范

4.1 存储原则

  • 数据库存储统一使用 timestamptz
  • 所有 start_ts / end_ts 均保存为 UTC 对应绝对时间
  • session 定义使用业务时区解释,不直接使用服务器本地时区

4.2 第一版默认业务时区

第一版默认业务时区统一为:

  • America/New_York

原因:

  • 当前默认 session 模型围绕纽约交易时段定义
  • LONDON / NY_AM / NY_LUNCH / NY_PM 都依赖纽约时区解释
  • 能统一 crypto 与 XAU 的 session 观察口径

4.3 交易日定义

第一版 session_date 定义为“业务时区下该组 session 所属日期”。

例如:

  • ASIA 2026-04-23 指的是在 America/New_York 语义下,属于 2026-04-23 交易日的 ASIA 会话
  • 虽然其 UTC 时间可能跨自然日,但 session_date 不按 UTC 日历切换,而按业务时区日历归属

4.4 DST 处理原则

必须支持 America/New_York 夏令时切换。

规则:

  1. session 定义始终以业务时区本地时钟解释
  2. 转换到数据库时,再映射为 UTC start_ts / end_ts
  3. 不允许通过手写固定 UTC 偏移硬编码 session
  4. DST 切换日必须通过时区库计算,不能人工推导

5. Session 定义与切分规则

5.1 默认 session 列表

第一版采用以下默认 session:

  • ASIA: 20:00 - 00:00
  • LONDON: 02:00 - 05:00
  • NY_AM: 09:30 - 11:00
  • NY_LUNCH: 12:00 - 13:00
  • NY_PM: 13:30 - 16:00

时区基准:America/New_York。

5.2 Session 边界约定

统一采用:

  • start_ts inclusive
  • end_ts exclusive

即:

start_ts <= candle.ts_open < end_ts

这样可以避免相邻 session 在边界 candle 上重复归属。

5.3 跨午夜处理

ASIA: 20:00 - 00:00 会跨本地日内晚间到午夜边界。

处理规则:

  • 如果 session 结束时间小于等于开始时间,则视为跨日 session
  • end_ts 应自动落到下一自然日的 00:00
  • session_date 仍归属该交易日定义,不因为 UTC 或本地午夜而拆成两段

5.4 单 candle 归属原则

一根 candle 在第一版中只能归属一个 session。

归属依据:

  • 用 candle.ts_open 判断所属 session
  • 不使用 ts_close 参与归属判定
  • 若某 candle 不落在任何 session 区间,则不进入 market_sessions 聚合

5.5 推荐运行粒度

第一版建议以基础数据主时间框架生成 session,推荐:

  • 1m 为最优
  • 5m 可作为退化版本

原因:

  • NY_AM、NY_LUNCH 等窗口较短
  • 更细粒度有利于后续 pivot、sweep、session high/low 分析

6. Session 聚合逻辑

6.1 选取数据范围

给定 instrument_id + session_date + session_code + timezone:

  1. 计算业务时区下的本地 start_local / end_local
  2. 转换成 UTC start_ts / end_ts
  3. 查询满足以下条件的 candles:
instrument_id = ?
timeframe = configured_base_tf
candle.ts_open >= start_ts
candle.ts_open < end_ts

6.2 high / low 计算

  • high = max(candle.high)
  • low = min(candle.low)

前提:至少存在一根有效 candle。

6.3 midpoint 计算

第一版 midpoint 定义为:

midpoint = (high + low) / 2

注意:

  • midpoint 不是 VWAP
  • midpoint 不是 open/close 平均值
  • midpoint 是 session range 的几何中点

6.4 扩展元数据

建议在 meta 写入:

  • timeframe_used
  • candle_count
  • expected_candle_count
  • completeness_ratio
  • is_dst
  • source
  • generated_at
  • data_gaps
  • rebuild_reason

7. 数据完整性检查

7.1 检查目标

session generator 不能只算出 high / low,还必须判断该 session 是否足够完整,避免缺失 candles 导致 pivot 失真。

7.2 期望 K 线数量

应按 session 时长与 configured_base_tf 计算理论 candle 数量。

示例:

  • ASIA 20:00 - 00:00,若 1m 粒度,理论 240 根
  • LONDON 02:00 - 05:00,若 1m 粒度,理论 180 根
  • NY_AM 09:30 - 11:00,若 1m 粒度,理论 90 根

7.3 完整性比率

completeness_ratio = actual_candle_count / expected_candle_count

7.4 第一版状态建议

status 建议值:

  • closed:会话已结束且完整性达标
  • partial:会话已结束但数据缺失
  • open:会话尚未结束,仍在生成中
  • empty:窗口内无有效 candle
  • invalid:时间配置或输入异常,结果不可用

7.5 第一版完整性阈值

建议:

  • >= 0.98 视为 closed
  • > 0 and < 0.98 视为 partial
  • = 0 视为 empty

是否采用 0.98 可配置,但第一版文档默认使用该值。

7.6 Gap 检查

除了 candle 数量,还应检查时间连续性:

  • 相邻 ts_open 间隔应等于 timeframe 步长
  • 若出现跳点,则记录 gap 段
  • 若出现重复 candle,应在上游 candles 唯一约束阶段拦截;session generator 不负责去重修复

建议记录到 meta.data_gaps:

[
  {
    "expected": "2026-04-23T13:15:00Z",
    "actual": "2026-04-23T13:17:00Z",
    "missing_count": 1
  }
]

8. 生成流程规范

8.1 全量重算

适用场景:

  • 初始化历史数据
  • 修复 session 定义
  • 迁移后重建 session 数据

流程:

  1. 读取日期范围
  2. 按 instrument 逐日生成 session 窗口
  3. 查询 candles
  4. 计算 high / low / midpoint
  5. 执行完整性检查
  6. upsert 到 market_sessions

8.2 增量更新

适用场景:

  • 新 candles 持续进入
  • 当天 session 持续刷新

流程:

  1. 找到受影响 instrument + session_date + session_code
  2. 重新聚合整个 session 窗口
  3. 用 upsert 覆盖原记录
  4. 若会话尚未结束,状态保持 open
  5. 会话结束后再转为 closed / partial / empty

8.3 Upsert 规则

基于唯一键:

(instrument_id, session_date, session_code, timezone)

建议行为:

  • 不做 append-only
  • 直接 upsert 最新聚合结果
  • updated_at 反映最近刷新时间

9. market_sessions 输出规范

9.1 字段映射

  • instrument_id:来自上游 instrument
  • session_date:业务时区下的交易日
  • timezone:第一版固定 America/New_York
  • session_code:ASIA / LONDON / NY_AM / NY_LUNCH / NY_PM
  • start_ts:本地 session 起点转 UTC
  • end_ts:本地 session 终点转 UTC
  • high:session 期间最高价
  • low:session 期间最低价
  • midpoint:(high + low) / 2
  • status:open / closed / partial / empty / invalid
  • meta:完整性与生成元数据

9.2 约束要求

写入前必须保证:

  • high >= low
  • 当 status in ('closed', 'partial', 'open') 时,high 与 low 不应为空
  • 当 status in ('empty', 'invalid') 时,high / low / midpoint 可为空

9.3 推荐 meta 结构

{
  "timeframe_used": "1m",
  "expected_candle_count": 90,
  "actual_candle_count": 89,
  "completeness_ratio": 0.9889,
  "is_dst": true,
  "source": "session-generator",
  "generated_at": "2026-04-23T14:05:00Z",
  "data_gaps": []
}

10. 异常与边界情况

10.1 空窗口

若 session 时间窗口内完全没有 candle:

  • 写入一条 status = empty 的记录
  • high / low / midpoint 留空
  • 在 meta 记录原因

10.2 未结束会话

若当前时间仍早于 end_ts:

  • 允许生成实时中的 session
  • status = open
  • 可用于盘中监控,但不能视为最终 session pivot

10.3 DST 切换日

DST 切换导致 UTC 映射变化时:

  • 仍按本地 session 时钟定义生成
  • 允许 expected_candle_count 因本地时间异常而变化,但必须有明确计算依据
  • meta.is_dst 与相关说明必须保留

10.4 上游 candle 重建

若 candles 历史数据被修复或补齐:

  • 必须触发对应日期 session 重算
  • 不允许沿用旧 session 结果

10.5 非连续交易市场

若后续接入存在休市机制的 market:

  • 第一版仍沿用统一 session 规则
  • 节假日与休市判断暂由外部日历模块处理
  • session generator 只消费“应该参与生成的日期集合”

11. 验证与验收要求

11.1 功能验证

至少验证:

  • 能为同一 instrument 连续生成 5 个 session_code
  • 同一天查询能拿到完整 session 列表
  • midpoint 计算正确
  • 重复执行生成任务结果稳定

11.2 数据验证

至少验证:

  • session_date 归属正确
  • start_ts / end_ts 对应的业务时区时间正确
  • high / low 与原始 candle 对齐
  • partial / empty 状态能正确触发

11.3 人工抽查

至少抽查:

  • 一个正常交易日
  • 一个存在 gap 的交易日
  • 一个 DST 切换附近交易日

11.4 与检查清单对齐

任务关闭前至少满足:

  • session generator 规格已写入本地 .md
  • 路径存在
  • 已检查标题、章节、关键内容
  • 规格足以指导后续实现与测试

12. 推荐实现顺序

建议按以下顺序落地:

  1. 固定 America/New_York session 定义
  2. 完成窗口计算与 UTC 转换
  3. 完成 candles 聚合
  4. 完成 high / low / midpoint 计算
  5. 完成 completeness / gap 检查
  6. 完成 market_sessions upsert
  7. 再补增量重算与异常记录

这样可以先让 session 数据可落库,再逐步增强完整性判断。


13. 最终结论

session generator 是全部后续 ICT 结构识别的重要上游。

第一版实现必须保证三件事:

  1. 时间边界稳定
  2. 聚合结果可重复
  3. 缺失数据可识别

只有在这三点成立后,market_sessions 才能可靠支撑 liquidity pools、session pivots、sweep 判定和执行窗口过滤。