知识
← 返回

短线猎手改造施工方案

2026-05-15 金融
#金融 #股票研究

金融专家短线猎手改造施工方案

文档类型: 工程实施文档
创建时间: 2026-05-15
目标: 为 junjun 的短线交易需求新增「短线猎手」角色,解决策略专家与用户需求错配问题


一、项目背景与问题

1.1 现状问题

策略专家(strategy)的 prompt 定位是中长线量化分析师,核心原则是:

  • 多空双视角、置信度量化
  • 禁止给出具体买卖点位
  • 默认保守,偏好估值低、技术形态稳的票

但 junjun 的实际需求是:

  • 短线交易,几天到一周内见效果
  • 高弹性,愿意承担波动,要的是涨幅不是安全边际
  • 追热点追动量,不是抄底等启动

结果: 策略专家连续两周推荐海信、中远海控、建投能源、东方财富等稳健票,全部不涨甚至下跌,用户信任崩塌。

1.2 解决思路

不改现有策略专家(避免影响其他用户),新增「短线猎手」角色(hunter),专门服务短线交易需求。


二、改造后的文件树

/opt/agent/financial-team/
├── prompts/
   ├── research.md              # 调研专家(不变)
   ├── strategy.md              # 策略专家(微调,见下文)
   └── hunter.md                # 短线猎手(新增)★
├── agents/
   ├── base_agent.py            # 基础 agent 框架(不变)
   ├── expert_runner.py         # 专家统一入口(改)★
   └── router.py                # 路由分发(改)★
├── tools/
   ├── real_tools.py            # 真实工具注册(改)★
   ├── memory_manager.py        # 记忆管理(不变)
   ├── tools_memory/            # 记忆文件目录(不变)
   └── akshare_wrappers.py      # AKShare 接口封装(新增)★
├── data/
   └── portfolios/              # 持仓数据(不变)
└── docs/
    └── migration_guide.md       # 迁移说明(新增)

文件改动清单

文件 操作 说明
prompts/hunter.md 新增 短线猎手角色定义
prompts/strategy.md 微调 增加「长短答判断」中对短线需求的识别,避免抢 hunter 的活
agents/expert_runner.py ROLE_CONFIG 增加 hunter
agents/router.py 路由规则增加 hunter 分支
tools/real_tools.py 注册 hunter 专用工具
tools/akshare_wrappers.py 新增 AKShare 资金/龙虎榜/概念热度接口封装

三、代码关系与调用链

3.1 整体架构图

┌─────────────────────────────────────────────────────────────┐
                     OpenClaw (junjunclaw)                    
                                                              
  用户消息: "明天买什么票能涨?"                               
                                                             
                                                             
  ┌─────────────────┐                                         
    意图识别层        关键词匹配: "明天"/"下周"/"短线"/"必涨"  
    (OpenClaw )      路由到 financial-team/hunter        
  └────────┬────────┘                                         
                                                             
                                                             
  ┌────────────────────────────────────────────────────────┐  
            financial-team (Docker 容器)                     
                                                            
     ┌─────────────┐    ┌─────────────┐    ┌──────────┐    
        router.py  │───▶│expert_runner│───▶│ BaseAgent    
       (路由分发)         (统一入口)       (执行层)      
     └─────────────┘    └─────────────┘    └────┬─────┘    
                                                          
                                                          
     ┌─────────────┐                      ┌────────────┐    
      prompts/                            tools/          
      hunter.md                           akshare_        
      (角色定义)                           wrappers.py     
     └─────────────┘                       (资金/龙虎)     
                                           └────────────┘    
  └────────────────────────────────────────────────────────┘  
                                                             
                                                             
  ┌────────────────────────────────────────────────────────┐  
                        数据源层                              
     ┌──────────┐  ┌──────────┐  ┌──────────┐              
       sina        tencent     akshare                 
      实时行情     历史K线     资金/龙虎               
     └──────────┘  └──────────┘  └──────────┘              
  └────────────────────────────────────────────────────────┘  
└─────────────────────────────────────────────────────────────┘

3.2 router.py 的路由逻辑(改造后)

# router.py 核心逻辑

