Files
kyugao ec02a791ee 迭代22+23: 策略tab静态化 + 计算字段(数字/判定型)+ 网格超市信号字段
- R-027 静态化:策略恒为内置两项(不可增删改名,保留显隐/排序);设置页移除「策略分组」;
  字段配置入口迁到策略 tab 内「列设置」旁(FieldConfigDialog + schema-update 单策略写入)
- R-026 计算字段:自写公式引擎(中文变量、四则/括号/round·abs·min·max、缺值短路→—)+
  变量目录(行情/合约/持仓/自定义字段)+ strategy-positions 逐行现算(只读内存缓存,不落库、列只读)
- R-028 判定型:比较运算 + and/or + inferResultKind + 结果类型一致性校验 + 判定列 ✓/— 渲染;
  网格超市落地 可下空单=涨停价>基准值+网格大小、可下多单=跌停价<基准值-网格大小
- 变量选择改标签平铺(老师反馈);公式手册 docs/99-其他材料/计算字段公式说明.md
- 约束同步:产品约束-002/003/004/009/013/014、技术约束-014/015/022/023/024、UI约束-002/003/005/008
- 回归:新增 test-r026/test-r027,更新 r011/r013/r017,17 个脚本全绿;typecheck/build 通过
2026-09-10 14:05:06 +08:00

