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

18 KiB
Raw Permalink Blame History

AI ICT PostgreSQL Schema 设计稿 v1

1. 文档目标

本文档定义 AI ICT 交易辅助系统第一阶段的 PostgreSQL 数据库设计方案,用于指导后续开发、建表、索引、分区和数据落库规范。

目标:

  • 支撑 K 线与时间序列数据
  • 支撑 ICT 结构事件与信号建模
  • 支撑回测、复盘和审计
  • 支撑半结构化 evidence / narrative / labels 存储

2. 设计原则

  1. PostgreSQL 作为主库
  2. 时间序列主表优先做唯一键与分区设计
  3. 结构事件独立存表,不混入自由文本
  4. AI 相关说明使用 jsonb,但不替代核心字段
  5. 回测与实盘使用同一事件口径
  6. 先保守建模,预留扩展字段,不做过早复杂抽象

3. 命名规范

  • 表名:复数下划线风格,如 trade_signals
  • 主键:统一使用 bigserial 或 uuid
  • 时间字段:统一使用 timestamptz
  • 创建更新时间:created_at, updated_at
  • 逻辑状态:status
  • 配置或证据:jsonb

建议:

  • 若系统由 Python / TypeScript 混合开发,业务主键可用 uuid
  • 若偏简洁开发,内部主键可用 bigserial,外部展示再加 public_id

第一版建议:

  • 主表内部主键:bigserial
  • 对外引用可追加 code / public_id

4. 核心实体关系概览

venues
  -> instruments
      -> candles
      -> market_sessions
      -> swings
      -> dealing_ranges
      -> liquidity_pools
      -> displacement_events
      -> structure_events
      -> fvg_zones
      -> bias_snapshots
      -> trade_signals
          -> trade_executions

backtest_runs
  -> backtest_results

5. 基础表设计

5.1 venues

用途:交易所定义表。

建议字段:

id              bigserial primary key
code            text not null unique
name            text not null
timezone        text not null
status          text not null default 'active'
created_at      timestamptz not null default now()
updated_at      timestamptz not null default now()

示例数据:

  • OKX
  • LMAX

5.2 instruments

用途:交易品种定义表。

建议字段:

id              bigserial primary key
venue_id        bigint not null references venues(id)
symbol          text not null
asset_class     text not null
base_asset      text
quote_asset     text
price_scale     integer not null
qty_scale       integer not null
tick_size       numeric(20,10) not null
lot_size        numeric(20,10)
active          boolean not null default true
meta            jsonb not null default '{}'
created_at      timestamptz not null default now()
updated_at      timestamptz not null default now()

唯一约束:

unique (venue_id, symbol)

说明:

  • meta 存放交易所特定扩展信息
  • 如 XAU 在不同 venue 上合约不同,可通过 meta 补充合约属性

6. 行情与时间表设计

6.1 candles

用途:标准化 K 线主表。

建议字段:

id              bigserial primary key
instrument_id   bigint not null references instruments(id)
timeframe       text not null
ts_open         timestamptz not null
ts_close        timestamptz not null
open            numeric(20,10) not null
high            numeric(20,10) not null
low             numeric(20,10) not null
close           numeric(20,10) not null
volume          numeric(28,10)
source          text not null default 'api'
created_at      timestamptz not null default now()

唯一约束:

unique (instrument_id, timeframe, ts_open)

核心索引:

index on (instrument_id, timeframe, ts_open desc)
index on (instrument_id, timeframe, ts_close desc)

分区建议:

  • 第一版按月范围分区
  • 分区键建议使用 ts_open

例如:

  • candles_2026_04
  • candles_2026_05

说明:

  • timeframe 先使用文本:1m, 5m, 15m, 1h, 4h, 1d
  • 后期可引入枚举或维表

6.2 market_sessions

用途:保存会话级别数据与 pivot。

建议字段:

id              bigserial primary key
instrument_id   bigint not null references instruments(id)
session_date    date not null
timezone        text not null
session_code    text not null
start_ts        timestamptz not null
end_ts          timestamptz not null
high            numeric(20,10)
low             numeric(20,10)
midpoint        numeric(20,10)
status          text not null default 'closed'
meta            jsonb not null default '{}'
created_at      timestamptz not null default now()
updated_at      timestamptz not null default now()

