Files
kyugao 2aacd8a25d docs(迭代07/08): 交易记录本地存储 + 策略持仓展开全量文档 + 需求归档(R-009/R-010)
- PLAN-008/PLAN-009 计划(已完成)
- 迭代 07/08 四件套(目标/技术方案/验收标准/复盘)
- 设计约束:数据存储设计 §10/§10.1、技术约束-012/013、产品约束-008
- R-009/R-010 需求归档(含二次定稿:手动归属、Q4 成本价/成交价)
- 需求池索引同步
2026-09-02 01:21:10 +08:00

5.8 KiB
Raw Permalink Blame History

技术实现方案:07-交易记录本地存储(SQLite)+ 策略关联

依据:PLAN-008 需求:R-009(Q1-Q8 定稿)| 设计约束:技术约束-012(数据存储设计)、技术约束-011(测试隔离)

技术选型

  • 存储:沿用 SqliteStorenode: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 落实)

-- 交易委托(委托主行;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,      -- 交易日 YYYYMMDDm_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(改)
  └─ 装配 TradeSyncdispose 停止)+ 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.jstrades/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