--- name: news-sentiment-research description: "新闻情绪研究方法论 — Huntly RSS 42万篇历史新闻 → FinBERT+词典双引擎情绪 → 事件研究/来源预测力/时段特征/信号强度/首日动量/情绪反转/事件标签 七维深度分析 → 融合规律优化策略回测(来源白名单+时段过滤+多篇确认+首日动量+反转出场+连续/标签加成+无止损+动态止盈)→ 研报级 MD+PDF。用户说「新闻情绪」「新闻规律」「新闻策略」「情绪回测」「消息面研究」时使用。触发词:新闻情绪、新闻规律、情绪分析、消息面、新闻回测、情绪策略" --- > ⚙️ 本技能遵循公共运行环境契约(最高优先级,先于本文其余内容执行): > 详见 [_shared/env-contract.md](../_shared/env-contract.md),执行前先读它。 # 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 步:事件研究(消息出来后股价怎么走?) ```bash 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 步:七维深度分析(找规律) ```bash 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 步:优化策略回测(融合规律) ```bash docker exec quantmind python3 /app/scripts/backtest_news_optimized.py ``` **优化开关**(`scripts/backtest_news_optimized.py` 顶部,可独立控制每个优化项做消融实验): ```python 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 | **铁律**: 1. **禁用固定止损**——所有版本止损出场 0% 胜率,新闻行情「先洗盘再拉升」 2. **动态止盈是唯一引擎**——盈利>15% 激活、回撤 5% 出场,100% 胜率 3. **多篇确认+首日动量贡献 53pp 收益**——关掉后 84%→31% 4. **止盈不能太敏感**——激活 10%/回撤 3% 反而不如 15%/5%(+75.7% vs +84.3%) 5. **到期浮盈续持,浮亏照离场**(P0 结论)——到期时赚钱的仓位继续持有到动态止盈兑现,亏钱的照常 20 天离场;数据上是 +105.35% vs 基线的 +54.70%,Calmar 12.76 vs 6.15(同数据快照) ### 第 4 步:研报生成与落盘 ```bash # 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/stock_reports/每日复盘/新闻情绪研究报告_$(date +%F).md docker cp report.pdf quantmind:/data/reports/stock_reports/每日复盘/新闻情绪研究报告_$(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`,默认已开启): ```python 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): ```bash docker exec quantmind python3 /app/scripts/