唯一约束:

unique (instrument_id, session_date, session_code, timezone)

建议的 session_code:

  • ASIA
  • LONDON
  • NY_AM
  • NY_LUNCH
  • NY_PM

说明:

  • meta 可保存 broken / mitigated / extension 信息
  • 该表是会话 pivot、killzone 和执行许可的重要基础

7. 结构识别表设计

7.1 swings

用途:保存结构高低点。

建议字段:

id              bigserial primary key
instrument_id   bigint not null references instruments(id)
timeframe       text not null
kind            text not null
strength        text not null
price           numeric(20,10) not null
ts              timestamptz not null
left_bars       integer not null
right_bars      integer not null
confirmed       boolean not null default true
meta            jsonb not null default '{}'
created_at      timestamptz not null default now()

索引建议:

index on (instrument_id, timeframe, ts desc)
index on (instrument_id, timeframe, kind, ts desc)
index on (instrument_id, timeframe, strength, ts desc)

约束建议:

  • kind in ('swing_high', 'swing_low')
  • strength in ('ST', 'IT', 'LT')

7.2 dealing_ranges

用途:保存当前工作区间。

建议字段:

id                  bigserial primary key
instrument_id       bigint not null references instruments(id)
timeframe           text not null
high                numeric(20,10) not null
low                 numeric(20,10) not null
equilibrium         numeric(20,10) not null
high_swing_id       bigint references swings(id)
low_swing_id        bigint references swings(id)
state               text not null default 'valid'
ts_start            timestamptz not null
ts_end              timestamptz
meta                jsonb not null default '{}'
created_at          timestamptz not null default now()
updated_at          timestamptz not null default now()

索引建议:

index on (instrument_id, timeframe, ts_start desc)
index on (instrument_id, timeframe, state, ts_start desc)

说明:

  • 同一时刻可能存在多个 timeframe 的 range
  • 第一版允许一个 timeframe 存多条历史记录,由 state 标识当前有效项

7.3 liquidity_pools

用途:保存流动性目标区域。

建议字段:

id              bigserial primary key
instrument_id   bigint not null references instruments(id)
timeframe       text not null
side            text not null
pool_type       text not null
price_low       numeric(20,10) not null
price_high      numeric(20,10) not null
reference_ids   jsonb not null default '[]'
status          text not null default 'untouched'
created_ts      timestamptz not null
updated_ts      timestamptz not null default now()
meta            jsonb not null default '{}'
created_at      timestamptz not null default now()

建议约束:

  • side in ('buy_side', 'sell_side')
  • status in ('untouched', 'swept', 'consumed')

pool_type 建议值:

  • prior_high
  • prior_low
  • equal_highs
  • equal_lows
  • session_high
  • session_low

索引建议:

index on (instrument_id, timeframe, status, created_ts desc)
index on (instrument_id, timeframe, side, created_ts desc)

7.4 displacement_events

用途:保存有效位移事件。

建议字段:

id                  bigserial primary key
instrument_id       bigint not null references instruments(id)
timeframe           text not null
direction           text not null
start_ts            timestamptz not null
end_ts              timestamptz not null
strength_score      numeric(8,4)
body_ratio          numeric(8,4)
has_fvg             boolean not null default false
is_valid            boolean not null default true
meta                jsonb not null default '{}'
created_at          timestamptz not null default now()

索引建议:

index on (instrument_id, timeframe, end_ts desc)
index on (instrument_id, timeframe, direction, end_ts desc)

7.5 structure_events

用途:保存 MSB / MSS 等结构事件。

建议字段:

id                      bigserial primary key
instrument_id           bigint not null references instruments(id)
timeframe               text not null
event_type              text not null
direction               text not null
broken_level            numeric(20,10) not null
reference_swing_id      bigint references swings(id)
displacement_event_id   bigint references displacement_events(id)
accepted                boolean
signal_relevant         boolean not null default true
ts                      timestamptz not null
meta                    jsonb not null default '{}'
created_at              timestamptz not null default now()

