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

807 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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. 核心实体关系概览
```text
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
用途:交易所定义表。
建议字段:
```sql
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
用途:交易品种定义表。
建议字段:
```sql
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()
```
唯一约束:
```sql
unique (venue_id, symbol)
```
说明:
- `meta` 存放交易所特定扩展信息
- 如 XAU 在不同 venue 上合约不同,可通过 `meta` 补充合约属性
---
## 6. 行情与时间表设计
## 6.1 candles
用途:标准化 K 线主表。
建议字段:
```sql
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()
```
唯一约束:
```sql
unique (instrument_id, timeframe, ts_open)
```
核心索引:
```sql
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。
建议字段:
```sql
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()
```
唯一约束:
```sql
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
用途:保存结构高低点。
建议字段:
```sql
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()
```
索引建议:
```sql
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
用途:保存当前工作区间。
建议字段:
```sql
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()
```
索引建议:
```sql
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
用途:保存流动性目标区域。
建议字段:
```sql
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
索引建议:
```sql
index on (instrument_id, timeframe, status, created_ts desc)
index on (instrument_id, timeframe, side, created_ts desc)
```
---
## 7.4 displacement_events
用途:保存有效位移事件。
建议字段:
```sql
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()
```
索引建议:
```sql
index on (instrument_id, timeframe, end_ts desc)
index on (instrument_id, timeframe, direction, end_ts desc)
```
---
## 7.5 structure_events
用途:保存 MSB / MSS 等结构事件。
建议字段:
```sql
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')`
索引建议:
```sql
index on (instrument_id, timeframe, ts desc)
index on (instrument_id, timeframe, event_type, ts desc)
```
---
## 7.6 fvg_zones
用途:保存 FVG / imbalance 区域。
建议字段:
```sql
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')`
索引建议:
```sql
index on (instrument_id, timeframe, start_ts desc)
index on (instrument_id, timeframe, status, start_ts desc)
```
---
## 8. 决策与执行表设计
## 8.1 bias_snapshots
用途:保存特定时刻的 bias 结果。
建议字段:
```sql
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')`
索引建议:
```sql
index on (instrument_id, snapshot_ts desc)
index on (instrument_id, daily_bias, snapshot_ts desc)
```
---
## 8.2 trade_signals
用途:保存候选交易信号。
建议字段:
```sql
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
索引建议:
```sql
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
用途:保存实际执行记录。
建议字段:
```sql
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')`
索引建议:
```sql
index on (signal_id)
index on (status, created_at desc)
index on (execution_mode, created_at desc)
```
---
## 9. 回测与分析表设计
## 9.1 backtest_runs
用途:保存回测任务定义与结果摘要。
建议字段:
```sql
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()
```
索引建议:
```sql
index on (model_code, started_ts desc)
index on (instrument_id, started_ts desc)
```
---
## 9.2 backtest_results
用途:保存回测明细结果。
建议字段:
```sql
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')`
索引建议:
```sql
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`
然后再建:
6. `dealing_ranges`
7. `liquidity_pools`
之后进入:
8. `displacement_events`
9. `structure_events`
10. `fvg_zones`
11. `bias_snapshots`
12. `trade_signals`
13. `trade_executions`
14. `backtest_runs`
15. `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`
后续开发中,所有新增字段和表都应优先服从这条主链路的一致性,不要为了术语完整性提前引入过多复杂实体。