Files
aiagents-stock/docs/UNIFIED_ANALYSIS_SPEC.md
T

273 lines
7.9 KiB
Markdown
Raw 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.
# 统一股票分析调用规范
## 📌 核心原则
**所有涉及股票分析的功能必须使用统一的分析函数和数据结构!**
---
## 🎯 适用场景
✅ 以下所有场景必须遵循此规范:
- 首页单股分析
- 首页批量分析
- 持仓批量分析(UI触发)
- 持仓定时分析(自动触发)
- 智策板块中的个股分析
- 智瞰龙虎中的个股分析
- 主力选股中的个股分析
- **任何未来新增的股票分析功能**
---
## ✅ 正确做法
### 1. 调用统一分析函数
```python
from app import analyze_single_stock_for_batch
result = analyze_single_stock_for_batch(
symbol="600519.SH",
period="1y",
enabled_analysts_config={
'technical': True,
'fundamental': True,
'fund_flow': True,
'risk': True,
'sentiment': False,
'news': False
},
selected_model="deepseek-chat"
)
```
### 2. 使用统一字段名
```python
# 提取分析结果
final_decision = result["final_decision"]
stock_info = result["stock_info"]
# 使用正确的字段名
rating = final_decision.get("rating", "未知") # ✅
confidence = final_decision.get("confidence_level", "N/A") # ✅
entry_range = final_decision.get("entry_range", "N/A") # ✅
take_profit = final_decision.get("take_profit", "N/A") # ✅
stop_loss = final_decision.get("stop_loss", "N/A") # ✅
target_price = final_decision.get("target_price", "N/A") # ✅
advice = final_decision.get("advice", "") # ✅
```
### 3. 统一数据解析
```python
import re
# 解析进场区间(格式如"10.5-12.3"
entry_range = final_decision.get("entry_range", "")
entry_min, entry_max = None, None
if entry_range and isinstance(entry_range, str) and "-" in entry_range:
try:
parts = entry_range.split("-")
entry_min = float(parts[0].strip())
entry_max = float(parts[1].strip())
except:
pass
# 解析止盈止损(提取数字,如"15.8元" → 15.8
take_profit_str = final_decision.get("take_profit", "")
take_profit = None
if take_profit_str:
try:
numbers = re.findall(r'\d+\.?\d*', str(take_profit_str))
if numbers:
take_profit = float(numbers[0])
except:
pass
# 止损位同理
stop_loss_str = final_decision.get("stop_loss", "")
stop_loss = None
if stop_loss_str:
try:
numbers = re.findall(r'\d+\.?\d*', str(stop_loss_str))
if numbers:
stop_loss = float(numbers[0])
except:
pass
```
### 4. 统一结果展示
```python
# 评级颜色标识
if "强烈买入" in rating or "买入" in rating:
rating_color = "🟢"
elif "卖出" in rating:
rating_color = "🔴"
else:
rating_color = "🟡"
# UI展示(Streamlit示例)
with st.expander(f"{rating_color} {code} - {rating} (信心度: {confidence})"):
col1, col2 = st.columns(2)
with col1:
st.markdown("**进出场位置**")
st.write(f"进场区间: {entry_range}")
st.write(f"目标价: {target_price}")
with col2:
st.markdown("**风控位置**")
st.write(f"止盈位: {take_profit}")
st.write(f"止损位: {stop_loss}")
if advice:
st.markdown("**投资建议**")
st.info(advice)
```
---
## ❌ 禁止行为
### 1. 不要直接调用 ai_agents
```python
# ❌ 错误做法
from ai_agents import StockAnalysisAgents
agents = StockAnalysisAgents()
result = agents.technical_analyst_agent(...) # 禁止!
```
### 2. 不要使用废弃字段名
```python
# ❌ 错误的字段名
rating = final_decision.get("investment_rating") # 已废弃
confidence = final_decision.get("confidence") # 已废弃
positions = final_decision.get("entry_exit_positions") # 已废弃
entry_min = positions.get("entry_zone_min") # 已废弃
```
### 3. 不要重复实现分析逻辑
```python
# ❌ 错误做法
from stock_data import StockDataFetcher
from ai_agents import StockAnalysisAgents
fetcher = StockDataFetcher()
agents = StockAnalysisAgents()
# 自己获取数据
stock_data = fetcher.get_stock_data(symbol)
indicators = fetcher.calculate_technical_indicators(stock_data)
# 自己调用分析师
result = agents.technical_analyst_agent(...) # 禁止!
```
---
## 📋 字段对照表
| 正确字段名 | 废弃字段名 | 数据类型 | 示例值 |
|-----------|-----------|---------|-------|
| `rating` | `investment_rating` | string | "买入", "持有", "卖出" |
| `confidence_level` | `confidence` | string/number | "8/10", "N/A" |
| `entry_range` | `entry_exit_positions["entry_zone_min/max"]` | string | "10.5-12.3" |
| `take_profit` | `entry_exit_positions["take_profit"]` | string | "止盈: 15.8元" |
| `stop_loss` | `entry_exit_positions["stop_loss"]` | string | "止损: 9.2元" |
| `target_price` | - | string | "目标价: 18.5元" |
| `advice` | `summary` | string | "建议买入..." |
---
## 🔍 代码审查检查清单
提交涉及股票分析的代码时,请确认:
- [ ] 使用了 `app.analyze_single_stock_for_batch()` 而非直接调用 `ai_agents`
- [ ] 使用了正确的字段名(`rating`, `confidence_level`, `entry_range`等)
- [ ] 没有使用废弃字段名(`investment_rating`, `entry_exit_positions`等)
- [ ] 数据解析逻辑与规范一致(split("-"), re.findall()
- [ ] UI展示格式与其他模块保持一致
- [ ] 通知推送使用相同的数据结构
---
## 📚 参考代码
### 推荐参考
1. **`portfolio_manager.py`** - 完整的分析调用和数据保存示例
2. **`portfolio_ui.py`** - UI展示和数据解析示例
3. **`portfolio_scheduler.py`** - 监测同步和通知推送示例
4. **`notification_service.py`** - 通知内容构建示例
### 设计文档
- **`openspec/changes/add-portfolio-scheduled-analysis/design.md`** - Decision 4: 统一股票分析调用规范
- **`openspec/changes/add-portfolio-scheduled-analysis/specs/stock-analysis/spec.md`** - Requirement: 统一股票分析调用规范
---
## 💡 好处
遵循此规范可以获得:
1.**维护成本降低**:只需维护一个分析函数
2.**测试成本降低**:只需测试一个分析流程
3.**Bug修复效率**:一处修复,全局生效
4.**新功能快速开发**:直接复用,无需重写
5.**用户体验一致**:所有场景看到的结果格式一致
6.**代码复用最大化**:避免重复代码
7.**自动兼容优化**:首页分析的优化自动应用到所有场景
---
## ⚠️ 违规后果
不遵循此规范可能导致:
- ❌ 字段名不一致,UI显示"未知"或错误
- ❌ 数据解析失败,监测同步失败
- ❌ 通知推送格式错误
- ❌ 代码重复,维护困难
- ❌ Bug修复需要改多处
- ❌ 用户体验不一致
---
## 🆘 常见问题
### Q: 为什么必须使用统一函数?
A: 确保所有场景使用相同的AI模型、数据源、分析流程,避免结果不一致。首页分析的任何优化都会自动应用到所有场景。
### Q: 为什么不能直接调用 ai_agents?
A: `app.analyze_single_stock_for_batch()` 已经封装了完整的数据获取、分析、错误处理流程。直接调用 ai_agents 会导致代码重复和逻辑不一致。
### Q: 旧代码使用了废弃字段怎么办?
A: 必须修改!参考 `portfolio_manager.py` 中的正确用法,使用新的字段名。
### Q: 如何解析字符串字段(如进场区间)?
A: 参考本文档"统一数据解析"章节的代码示例,使用 `split("-")` 和正则表达式。
### Q: 新功能可以不遵循此规范吗?
A: **不可以!** 所有涉及股票分析的功能都必须遵循此规范,这是强制要求。
---
## 📝 更新日志
- **2024-10-20**: 初始版本,基于持仓定时分析功能的实践总结
- **规范来源**: OpenSpec - `add-portfolio-scheduled-analysis` - Decision 4
---
**遵循规范,代码更优!** 🎉