7.9 KiB
7.9 KiB
统一股票分析调用规范
📌 核心原则
所有涉及股票分析的功能必须使用统一的分析函数和数据结构!
🎯 适用场景
✅ 以下所有场景必须遵循此规范:
- 首页单股分析
- 首页批量分析
- 持仓批量分析(UI触发)
- 持仓定时分析(自动触发)
- 智策板块中的个股分析
- 智瞰龙虎中的个股分析
- 主力选股中的个股分析
- 任何未来新增的股票分析功能
✅ 正确做法
1. 调用统一分析函数
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. 使用统一字段名
# 提取分析结果
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. 统一数据解析
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. 统一结果展示
# 评级颜色标识
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
# ❌ 错误做法
from ai_agents import StockAnalysisAgents
agents = StockAnalysisAgents()
result = agents.technical_analyst_agent(...) # 禁止!
2. 不要使用废弃字段名
# ❌ 错误的字段名
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. 不要重复实现分析逻辑
# ❌ 错误做法
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展示格式与其他模块保持一致
- 通知推送使用相同的数据结构
📚 参考代码
推荐参考
portfolio_manager.py- 完整的分析调用和数据保存示例portfolio_ui.py- UI展示和数据解析示例portfolio_scheduler.py- 监测同步和通知推送示例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: 统一股票分析调用规范
💡 好处
遵循此规范可以获得:
- ✅ 维护成本降低:只需维护一个分析函数
- ✅ 测试成本降低:只需测试一个分析流程
- ✅ Bug修复效率:一处修复,全局生效
- ✅ 新功能快速开发:直接复用,无需重写
- ✅ 用户体验一致:所有场景看到的结果格式一致
- ✅ 代码复用最大化:避免重复代码
- ✅ 自动兼容优化:首页分析的优化自动应用到所有场景
⚠️ 违规后果
不遵循此规范可能导致:
- ❌ 字段名不一致,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
遵循规范,代码更优! 🎉