def dispatch(caller, room, message):
    msg = message.lower()

    # 短线猎手关键词(优先级最高)
    hunter_keywords = [
        "明天", "下周", "短线", "必涨", "追", "打板",
        "涨停", "热点", "题材", "龙头", "游资", "龙虎榜",
        "资金流入", "主力", "放量", "冲", "梭哈"
    ]
    if any(kw in msg for kw in hunter_keywords):
        return route_to("hunter", caller, room, message)

    # 调研专家关键词
    research_keywords = ["调研", "分析", "基本面", "财报", "深度"]
    if any(kw in msg for kw in research_keywords):
        return route_to("research", caller, room, message)

    # 策略专家(默认兜底)
    return route_to("strategy", caller, room, message)

3.3 expert_runner.py 的 ROLE_CONFIG(改造后)

ROLE_CONFIG = {
    "research": {
        "prompt_file": "research.md",
        "temperature": 0.3,
        "output_dir": "research-reports",
        "output_title": "调研报告",
        "prefix": "📊 [调研专家]",
    },
    "strategy": {
        "prompt_file": "strategy.md",
        "temperature": 0.3,
        "output_dir": "strategy-advice",
        "output_title": "策略建议",
        "prefix": "📈 [策略专家]",
    },
    "hunter": {                           # ★ 新增
        "prompt_file": "hunter.md",
        "temperature": 0.5,               # 稍高,允许更大胆的推断
        "output_dir": "hunter-picks",
        "output_title": "短线猎手",
        "prefix": "⚡ [短线猎手]",
    },
}

四、怎么生效

4.1 部署步骤

Step 1: 写入新文件

cd /opt/agent/financial-team

# 1. 写 hunter.md
vim prompts/hunter.md

# 2. 改 strategy.md(增加长短答判断中对短线需求的识别)
vim prompts/strategy.md

# 3. 改 expert_runner.py(ROLE_CONFIG 加 hunter)
vim agents/expert_runner.py

# 4. 改 router.py(路由规则加 hunter 分支)
vim agents/router.py

# 5. 新增 akshare_wrappers.py
touch tools/akshare_wrappers.py

Step 2: 重启生效

# financial-team 是 ywz-local-fin 容器的一部分
# 由于它是被 OpenClaw 容器通过 exec 调用的,不需要单独重启
# 只需确保 financial-team 代码在宿主机上是最新的即可

# 但如果是独立容器运行:
docker compose restart financial-team  # 如果有独立服务

# 实际上 financial-team 是被 ywzclaw/junjunclaw exec 调用的
# 所以改完代码立即生效,不需要重启 OpenClaw 容器

Step 3: 验证

# 在 junjun 聊天室发一条消息测试:
# "明天有什么票可以追?"
# 观察日志确认路由到了 hunter 而不是 strategy

4.2 回滚方案

如果 hunter 效果不佳,只需改 router.py,把 hunter 关键词注释掉,请求自动 fallback 到 strategy:

# router.py 中注释掉 hunter 路由
# hunter_keywords = [...]
# if any(kw in msg for kw in hunter_keywords):
#     return route_to("hunter", ...)

无需重启,改完即生效。


五、新增/调用的工具

5.1 新增工具列表

工具名 功能 数据源 用途
get_sector_fund_flow 板块资金流向排名 akshare 找当前资金主攻方向
get_stock_fund_flow 个股资金流向 akshare 看单票主力资金进出
get_lhb_daily 龙虎榜数据 akshare 看游资在炒哪些票
get_north_hold_change 北向资金持股变化 akshare 看外资动向
get_concept_board 概念题材热度 akshare 找当前热点题材
get_limit_up_pool 涨停池 akshare 看今日涨停票和连板情况

5.2 工具调用链(典型场景)

场景:用户问”明天买什么票能涨?”

router.py 识别到 hunter 关键词 → 调 expert_runner.py (role=hunter)
    │
    ▼
