news-sentiment-research
GitHub基于42万篇新闻数据,利用FinBERT与词典进行情绪分析,结合事件研究与回测引擎,挖掘新闻情绪对股价的影响规律并优化交易策略,输出研报。
Trigger Scenarios
Install
npx skills add qusong0627/QuantMind --skill news-sentiment-research -g -y
SKILL.md
Frontmatter
{
"name": "news-sentiment-research",
"description": "新闻情绪研究方法论 — Huntly RSS 42万篇历史新闻 → FinBERT+词典双引擎情绪 → 事件研究\/来源预测力\/时段特征\/信号强度\/首日动量\/情绪反转\/事件标签 七维深度分析 → 融合规律优化策略回测(来源白名单+时段过滤+多篇确认+首日动量+反转出场+连续\/标签加成+无止损+动态止盈)→ 研报级 MD+PDF。用户说「新闻情绪」「新闻规律」「新闻策略」「情绪回测」「消息面研究」时使用。触发词:新闻情绪、新闻规律、情绪分析、消息面、新闻回测、情绪策略"
}
⚙️ 运行环境契约(最高优先级,先于本文其余内容执行)
本技能可能运行在 QuantBot(QwenPaw 容器) 或宿主机/本地 Claude Code。执行前先探测环境(
which docker、API 连通性),并遵守以下映射规则:
- 后端 API 地址:QwenPaw / 容器网络内一律用
http://quantmind:8000(quantmind是 docker 网络别名);仅宿主机调试用http://127.0.0.1:8000。正文中出现的127.0.0.1:8000、localhost:800x,在 QwenPaw 环境下自动替换为http://quantmind:8000。- 取数脚本执行:凡 import 了
pandas / duckdb / psycopg2 / numpy / sqlalchemy等重依赖或backend包的脚本,必须在 quantmind 容器内执行(QwenPaw 本地 venv 无这些依赖):脚本源三选一:宿主机 repodocker cp <脚本路径> quantmind:/tmp/<脚本名> && docker exec -w /app quantmind python3 /tmp/<脚本名> <参数>skills/<name>/scripts/、QwenPaw 工作区/app/working/workspaces/default/skills/<name>/scripts/、挂载目录/quantmind/skills/<name>/scripts/。纯标准库脚本(无重依赖)可在 QwenPaw 本地直接跑。- 报告落盘:股票报告页可见的 MD/PDF 报告,直接写
/data/reports/trading_agents/{市场或类别}/{股票名}/(QwenPaw 对/app/db有写权限,直接写文件,不要 docker cp);过程数据 facts 写/data/reports/<类别>/(/data可写)。- MD → PDF 转换(按优先级降级): ①
docker exec -w /app quantmind python3 backend/scripts/md_to_pdf_report.py <输入.md> <输出.pdf>(研报级排版,首选); ② docker 不可用时,改用 QwenPaw 内置- 本文中的
~/.claude、cp -r ... ~/.claude/skills等说明仅适用于本地 Claude Code 维护者,QuantBot 不要执行。
news-sentiment-research — 新闻情绪研究方法论
把「RSS 新闻 → 情绪信号 → 交易规律」的完整研究管线沉淀为一套可复现、可升级的流程。核心成果(2026-08-20 实测):
- 51,741 个有效事件、5,661 只股票、98 个交易日的完整研究
- 最优策略:+84.34% / Calmar 7.76(无止损 + 四重过滤 + 动态止盈)
- 动态止盈 100% 胜率是唯一利润引擎;固定止损 100% 亏损
- 来源预测力跨度 8.66pp(财联社 +5.26% vs 南华早报 -3.40%)
数据链路
Huntly SQLite /data/huntly/db.sqlite (423,848 篇)
└─ page.connected_at = Asia/Shanghai 本地时间字符串(陷阱:无 tzinfo,需手动 replace)
▼
PostgreSQL news_article_enrichment 富集
└─ huntly_page_id, tickers[] (后缀 600036.SH), sentiment_label, sentiment_score,
event_tags[], industries[]
└─ 情绪 = FinBERT (0.6) + 金融词典 51,887 词 (0.4) 融合
▼
信号生成 |score| ≥ 0.25
└─ 时间对齐: 盘中(9:30-11:30/13:00-15:00)→当日收盘成交;盘后/盘前/非交易日→下一交易日
▼
QuantDB 前复权日K线 data/quantdb/1_kline_data/daily_forward/dt=YYYYMMDD/data.parquet
└─ compute_limits 涨跌停 / T+1 / ST 剔除 / 停牌顺延
▼
回测引擎 → 研报 MD → md_to_pdf_report.py → PDF → 落盘股票报告目录
⚠️ 核心陷阱(每个都实测踩过)
| 陷阱 | 正确做法 |
|---|---|
Huntly connected_at 是上海本地时间字符串 |
datetime.strptime(s, "%Y-%m-%d %H:%M:%S.%f").replace(tzinfo=SHANGHAI_TZ),不能用 UTC |
| 做空权益计算 | equity = cash + (cost - close) * shares,不是 cash - close * shares(曾因算错虚增 +516%) |
| 做空现金流 | 开仓 加 现金(收钱),平仓 减 现金(买回);与做多相反 |
| 回测循环必须遍历所有交易日 | 只遍历信号日会漏掉持仓的每日止损/止盈检查(持仓 30+ 天无检查的 bug) |
| 消息日期需对齐交易日历 | 用 bisect 找下一交易日;盘中消息才当天成交 |
| 同股同日多篇文章 | 取绝对分值最高的一篇作为当日信号 |
| 回测期市场环境 | 2026-03~08 是下行/震荡市,T+15 后大盘 beta 主导,情绪效应 15 天内耗尽 |
执行流程
第 1 步:事件研究(消息出来后股价怎么走?)
docker exec quantmind python3 /app/scripts/backtest_news_event_study.py
输出:利好/利空 T+0~T+20 平均累计收益曲线、胜率曲线、板块差异、强/弱信号对比、T+5 收益分布(分位数+盈亏比)。
关键口径:
- 利空预测力 > 利好(强利空 T+5 -2.39% vs 强利好 -0.17%)
- 利好效应 T+1~T+3 最强,T+15 耗尽
- 利好分布右偏(均值 +0.15% / 中位数 -1.05%),少数大牛股拉高均值 → 动态止盈适配
第 2 步:七维深度分析(找规律)
docker exec quantmind python3 /app/scripts/backtest_news_deep_analysis.py
| 维度 | 分析方法 | 实测发现 |
|---|---|---|
| 来源预测力 | 利好T+5 − 利空T+5,按来源分组 | 财联社 +5.26% 最强;南华早报 -3.40% 反向 |
| 时段特征 | 按小时分组利好 T+5 | 21点 +1.27% 黄金;凌晨1-5点 -1~-2% 噪声 |
| 多篇集中 | 单篇 vs 2篇+ vs 3篇+ | 3篇+ 利好 +0.80% = 单篇 2.2 倍 |
| 首日动量 | 消息日涨跌 → 后续 T+5/T+10 | 首日涨>3% 后续 +0.58%;首日跌继续跌 |
| 情绪反转 | 利好→利空 / 利空→利好 反转后走势 | 利好→利空反转 T+20 -6.23%,有效出场信号 |
| 事件标签 | 按 event_tags 分组 T+5 | 警示函利好+9.99%(样本小慎用);监管利空 -2.67% 真实 |
| 连续信号 | 同股连续 1/2/3 天同向 | 连续3天 T+10 +0.63%,唯一全正组合 |
第 3 步:优化策略回测(融合规律)
docker exec quantmind python3 /app/scripts/backtest_news_optimized.py
优化开关(scripts/backtest_news_optimized.py 顶部,可独立控制每个优化项做消融实验):
ENABLE_SOURCE_FILTER = True # 来源白/黑名单
ENABLE_TIME_FILTER = True # 时段过滤
ENABLE_MULTI_CONFIRM = True # 多篇确认 ≥2 篇同向
ENABLE_MOMENTUM_FILTER = True # 首日动量(利好+涨/利空+跌才入场)
ENABLE_REVERSAL_EXIT = True # 情绪反转出场
ENABLE_CONSECUTIVE_BOOST = True # 连续3天同向 → 仓位 1.5x
ENABLE_TAG_BOOST = True # 事件标签 → 仓位 1.3-1.5x
参数寻优结论(5 版本实测):
| 版本 | 止损 | 过滤 | 收益 | Calmar |
|---|---|---|---|---|
| v1 严格 | 15% | 全开 | +57.80% | 5.93 |
| v2 放宽 | 20% | 关多篇/动量 | +31.41% | 1.69 |
| v3 最终 | 禁用 | 全开 | +84.34% | 7.76 |
| v4 中档 | 25% | 全开 | +39.72% | 4.17 |
| v5 激进止盈 | 禁用 | 全开 | +75.65% | 6.70 |
铁律:
- 禁用固定止损——所有版本止损出场 0% 胜率,新闻行情「先洗盘再拉升」
- 动态止盈是唯一引擎——盈利>15% 激活、回撤 5% 出场,100% 胜率
- 多篇确认+首日动量贡献 53pp 收益——关掉后 84%→31%
- 止盈不能太敏感——激活 10%/回撤 3% 反而不如 15%/5%(+75.7% vs +84.3%)
- 到期浮盈续持,浮亏照离场(P0 结论)——到期时赚钱的仓位继续持有到动态止盈兑现,亏钱的照常 20 天离场;数据上是 +105.35% vs 基线的 +54.70%,Calmar 12.76 vs 6.15(同数据快照)
第 4 步:研报生成与落盘
# 1) 手工撰写或脚本生成 MD(模板见 docs/news_sentiment_deep_report.md)
# 2) 容器内转 PDF(研报排版:深蓝封面+金色双线+斑马纹+红涨绿跌)
docker exec quantmind python3 /app/backend/scripts/md_to_pdf_report.py /tmp/report.md /tmp/report.pdf
# 3) 落盘前端可见目录(必做,只发 /tmp = 未交付)
docker cp report.md quantmind:/data/reports/trading_agents/每日复盘/新闻情绪研究报告_$(date +%F).md
docker cp report.pdf quantmind:/data/reports/trading_agents/每日复盘/新闻情绪研究报告_$(date +%F).pdf
报告标准结构(13 章):数据基础 → 事件研究 → 来源特征 → 时间特征 → 信号强度 → 价格行为 → 事件标签 → 策略回测(含 P0 升级 v6/hw40)→ 极端案例 → 规律清单 → 风险局限 → 结论 → 单股深度分析应用手册。模板:docs/news_sentiment_deep_report.md(2026-08-21 升华版)。
第 5 步:单股新闻面三步纵深(stock-market-analysis 的 L7 层)
用户对单只股票做深度分析时,把本技能 21 条规律退化为「三步纵深」(详见
docs/news_sentiment_deep_report.md§13)。这不是本技能的完整回测流程,而是统计规律在单股的落地。
① 直接消息判定 —— 窗口 [T-2, T] 内 Huntly 库标题 + 正文搜 {股票名}/{code}:
- 命中 → 来源(白名单财政联/同花顺?黑名单南华/彭博?)、时段(19-22 黄金?凌晨噪声)、多篇(≥2 同向→×2.2)、当天涨跌(首日动量双确认)
- 零命中 → 明确写「个股近期无直接催化」,禁止用行业新闻冒充个股消息
② 相关行业归类 —— 标题含行业词(超级电容/薄膜电容/电力设备等)的新闻按板块定性:
- 利好共振源(同行量产/业绩预增)vs 利空分化源(同行亏损/行业竞争叙事),写清"间接、板块级"
③ 21 条规律对照打分 —— 按来源/时段/多篇/首日动量/反转/标签/板块逐条对位,输出明确新闻面结论(不许含混)。再与 L2 微观结构截面交叉(见 [[quantdb-full-analysis-design]] L4b):
| 新闻 × L2 组合 | 含义 | 操作含义 |
|---|---|---|
| 直接利空新闻 + L2 负IC族高位 | 事件驱动+盘面确认 | 强利空,回避/做空候选 |
| 无消息 + L2 缩量阴跌(大单流出收敛、买盘弱) | 资金惯性下行、无催化剂 | 左侧末段,勿接飞刀 |
| 直接利好 + L2 正IC族扩散(vpin_vol_ratio↑/informed↑) | 消息+知情资金共振 | 高置信做多候选 |
| 有利好但 L2 正IC族低位(无资金跟进) | 假利好 | 一日游,不追 |
| 无消息 + L2 vpin_vol_ratio 率先恢复 | 反转前兆 | 观察确认,等第二信号 |
(阈值:L2 负IC因子≥70% 分位 + 正IC因子≤40% = 负面组合;反之为正面组合。)
已验证的 21 条规律清单
| # | 规律 | 强度 | 落地方式 |
|---|---|---|---|
| 1 | 财联社电报利空 → T+5 -6.57% | ★5 | 做空信号金矿 |
| 2 | 同花顺实时利好 → T+5 +5.19% | ★5 | 做多信号金矿 |
| 3 | 动态止盈(>15%激活/回撤5%)100% 胜率 | ★5 | 核心出场机制 |
| 4 | 固定止损 100% 亏损 | ★5 | 禁用固定止损 |
| 5 | 多篇(≥2)同向报道 → 信号强度 2.2x | ★4 | 入场过滤器 |
| 6 | 首日动量双确认 | ★4 | 入场过滤器 |
| 7 | 21点晚间消息利好 T+5 +1.27% | ★4 | 时段加权 |
| 8 | 凌晨 1-5 点消息为噪声 | ★4 | 时段过滤 |
| 9 | 强利空(≤-0.6)T+5 -2.39% | ★4 | 做空分值加权 |
| 10 | 连续 3 天同向信号 T+10 +0.63% | ★4 | 仓位加成 1.5x |
| 11 | 利好→利空反转 T+20 -6.23% | ★4 | 反转出场 |
| 12 | 沪主板利好 T+5 +0.49%(板块最优) | ★3 | 板块加权 |
| 13 | 深主板利空 T+5 -3.56%(做空首选) | ★3 | 做空选股 |
| 14 | 监管/立案调查利空真实有效 | ★3 | 事件标签加权 |
| 15 | 业绩预告/净利润增长利好有效 | ★3 | 事件标签加权 |
| 16 | 利好效应 T+3 内最强、T+15 耗尽 | ★3 | 持仓周期设计 |
| 17 | 南华早报/创业邦/彭博为反向指标 | ★3 | 黑名单 |
| 18 | 创业板利空无效(T+5 +0.67%) | ★3 | 禁止做空创业板 |
升级路线图(按优先级)
P0:消除到期亏损 ✅ 已完成(2026-08-20)
25 笔 max_hold 出场贡献全部净亏损。实验了三条路线(9 个变体):
| 路线 | 变体 | 结果 | 结论 |
|---|---|---|---|
| 缩短持仓 | mh15 / mh10 | +56.6% / -4.6% | ❌ 证伪:到期亏损是信号弱,不是持仓长 |
| MA5 提前离场 | ma5h10 / ma5h5 | +24.2% / +3.0% | ❌ 证伪:洗盘期全被踢出,ma5_exit 76 笔 -18.2 万 |
| 浮盈续持 | hw20 / hw40 / hw60 | +78.5% / +54.7% / +105.4% | ✅ hw60 最优 |
最终采纳 hw40:到期(20 天)时浮盈仓位不卖,继续持有到动态止盈/情绪反转/绝对上限 60 天;浮亏仓位照常到期离场。同数据快照对比:+105.35% / Calmar 12.76 vs 基线 +84.34% / 7.76。
续持上限单调性实验(2026-08-20 同快照):
续持上限: 0天(v3) 20天 40天 60天 80天
收益: +84.3% +78.5% +105.3% +54.7% +54.7%
回撤: 49.2% 47.7% 42.0% 26.6% 26.6%
Calmar: 7.76 7.20 12.76 7.79 7.79
- 曲线非单调:hw40 是甜点,hw20 反而不如 v3(续持太短,多数赢家到期二次离场而非跑到止盈)
- hw60/hw80 完全一致(8 位小数):60 天续持上限已是事实上的「无限期」,无仓位能活过 60 天
- 回撤随续持上限递减:更长的续持减少「到期一刀切」的集中亏损,但收益在 hw40 后急剧塌方
- 续持 20 天不够:hw20 的 7 笔续持中仅 2 笔跑到止盈;hw40 的 9 笔中 5 笔跑到止盈——赢家需要 30-50 天才能激活 +15% 止盈线
配套开关(scripts/backtest_news_optimized.py,默认已开启):
HOLD_WINNERS = True # QM_HOLD_WINNERS 环境变量可关
MAX_EXTEND_DAYS = 60 # 续持上限(自入场日算总持仓 80 天)
实验注意:PG 富集表是活数据(情绪富集持续更新),不同时间跑回测输入会变(信号数曾差 16 个),对比变体必须在同一数据快照下完成。
P1:动态来源权重
来源预测力会随时间漂移(媒体风格/受众结构变化)。改为:
- 每月滚动复测各来源预测力(用最近 60 个交易日事件)
- 白名单从静态集合改为 Top-N 动态入选
- 信号分值 = 情绪分 × 来源权重
P2:做空现实化
当前假设无障碍做空。实盘化:
- 引入两融标的过滤(PG 查询
margin_trading标记) - 融券成本(年化 ~8%)计入做空持仓成本
- 北交所/科创板做空已剔除,继续剔除流动性不足标的
P3:日内时间对齐精度
当前盘中消息统一按收盘价成交。升级:
- 盘中消息按「消息时刻 + 15 分钟」的分钟线价格成交(QuantDB 若有分钟线)
- 盘后消息按次日开盘价成交(当前已如此)
- 涨停板排队:开盘一字板挂单等开板的 pending 机制(参考 backtest_l2_year.py)
P4:情绪模型升级
- FinBERT 中文金融微调数据增强(当前利空识别 58.7% > 利好 43.2%,可能含模型偏差)
- 加入标题/正文分离评分(标题情绪权重更高)
- 事件类型分类器(业绩/监管/合作/增减持)替代 event_tags 关键词
P5:多市场扩展
- 港股/美股新闻源接入 Huntly(SKILL.md 已有架构,数据管线复用)
- 美股情绪模型需英文 FinBERT(当前是中文模型)
- 加密货币新闻源已有 QuantBC 数据平台,可先行试点
脚本清单
| 脚本 | 用途 | 输入 | 输出 |
|---|---|---|---|
scripts/backtest_news_event_study.py |
事件研究 | Huntly+PG+QuantDB | T+0~T+20 收益曲线/胜率/板块/分布 |
scripts/backtest_news_deep_analysis.py |
七维深度分析 | 同上+来源/标签/市值 | 8 个分析章节 |
scripts/backtest_news_sentiment.py |
基线三模式回测 | 同上 | follow/fade/long_only 对比 |
scripts/backtest_news_optimized.py |
优化策略回测 | 同上+优化开关 | 消融实验+最终策略 |
scripts/backtest_news_compare.py |
三模式对比运行器 | 基线脚本 | 对比表 JSON |
所有脚本在容器内运行(本地 Python 缺 asyncpg):
docker exec quantmind python3 /app/scripts/<script>.py
宿主机副本在 scripts/,容器内 /app/scripts/(挂载同步)。
报告模板
完整研报模板:docs/news_sentiment_deep_report.md(12 章结构,2026-08-20 版 13 页 PDF)。
复用时替换数据即可,章节结构不动。
关联技能
- [[news-sentiment-finbert]] — 情绪识别管线(FinBERT+词典融合的源头)
- [[quantdb-fields]] — QuantDB 字段单位速查(volume 股/amount 万元等陷阱)
- [[daily-review]] — 报告落盘「每日复盘」目录的路径规范
- [[model-train-infer-backtest-report]] — md_to_pdf_report.py 研报排版细节
- [[stock-market-analysis]] — 单股深分主技能(本技能是它的 L7 新闻层底座;L4b 订单微结构截面层底座 =
scripts/L2_微观结构因子系统化分析报告.md) - [[quantdb-full-analysis-design]] — 9 层个股深分框架(L7 三步纵深在此落地,含新闻×L2 交叉印证矩阵)
Version History
- 2b47c67 Current 2026-09-02 21:03