约束建议:

  • event_type in ('MSB', 'MSS')
  • direction in ('bullish', 'bearish')

索引建议:

index on (instrument_id, timeframe, ts desc)
index on (instrument_id, timeframe, event_type, ts desc)

7.6 fvg_zones

用途:保存 FVG / imbalance 区域。

建议字段:

id                          bigserial primary key
instrument_id               bigint not null references instruments(id)
timeframe                   text not null
direction                   text not null
upper                       numeric(20,10) not null
lower                       numeric(20,10) not null
start_ts                    timestamptz not null
end_ts                      timestamptz not null
fill_pct                    numeric(8,4) not null default 0
status                      text not null default 'open'
related_displacement_id     bigint references displacement_events(id)
meta                        jsonb not null default '{}'
created_at                  timestamptz not null default now()
updated_at                  timestamptz not null default now()

约束建议:

  • direction in ('bullish', 'bearish')
  • status in ('open', 'touched', 'mitigated', 'invalidated')

索引建议:

index on (instrument_id, timeframe, start_ts desc)
index on (instrument_id, timeframe, status, start_ts desc)

8. 决策与执行表设计

8.1 bias_snapshots

用途:保存特定时刻的 bias 结果。

建议字段:

id                  bigserial primary key
instrument_id       bigint not null references instruments(id)
bias_tf             text not null
setup_tf            text not null
trigger_tf          text not null
snapshot_ts         timestamptz not null
daily_bias          text not null
confidence          numeric(8,4)
execution_intensity text not null
narrative_code      text
draw_side           text
range_id            bigint references dealing_ranges(id)
reason_codes        jsonb not null default '[]'
meta                jsonb not null default '{}'
created_at          timestamptz not null default now()

约束建议:

  • daily_bias in ('bullish', 'bearish', 'neutral')
  • execution_intensity in ('low', 'medium', 'high')

索引建议:

index on (instrument_id, snapshot_ts desc)
index on (instrument_id, daily_bias, snapshot_ts desc)

8.2 trade_signals

用途:保存候选交易信号。

建议字段:

id                  bigserial primary key
instrument_id       bigint not null references instruments(id)
model_code          text not null
side                text not null
status              text not null
bias_snapshot_id    bigint references bias_snapshots(id)
entry_type          text not null
entry_low           numeric(20,10)
entry_high          numeric(20,10)
stop_loss           numeric(20,10)
tp1                 numeric(20,10)
tp2                 numeric(20,10)
rr_tp1              numeric(8,4)
rr_tp2              numeric(8,4)
session_code        text
created_ts          timestamptz not null
expires_ts          timestamptz
invalidations       jsonb not null default '[]'
evidence            jsonb not null default '{}'
meta                jsonb not null default '{}'
created_at          timestamptz not null default now()
updated_at          timestamptz not null default now()

建议状态值:

  • draft
  • awaiting_context
  • awaiting_confirmation
  • active
  • tp1_hit
  • tp2_hit
  • invalidated
  • expired
  • cancelled

索引建议:

index on (instrument_id, created_ts desc)
index on (instrument_id, status, created_ts desc)
index on (instrument_id, model_code, created_ts desc)

说明:

  • evidence 保存 rule engine 引用对象,如 range_id, sweep_event_id, structure_event_id, fvg_id
  • 核心交易字段必须显式建列,不应只放进 JSON

8.3 trade_executions

用途:保存实际执行记录。

建议字段:

id                  bigserial primary key
signal_id           bigint not null references trade_signals(id)
venue_order_id      text
execution_mode      text not null
side                text not null
entry_price         numeric(20,10)
stop_loss           numeric(20,10)
take_profit_1       numeric(20,10)
take_profit_2       numeric(20,10)
size                numeric(28,10)
risk_pct            numeric(8,4)
status              text not null
opened_ts           timestamptz
closed_ts           timestamptz
pnl                 numeric(28,10)
meta                jsonb not null default '{}'
created_at          timestamptz not null default now()
updated_at          timestamptz not null default now()