hunter.md 驱动 BaseAgent 执行 ReAct 循环
    │
    ├── Step 1: get_sector_fund_flow() → 获取今日板块资金流入 Top10
    │          "今日资金主攻:半导体 +15亿、新能源 +8亿、地产 +3亿"
    │
    ├── Step 2: get_concept_board() → 获取概念热度排名
    │          "热度最高:光刻胶、固态电池、跨境电商"
    │
    ├── Step 3: get_lhb_daily() → 获取龙虎榜,看游资在买什么
    │          "游资买入:XXX(光刻胶)、YYY(固态电池)"
    │
    ├── Step 4: get_stock_spot() → 获取候选票的实时行情
    │          "XXX: 涨停、换手率 12%、量比 3.5"
    │
    ├── Step 5: calculate_technical() → 技术面确认
    │          "MACD 金叉、放量突破、RSI 65(未超买)"
    │
    └── Step 6: 综合输出
               "明天可关注:XXX(光刻胶龙头),理由:...
                备选:YYY(固态电池),理由:...
                风险提示:..."

5.3 与现有工具的关系

┌─────────────────────────────────────────────────────────┐
│                    工具层                                │
├──────────────┬──────────────┬───────────────────────────┤
│  通用工具     │ 策略专家专用  │ 短线猎手专用(新增)       │
├──────────────┼──────────────┼───────────────────────────┤
│ get_stock_   │ calculate_   │ get_sector_fund_flow      │
│ spot         │ technical    │ get_stock_fund_flow       │
│              │              │                           │
│ get_stock_   │ get_stock_   │ get_lhb_daily             │
│ history      │ news         │ get_north_hold_change     │
│              │              │                           │
│ read_portfo- │ save_to_     │ get_concept_board         │
│ lio          │ siyuan       │ get_limit_up_pool         │
└──────────────┴──────────────┴───────────────────────────┘

六、预期典型场景的动线流程图

场景 A:用户问”明天买什么票能涨?”

用户: "明天买什么票能涨?"
  
  
[OpenClaw] 意图识别
    关键词命中: "明天"  hunter
  
  
[router.py] route_to("hunter")
  
  
[expert_runner.py] role=hunter
  
  
[hunter.md 驱动 ReAct]
  
  ├─▶ get_sector_fund_flow()
      返回: 半导体 +15亿新能源 +8亿
  
  ├─▶ get_concept_board()
      返回: 光刻胶(热度1)固态电池(热度2)
  
  ├─▶ get_lhb_daily()
      返回: 游资买入 XXX(光刻胶)YYY(固态电池)
  
  ├─▶ get_stock_spot() + calculate_technical()
      返回: XXX 涨停放量MACD金叉RSI65
  
  └─▶ 综合输出
       "明天可关注:
        1. XXX(光刻胶龙头)—— 今日涨停、游资介入、板块资金流入第一
           建议:若开盘涨幅 < 3% 可追,> 5% 观望
           持有周期:2-3 天,跌破今日涨停价止损

        2. YYY(固态电池)—— 放量突破、北向加仓
           建议:回踩 5 日线低吸
           持有周期:3-5 天,跌破 MA5 止损"
  
  
[Matrix 发送给用户]

场景 B:用户问”帮我看看中远海控下周能不能涨?

用户: "中远海控下周能不能涨?"
  
  
[OpenClaw] 意图识别
    关键词命中: "下周"  hunter
  
  
[router.py] route_to("hunter")
  
  
[hunter.md 驱动 ReAct]
  
  ├─▶ get_stock_spot("中远海控")
      返回: 当前价涨跌幅换手率
  
  ├─▶ get_stock_fund_flow("中远海控")
      返回: 主力资金连续 3 日净流出
  
  ├─▶ get_sector_fund_flow()
      返回: 海运板块资金流出第 3
  
  ├─▶ get_stock_news("中远海控")
      返回: 中美关税缓和但运费仍承压
  
  ├─▶ calculate_technical("中远海控")
      返回: MACD 死叉缩量跌破 MA20
  
  └─▶ 综合输出
       "中远海控下周看法:

        偏空信号:
        - 主力资金连续 3 日净流出
        - 海运板块整体资金流出
        - 技术面上 MACD 死叉、跌破 MA20
        - 缩量下跌,没有企稳迹象

        唯一支撑:
        - 中美关税缓和长期利好海运,但短期未反映在股价上

        结论:下周继续调整概率大。建议:
        - 若已持仓:明天反弹即减仓,跌破 xx 元止损
        - 若未持仓:观望,等放量阳线再考虑"
  
  
[Matrix 发送给用户]

