2aacd8a25d
- PLAN-008/PLAN-009 计划(已完成) - 迭代 07/08 四件套(目标/技术方案/验收标准/复盘) - 设计约束:数据存储设计 §10/§10.1、技术约束-012/013、产品约束-008 - R-009/R-010 需求归档(含二次定稿:手动归属、Q4 成本价/成交价) - 需求池索引同步
121 lines
5.8 KiB
Markdown
121 lines
5.8 KiB
Markdown
# 技术实现方案:07-交易记录本地存储(SQLite)+ 策略关联
|
||
|
||
> 依据:PLAN-008 | 需求:R-009(Q1-Q8 定稿)| 设计约束:技术约束-012(数据存储设计)、技术约束-011(测试隔离)
|
||
|
||
## 技术选型
|
||
|
||
- **存储**:沿用 SqliteStore(node:sqlite)——新增 trade_orders + trade_fills 两表(R-009 Q1);
|
||
- **同步**:服务端 TradeSync 模块(定时 60s + 启动预热 + 前端今日轮询写穿;UPSERT 幂等);
|
||
- **关联**:外键链推导(Q3 老师定稿):成交→委托(order_id 外键)→策略/holding(委托时间 join strategy_holdings 生命周期窗口)——两表零冗余 strategy_id/holding_id;
|
||
- **历史查询**:api/trades.js 新增 trades/history 端点(查本地 SQLite);
|
||
- **前端**:TradeRecordsTab 加策略过滤 + 历史范围查本地。
|
||
|
||
## 表结构(数据存储设计.md §10 落实)
|
||
|
||
```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 合成毫秒时间戳(join 持仓窗口用)
|
||
cancel_info TEXT NOT NULL DEFAULT '',
|
||
error_msg TEXT NOT NULL DEFAULT '',
|
||
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);
|
||
```
|
||
|
||
**策略归属推导(查询期,FK 链)**:
|
||
|
||
- 委托归属:`trade_orders JOIN strategy_holdings ON o.code=h.code AND h.created_at <= o.insert_ts AND (h.closed_at IS NULL OR o.insert_ts < h.closed_at)`;
|
||
- 一码多策略消歧:命中多笔持仓时取 shares 最大者(确定性规则);
|
||
- 成交归属 = 所属委托归属(fill → order → holding → strategy);
|
||
- 无命中 → 未关联(strategy_id 返回 null)。
|
||
|
||
## 架构设计
|
||
|
||
```
|
||
SqliteStore(改)
|
||
├─ init() 建表:+trade_orders/trade_fills + 索引
|
||
├─ upsertOrders(orders) / upsertFills(fills) # UPSERT 幂等
|
||
├─ getOrderHistory({start,end,code,strategyId,direction}) # 委托 + 策略归属推导
|
||
├─ getFillHistory({start,end,code,strategyId,direction}) # 成交(按委托归属 join)
|
||
└─ close()
|
||
|
||
DataStore(改)
|
||
└─ 委托交易记录方法(upsertTradeOrders/upsertTradeFills/queryTradeHistory)
|
||
|
||
TradeSync(新增)
|
||
├─ start() : 启动预热同步一次 + 60s 定时
|
||
├─ syncNow() : 拉今日 orders+trades → upsertOrders/upsertFills(幂等)
|
||
└─ stop() : 清理定时器
|
||
|
||
api/trades.js(改)
|
||
└─ trades/history → storage.queryTradeHistory(时间段/code/策略/方向过滤)
|
||
|
||
index.js(改)
|
||
└─ 装配 TradeSync(dispose 停止)+ storage 注入 api runtime
|
||
|
||
client/views/TradeRecordsTab.jsx(改)
|
||
├─ 策略过滤下拉(全部/各策略/未关联)——今日实时过滤前端、历史走服务端过滤
|
||
└─ 历史范围:调 trades/history 查本地库(不再占位)
|
||
```
|
||
|
||
## 实现步骤
|
||
|
||
1. **文档骨架**:PLAN-008 + 迭代 07(本步);
|
||
2. **设计约束**:数据存储设计.md §10 + 技术方案约束新增条目;
|
||
3. **SqliteStore**:建表 + upsertOrders/upsertFills + getOrderHistory/getFillHistory(策略归属 join);
|
||
4. **DataStore**:委托交易记录方法;
|
||
5. **TradeSync**:定时同步(60s + 启动预热 + UPSERT 幂等);
|
||
6. **api/trades.js**:trades/history 端点;
|
||
7. **index.js**:装配 TradeSync + storage 注入 runtime;
|
||
8. **前端**:TradeRecordsTab 策略过滤 + 历史本地展示;
|
||
9. **构建测试**:pnpm run build + typecheck + 独立数据目录回归(技术约束-011);
|
||
10. **验收 + 复盘**。
|
||
|
||
## 涉及设计约束
|
||
|
||
| 约束 | 内容 |
|
||
|---|---|
|
||
| 技术约束-012 | 数据存储遵循数据存储设计.md(本迭代增补 §10 交易记录表设计) |
|
||
| 技术约束-011 | 测试/回归脚本禁止在真实数据上写操作:ODL_TEST_DATA_DIR 独立数据目录 |
|
||
| 技术约束-001/003/004/010 | 数据源抽象 / 直连 REST / webServer 自开路由 / 服务端中转+前端轮询(沿用) |
|
||
| 产品约束-007 | 方向语义红买绿卖(沿用 R-007) |
|