建议枚举:

  • execution_mode in ('paper', 'semi_auto', 'live')
  • status in ('pending', 'open', 'partially_closed', 'closed', 'cancelled', 'rejected')

索引建议:

index on (signal_id)
index on (status, created_at desc)
index on (execution_mode, created_at desc)

9. 回测与分析表设计

9.1 backtest_runs

用途:保存回测任务定义与结果摘要。

建议字段:

id              bigserial primary key
model_code      text not null
instrument_id   bigint references instruments(id)
timeframe_set    jsonb not null default '{}'
started_ts      timestamptz not null
ended_ts        timestamptz
config          jsonb not null default '{}'
summary         jsonb not null default '{}'
created_at      timestamptz not null default now()

索引建议:

index on (model_code, started_ts desc)
index on (instrument_id, started_ts desc)

9.2 backtest_results

用途:保存回测明细结果。

建议字段:

id                      bigserial primary key
backtest_run_id         bigint not null references backtest_runs(id)
signal_id               bigint references trade_signals(id)
outcome                 text not null
mfe                     numeric(20,10)
mae                     numeric(20,10)
tp1_hit                 boolean
tp2_hit                 boolean
invalidated_before_entry boolean
error_tags              jsonb not null default '[]'
meta                    jsonb not null default '{}'
created_at              timestamptz not null default now()

建议枚举:

  • outcome in ('win', 'loss', 'breakeven', 'missed')

索引建议:

index on (backtest_run_id)
index on (outcome)

10. JSONB 边界建议

适合放入 jsonb 的内容:

  • evidence 引用集合
  • narrative reason codes
  • 回测 error tags
  • 风控检查详情
  • 第三方交易所扩展字段
  • 会话扩展状态

不应只存在于 jsonb 的内容:

  • side
  • status
  • timeframe
  • symbol / instrument_id
  • stop_loss
  • tp1 / tp2
  • bias
  • event_type
  • direction
  • ts

原则:

  • 查询高频、过滤高频、排序高频字段必须单独建列
  • JSONB 仅用于补充与扩展

11. 索引策略建议

11.1 时间序列表

优先索引:

  • (instrument_id, timeframe, ts_open desc)
  • (instrument_id, timeframe, ts desc)
  • (instrument_id, status, created_ts desc)

11.2 事件表

优先索引:

  • 按 instrument_id + timeframe + time
  • 按 event_type
  • 按 status

11.3 回测表

优先索引:

  • backtest_run_id
  • outcome
  • instrument_id + started_ts

12. 分区建议

12.1 必须优先分区的表

  1. candles
  2. 后期若数据量变大,可考虑:
    • trade_signals
    • trade_executions
    • backtest_results

12.2 第一版建议

  • candles 采用月分区
  • 其他表先普通表 + 合理索引
  • 不要一开始对所有事件表做过度分区

原因:

  • candles 数据量增长最快
  • 其余表前期量可控
  • 先简化迁移和开发成本

13. 当前优先落地的 5 张基础表

按照基础模块优先,建议先建:

  1. venues
  2. instruments
  3. candles
  4. market_sessions
  5. swings

然后再建:

  1. dealing_ranges
  2. liquidity_pools

之后进入:

  1. displacement_events
  2. structure_events
  3. fvg_zones
  4. bias_snapshots
  5. trade_signals
  6. trade_executions
  7. backtest_runs
  8. backtest_results

14. 建表顺序建议

第一阶段

  • venues
  • instruments
  • candles
  • market_sessions

第二阶段

  • swings
  • dealing_ranges
  • liquidity_pools

第三阶段

  • displacement_events
  • structure_events
  • fvg_zones

第四阶段

  • bias_snapshots
  • trade_signals
  • trade_executions

第五阶段

  • backtest_runs
  • backtest_results

15. 当前结论

Schema v1 的目标不是一次性穷尽全部 ICT 概念,而是先稳定支撑以下主链路:

Candles -> Sessions -> Swings -> Ranges -> Liquidity -> Sweep -> MSS -> FVG -> Signal -> Execution -> Backtest

后续开发中,所有新增字段和表都应优先服从这条主链路的一致性,不要为了术语完整性提前引入过多复杂实体。