场景 C:用户问”帮我深度调研一下茅台”(不应走 hunter)

用户: "帮我深度调研一下茅台"
  
  
[OpenClaw] 意图识别
    关键词命中: "深度调研"  research
     hunter 关键词明天/下周/短线/必涨
  
  
[router.py] route_to("research")
  
  
[research.md 驱动 ReAct]
  
  ├─▶ get_stock_spot("茅台")
  ├─▶ get_stock_news("茅台")
  ├─▶ get_stock_history("茅台")
  └─▶ 输出完整调研报告保存到思源
  
  
[Matrix 发送给用户: 摘要 + 思源链接]

七、风险提示与边界

7.1 hunter 的局限

  • 不能预测未来:所有判断基于历史数据和当前资金动向,市场随时可能反转
  • 不适合大盘暴跌期:短线猎手在系统性风险面前同样失效
  • 信息延迟:akshare 数据有延迟(T 日数据 T+1 早上更新),无法做到真正的实时

7.2 用户预期管理

hunter 的输出必须包含:

⚠️ 风险提示:
1. 以上分析基于公开历史数据,不构成投资建议
2. 短线交易风险极高,可能面临大幅亏损
3. 请设置止损位并严格执行
4. 过往表现不代表未来收益

7.3 与策略专家的边界

场景 走 hunter 走 strategy
“明天买什么?”
“下周哪个板块有戏?”
“帮我看看这只票的技术面”
“这只票估值贵不贵?”
“我的持仓怎么调整?”
“短线和中长线怎么配置?” 两者结合 两者结合

八、验收标准

改造完成后,junjun 在聊天室发送以下测试消息,验证路由和输出质量:

测试消息 预期路由 预期输出特征
“明天买什么票能涨?” hunter 给出 1-3 只票,带理由、持有周期、止损位
“下周哪个板块有戏?” hunter 给出板块 + 逻辑 + 代表股
“帮我看看中远海控” hunter 资金动向 + 技术判断 + 操作建议
“深度调研一下比亚迪” research 完整研报,保存到思源
“我的持仓怎么调整?” strategy 组合分析 + 仓位建议

九、下一步行动

  1. 写 hunter.md(短线猎手角色 prompt)
  2. 写 akshare_wrappers.py(资金/龙虎榜/概念热度工具)
  3. 改 router.py(增加 hunter 路由分支)
  4. 改 expert_runner.py(ROLE_CONFIG 加 hunter)
  5. 改 strategy.md(增加对短线需求的识别,避免抢活)
  6. 测试验证(用 junjun 的测试消息跑一轮)
  7. 观察 1-2 周,看推荐命中率和用户满意度

本文档已同步保存至 SiYuan 知识库

如需修改或补充,直接在思源里编辑或告知我更新。


十、用户追加四问深度调研结论

调研时间: 2026-05-15
调研范围: router.py / expert_runner.py / strategy.md / real_tools.py / daily-stock-analysis 全项目


10.1 时间感知问题:专家是”瞎子”,不知道今天几号

问题复现

专家说”5月16日继续涨”,但5月16日是周六休市。这种低级错误直接摧毁用户信任。

根因定位(三层断层)

第一层 — OpenClaw 有时间但不传:
OpenClaw 运行时上下文明文带有时间戳,如 "timestamp": "Thu 2026-05-14 05:20 UTC"​。但 router.py 的 _build_child_env() 环境变量白名单里没有任何时间相关字段,时间信息被完全丢弃。

第二层 — expert_runner.py 有占位符但不替换:
strategy.md prompt 里有 "分析时间:{YYYY-MM-DD HH:MM}" 占位符,但 expert_runner.py 加载 prompt 后没有做任何变量替换,模型拿到的是纯文本占位符。

第三层 — 模型没有交易日历概念:
即使知道今天是5月14日周四,模型也不知道5月16日是周六、A股休市。模型的时间知识来自预训练数据,可能滞后,也无法感知实时节假日安排。

修复方案(分三级)

P0 — 传真实时间:
router.py 的 _build_child_env()​ 增加 "FT_CURRENT_TIME": datetime.now().isoformat()​,expert_runner.py 在加载 prompt 前用 datetime.now().strftime("%Y-%m-%d %H:%M")​ 替换 {YYYY-MM-DD HH:MM} 占位符。

