# Portfolio Quick Diagnosis

> 整理持仓、补全标的识别、生成确认表和快速诊断结果。先做识别与整理，完成后只问缺失的关键字段。

- Skill: `beixihub/portfolio-quick-diagnosis` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add beixihub/portfolio-quick-diagnosis`
- Raw SKILL.md: https://api.skillmd.com/api/skills/beixihub/portfolio-quick-diagnosis/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: BeixiHub (https://skillmd.com/u/beixihub)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/beixihub/portfolio-quick-diagnosis

---


# 投资组合快速诊断

## 目标

把用户持仓整理成可确认的结构化结果，并输出简洁的快速诊断。

## 核心规则

- 全程中文。不给买卖指令。
- 先做标的识别和整理，再提问。
- 只问完成当前阶段所必需的最少信息，最多补问 3 轮。
- 本技能只负责第 1 阶段，不处理 Phase 2 / 3。

---

## 执行流程（严格按 8 步执行）

### 步骤 1：接收用户持仓输入

用户输入可能有以下几种格式，你需要识别并解析：

**格式 A：只有股票名**
> "我有茅台、宁德时代、比亚迪"

→ 解析为：`[{name: "茅台"}, {name: "宁德时代"}, {name: "比亚迪"}]`，仓位待补全。

**格式 B：股票名 + 占比**
> "茅台 30%，宁德时代 25%，比亚迪 20%，现金 25%"

→ 解析为：`[{name: "茅台", pct: 30}, {name: "宁德时代", pct: 25}, {name: "比亚迪", pct: 20}]`，`cash_pct: 25`。

**格式 C：股票名 + 股数**
> "茅台 100 股，宁德时代 500 股"

→ 解析为：`[{name: "茅台", shares: 100}, {name: "宁德时代", shares: 500}]`，需查股价计算市值。

**格式 D：代码 + 口语化仓位**
> "600519 三成仓，300750 两成仓，现金五成"

→ 解析为：`[{code: "600519", pct: 30}, {code: "300750", pct: 20}]`，`cash_pct: 50`。

**格式 E：混合格式**
> "茅台重仓大概 40%，还有一些宁德时代和比亚迪"

→ 解析为：`[{name: "茅台", pct: 40}, {name: "宁德时代", pct: ?}, {name: "比亚迪", pct: ?}]`，宁德和比亚迪的占比待补全。

如果用户分多条消息给出持仓，等用户说"就这些"、"没了"、"以上"后再开始处理。

### 步骤 2：调用 QVeris identify 识别标的

对用户提供的每个股票名或代码，调用 QVeris 识别接口获取标准信息。

**调用方式**：
在 `portfolio-health-check/workspace/skills/portfolio-health-check/` 目录下运行：

```bash
python qveris_client.py identify "贵州茅台" "宁德时代" "比亚迪"
```

**调用要求**：
- 使用当前技能目录内的 `qveris_client.py` 执行 `identify`
- 一次尽量批量识别多个标的，避免逐只反复调用

**期望返回**（示例）：
```json
[
  {"query": "贵州茅台", "code": "600519.SH", "name": "贵州茅台", "industry": "白酒", "exchange": "上交所"},
  {"query": "宁德时代", "code": "300750.SZ", "name": "宁德时代", "industry": "动力电池", "exchange": "深交所"},
  {"query": "比亚迪", "code": "002594.SZ", "name": "比亚迪", "industry": "新能源汽车", "exchange": "深交所"}
]
```

**歧义处理**：如果一个名字匹配到多个结果（如"平安"可能是中国平安或平安银行），向用户列出候选：
```
"平安"匹配到多个标的，请确认您指的是哪一个：
1. 中国平安（601318.SH）— 保险
2. 平安银行（000001.SZ）— 银行
```

**QVeris 不可用时**：使用 web search 搜索 `{股票名} 股票代码 A股`，从搜索结果中提取代码和行业信息。告知用户："标的识别服务暂时不可用，我通过网络搜索来确认信息。"

### 步骤 3：补全仓位信息

根据用户提供的信息类型，分三条路径处理：

**路径 A：用户给了占比或金额**
- 直接使用，归一化为百分比
- 例：用户说"茅台 50 万，宁德 30 万，比亚迪 20 万"
  → 总额 100 万 → 茅台 50%，宁德 30%，比亚迪 20%

**路径 B：用户给了股数**
- 对每只股票，web search 查询最新股价：
  - 搜索关键词：`{股票名} 最新股价` 或 `{代码} 股价`
  - 例：搜索"贵州茅台 最新股价"，获取收盘价 1800 元
- 计算市值：股数 × 股价
  - 例：100 股 × 1800 元 = 18 万
- 所有股票市值求和，归一化为百分比
- 在确认表中标注"数据来源：网络查询估算"

**路径 C：用户只给了股票名，没有仓位信息**
- 对每只股票，web search 查询最新总市值：
  - 搜索关键词：`{股票名} 总市值`
  - 例：搜索"贵州茅台 总市值"，获取 2.2 万亿
- 按市值比例计算各股票的占比
  - 例：茅台 2.2 万亿，宁德 1.1 万亿，比亚迪 0.8 万亿
  - 总市值 4.1 万亿 → 茅台 53.7%，宁德 26.8%，比亚迪 19.5%
- 在确认表中标注"数据来源：按总市值比例估算，请核实实际持仓占比"

**搜不到可靠数据时**：在确认表中该股票的占比列写"待确认"，并向用户询问。

### 步骤 4：检查比例是否合计 100%

- **合计 = 100%**：直接进入步骤 5。
- **合计 < 100%**：询问用户剩余部分的归属：
  ```
  目前持仓合计 {X}%，剩余 {100-X}% 是现金还是还有其他持仓？
  ```
- **合计 > 100%**：提示不一致：
  ```
  目前持仓合计 {X}%，超过了 100%。请确认各项占比是否正确。
  ```

### 步骤 5：输出持仓确认表

使用以下**固定格式**输出确认表：

```markdown
### 持仓确认表

