31ece2e99a
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
807 lines
18 KiB
Markdown
807 lines
18 KiB
Markdown
# 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`
|
||
|
||
后续开发中,所有新增字段和表都应优先服从这条主链路的一致性,不要为了术语完整性提前引入过多复杂实体。
|