P1 — 加交易日历校验:
新增 get_trade_calendar()​ 工具,调用 akshare.tool_trade_date_hist_sina() 获取官方交易日历。当用户提到”明天”“下周”等时间词时,先校验目标日期是否为交易日,如果不是则明确告知”X月X日为周末/节假日,A股休市”。

P2 — 开盘后时间感:
在 prompt 里注入当前时段信息(如”当前为周四下午盘 14:30,距收盘还有90分钟”),让专家在推荐”今天买入”时能判断是否还有交易时间。

代码改动点

文件: router.py​,在 _build_child_env()​ 里加一行:"FT_CURRENT_TIME": datetime.now(ZoneInfo("Asia/Shanghai")).isoformat()

文件: expert_runner.py​,在加载 prompt 后加替换逻辑:prompt = prompt.replace("{YYYY-MM-DD HH:MM}", datetime.now().strftime("%Y-%m-%d %H:%M"))

文件: tools/real_tools.py​,新增工具:get_trade_calendar(date_str: str) -> str,返回该日期是否为交易日、前一个交易日、后一个交易日。


10.2 数据来源现状:只有基础行情,缺短线灵魂数据

当前已有工具清单(real_tools.py,共801行)

get_stock_spot:新浪 + 腾讯实时行情,覆盖最新价、涨跌幅、PE、PB、换手率。

get_stock_history:akshare 历史K线优先,sina fallback,覆盖60-120天日线。

get_stock_news:r.jina.ai 新闻聚合 + 新浪搜索 + 巨潮公告,覆盖近期新闻催化。

calculate_technical:pandas_ta 本地计算,覆盖 MACD、RSI、布林带、均线系统。

read/write_portfolio​ + check_risk_limits:本地 JSON 持仓管理,按 caller 隔离。

save_to_siyuan:报告存储到知识库。

缺失的短线关键数据

这些数据是 hunter 角色做短线推荐的核心依据,当前全部缺失:

板块资金流向 — 判断热点轮动、资金主攻方向。没有它, hunter 不知道哪个板块在吸金。

龙虎榜数据 — 看机构/游资动向,识别强庄。没有它, hunter 不知道谁在拉盘。

北向资金实时流入 — 外资风向直接影响A股情绪。没有它, hunter 看不到外资态度。

融资融券余额变化 — 杠杆资金态度。没有它, hunter 不知道市场在加杠杆还是去杠杆。

涨停池/炸板率 — 市场情绪温度计。没有它, hunter 不知道市场情绪是亢奋还是恐慌。

概念题材热度排名 — 判断题材持续性。没有 it, hunter 不知道热点能火多久。

结论:没有这些数据,hunter 角色即使加了 prompt 也是”盲人摸象”,推荐质量不会比现有 strategy 好多少。


10.3 daily-stock-analysis 联动:系统里已有一个更强大的”外挂”没接

重大发现

系统里存在一个完整的开源股票分析系统:/opt/vendor/daily-stock-analysis/(GitHub: ZhuLinsen/daily_stock_analysis)。目前完全独立运行,和 financial-team 零联动。

它的能力远超 financial-team

数据源层面:daily-stock-analysis 支持 TickFlow、Tushare、Pytdx、Baostock、YFinance、Longbridge 等10+数据源,且有自动 fallback 机制;financial-team 只有新浪+腾讯+akshare。

策略系统层面:daily-stock-analysis 内置11种策略(缠论、波浪、情绪周期、龙头战法、均线金叉等);financial-team 没有任何策略框架,纯靠 prompt 驱动。

新闻搜索层面:daily-stock-analysis 支持 Anspire、SerpAPI、Tavily、Bocha、Brave、MiniMax 等6种搜索;financial-team 只有 r.jina.ai + 新浪。

推送渠道层面:daily-stock-analysis 支持企业微信、飞书、TG、Discord、Slack、邮件;financial-team 只有 Matrix。

Agent问股层面:daily-stock-analysis 支持多轮策略问答、WebUI、FastAPI 服务;financial-team 只有单轮专家分析。

回测验证层面:daily-stock-analysis 支持对历史分析做事后验证;financial-team 没有任何回测能力。