| 序号 | 名称 | 代码 | 占比 | 数据来源 |
|------|------|------|------|----------|
| 1 | 贵州茅台 | 600519.SH | 30.0% | 用户提供 |
| 2 | 宁德时代 | 300750.SZ | 25.0% | 用户提供 |
| 3 | 比亚迪 | 002594.SZ | 20.0% | 网络查询估算 |
| 4 | 现金 | — | 25.0% | 用户提供 |
| | **合计** | | **100.0%** | |

请确认以上信息。如有不准确的地方，请直接告诉我需要修改哪一行。
```

"数据来源"列的可选值：
- `用户提供` — 用户直接给了占比/金额
- `网络查询估算` — 通过 web search 股价或市值计算
- `按市值比例估算` — 用户只给了名字，按总市值算
- `待确认` — 搜不到可靠数据

### 步骤 6：等待用户确认

- 用户说"确认"/"没问题"/"对的"/"可以" → 进入步骤 7
- 用户说"茅台应该是 35%" → 修改对应行，重新输出确认表，再次请确认
- 用户说"还有一只 招商银行" → 对新标的执行步骤 2-4，更新确认表
- 用户说"把比亚迪去掉" → 删除对应行，重新归一化，更新确认表

### 步骤 7：生成快速诊断

用户确认持仓后，进行定性分析：

1. 使用 [analysis_prompt.md](analysis_prompt.md) 作为分析框架
2. 对每只持仓，通过 web search 补充以下信息：
   - 搜索 `{股票名} 主营业务 行业地位`
   - 搜索 `{股票名} 最新动态 2026`
3. 按 analysis_prompt.md 的结构完成分析：标的识别 → 单票逻辑 → 组合共性 → 研究结论

### 步骤 8：输出报告并收口

1. 使用 [report_prompt.md](report_prompt.md) 的模板格式输出报告
2. 报告开头加声明：`"以下分析基于您提供的信息及公开资料，仅用于投资组合基础结构分析。"`
3. 报告包含三部分：持仓概览、集中度与重叠分析、总体评价
4. 报告完成后，**不要继续展开**，用总控 SKILL.md 中的过渡话术询问是否进入深度诊断

---

## 常见场景处理

| 场景 | 处理方式 |
|------|---------|
| 用户说"我有十几只股票"然后一只只给 | 等用户说"没了"后统一处理，中间可回复"好的，继续" |
| 用户给了 ETF 名称（如"沪深300ETF"） | 正常识别，代码通常是 `51xxxx.SH` 或 `15xxxx.SZ` |
| 用户给了基金（如"易方达蓝筹"） | 识别为场外基金，代码格式 `xxxxxx.OF` |
| 用户说"大概各一半" | 按等权处理，如 2 只各 50%，3 只各 33.3% |
| 用户说"茅台重仓，其他少量" | 建议分配方案如"茅台 40%，其余平分"，让用户确认 |
| 用户给了美股（如"苹果""AAPL"） | 标注为"非 A 股标的"，提醒 Phase 2/3 目前主要支持 A 股 |

## 错误处理

| 错误 | 处理方式 |
|------|---------|
| QVeris 超时或报错 | 降级为 web search：搜索 `{名字} 股票代码 A股`，提取代码和行业 |
| Web search 找不到股价 | 在确认表中标记"待确认"，询问用户该股票的大致占比 |
| 股票名有歧义 | 列出所有候选（含代码和行业），让用户选 |
| 用户给了不存在的股票名 | 回复"未能识别'{名字}'，请确认是否拼写正确，或提供股票代码" |

## 参考文件

- [analysis_prompt.md](analysis_prompt.md) — 定性分析的系统提示词
- [report_prompt.md](report_prompt.md) — 报告输出模板

