From 8cef092c748a5b9e0516185b6c1e102a4ad947ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=A5=E5=BE=AE?= Date: Sat, 20 Jun 2026 20:55:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0pipeline=E6=96=87=E6=A1=A3?= =?UTF-8?q?=EF=BC=9AJSON=E2=86=92SQLite?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/market-screening-pipeline.md | 223 ++++++++++++++---------------- 1 file changed, 105 insertions(+), 118 deletions(-) diff --git a/docs/market-screening-pipeline.md b/docs/market-screening-pipeline.md index 7fa6508..2fa2a57 100644 --- a/docs/market-screening-pipeline.md +++ b/docs/market-screening-pipeline.md @@ -4,7 +4,7 @@ 本流程在收盘后(16:00)通过一个 LLM cron(市场精选推荐-每日)一次性完成。全程只有一个 LLM 入口:**我(知微,deepseek-v4-flash)** 根据 cron prompt 的指令逐步执行。 -数据采集层(market_watch.py)为 no_agent 脚本,不调 LLM,只拉 API 写文件。 +数据采集层(market_watch.py)为 no_agent 脚本,不调 LLM,只拉 API 写数据库。 --- @@ -12,34 +12,23 @@ ### market_watch.py -对 A 股 90 个行业板块逐个拉取同花顺(akshare)数据,写入 `market.json`: +对 A 股 90 个行业板块逐个拉取同花顺(akshare)数据,写入 `mofin.db` 两张表: -```json -{ - "timestamp": "2026-06-19 15:30", - "source": "ths", // 数据来源:ths/eastmoney - "total_sectors": 90, - "up_ratio": 27.8, // 上涨板块占比(%) - "mood": "bearish", // bullish/neutral/bearish - "top_gainers": [...], // 涨幅前5 - "top_losers": [...], // 跌幅前3 - "sectors": [ - { - "name": "半导体", // 板块名称 - "change": 2.29, // 涨跌幅(%) - "up_count": 131, // 上涨家数 - "down_count": 46, // 下跌家数 - "net_inflow": 120.97, // 资金净流入(亿) - "lead_stock": "晶升股份", // 领涨股名 - "lead_stock_change": 20.01 // 领涨股涨跌幅(%) - }, - ... - ], - "insights": [...] // 旧管道残留,可忽略 -} -``` +**market_snapshots**(每次采集一条): +- timestamp(采集时间) +- source(ths/eastmoney) +- up_ratio(上涨板块占比%) +- mood(bullish/neutral/bearish) -注意:`source` 为 `eastmoney` 时,`change` 单位是万分比(如 596 = 5.96%),需除以 100;`source` 为 `ths` 时已是百分比。 +**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` 时已是百分比。 --- @@ -51,93 +40,66 @@ cron 任务: 市场精选推荐-每日 job_id: 759064f56c03 时间: 0 16 * * 1-5(交易日16:00) -模型: deepseek-v4-flash(通过 Hermes gateway,hermes-agent model name) +模型: deepseek-v4-flash Tools: terminal, file, web, search ``` ### 2.2 完整 Prompt -以下为 cron prompt 的完整内容。LLM(即我)按照这个提示一步步执行,每一步的思考过程不对外输出,最终产出是写入数据文件 + 返回报告文本。 +以下为 cron prompt 的完整内容(2026-06-20 更新,SQLite 版): ``` ## 任务:每日全市场潜力股精选 + 星级推荐 -收盘后执行。分三步,每一步都要出具体结果,不能输出模板示例。 +收盘后执行。全部通过 mofin.db SQLite 读数据。 ### 第1步:读数据 -读 /home/hmo/web-dashboard/data/market.json: -- sectors[] — 全行业板块数据(名称、涨跌幅、涨跌家数、资金流入、领涨股) -- source — 数据来源(ths 或 eastmoney,影响涨跌幅单位:ths已是百分比,EM需除以100) +运行以下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" +``` -读 /home/hmo/web-dashboard/data/candidate_pool.json — 历史候选池 +### 第2步:全市场分析 -### 第2步:全市场筛选 +用板块数据分析: +- 市场情绪(涨跌比、mood字段) +- 领涨行业(涨幅前5,看涨跌家数比、资金流入) +- 领跌行业(跌幅前3) +- 判断哪些板块是真趋势、哪些是一日游 -用 market.json 的板块数据做分析: +### 第3步:筛选潜力股 -**2a 市场判断** -分析涨跌比、领涨板块特征,输出一句话判断:强势/中性/弱势 + 理由。 -写入 market.json 的 market_verdict 和 verdict_reason 字段。 +从领涨行业中基于你对A股的了解,选出2-3只候选股。 +用腾讯API查实时价:`curl -s --noproxy '*' "http://qt.gtimg.cn/q=sh{code}"` 或 `sz{code}` -**2b 选热门行业** -从涨幅前10板块中选出2-3个你最看好的行业。 -标准:不只看出涨幅,还要看涨跌家数比(上涨家数远大于下跌家数)、资金流入为正、不是一日游。 -每个行业给一句话理由。 -写入 market.json 的 hot_sectors 字段。 +每只给:评分1-10、推荐理由、入场区间、止损价、目标价 -**2c 选危险行业** -从跌幅前5板块中选出1-2个需回避的行业。 -写入 market.json 的 danger_sectors 字段。 +### 第4步:更新候选池 -**2d 查个股** -对每个热门行业,用腾讯API查该行业知名龙头股的当前价格: -`curl -s --noproxy '*' "http://qt.gtimg.cn/q=sh{代码}"` 或 `sz{代码}` -解析格式:vt_sh代码="1~名称~...~第4字段=当前价~...~第32字段=涨跌幅" -用真实价格辅助判断。 +将本次结果与candidates表合并: +- 新候选 → INSERT(最新评分写入candidate_score_history) +- 已有候选 → INSERT新的评分记录到candidate_score_history +- 连续3次评分下降 → candidates.trend_warning=true +- 平均分<5或7天未更新 → candidates.dropped=true -选2-3只候选股,每只给出: -- 评分 1-10(9-10强趋势+最佳时机;7-8板块向好+安全边际;5-6有逻辑但需等入场) -- 推荐理由一句话 -- 入场区间(具体数字) -- 止损价(具体数字) -- 目标价(具体数字) +### 第5步:出推荐 -### 第3步:更新候选池 + 出推荐 - -将上述结果与 candidate_pool.json 合并: -- 新的候选股 → 新增(xiaoguo_score填评分,num_observations=1) -- 已有候选 → 更新评分,追加评分历史,num_observations+1 -- 连续3次评分下降 → trend_warning=true -- 平均分<5或7天未更新 → dropped=true - -从候选池中选出最佳推荐(满足:未淘汰、未推荐过、评分>=7): -- 用你的知识做最终验证 -- 给星级:5.0/4.5/4.0/3.5/3.0 -- 写入 zhiwei_star、zhiwei_reviewed=true -- promoted=true +从candidates中选最佳(未淘汰、未推荐过、最新评分>=7): +- 给星级写入candidates.zhiwei_star +- candidates.promoted=true ### 输出格式 -最终回复必须包含以下内容,直接发给老爸: +最终回复三段式推送给老爸: +【📊 今日市场】判断/热门行业/风险行业 +【⚡ 潜力股推荐】股票名(代码) ★星级 | 入场X~X | 止损X | 目标X | 理由 +【📋 候选池状态】活跃X只,今日新增X只,已推荐X只 -【📊 今日市场】 -判断:强势/中性/弱 — 一句话理由 -热门行业:xxx(理由)、xxx(理由) -风险行业:xxx(理由) - -【⚡ 潜力股推荐】 -按星级排序,每只格式: -股票名(代码) ★星级 | 所属板块 -入场区间 X~X | 止损 X | 目标 X -理由:一句话 - -【📋 候选池状态】 -活跃X只,今日新增X只,已推荐X只,淘汰X只 - -没有符合条件的就说"今日无符合条件的新标的"。 - -禁止使用:可关注、可考虑、建议观察、试试、谨慎关注、择机 +禁止:可关注、可考虑、建议观察、试试、谨慎关注、择机 ``` --- @@ -146,17 +108,14 @@ Tools: terminal, file, web, search ### 3.1 LLM 工具调用序列 -在实际执行中,LLM 会依次调用以下工具: - | 顺序 | 工具 | 用途 | |------|------|------| -| 1 | read_file market.json | 读板块数据 | -| 2 | read_file candidate_pool.json | 读历史候选池 | -| 3 | read_file xiaoguo_insights.json | 读当日情感(可选) | -| 4 | terminal curl 腾讯API | 验证候选股实时价格(每只一次) | -| 5 | write_file candidate_pool.json | 写回更新后的候选池 | -| 6 | write_file market.json | 写回 market_verdict/hot_sectors 等 | -| 7 | 最终回复 | 输出报告文本 | +| 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调用示例 @@ -170,12 +129,12 @@ curl -s --noproxy '*' "http://qt.gtimg.cn/q=sh688981" curl -s --noproxy '*' "http://qt.gtimg.cn/q=sz002371" ``` -### 3.3 候选池治理规则(硬编码在 LLM 指令中) +### 3.3 候选池治理规则 -由 LLM 在执行第3步时自行判断: -- 候选评分连续 3 次下降 → trend_warning=true -- 近 3 次平均分 < 5 → dropped=true -- 距上次更新超过 7 天 → dropped=true +由 LLM 执行时自行判断: +- 候选评分连续 3 次下降 → candidates.trend_warning=true +- 近 3 次平均分 < 5 → candidates.dropped=true +- 距上次更新超过 7 天 → candidates.dropped=true - dropped 的候选保留在池中供追溯,不再参与推荐 --- @@ -188,23 +147,19 @@ curl -s --noproxy '*' "http://qt.gtimg.cn/q=sz002371" │ │ │ market_watch.py │ │ → akshare 拉取同花顺90个行业板块 │ -│ → 写入 /data/market.json │ +│ → INSERT INTO market_snapshots + sector_snapshots │ └──────────────────────┬─────────────────────────────────┘ │ ▼ ┌────────────────────────────────────────────────────────┐ │ 16:00 LLM层(deepseek-v4-flash,单次cron调用) │ │ │ -│ 读 market.json │ -│ → 分析涨跌比 → market_verdict │ -│ → 选热门行业 → hot_sectors │ -│ → 选危险行业 → danger_sectors │ -│ → 写回 market.json │ -│ │ -│ 读 candidate_pool.json │ -│ → 腾讯API查实时价 → 验证候选 │ -│ → 合并新候选、更新评分、淘汰劣质 │ -│ → 写回 candidate_pool.json │ +│ SELECT mofin.db 板块数据 │ +│ → 分析涨跌比 → 市场判断 │ +│ → 选热门行业 → 选危险行业 │ +│ → 腾讯API查实时价 │ +│ → 筛选候选股 │ +│ → INSERT评分历史 + UPDATE候选状态 │ │ → 给最终星级 → 输出报告 │ └──────────────────────┬─────────────────────────────────┘ │ @@ -214,12 +169,44 @@ curl -s --noproxy '*' "http://qt.gtimg.cn/q=sz002371" --- -## 五、与其他管道的关系 +## 五、数据库表结构 + +### 核心表 + +| 表 | 用途 | 关键字段 | +|----|------|---------| +| 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) | 每30分 | 本管道的唯一数据源 | | 市场精选推荐 (本管道) | 16:00 | 依赖 market_watch 的最新一次写入 | -| 小果情感分析 | 16:00 | 独立管道,结果写入 xiaoguo_insights.json,本管道可选读取 | -| 策略评估-每日 | 21:00 | 与本管道无关,独立评估持仓策略 | -| 知识萃取 | 16:30 | 本管道的输出可作为知识萃取的输入 | +| 小果情感分析 | 16:00 | 独立管道,本管道可选参考 | +| 策略评估-每日 | 21:00 | 无关,独立评估持仓策略 | +| 知识萃取 | 16:30 | 本管道的输出可作为输入 |