联动方案

hunter 专家不要从零造轮子,直接调用 daily-stock-analysis 的 FastAPI 服务(端口8000,已有 analyzer_service.py 封装)。

具体做法:在 tools/real_tools.py​ 中新增 call_dsa_analyze(stock_code: str)​ 工具,向 http://localhost:8000/api/v1/analysis/single 发送请求,获取决策仪表盘、评分、买卖点位、风险警报等结构化数据,然后由 hunter 做二次解读和推荐。

已有接口验证:daily-stock-analysis 的 run_junjun.py​ 已经实现了读取 junjun 持仓并调用 analyze_stocks() 的分析脚本,证明技术上是可行的。


10.4 数据隔离:新增 hunter 不影响用户间隔离

隔离机制

router.py 通过 --caller​ 参数注入 FT_CALLER 环境变量。

memory_manager.py 按 shared/users/<caller>/ 物理目录隔离。

验证结果:junjun 目录下 portfolio.json 9.6K、历史记录 30K、研究/策略/风控报告齐全;ywz 目录下 portfolio.json 400 bytes、历史记录 6.4K。数据确实完全隔离。

结论:新增 hunter 角色只是 router 的 EXPERT_ROLES 字典里加一行,caller 不变,隔离逻辑完全不受影响。


10.5 daily-stock-analysis 第三方依赖风险评估

用户核心担忧:这个工具是否依赖别人提供服务,有没有可能有一天就用不了了?

数据源分层分析

daily-stock-analysis 设计了多层 fallback 架构,不是单点依赖:

免费数据源(不依赖任何 API Key,不会被封):
akshare_fetcher — 东方财富公开接口,完全免费,无配额限制,代码已内置在项目中。
efinance_fetcher — 东方财富接口,完全免费,无配额限制。
baostock_fetcher — 完全免费,无配额限制。
pytdx_fetcher — 通达信本地协议,完全免费。
yfinance_fetcher — Yahoo Finance,免费但受网络环境影响。

免费但有额度限制的数据源:
tushare_fetcher — 有免费配额(80次/分钟),超额需付费。但即使 tushare 停了,前面5个免费数据源可以兜底。

付费数据源(可选,不是必须):
tickflow_fetcher — 付费实时行情,配置即生效,不配置不影响核心功能。
longbridge_fetcher — 付费港股/美股行情,不配置不影响A股分析。

新闻搜索依赖(这是真正的风险点)

daily-stock-analysis 的新闻搜索依赖外部 API:Anspire、SerpAPI、Tavily、Bocha、Brave、MiniMax。这些全是第三方付费或免费额度服务,确实可能有一天被封或涨价。

但 news 对 hunter 的短线推荐不是核心——短线看的是资金流向和技术形态,新闻只是辅助。即使所有新闻 API 全挂,akshare + efinance + baostock + pytdx 依然能提供完整的行情、K线、板块排名、资金流向等核心数据。

LLM 分析依赖(这是最大风险点)

daily-stock-analysis 的决策仪表盘、评分、买卖点位推荐,全部依赖 LLM API(DeepSeek / Gemini / Claude / OpenAI / Anspire 等)。

这是不可回避的依赖:没有 LLM,它只能输出原始数据,无法做”智能分析”。但 financial-team 本身也依赖 LLM(DEEPSEEK_API_KEY),两者风险相同。

唯一缓解措施:Gemini 有免费额度,可作为低成本兜底。

风险评估总结

数据获取层面:低风险。60%以上的核心数据源完全免费且无需 API Key,多层 fallback 确保单点故障不影响整体。

新闻搜索层面:中风险。依赖多个第三方搜索 API,但新闻不是 hunter 的核心输入,即使全挂也能降级为纯技术面分析。

LLM 分析层面:高风险。和 financial-team 一样,完全依赖外部 LLM API。这是行业通病,没有自托管大模型就无法完全独立。

建议:把 daily-stock-analysis 作为 hunter 的数据源补充(调用它的原始数据接口),而不是完全替代 financial-team 的 LLM 分析流程。这样即使 daily-stock-analysis 的某个模块挂了,financial-team 自己的 LLM + 基础工具链还能兜底。