{"skill":{"slug":"tradingagents-cn-skill","displayName":"Tradingagents Cn Skill","summary":"股票多智能体分析报告生成。通过 6 个分析师串行分析 + 多空辩论 + 交易计划 + 风险评估， 生成专业 PDF 报告。触发场景：用户要求分析股票、生成股票报告、提供截图或代码进行分析、 询问买卖建议、要求技术分析或基本面分析或风险评估。","description":"---\nname: tradingagents-cn-skill\nversion: 2.0.0\ndescription: >\n  股票多智能体分析报告生成。通过 6 个分析师串行分析 + 多空辩论 + 交易计划 + 风险评估，\n  生成专业 PDF 报告。触发场景：用户要求分析股票、生成股票报告、提供截图或代码进行分析、\n  询问买卖建议、要求技术分析或基本面分析或风险评估。\nmetadata:\n  openclaw:\n    emoji: \"📊\"\n    requires:\n      bins: [\"python3\"]\n---\n\n# TradingAgents-CN Skill\n\n多智能体股票分析框架。Agent 串行完成 12 步分析，每步调用 LLM 并通过脚本验证输出，最终生成 PDF 报告。\n\n## 全局规则\n\n### 重试协议\n\n每次 LLM 调用后，**必须**通过 `validate_step.py` 验证输出：\n\n```bash\necho '<LLM原始输出>' | python3 {baseDir}/scripts/validate_step.py --step <步骤名> --stock-code <股票代码> --attempt <次数>\n```\n\n**处理规则：**\n- `exit 0` → stdout 是清洗后的 JSON，保存结果，进入下一步\n- `exit 1` → stderr 是 JSON 错误信息（含 `hint` 字段），将 hint 追加到 prompt 重新调用 LLM\n- 关键步骤（bull、bear、manager、trader、risk_manager）最多重试 **3 次**\n- 次要步骤（tech、fundamentals、news、social、debate、risk_debate）最多重试 **2 次**\n- 超过重试上限 → 获取默认值继续：\n  ```bash\n  python3 {baseDir}/scripts/validate_step.py --step <步骤名> --default\n  ```\n\n**重试时的 prompt 追加格式：**\n```\n注意：上次输出格式有误。{hint}。请严格按纯 JSON 格式返回，不要用 markdown 代码块包裹。\n```\n\n### 日志\n\n分析开始前，设置日志环境变量，确保同一次分析的所有步骤写入同一日志文件：\n\n```bash\nexport TRADINGAGENTS_LOG_FILE=\"{baseDir}/scripts/logs/{股票代码}_{YYYYMMDD}_{HHMMSS}.log\"\nmkdir -p {baseDir}/scripts/logs\n```\n\n分析结束后，告知用户日志文件路径。\n\n### 语言要求\n\n所有 LLM 调用的 system_prompt 和 user_message 使用**中文**。所有分析内容使用**中文**输出。\n\n---\n\n## 工作流程\n\n```\nStep 1A: 获取原始文本（截图 → OCR / 文字 → 直接使用）\nStep 1B: 结构化提取 LLM → validate → stock_data JSON\nStep 2:  web_search 获取新闻 → news_data\nStep 3:  多头分析师 LLM → validate → bull_analyst\nStep 4:  空头分析师 LLM → validate → bear_analyst\nStep 5:  技术分析师 LLM → validate → tech_analyst\nStep 6:  基本面分析师 LLM → validate → fundamentals_analyst\nStep 7:  新闻分析师 LLM → validate → news_analyst\nStep 8:  社交媒体分析师 LLM → validate → social_analyst\nStep 9:  多空辩论 + 研究经理决策 LLM → validate → debate + manager_decision\nStep 10: 交易员计划 LLM → validate → trading_plan\nStep 11: 风险辩论 + 风险经理评估 LLM → validate → risk_debate + final_decision\nStep 12: 组装 JSON → 生成 PDF\n```\n\n---\n\n## Step 1A: 获取原始文本\n\n根据用户输入类型，获取原始文本：\n\n**情况 1：用户提供截图/图片**\n- 调用 OCR MCP tool（如 `image-ocr`）或 Agent 内建的图片识别能力\n- 将识别结果作为原始文本\n- 截图可能包含：K 线图、技术指标面板、财报数据、交易软件截图等\n\n**情况 2：用户提供文字描述**\n- 直接使用用户提供的文字作为原始文本\n\n**情况 3：用户只提供股票代码/名称**\n- 将股票代码和名称作为原始文本，后续步骤会通过 web_search 补充数据\n\n---\n\n## Step 1B: 结构化数据提取\n\n**LLM 调用：**\n- system_prompt:\n  ```\n  你是股票数据提取专家。从用户提供的文本（可能来自截图OCR、交易软件、财报等）中，\n  提取结构化的股票数据。只提取文本中明确存在的信息，缺失的字段设为 null。\n  不要虚构或推测任何数据。以纯 JSON 格式返回。\n  ```\n- user_message:\n  ```\n  请从以下文本中提取股票数据，以纯 JSON 格式返回：\n\n  {原始文本}\n\n  要求返回的 JSON 格式：\n  {\n    \"stock_code\": \"股票代码（如 PDD、600519、HK.00700）\",\n    \"stock_name\": \"股票名称\",\n    \"current_price\": 数字或null,\n    \"change_pct\": \"涨跌幅字符串或null\",\n    \"volume\": \"成交量或null\",\n    \"turnover\": \"成交额或null\",\n    \"technical_indicators\": {\n      \"MA5\": 数字或null,\n      \"MA10\": 数字或null,\n      \"MA20\": 数字或null,\n      \"MA60\": 数字或null,\n      \"RSI\": 数字或null,\n      \"MACD\": \"描述或null\",\n      \"KDJ\": \"描述或null\",\n      \"BOLL_upper\": 数字或null,\n      \"BOLL_mid\": 数字或null,\n      \"BOLL_lower\": 数字或null\n    },\n    \"fundamentals\": {\n      \"PE\": 数字或null,\n      \"PB\": 数字或null,\n      \"ROE\": \"字符串或null\",\n      \"market_cap\": \"字符串或null\",\n      \"revenue\": \"字符串或null\",\n      \"net_profit\": \"字符串或null\"\n    },\n    \"k_line_pattern\": \"K线形态描述或null（如：近5日缩量调整、均线多头排列等）\",\n    \"other_info\": \"其他有价值的信息或null\"\n  }\n  ```\n\n**验证：**\n```bash\necho '<LLM输出>' | python3 {baseDir}/scripts/validate_step.py --step parse_input --stock-code {股票代码} --attempt 1\n```\n\n**后处理：**\n- 将验证通过的 JSON 保存为 `stock_data`\n- 从 `stock_data` 中提取 `stock_code` 和 `stock_name` 供后续步骤使用\n- 构建 `text_description`：将 `stock_data` 格式化为可读文本，包含所有非 null 字段：\n  ```\n  股票代码: {stock_code}\n  股票名称: {stock_name}\n  当前价格: ¥{current_price}\n  涨跌幅: {change_pct}\n  技术指标: MA5={MA5}, MA10={MA10}, RSI={RSI}, MACD={MACD} ...\n  基本面: PE={PE}, PB={PB}, 市值={market_cap} ...\n  K线形态: {k_line_pattern}\n  ```\n- 缺失字段标注\"待获取\"\n\n---\n\n## Step 2: 获取新闻数据\n\n使用 web_search 搜索 4 次：\n\n```\nweb_search: \"{股票代码} {股票名称} 最新新闻\"\nweb_search: \"{股票代码} 财报 业绩\"\nweb_search: \"{股票名称} 分析师评级\"\nweb_search: \"{股票代码} 技术分析 走势\"\n```\n\n**过滤规则**：只保留最近 **3 天内**（不含当天）的新闻。\n\n构建 `news_data` 列表，每条必须包含：`title`、`date`（YYYY-MM-DD）、`source`、`summary`（≤50 字，基于 title+snippet 生成）、`sentiment`（偏多/偏空/中性）。\n\n---\n\n## Step 3: 多头分析师\n\n**LLM 调用：**\n- system_prompt: 读取 `references/bull_prompt.md` 的完整内容\n- user_message:\n  ```\n  请分析以下股票，以纯 JSON 格式返回分析结果，不要用 markdown 代码块包裹。\n\n  {text_description}\n\n  近期新闻：\n  {news_data 格式化列表}\n  ```\n\n**验证：**\n```bash\necho '<LLM输出>' | python3 {baseDir}/scripts/validate_step.py --step bull_analyst --stock-code {股票代码} --attempt 1\n```\n\n**保存：** 将验证通过的 JSON 存为 `bull_analyst` 结果。\n\n---\n\n## Step 4: 空头分析师\n\n**LLM 调用：**\n- system_prompt: 读取 `references/bear_prompt.md`\n- user_message: 同 Step 3 格式\n\n**验证：**\n```bash\necho '<LLM输出>' | python3 {baseDir}/scripts/validate_step.py --step bear_analyst --stock-code {股票代码} --attempt 1\n```\n\n---\n\n## Step 5: 技术分析师\n\n**LLM 调用：**\n- system_prompt: 读取 `references/tech_prompt.md`\n- user_message: 同 Step 3 格式\n\n**验证：**\n```bash\necho '<LLM输出>' | python3 {baseDir}/scripts/validate_step.py --step tech_analyst --stock-code {股票代码} --attempt 1\n```\n\n---\n\n## Step 6: 基本面分析师\n\n**LLM 调用：**\n- system_prompt: 读取 `references/fundamentals_prompt.md`\n- user_message: 同 Step 3 格式\n\n**验证：**\n```bash\necho '<LLM输出>' | python3 {baseDir}/scripts/validate_step.py --step fundamentals_analyst --stock-code {股票代码} --attempt 1\n```\n\n---\n\n## Step 7: 新闻分析师\n\n**LLM 调用：**\n- system_prompt: 读取 `references/news_prompt.md`\n- user_message: 同 Step 3 格式\n\n**验证：**\n```bash\necho '<LLM输出>' | python3 {baseDir}/scripts/validate_step.py --step news_analyst --stock-code {股票代码} --attempt 1\n```\n\n---\n\n## Step 8: 社交媒体分析师\n\n**LLM 调用：**\n- system_prompt: 读取 `references/social_prompt.md`\n- user_message: 同 Step 3 格式\n\n**验证：**\n```bash\necho '<LLM输出>' | python3 {baseDir}/scripts/validate_step.py --step social_analyst --stock-code {股票代码} --attempt 1\n```\n\n---\n\n## Step 9: 多空辩论 + 研究经理决策\n\n### 阶段 A: 多空辩论\n\n**LLM 调用：**\n- system_prompt: \"你是一位专业的投资辩论主持人。\"\n- user_message:\n  ```\n  以下是多头和空头的观点：\n\n  多头观点：\n  {bull_analyst 的 analysis 部分，JSON 格式}\n\n  空头观点：\n  {bear_analyst 的 analysis 部分，JSON 格式}\n\n  请进行 2 轮辩论，每轮让多头反驳空头、空头反驳多头。\n  以纯 JSON 格式返回，不要用 markdown 代码块：\n  {\"rounds\": [{\"round\": 1, \"bull_points\": [\"论点1\", \"论点2\"], \"bear_points\": [\"论点1\", \"论点2\"]}]}\n  ```\n\n**验证：**\n```bash\necho '<LLM输出>' | python3 {baseDir}/scripts/validate_step.py --step debate --stock-code {股票代码} --attempt 1\n```\n\n### 阶段 B: 研究经理决策\n\n**LLM 调用：**\n- system_prompt: 读取 `references/manager_prompt.md`\n- user_message:\n  ```\n  基于以下分析师观点，给出最终决策。\n\n  {text_description + news_data 上下文}\n\n  分析师汇总：\n  {bull_analyst, bear_analyst, tech_analyst, fundamentals_analyst, news_analyst 的 analysis 和 sentiment 摘要，JSON 格式}\n\n  辩论结果：\n  {debate 结果 JSON}\n\n  请以纯 JSON 格式返回：\n  {\"decision\": \"买入/卖出/持有\", \"rationale\": \"核心逻辑\"}\n  ```\n\n**验证：**\n```bash\necho '<LLM输出>' | python3 {baseDir}/scripts/validate_step.py --step manager --stock-code {股票代码} --attempt 1\n```\n\n---\n\n## Step 10: 交易员计划\n\n**LLM 调用：**\n- system_prompt: 读取 `references/trader_prompt.md`\n- user_message:\n  ```\n  研究经理决策: {manager_decision.decision}\n  理由: {manager_decision.rationale}\n  当前股价: {current_price} 港元\n\n  请根据决策制定交易计划，以纯 JSON 格式返回：\n\n  decision 为\"买入\"时：\n  {\"buy_price\": 回调入场价（当前价×0.98）, \"target_price\": 目标价（buy_price×1.10~1.20）, \"stop_loss\": 止损价（buy_price×0.92~0.95）, \"position_size\": \"15%-20%\", \"entry_criteria\": \"...\", \"exit_criteria\": \"...\"}\n\n  decision 为\"持有/观望\"时：\n  {\"buy_price\": null, \"target_price\": null, \"stop_loss\": null, \"position_size\": \"0%\", \"reference_price\": 当前价, \"reference_target\": 当前价×1.10, \"reference_stop\": 当前价×0.95, \"entry_criteria\": \"观望理由和入场条件\", \"exit_criteria\": \"不适用\"}\n  ```\n\n**注意：**\n- buy_price/target_price/stop_loss **仅在 decision=\"买入\" 时必填数字**\n- 持有/观望时这三个字段**允许为 null**\n- 任何决策都必须包含 position_size（非 null）\n- price 必须使用数字类型（如 1.37），不允许文字描述\n\n**验证：**\n```bash\necho '<LLM输出>' | python3 {baseDir}/scripts/validate_step.py --step trader --stock-code {股票代码} --attempt 1\n```\n\n**后处理：** 将 `manager_decision.decision` 写入 trading_plan 的 `decision` 字段。\n\n---\n\n## Step 11: 风险评估\n\n### 阶段 A: 三方风险辩论\n\n**LLM 调用：**\n- system_prompt: 读取 `references/risk_debate_prompt.md`\n- user_message:\n  ```\n  交易计划：\n  {trading_plan JSON}\n\n  {text_description + news_data 上下文}\n\n  请从激进派、中性派、保守派三个角度辩论，以纯 JSON 格式返回：\n  {\"aggressive\": {\"stance\": \"...\", \"points\": [...]}, \"moderate\": {\"stance\": \"...\", \"points\": [...]}, \"conservative\": {\"stance\": \"...\", \"points\": [...]}}\n  ```\n\n**验证：**\n```bash\necho '<LLM输出>' | python3 {baseDir}/scripts/validate_step.py --step risk_debate --stock-code {股票代码} --attempt 1\n```\n\n### 阶段 B: 风险经理最终评估\n\n**LLM 调用：**\n- system_prompt: 读取 `references/risk_manager_prompt.md`\n- user_message:\n  ```\n  交易计划：{trading_plan JSON}\n  三方风险辩论观点：{risk_debate JSON}\n\n  {text_description + news_data 上下文}\n\n  请综合评估，以纯 JSON 格式返回：\n  {\"final_recommendation\": \"买入/卖出/持有\", \"risk_level\": \"低/中/高\", \"investment_horizon\": \"短期/中期\",\n   \"risk_assessment\": {\"市场风险\": \"...\", \"流动性风险\": \"...\", \"波动性风险\": \"...\"},\n   \"suitable_investors\": [\"稳健型\"], \"monitoring_points\": [\"...\"]}\n  ```\n\n**验证：**\n```bash\necho '<LLM输出>' | python3 {baseDir}/scripts/validate_step.py --step risk_manager --stock-code {股票代码} --attempt 1\n```\n\n---\n\n## Step 12: 生成 PDF 报告\n\n将所有结果组装为完整 JSON（格式详见 `references/data_schema.md`）：\n\n```json\n{\n  \"stock_code\": \"{股票代码}\",\n  \"stock_name\": \"{股票名称}\",\n  \"current_price\": {当前价格},\n  \"timestamp\": \"{ISO 8601 时间戳}\",\n  \"parallel_analysis\": {\n    \"bull_analyst\": {Step 3 结果},\n    \"bear_analyst\": {Step 4 结果},\n    \"tech_analyst\": {Step 5 结果},\n    \"fundamentals_analyst\": {Step 6 结果},\n    \"news_analyst\": {Step 7 结果},\n    \"social_analyst\": {Step 8 结果}\n  },\n  \"debate\": {Step 9A 结果},\n  \"manager_decision\": {Step 9B 结果},\n  \"trading_plan\": {Step 10 结果},\n  \"risk_debate\": {Step 11A 结果},\n  \"final_decision\": {Step 11B 结果}\n}\n```\n\n调用脚本生成 PDF：\n\n```bash\necho '<完整JSON>' | python3 {baseDir}/scripts/generate_report.py --stdin\n```\n\n脚本输出 PDF 文件路径。\n\n**重要：必须将 PDF 文件直接发送给用户，不要只显示文件路径。** 使用文件发送能力将 PDF 作为附件发给用户，让用户可以直接下载查看。\n\n同时附上简要的分析摘要：\n- 核心结论（买入/卖出/持有）\n- 关键价格：买入价、目标价、止损价\n- 风险等级和投资期限\n- 一句话看多/看空逻辑\n\n---\n\n## 输出文件\n\nPDF 保存到 `{baseDir}/scripts/reports/`，文件名格式：`{股票代码}_{YYYYMMDD}_{HHMMSS}.pdf`\n\n---\n\n## 调试方法\n\n### CLI 直接触发\n```bash\nopenclaw agent --message \"分析一下 PDD\" --verbose on --json\n```\n\n### 单步验证工具\n```bash\n# 测试某个 LLM 输出是否通过验证\necho '{\"bull_detail\":{\"core_logic\":\"test\",\"bull_case\":[\"point1\"]}}' | python3 {baseDir}/scripts/validate_step.py --step bull_analyst\n\n# 获取某步骤的默认值\npython3 {baseDir}/scripts/validate_step.py --step bull_analyst --default\n```\n\n### 日志查看\n```bash\n# 查看最新日志\ncat {baseDir}/scripts/logs/latest.log\n\n# 查看指定股票的日志\nls {baseDir}/scripts/logs/PDD_*.log\n```\n","tags":{"latest":"2.0.1","multi-agent":"1.0.4","stock-analysis":"1.0.4","trading":"1.0.4"},"stats":{"comments":0,"downloads":771,"installsAllTime":0,"installsCurrent":0,"stars":0,"versions":7},"createdAt":1775539685246,"updatedAt":1779123708279},"latestVersion":{"version":"2.0.1","createdAt":1779123685829,"changelog":"2.0.1:\n- 修复 trader 步骤验证逻辑：decision=持有/观望 时 buy_price/target_price/stop_loss 允许为 null\n- generate_report.py: 加了 moderate→neutral 自动兼容\n- pdf_generator.py: 修复 position_size=0% 显示为'观望'而非'数据获取失败'\n- fundamentals_prompt.md: 重写估值分析示例，明确要求中文键名（当前市盈率/P/E、同业比较、PEG指标等）\n- SKILL.md Step 10: 补充说明持有/观望时价格字段允许 null\n- 清理所有测试产物（reports/ logs/ __pycache__/）","license":"MIT-0"},"metadata":{"setup":[],"os":null,"systems":null},"owner":{"handle":"tanteng","userId":"s17arxxkc5tdc79a7pbqxxapad83jnyw","displayName":"Tony","image":"https://avatars.githubusercontent.com/u/3405598?v=4"},"moderation":null}