docs(迭代07/08): 交易记录本地存储 + 策略持仓展开全量文档 + 需求归档(R-009/R-010)
- PLAN-008/PLAN-009 计划(已完成) - 迭代 07/08 四件套(目标/技术方案/验收标准/复盘) - 设计约束:数据存储设计 §10/§10.1、技术约束-012/013、产品约束-008 - R-009/R-010 需求归档(含二次定稿:手动归属、Q4 成本价/成交价) - 需求池索引同步
This commit is contained in:
+93
-3
@@ -261,8 +261,98 @@ CREATE TABLE IF NOT EXISTS market_quotes_cache (
|
||||
| MarketFeed | 行情获取(WS + REST 定时刷新 + 启动 prime) | src/component/MarketFeed.js |
|
||||
| migrate 脚本 | 一次性迁移脚本 | scripts/migrate-json-to-sqlite.mjs |
|
||||
|
||||
## 10. 约束条目(引用)
|
||||
## 10. 交易记录存储设计(R-009 落实,2026-09-01 迭代 07 实施)
|
||||
|
||||
- 技术约束-012:数据存储遵循本文件(SQLite 存储设计);
|
||||
> 依据:R-009(Q1-Q8 定稿,2026-09-01)。在 SQLite 新增交易记录两表(trade_orders + trade_fills),QMT 当日交易数据本地持久化(跨日积累成历史库),支持按策略过滤 / 复盘交易。
|
||||
|
||||
### 10.1 表结构
|
||||
|
||||
```sql
|
||||
-- 交易委托(委托主行;order_id 唯一,UPSERT 幂等;零冗余 strategy_id/holding_id)
|
||||
CREATE TABLE IF NOT EXISTS trade_orders (
|
||||
order_id TEXT PRIMARY KEY, -- m_strOrderSysID
|
||||
trade_date TEXT NOT NULL, -- 交易日 YYYYMMDD(m_strInsertDate)
|
||||
code TEXT NOT NULL,
|
||||
name TEXT NOT NULL DEFAULT '',
|
||||
exchange TEXT NOT NULL DEFAULT '',
|
||||
direction TEXT NOT NULL DEFAULT '', -- buy / sell
|
||||
direction_code INTEGER,
|
||||
opt_name TEXT NOT NULL DEFAULT '',
|
||||
status INTEGER,
|
||||
order_volume REAL NOT NULL DEFAULT 0,
|
||||
traded_volume REAL NOT NULL DEFAULT 0,
|
||||
limit_price REAL NOT NULL DEFAULT 0,
|
||||
traded_price REAL NOT NULL DEFAULT 0,
|
||||
amount REAL NOT NULL DEFAULT 0,
|
||||
insert_date TEXT NOT NULL DEFAULT '',
|
||||
insert_time TEXT NOT NULL DEFAULT '',
|
||||
insert_ts INTEGER NOT NULL, -- 派生:insert_date+insert_time 合成毫秒时间戳
|
||||
cancel_info TEXT NOT NULL DEFAULT '',
|
||||
error_msg TEXT NOT NULL DEFAULT '',
|
||||
strategy_id TEXT, -- 用户手动设置的策略归属(冗余,Q1 确认)
|
||||
holding_id INTEGER, -- 用户手动设置的持仓归属(冗余,Q1 确认)
|
||||
fetched_at INTEGER NOT NULL -- 同步时间戳
|
||||
);
|
||||
|
||||
-- 交易成交(trade_id 唯一,order_id 外键关联委托;零冗余 strategy_id/holding_id)
|
||||
CREATE TABLE IF NOT EXISTS trade_fills (
|
||||
trade_id TEXT PRIMARY KEY, -- m_strTradeID
|
||||
order_id TEXT NOT NULL, -- → trade_orders.order_id
|
||||
trade_date TEXT NOT NULL,
|
||||
code TEXT NOT NULL,
|
||||
name TEXT NOT NULL DEFAULT '',
|
||||
exchange TEXT NOT NULL DEFAULT '',
|
||||
direction TEXT NOT NULL DEFAULT '',
|
||||
direction_code INTEGER,
|
||||
opt_name TEXT NOT NULL DEFAULT '',
|
||||
price REAL NOT NULL DEFAULT 0,
|
||||
volume REAL NOT NULL DEFAULT 0,
|
||||
amount REAL NOT NULL DEFAULT 0,
|
||||
commission_rate_wan REAL NOT NULL DEFAULT 0,
|
||||
trade_time TEXT NOT NULL DEFAULT '',
|
||||
fetched_at INTEGER NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_trade_orders_date ON trade_orders (trade_date);
|
||||
CREATE INDEX IF NOT EXISTS idx_trade_orders_ts ON trade_orders (insert_ts);
|
||||
CREATE INDEX IF NOT EXISTS idx_trade_fills_order ON trade_fills (order_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_trade_fills_date ON trade_fills (trade_date);
|
||||
```
|
||||
|
||||
### 10.2 关键设计决策(R-009 Q1-Q8 定稿)
|
||||
|
||||
| 决策 | 结论 | 理由 |
|
||||
|---|---|---|
|
||||
| 表范围 | trade_orders + trade_fills 两表 | 委托 1:N 成交,忠实 R-007 单表合并模型;保留无成交委托(待报/已撤/废单);避免 JSON 压扁 |
|
||||
| 冗余 | **trade_orders 冗余 strategy_id + holding_id**(用户手动设置) | 老师二次定稿(Q3 修正):手动设置归属,便于过滤/展示/复盘;trade_fills 仍零冗余(跟随委托) |
|
||||
| 委托时间派生列 | insert_ts(insert_date+insert_time 合成毫秒) | join 持仓生命周期窗口用(created_at ≤ t < closed_at) |
|
||||
| 策略/持仓归属 | **用户手动设置**(交易记录 tab 下拉:候选 = 该 code 当前持仓策略 + 未关联);持久化到 trade_orders.strategy_id + holding_id;UPSERT 不覆盖归属列;可随时改以最终为准 | 一票多策略无法算法区分(300057.SZ 分属 grid/manual),人为确认符合「人机合一」(2026-09-01 老师二次定稿) |
|
||||
| 同步 | 服务端 TradeSync:启动预热 + 60s 定时 UPSERT(幂等);前端今日轮询写穿 | 不依赖前端开 tab 也持续积累 |
|
||||
| 代码归一化 | QMT 委托/成交 code 无后缀(001330),持仓带后缀(001330.SZ)——数据源映射层统一 `normalizeInstrumentCode`(补交易所后缀);委托交易日 = insertDate(无独立 tradeDate 字段),tradeDate 兜底 insertDate | 保证 FK 链 join 匹配 + 历史按时间段过滤正确(迭代 07 真实数据发现) |
|
||||
| 同步范围 | 只同步当日(QMT 无历史接口) | 数据逐日积累 = 本地历史库 |
|
||||
| 历史查询 | trades/history 端点(时间段/code/策略/方向过滤) | 复盘 + 按策略过滤 |
|
||||
| 数据清理 | 不做自动清理(复盘需要历史) | 导出/清理后续迭代 |
|
||||
|
||||
### 10.3 数据流
|
||||
|
||||
```
|
||||
启动时:TradeSync 启动预热一次(拉今日 orders+trades → UPSERT 落库,不覆盖归属列)
|
||||
实盘中:TradeSync 60s 定时同步(UPSERT 幂等,状态覆盖更新,归属列保留)
|
||||
前端今日轮询命中 orders/trades 端点 → 写穿本地(机会式)
|
||||
用户: 交易记录 tab 手动设置每笔委托归属(strategy_id + holding_id 落库,可随时改)
|
||||
查询时:今日 → QMT 实时(+ 本地归属);历史范围 → trades/history 查本地 SQLite(策略过滤 = 用户设置的归属)
|
||||
```
|
||||
|
||||
### 10.4 对应实现(更新)
|
||||
|
||||
| 模块 | 职责 | 文件 |
|
||||
|---|---|---|
|
||||
| SqliteStore | +trade_orders/trade_fills 建表 + 交易 UPSERT/历史查询 + 策略归属推导 | src/component/SqliteStore.js |
|
||||
| DataStore | +交易记录方法(upsertTradeOrders/upsertTradeFills/queryTradeHistory) | src/component/DataStore.js |
|
||||
| TradeSync | 服务端定时同步(启动预热 + 60s + UPSERT 幂等) | src/component/TradeSync.js |
|
||||
| api/trades.js | +trades/history 端点 | src/api/trades.js |
|
||||
|
||||
## 11. 约束条目(引用)
|
||||
|
||||
- 技术约束-012:数据存储遵循本文件(SQLite 存储设计,含交易记录表 §10);
|
||||
- 技术约束-011:测试/回归脚本禁止在真实数据上执行写操作(独立数据目录);
|
||||
- 本文件为新领域设计约束,后续数据存储变更以本文件为最终依据。
|
||||
- 本文件为新领域设计约束,后续数据存储变更以本文件为最终依据。
|
||||
Reference in New Issue
Block a user