128 lines
8.6 KiB
Markdown
Raw Permalink 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.
# 需求:R-026 策略计算字段(公式字段)· 已定稿
> 登记:2026-09-10 来源:老师指令(2026-09-10 功能讨论「策略组字段配置优化」)| 状态:**已定稿(2026-09-10 老师确认)**
> 归属:**22-策略计算字段与策略tab静态化 · 第二阶段**(PLAN-019)| 实现状态:**已实现(2026-09-10 完成,typecheck/build/17 个回归脚本全绿),待老师人工验收**
> **入口条款修订(2026-09-10,R-027 取代)**:字段配置入口由「设置页 → 策略分组 → 策略行展开」**迁至「策略 tab 内、列设置旁的『字段配置』弹层」**;本文档 §9 配置 UI 的入口位置随 R-027 变更,字段模型 / 公式语义 / 只读列 / 列机制均不变。
> 前身:草稿 T-010(已转正,草稿文件已清理)
## 诉求(老师,2026-09-10
> 策略组字段配置优化:添加的字段,目前仅是支持用户指定值;接下来添加新的字段类型,就是**可以计算**,
> 目标是让用户**写一个公式**,公式中支持来自几个**服务端缓存的数据集**,然后通过计算得出结果。
## 背景(现状 R-013/迭代 11
- 策略字段定义 = `settings.strategies[].configSchema``{ key, label, type(text|number|boolean|enum), enum[], def, unit }`
- 字段值 = `strategy_holdings.values` JSON 列(**用户手工填写**,单元格内联编辑);
- 展示 = 持仓表列化(列显隐/顺序由 `strategyColumns` 每策略独立配置);
- 本次扩展:新增**第五种字段类型「计算(formula)」**——值不是填的,是**算的**。
## 定稿结论(2026-09-10 老师逐项确认)
### 1. 字段类型与存储语义
- `configSchema.type` 增加 `'formula'`;新增 `formula` 表达式串字段(与 `unit` 同级,随策略定义存 settings);
- **计算字段不落库**:不读写 `strategy_holdings.values`,每次读 `strategy-positions` 时**逐行实时现算**
- 表格内**只读**(点击不进内联编辑);列配置兼容零改动(formula 字段自动进列集,新增默认追加末尾)。
### 2. 公式可引用的数据集(首批 = 行情/合约 + 持仓账本 + 本行自定义字段)
| 数据集 | 来源(服务端缓存) | 可引用字段 | 刷新 |
|---|---|---|---|
| 行情盘口 | QuoteHub.quotes(内存) | 现价 / 昨收 / 今开 / 最高 / 最低 / 成交量 / 成交额 | 5s REST |
| 合约信息 | QuoteHub.instruments(内存) | 涨停价 / 跌停价 / 昨收 | 按交易日 |
| 持仓账本 | SQLite strategy_holdings | 策略份额 / 成本价 / 最后一笔成交价 | 交易关联驱动 |
| 本行自定义字段值 | strategy_holdings.values | 本行手填字段(如网格间距、目标价) | 内联编辑 |
**后补(本期不做)**:QMT 账户域持仓(全账户 volume/可用/市值,跨策略视角)、交易记录聚合(当日已成交量/买卖笔数)——用例尚不明确。
### 3. 变量命名:**中文变量名**
- 公式形如 `(现价 - 成本价) × 份额`,可读性优先;
- 配置时校验**变量名唯一**;配置 UI 提供**变量选择器**(按数据集分组,点击插入);
- 引擎需支持中文标识符(自写解析器,见 §4)。
### 4. 公式引擎:自写小型表达式解析器(零依赖)
- 能力:四则运算 + 括号 + 常见函数(round / abs / min / max);
- 选型理由:中文标识符需自定义词法,第三方库(expr-eval/mathjs/jexl)均不支持中文变量;该层未来即 T-006 数据池的表达式层,值得自有。
### 5. 计算位置与粒度:**服务端计算 + 仅行级**
- 服务端在 `strategy-positions` 返回时逐行现算随行带回(行情单一入口 QuoteHub 在服务端);前端仅渲染;
- 行级上下文 = 本行行情 + 本行持仓账本 + 本行自定义字段值 → 一个结果;
- **策略级聚合(跨行求和,如本策略总盈亏)留二期**。
### 6. 循环引用边界:公式**只允许引用非公式字段**
- 变量目录直接排除 formula 字段 → 不存在循环依赖(不做检测与拓扑排序)。
### 7. 结果类型与格式
- 首批结果**只做数字**(布尔型公式后续再议);
- 复用现有 `unit`(展示拼在值后);新增**小数位**配置(默认 2 位)。
### 8. 缺数据与错误处理
- **保存时校验**:语法 + 变量存在性(服务端编译试算一次),非法公式直接拒绝保存并提示;
- **运行期**:缺行情 / 除零 / 无法计算 → 该单元格显示 `—`(不显示 NaN、不报错、不炸整表)。
### 9. 配置 UI(设置页「策略分组」字段表单)
- 类型下拉增加「计算」→ 出现公式输入框 + 变量选择器(分组:行情 / 合约 / 持仓 / 自定义字段)+ 变量速查;
- 加分项:**试算预览**(取一行真实持仓数据现场算出结果)。
### 10. 历史持仓行(已清仓)
- 历史 tab 的公式列统一显示 `—`:清仓行无「现价」语义,**不做历史时点计算**(属另一需求,不混入本期)。
### 11. 与服务端数据池(T-006)的关系
- 本期先落**轻量变量目录**(服务端声明:数据集 → 字段清单 → 取数函数),公式引擎跑在目录之上;
- 该目录即 T-006「数据池中间层」的第一块砖,**不一次性建完整数据池**(避免过度设计)。
## 典型用例(老师视角验收样例)
| 字段 | 公式 |
|---|---|
| 浮动盈亏 | `(现价 - 成本价) × 份额` |
| 盈亏比例 | `(现价 ÷ 成本价 - 1) × 100` |
| 距涨停 | `(涨停价 - 现价) ÷ 现价 × 100` |
| 网格占用(手填+计算组合) | `现价 × 份额 × 网格间距` |
## 决策记录
| 项 | 结论 | 讨论 |
|---|---|---|
| 字段类型 | configSchema.type 加 `formula` + `formula` 串 | 老师指令(新字段类型) |
| 存储语义 | **不落库**,读接口时逐行现算 | 「计算」的本质;values 列不参与 |
| 数据集范围 | 首批 行情+合约 / 持仓账本 / 本行自定义字段值 | 选择题确认(1+2+3);QMT账户域、交易聚合后补 |
| 变量命名 | **中文变量名** + 选择器插入 | 选择题确认;配置时校验唯一 |
| 计算粒度 | **仅行级**;策略级聚合二期 | 选择题确认 |
| 计算位置 | 服务端(strategy-positions 现算随行返回) | 老师方向「引用服务端缓存数据集」;行情单一入口在服务端 |
| 公式引擎 | 自写小型解析器(零依赖,支持中文标识符) | 第三方库不支持中文变量;未来即数据池表达式层 |
| 循环引用 | 只允许引用非公式字段 | 目录层排除,无循环问题 |
| 结果类型 | 数字 + unit + 小数位(默认 2) | 布尔型后议 |
| 错误处理 | 保存校验拒绝 + 运行期显示 `—` | 不炸整表 |
| 配置 UI | 公式输入 + 变量选择器(+试算预览) | 计算字段只读不内联编辑 |
| 历史行 | 公式列显示 `—` | 不做历史时点计算 |
| 数据池关系 | 轻量变量目录先行(T-006 第一块砖) | 避免一次性建完整中间层 |
## 关联
- 上游:R-013(自定义字段配置,字段类型与列机制)/ 迭代 11(列配置 strategyColumns);
- 数据来源:R-015QuoteHub 盘口内存快照)、R-014PositionSync 账户域)、R-010(最后一笔成交价)、R-018(份额账本);
- 延展:T-006(数据池中间层草稿)——本需求的变量目录为其起点;
- 约束条目待实施时补充(拟:产品功能约束 / 技术方案约束 / UI交互约束 各一条,沿用 R-013 惯例)。
## 讨论过程
- 2026-09-10 老师提出功能方向(策略组字段配置优化 → 可计算公式字段);
- AI 摸清 R-013 现状 + 盘活服务端缓存数据集清单,提出 Q1-Q10 设计问题清单(各附建议);
- 老师「定」:Q4-Q10 按 AI 建议;
- 选择题三项确认:Q1 数据集 1+2+3、Q2 中文变量名、Q3 仅行级计算;
- 转正定稿:T-010 草稿 → R-026(草稿文件已清理,索引同步);
- 2026-09-10 迭代 22 交互设计过审:老师逐项拍板 D-1~D-7(全采纳 AI 建议)→ `docs/04-迭代记录/22-策略计算字段与策略tab静态化/UI交互设计.md` 定稿;
- 2026-09-10 老师提出重构想法(策略 tab 静态化 + 字段配置入口迁移)→ 定稿 **R-027**:本需求的**字段配置入口**随之从设置页迁到「策略 tab 内、列设置旁的『字段配置』弹层」(迭代 22 调整为「第一阶段=重构、第二阶段=本需求」);
下一步:技术实现方案 + 验收标准(本轮按老师指令未做技术方案与编码)。