Files
MoFin/docs/market-screening-pipeline.md
T

383 lines
14 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.
# 全市场潜力股筛选 - LLM调用流程与提示词文档
## 概述
本流程在收盘后(16:00)通过一个 LLM cron(市场精选推荐-每日)一次性完成。全程只有一个 LLM 入口:**我(知微,deepseek-v4-flash** 根据 cron prompt 的指令逐步执行。
数据采集层(market_watch.py)为 no_agent 脚本,不调 LLM,只拉 API 写数据库。
---
## 一、数据源准备(15:30no_agent,不调LLM
### market_watch.py
对 A 股 90 个行业板块逐个拉取同花顺(akshare)数据,写入 `mofin.db` 两张表:
**market_snapshots**(每次采集一条):
- timestamp(采集时间)
- sourceths/eastmoney
- up_ratio(上涨板块占比%
- moodbullish/neutral/bearish
**sector_snapshots**(每条记录一个板块):
- snapshot_id ← 关联 market_snapshots.id
- name(板块名,如"半导体"
- change_pct(涨跌幅%
- up_count / down_count(涨跌家数)
- net_inflow(资金净流入亿)
- lead_stock / lead_stock_change(领涨股)
**兼容说明**`source=eastmoney` 时原始 change 是万分比(如 596 = 5.96%),需 ÷100`source=ths` 时已是百分比。
---
## 二、LLM 入口
### 2.1 定时触发
```
cron 任务: 市场精选推荐-每日
job_id: 759064f56c03
时间: 0 16 * * 1-5(交易日16:00
模型: deepseek-v4-flash
Tools: terminal, file, web, search
```
### 2.2 完整 Prompt
以下为 cron prompt 的完整内容(2026-06-20 更新,SQLite 版):
```
## 任务:每日全市场潜力股精选 + 星级推荐
收盘后执行。全部通过 mofin.db SQLite 读数据。
### 第1步:读数据
运行以下SQL获取数据:
```
sqlite3 /home/hmo/MoFin/data/mofin.db "SELECT ms.timestamp, ms.up_ratio, ms.mood, ss.name, ss.change_pct, ss.up_count, ss.down_count, ss.net_inflow, ss.lead_stock, ss.lead_stock_change FROM market_snapshots ms JOIN sector_snapshots ss ON ms.id=ss.snapshot_id WHERE ms.id=(SELECT MAX(id) FROM market_snapshots) ORDER BY ABS(ss.change_pct) DESC"
```
```
sqlite3 /home/hmo/MoFin/data/mofin.db "SELECT c.code, c.name, c.sector, c.reason, c.entry_range, c.stop_loss, c.target, c.zhiwei_star, c.promoted, c.dropped, (SELECT score FROM candidate_score_history WHERE code=c.code ORDER BY created_at DESC LIMIT 1) as latest_score FROM candidates c ORDER BY c.zhiwei_star DESC NULLS LAST"
```
### 第2步:全市场分析
用板块数据分析:
- 市场情绪(涨跌比、mood字段)
- 领涨行业(涨幅前5,看涨跌家数比、资金流入)
- 领跌行业(跌幅前3
- 判断哪些板块是真趋势、哪些是一日游
### 第3步:筛选潜力股
从领涨行业中基于你对A股的了解,选出2-3只候选股。
用腾讯API查实时价:`curl -s --noproxy '*' "http://qt.gtimg.cn/q=sh{code}"` 或 `sz{code}`
每只给:评分1-10、推荐理由、入场区间、止损价、目标价
### 第4步:更新候选池
将本次结果与candidates表合并:
- 新候选 → INSERT(最新评分写入candidate_score_history
- 已有候选 → INSERT新的评分记录到candidate_score_history
- 连续3次评分下降 → candidates.trend_warning=true
- 平均分<5或7天未更新 → candidates.dropped=true
### 第5步:出推荐
从candidates中选最佳(未淘汰、未推荐过、最新评分>=7):
- 给星级写入candidates.zhiwei_star
- candidates.promoted=true
### 输出格式
最终回复三段式推送给老爸:
【📊 今日市场】判断/热门行业/风险行业
【⚡ 潜力股推荐】股票名(代码) ★星级 | 入场X~X | 止损X | 目标X | 理由
【📋 候选池状态】活跃X只,今日新增X只,已推荐X只
禁止:可关注、可考虑、建议观察、试试、谨慎关注、择机
```
---
## 三、执行细节
### 3.1 LLM 工具调用序列
| 顺序 | 工具 | 用途 |
|------|------|------|
| 1 | terminal sqlite3 | 查 mofin.db 获取板块快照 |
| 2 | terminal sqlite3 | 查 mofin.db 获取候选池 |
| 3 | terminal curl 腾讯API | 验证候选股实时价格 |
| 4 | terminal sqlite3 | INSERT INTO candidate_score_history |
| 5 | terminal sqlite3 | UPDATE candidates SET zhiwei_star/promoted |
| 6 | 最终回复 | 输出三段式报告 |
### 3.2 腾讯API调用示例
```bash
# 沪市股票
curl -s --noproxy '*' "http://qt.gtimg.cn/q=sh688981"
# 返回: v_sh688981="1~中芯国际~688981~140.50~..."
# 字段[3]=当前价, 字段[32]=涨跌幅
# 深市股票
curl -s --noproxy '*' "http://qt.gtimg.cn/q=sz002371"
```
### 3.3 候选池治理规则
由 LLM 执行时自行判断:
- 候选评分连续 3 次下降 → candidates.trend_warning=true
- 近 3 次平均分 < 5 → candidates.dropped=true
- 距上次更新超过 7 天 → candidates.dropped=true
- dropped 的候选保留在池中供追溯,不再参与推荐
---
## 四、实时信号检测与小果情报处理(新增)
### 4.1 概述
在每10分的 market_watch 数据采集之外,增加一条实时信号处理链路:
```
market_watch(每10分)→ mofin.db
trend_detectorno_agent,每10分)
│ SQL扫最新 snapshots → 发现异常信号
│ 定位领涨股/成分股/持仓股/自选股
│ 写入 sector_signals
小果情报处理(no_agent,每10分)
│ 读未处理 signals
│ curl 搜新闻(板块+个股+持仓+自选)
│ 调本地 LLM 逐篇分析情感
│ 写入 signal_news
知微(盘中即时 + 收盘汇总)
│ 读 signal_news → 判断真伪
│ 紧急利空 → 盘中推老爸
│ 确认利好 → 更新 candidates
│ 16:00 → 整合到每日推荐
```
### 4.2 trend_detector — 信号检测规则
完整信号体系,按检测维度分5类共17种信号:
**A. 资金流信号**
| 信号 | 逻辑 | 严重性 |
|------|------|--------|
| A1 资金异动 | 单次净流入/出 > 近10次均值 + 3σ | high(>5σ) / medium(3-5σ) |
| A2 持续资金流入 | 同一板块连续≥3次净流入且逐次递增 | low |
| A3 持续资金流出 | 同一板块连续≥3次净流出且逐次扩大 | low |
| A4 资金转向 | 净流入从正转负或负转正,方向切换 | medium |
**B. 涨跌结构信号**
| 信号 | 逻辑 | 严重性 |
|------|------|--------|
| B1 涨跌比反转 | 上涨占比变化 > 30个百分点(如30%→70% | medium |
| B2 持续走强 | 连续≥3次采集涨幅排全市场前10 | low |
| B3 持续走弱 | 连续≥3次采集跌幅排全市场前10 | low |
| B4 普涨背离 | 板块涨幅 > 3% 但上涨家数 < 50% | medium |
| B5 极端分化 | 板块内上涨/下跌家数比 > 5:1 或 < 1:5 | medium |
**C. 领涨/成分股信号**
| 信号 | 逻辑 | 严重性 |
|------|------|--------|
| C1 领涨股更替 | 领涨股与前2次采集不同(换龙头了) | medium |
| C2 领涨股极端涨幅 | 领涨股单次涨跌幅 > 15%(消息驱动) | medium |
**D. 趋势拐点信号**
| 信号 | 逻辑 | 严重性 |
|------|------|--------|
| D1 趋势反转(多→空) | 连续≥3次净流入后突然转净流出 | high |
| D2 趋势反转(空→多) | 连续≥3次净流出后突然转净流入(吸筹) | high |
| D3 量价背离(涨) | 板块涨 > 2% 但资金净流出 > 均值2倍 | medium |
| D4 量价背离(跌) | 板块跌 > 2% 但资金净流入 > 均值2倍(埋伏) | medium |
**E. 关联信号**
| 信号 | 逻辑 | 严重性 |
|------|------|--------|
| E1 板块轮动 | 前3强势板块集体换血(前次TOP3全部跌出前10) | medium |
| E2 产业链联动 | 同产业链多个板块同时触发A/B/D类信号 | low |
| E3 持仓关联 | 持仓股所在板块触发任何 high 信号 | high |
检测到信号后,收集以下信息写入 `sector_signals`
- signal_type, sector, severity (high/medium/low)
- related_stocks — 该板块的领涨股+成分股(从 stock_sectors 表查)
- holdings_in_sector — signal 板块中属于持仓的股票(查 holdings 表)
- watchlist_in_sector — signal 板块中属于自选的股票(查 watchlist_stocks 表)
- trigger_reason — 一句话触发原因
### 4.3 小果情报处理流程
trend_detector 完成后的下一步,由小果处理每一条未处理的 signal。
**第1步:搜新闻**
对小果来说,一条 signal 需要搜索的范围:
- 板块层面:搜"板块名 + 行业/政策/走势"
- 领涨股:本次 signal 的领涨股
- related_stocks 中的每一只
- holdings_in_sector 中的每一只(如有持仓股)
- watchlist_in_sector 中的每一只(如有自选股)
搜索方式:curl 调百度/新浪公开新闻源,取标题(不要求全文)。
**第2步:调小果本地 LLM 逐篇分析**
对每篇新闻标题,小果本地 LLM 做:
- 内容摘要(一段话,不限字数)
- 情感分类:利好 / 利空 / 中性
- 判断依据一句话
**第3步:汇总(所有文章处理完后)**
- 总体情感判断
- 一段简短的总结
写入 `signal_news` 表。
**第4步:交知微盘中判断**
signal_news 写入后,知微立即读取:
- severity=high + sentiment=利空 → 盘中即时推送给老爸
- 确认利好信号 → 更新 candidates(加候选或升星级)
- 不确定的 → 标记待观察,累积到16:00汇总
### 4.4 小果 LLM 调用设计
**模型:** Qwen3.6-27B-MTPLX-Optimized-Speed192.168.1.122:18003
- 单次调用约 10-15 秒,无 thinking process 泄漏,直接输出 JSON
- 备用:Qwen3.6-27B-OptiQ-4bit(较慢,约 40-50 秒,输出带 thinking 过程需后处理)
**每次调用内容:**
```
输入:同一 signal 的 3-5 条新闻(标题 + 正文最多前200字)
任务:给每篇完整摘要(不限字数) + 情感(positive/negative/neutral
```
**注意:** MTPLX-Optimized-Speed 直接输出 JSON,无需后处理。备用模型 OptiQ-4bit 会先输出思考过程,JSON 在回复末尾。
**节流规则:**
- 同一板块同一 signal 类型24小时内已有 signal_news 记录 → 跳过
- 每次只处理未 processed 的 signals
- 无未处理 signals → 本轮跳过
### 4.5 新增表结构
```sql
-- 信号表
CREATE TABLE IF NOT EXISTS sector_signals (
id INTEGER PRIMARY KEY AUTOINCREMENT,
signal_type TEXT NOT NULL,
sector TEXT NOT NULL,
severity TEXT DEFAULT 'medium',
related_stocks TEXT, -- JSON [{code, name, change_pct}]
holdings_in_sector TEXT, -- JSON,持仓股
watchlist_in_sector TEXT, -- JSON,自选股
trigger_reason TEXT,
snapshot_id INTEGER, -- 触发的 snapshot
processed INTEGER DEFAULT 0,
detected_at TEXT DEFAULT (datetime('now','localtime'))
);
-- 小果情报表
CREATE TABLE IF NOT EXISTS signal_news (
id INTEGER PRIMARY KEY AUTOINCREMENT,
signal_id INTEGER REFERENCES sector_signals(id),
sector TEXT NOT NULL,
overall_sentiment TEXT,
summary TEXT,
key_articles TEXT, -- JSON [{title, sentiment, summary, reason}]
searched_stocks TEXT, -- JSON,本次搜了哪些股
created_at TEXT DEFAULT (datetime('now','localtime'))
);
```
---
## 五、完整数据流
```
┌────────────────────────────────────────────────────────┐
│ 15:30 数据采集层(no_agent
│ │
│ market_watch.py │
│ → akshare 拉取同花顺90个行业板块 │
│ → INSERT INTO market_snapshots + sector_snapshots │
└──────────────────────┬─────────────────────────────────┘
┌────────────────────────────────────────────────────────┐
│ 16:00 LLM层(deepseek-v4-flash,单次cron调用) │
│ │
│ SELECT mofin.db 板块数据 │
│ → 分析涨跌比 → 市场判断 │
│ → 选热门行业 → 选危险行业 │
│ → 腾讯API查实时价 │
│ → 筛选候选股 │
│ → INSERT评分历史 + UPDATE候选状态 │
│ → 给最终星级 → 输出报告 │
└──────────────────────┬─────────────────────────────────┘
老爸收到三段式报告
```
---
## 六、数据库表结构
### 核心表
| 表 | 用途 | 关键字段 |
|----|------|---------|
| market_snapshots | 每次采集元信息 | id, timestamp, up_ratio, mood |
| sector_snapshots | 板块快照 | snapshot_id, name, change_pct, net_inflow |
| candidates | 候选池 | code, zhiwei_star, promoted, dropped |
| candidate_score_history | 评分变更历史 | code, score, source, created_at |
### 关联查询示例
```sql
-- 最新板块排行
SELECT ss.name, ss.change_pct, ss.net_inflow, ss.up_count, ss.down_count, ss.lead_stock
FROM sector_snapshots ss
JOIN market_snapshots ms ON ss.snapshot_id = ms.id
WHERE ms.id = (SELECT MAX(id) FROM market_snapshots)
ORDER BY ABS(ss.change_pct) DESC;
-- 候选池最新评分
SELECT c.code, c.name, c.sector, c.zhiwei_star, c.promoted,
(SELECT score FROM candidate_score_history
WHERE code = c.code ORDER BY created_at DESC LIMIT 1) as latest_score
FROM candidates c
WHERE c.dropped = 0
ORDER BY c.zhiwei_star DESC NULLS LAST;
```
---
## 七、与其他管道的关系
| 管道 | 时间 | 关系 |
|------|------|------|
| 市场数据采集 (market_watch) | 每10分 | 本管道的唯一数据源 |
| 市场精选推荐 (本管道) | 16:00 | 依赖 market_watch 的最新一次写入 |
| 小果情感分析 | 16:00 | 独立管道,本管道可选参考 |
| 策略评估-每日 | 21:00 | 无关,独立评估持仓策略 |
| 知识萃取 | 16:30 | 本管道的输出可作为输入 |