This commit is contained in:
2026-08-29 16:20:33 +08:00
commit cba31428dc
52 changed files with 6553 additions and 0 deletions
+246
View File
@@ -0,0 +1,246 @@
# R-002 分仓管理工具(持仓策略标签管理)· 已完成
> 归档日期:2026-08-28 需求状态:**已完成**
> 原索引:docs/05-需求池/需求池索引.md(主索引保留 R-002 条目,指向本归档)
> 讨论记录:docs/05-需求池/已完成/R-002-讨论记录.md(随需求一并归档)
## 需求摘要
在 DSH 中实现「分仓管理」:插件设置中管理持仓策略(策略=标签,增删改 + 显示/隐藏开关);主窗口上方 tab 栏(对话/轨迹/上下文后)显示策略标签,每个标签下加载对应持仓数据;QMT 读全量真实持仓(插件直连 QMT Bridge RESTful 接口,非 MCP),策略分仓数据本地保存管理。
## 核心逻辑(定稿版)
1. **插件设置管理**:DSH 设置中添加「神之一手」菜单,管理持仓策略(策略=标签,可增删改 + 显示/隐藏开关);
2. **tab 栏展示**:主窗口上方「对话 | 轨迹 | 上下文」后显示策略标签(全部持仓/网格策略持仓/做T持仓),每个标签下加载对应持仓数据;
3. **数据与存储**:QMT 读全量真实持仓(插件直连 REST http://192.168.3.43:8610),策略分仓数据本地保存(~/.dsh/one-divine-lot/allocations.json)。
## 实现记录
| 项 | 内容 |
|---|---|
| 实现迭代 | 01-分仓管理工具 |
| 实现方式 | 独立插件(one-divine-lot),外部挂载到 DSH web profile |
| 服务端 | S1-S6:数据源适配(REST)、设置管理、本地存储、分仓逻辑、HTTP API/odl/api/* 8 端点) |
| 客户端 | S7:三个 conversation.view tab + settings.section 设置菜单 |
| 宿主挂载 | S8dsh plugin add + bundle patch |
## 验收结果(2026-08-28 老师确认完成)
- ✅ 全部持仓显示(12 只真实持仓)
- ✅ 三个策略 tab
- ✅ 设置菜单「神之一手」
- ✅ 份额编辑(添加/移出/步进100/手动输入)
- ✅ 响应式布局
- ✅ 本地存储持久化
- ✅ 服务端 API 全部工作
## 经验沉淀
- 迭代复盘:docs/04-迭代记录/01-分仓管理工具/迭代复盘.md
- 设计约束:技术约束-003~007DSH 插件开发规范,2026-08-28 补充)
---
## 需求讨论记录(2026-08-27 整合)
> 本需求从提出到定稿的完整讨论过程(原独立文件 R-002-讨论记录.md 整合于此)。
> 整合日期:2026-08-28(老师要求:归档后讨论记录并入需求文件)
# R-002 分仓管理工具 · 需求讨论记录
> 需求状态:**讨论中** | 本文件记录需求明确过程的讨论结论,供定稿时汇总。
> 关联:docs/05-需求池/需求池索引.mdR-002
## 讨论进程
### 2026-08-27 · 第 1 轮:分仓对应策略,账户核心策略为「网格超市 + 手动做T」
**老师给出的需求信息**
1. **分仓对应不同的策略** —— 分仓的维度是策略,不是持仓周期/风险等级等;
2. **当前账户核心策略:网格超市** —— 十几个标的都在做网格交易;
3. **配合手动做T** —— 在网格基础上,手动做 T(高抛低吸/日内差价)。
**讨论推论(待确认)**
- 分仓标签 ≈ 策略标签:每个策略对应一个分仓;
- 「网格超市」可能是一个策略族(多个网格标的同属此策略),或每个网格标的独立成策略 —— 需明确粒度;
- 「手动做T」是独立策略仓,还是叠加在网格仓上的操作动作 —— 需明确与网格仓的关系。
**待确认问题**
1. 网格超市的粒度:所有网格标的是否同属一个「网格超市」策略仓?还是每个标的一个策略?
2. 手动做T:是独立的策略仓,还是对网格标的的增强操作(同一标的同时在网格+做T)?
3. 同一标的是否可能同时归属多个策略仓(如 网格 + 做T)?
4. 除了网格超市 + 做T,是否还有其他策略仓(如长线持有)?
### 2026-08-27 · 第 2 轮:分仓标签初步定为两个策略标签
**老师确认**
1. 分仓标签初步就是两个策略标签:**「网格超市」** 和 **「手动做T」**
2. 账户核心策略 = 网格超市(十几个标的做网格)+ 手动做T;
3. 分仓 = 按这两个策略标签划分。
**推论(待确认)**
- 「网格超市」标签下:所有做网格的标的(十几个)归入此仓;
- 「手动做T」标签下:做T 的标的归入此仓;
- 一个标的可能同时属于两个标签(既是网格标的,又手动做T)?—— 需确认是否允许多标签。
**待确认问题(第 3 轮)**
1. 同一标的是否允许同时打「网格超市」+「手动做T」两个标签?
2. 每个策略仓下要看什么?只有汇总(市值/盈亏),还是包含网格参数(区间/格距/档位)?
3. 未来是否可能增加第三个策略标签(预留扩展)?
### 2026-08-27 · 第 3 轮:本期范围收敛 —— 标签可维护,其他功能先不管
**老师确认**
1. **标签可以维护** —— 本期核心能力是标签的维护(创建/删除/重命名/查看);
2. **其他功能先不管** —— 网格参数管理、做T 记录、策略仓汇总等复杂功能本期不做。
**本期范围(初步收敛)**
- ✅ 全量持仓展示(数据基础)
- ✅ 标签维护(增/删/改/查)
- ✅ 持仓打标签 / 移除标签(标签与持仓关联)
- ❌ 网格参数管理(后续)
- ❌ 做T 交易记录(后续)
- ❌ 策略仓的复杂汇总/风控(后续)
**待确认(第 4 轮,定稿前)**
1. 上述范围是否准确反映了老师意图?
2. 若确认,R-002 状态可推进为「已定稿」,正式进入计划/迭代。
### 2026-08-27 · 第 4 轮:允许「持仓份额拆分」—— 同一标的可分配到多个策略仓
**老师确认(关键设计决策)**
1. **允许多标签**:一个票可以同时属于多个策略仓;
2. **但持仓数据会分开**:不是整个持仓打标签,而是**按数量拆分份额分配到不同策略仓**;
3. **示例**:一个票持仓 1000 股,可能网格有 600 股,余下 400 股是准备做 T 的前期买入仓。
**模型含义(持仓份额分配模型)**
- 数据基础:全量真实持仓(每只票的总数量);
- 分仓 = 将每只票的持仓**数量份额**分配到各策略仓(如 600719.SH 1800 股 → 网格仓 1000 股 + 做T仓 800 股);
- **约束:各策略仓份额之和 = 该票总持仓量**;
- 不再是「持仓↔标签」的整票多对多,而是「持仓份额 → 策略仓」的精确分配。
**待确认(第 5 轮)**
1. 份额由谁维护?人工指定(老师输入每仓数量)?还是本期不做份额分配、只预留模型?
2. 各仓份额的展示:是否要展示「每仓数量/市值/占比」?
3. 未被分配的数量(份额之和 < 总持仓)怎么处理?归入「未分配」?
### 2026-08-27 · 第 5 轮:完整产品形态明确(三条核心逻辑)
**老师给出的完整需求(分仓/持仓管理逻辑)**
1. **插件设置管理能力**:在设置里,添加「神之一手插件设置管理能力」——
- 可以添加不同的持仓策略;
- 一个策略对应一个标签;
- 配置该策略/标签**是否显示 / 隐藏**。
2. **会话标签展示**:在当前 DSH 的会话标签旁边,根据上面的设置,显示对应的标签;
- 每个标签下,加载对应的持仓数据。
3. **数据处理与存储**:插件需要能够处理数据、存储——
- 通过 QMT 能读取到**全部持仓数据**(真实持仓);
- 但**策略的分仓数据只能本地保存并更新管理**(QMT 没有分仓概念,分仓是本地维护的元数据)。
**产品形态转变**:从「纯命令行工具」→「带 UI 设置的完整插件」:
- 设置管理(策略 CRUD + 显示开关)→ DSH 设置/配置扩展点
- 会话标签旁展示 → DSH 客户端 UI 扩展点
- 本地存储 → 插件持久化存储
**技术探索需求**
1. DSH 插件设置管理能力如何提供(settings 扩展点)?
2. DSH 会话标签旁的 UI 扩展机制(client modules / client UI)?
3. 本地存储机制(文件/数据库)?
**待确认(第 6 轮)**
- 策略 = 标签 = 分仓,三者现在等同(一个策略对应一个标签,标签即分仓);
- 「显示/隐藏」开关:隐藏的策略标签不显示在会话标签旁;
- 分仓数据本地存储:格式与位置待定(JSON 文件?DSH 数据目录?)。
### 2026-08-27 · 技术探索结论(DSH 扩展点验证)
对 DSH 宿主环境的技术探索确认以下扩展点可用:
1. **设置管理**DSH 提供 `ctx.settings` 服务(@deepseek-ai/dsh-settings)—— 插件可 `settings.register(ns, schema)` 注册自己的设置 namespace,用户文档持久化,天然适配「策略/标签配置 + 显示开关」;
2. **会话标签旁 UI**DSH 客户端 UI 通过 `dsh.client` 平台扩展(React 组件,参考 dsh-client-ui-conversation 等),插件可作为 client plugin 注入;「会话标签旁显示策略标签」属于客户端 UI 扩展点,需修改宿主 composition 加载 client 插件;
3. **本地存储**:策略分仓数据(本地维护的元数据)可存为 JSON 文件(DSH 数据目录)或复用 settings 持久化;QMT 只提供全量真实持仓,分仓分配为本地状态。
**技术可行性结论**:老师描述的三条逻辑(设置管理 / 会话标签旁展示 / 本地存储)在 DSH 均有对应扩展机制,可实现。实现涉及修改宿主 composition(加载 client 插件),需加载 editing-cordis-compositions 技能按规范操作。
### 2026-08-27 · 第 6 轮:需求定稿(老师确认)
**老师确认**
1. **需求基本确定** —— R-002 可定稿;
2. **标签展示位置**:展示在 DSH 主窗口上方,放在「对话 | 轨迹 | 上下文 |」**后面添加**(即顶部 tab 导航栏扩展,策略标签作为新增 tab);
3. **独立插件,作为外部插件挂载** —— one_divine_lot 保持独立插件仓库,通过外部插件机制挂载到 DSH 宿主。
**定稿结论**:R-002 状态 → 已定稿,可进入计划与迭代。
### 2026-08-27 · 第 7 轮:数据源架构修正 —— 插件直连 QMT Bridge RESTful 接口
**老师指出的架构问题**
- QMT Bridge MCP 是**给智能体(Agent)用**的桥接层(封装成 MCP 工具,供 AI 调用);
- 我们的插件**不应通过 MCP**,而应**直接调用 QMT Bridge 同一服务端口下的 RESTful 接口**;
- REST 接口相关信息可通过 MCP 的 OpenAPI 规范获取(qmt_list_apis detail)。
**技术探索确认(2026-08-27**
- QMT Bridge 服务:**http://192.168.3.43:8610**(局域网 IP,配置于 ~/.dsh/profiles/web/cordis.patch.yml
- REST 端点(OpenAPI v3):/health、/trade/asset、/trade/positions、/trade/orders、/trade/trades、/data/kline、/data/quote、/data/instrument、/data/calendar/trading_dates、/data/subscribe、/data/tick、/data/unsubscribe
- MCP 端点:http://192.168.3.43:8610/mcp(同端口,MCP 封装给 Agent
- **REST 直连验证通过**/health、/trade/asset、/trade/positions 均正常返回,数据与 MCP 一致
**架构结论**
- 插件数据源适配器:直接 HTTP 调用 QMT Bridge RESTful 接口(不经过 MCP);
- MCP 仅作为 Agent 侧访问同一服务的封装层;
- 设计约束技术约束-001 仍成立(统一数据源抽象),但实现层从「MCP 调用」改为「REST 调用」。
### 2026-08-27 · S5 分仓逻辑设计讨论(Q1-Q4 结论)
**老师确认**
1. **Q1 按股数分配**:份额分配以股数为单位(不按比例);
2. **Q2 允许未分配余额**:可能有未对应策略的持股余额(临时手动操作,无对应策略)—— 即份额之和 ≤ 总持仓,允许「未分配」余量存在;
3. **Q3 策略仅为人为分组**:当前阶段策略只是人为的分组管理,**不实现策略的管理逻辑**(份额不随策略自动调整);
4. **Q4 不做统计信息**:分仓聚合**不加市值/盈亏/占比等统计**,只展示份额分配本身。
**对 S5 设计的影响**
- getSummary() 去掉市值/盈亏/占比聚合,只返回「各策略的持仓份额 + 未分配份额」;
- 份额分配:按股数,允许 sum ≤ 总持仓,剩余为「未分配」;
- 份额是人为静态指定,不涉及策略逻辑。
**待讨论(Q5**UI 上如何实现份额编辑操作。
### 2026-08-27 · Q5 UI 编辑交互设计讨论(老师明确)
**老师确认的 UI 形态**
1. **在策略 tab 内编辑**(不是单独的编辑界面);
2. **tab 结构**:理论上会有三类 tab
- **全部持仓**:初始有数据(全量真实持仓,来自 QMT);
- **网格策略持仓**:初始为空;
- **做T持仓**:初始为空;
3. **添加**:在策略持仓页(网格/做T)提供「添加持仓」操作 —— 从全部持仓中找到标的,指定份额,添加到该策略分组;
4. **移出**:提供「移出」操作 —— 该部分持仓不再按策略管理(回到全部持仓/未分配)。
**设计要点**
- 全部持仓是**数据源**(从 QMT 读的真实持仓),也是「未分配」的展示处;
- 策略持仓(网格/做T)是**从全部持仓挑份额**组成的分组;
- 份额编辑 = 添加(全量→策略,指定股数)+ 移出(策略→全量)。
**待确认细节**
1. 全部持仓 tab 是否也显示已分配到策略的份额(灰色/标注)?
2. 添加时份额输入:一次添加一股数?还是可拆多策略?
3. 「移出」是移出全部份额还是可指定数量?
4. 全部持仓 tab 与「未分配」概念的关系:全部持仓 = 未分配 + 已分配?
### 2026-08-27 · Q5 细节确认(老师确认)
**细节确认结论**
1. **细节1(全部持仓 tab**:A —— 显示完整持仓(1800 股),已分配部分标注(网格 1000 / 做T 800 / 未分配 400);
2. **细节2(添加粒度)+ 细节4(多策略)**
- 每个策略 tab 是独立编辑上下文;
- 添加时份额**默认 0**,用户编辑填入要分配到**当前策略**的份额;
- 每次操作只确定「分配到当前策略」的份额,并更新总持仓的已分配数量;
- **同一标的可在多个策略**(分别在各自策略 tab 下添加,如网格 600 + 做T 800);
- 例:网格 tab 添加 600719.SH 输入 600 → 网格 600;做T tab 再添加输入 800 → 做T 800;已分配 = 1400,未分配 = 400
3. **细节3(移出)**:B —— 指定数量移出(如做T 800 移出 200 → 做T 600,未分配 +200)。
**核心模型**:份额按策略独立维护;添加默认 0 起填;已分配 = 各策略份额之和;未分配 = 总持仓 - 已分配。