Skill v1.0.0
currentAutomated scan100/100version: "1.0.0" name: event-impact description: 判断某个政策、消息或突发事件是否真的对某只股票的股价造成了冲击。当用户说「这个消息对股价有影响吗」「这个政策影响多大」「为什么今天跌了」「这利好有用吗」时使用本技能。
事件冲击扫描
何时使用
命中以下任意一种说法就启动本技能:
- 「这个消息对股价有影响吗?」
- 「这个政策影响多大?」
- 「为什么今天跌了?是不是因为那条新闻?」
- 「这利好有用吗?是不是已经price in了?」
- 「XX 公司出事了,对股价冲击有几个点?」
- 「帮我看下这个事件算不算显著,还是正常波动?」
典型场景:用户手里拿到一条新闻/公告/政策文件,想知道它对某只股票是真的冲击还是噪音。
轻问 vs 深问(成本控制)
| 档位 | 用户信号 | 做什么 | 成本 | |
|---|---|---|---|---|
| 轻问 | 「大致有影响吗」「感觉呢」 | 只跑 causal-event_study,看 CAR 与 p 值,一句话结论 | 低(1 次工具) | |
| 轻问(更省,可选) | 同上,但懒得自己凑 event_study 的入参 | 用 causal-chain-build_causal_links —— 一次调用同时给出 CAR + 方向 + 置信度,且能自动匹配该查哪些标的(match_event_symbols) | 低(1 次工具,见下方注) | |
| 深问 | 「算不算显著」「稳不稳」「能不能当依据」 | causal-event_study → 显著则 causal-refute 三重反驳 → 结构化报告 | 最贵的是 `causal-refute`(内部要跑安慰剂处理、随机共因、子集 bootstrap 三组重采样) |
默认走轻问,除非用户明确要「显著性/可靠性」判定。不要一上来就默认跑反驳,反驳要等 event_study 先给出显著结果(is_significant=true 且 p 值过线)才有意义——不显著就直接收尾,不必浪费一次反驳。
注意:本技能不涉及回测/训练类重任务。若用户后续要求对一批事件批量跑,用causal-event_study_batch;若批量超过几十个事件、耗时明显,走异步路径——先提交拿 `job_id`,再用 `job_status` 轮询取结果,不要原地傻等。
关于上面那条"更省的轻问":causal-chain-*是自建服务(causal-chain-mcp,需自己起)。它的便利在于:传入事件 + K 线就能一次拿到 CAR/方向/置信度,不必按event_study的字段逐个凑;代价是它的显著性判定是启发式(\|CAR\|>2%)而非 t 检验 —— 要严谨的 p 值仍必须走causal-event_study。没有部署该服务时,这条路径不适用,直接用下面的主路径。
工具链
第 0 步:先要数据(关键前置)
causal-event_study 是纯统计计算,它自己不去行情源取数。调用前必须凑齐:
symbol:股票代码,如002371或sh600519。用户只说公司名时先确认代码。event_date:事件日期YYYY-MM-DD。非交易日会自动取最近交易日。klines:该股票的日 K 线数组,按日期升序,格式[{date: 'YYYY-MM-DD', close: 123.4}, ...]。benchmark:指数日 K 线,格式同上,与klines等长。
klines / benchmark 从哪来(二选一,问清用户走哪条):
- 用户本地已有(CSV/数据库/导出文件)→ 让用户提供,或明确文件路径。
- 用户没有 → 说明本项目行情来源(腾讯行情接口 / mootdx / qlib 本地 cn_data),由数据管道先拉出事件前 60 个交易日 + 事件后 5 个交易日以上的日 K,再喂给工具。
窗口要求(不满足会被统计模块削掉精度):
- 事件前至少 60 个交易日用于估计正常收益模型;
- 事件后至少 5 个交易日用于 CAR (0,5);
benchmark与klines日期对齐、长度一致;不等长时工具按零收益处理——那就等于没对齐,结论不可信,所以务必先对齐。
⚠️ 本技能的硬性要求:必须带 `benchmark`(市场指数,如沪深300 / 中证500)对齐。 不带基准算出来的只是绝对涨跌,扣不掉大盘 beta,涨了可能只是大盘涨,跌了可能只是大盘跌——那不是冲击,是跟涨跟跌。
可选增强:若用户关心板块 beta,可再传 sector_benchmark(行业指数),工具会切到市场+板块双因子模型。
第 1 步:算冲击(必做)
调用 causal-event_study,参数:
symbol = 股票代码event_date = 事件日期klines = 个股日K(升序)benchmark = 市场指数日K(必须)sector_benchmark= 行业指数日K(可选,有则更准)
返回关注字段:status、car_1d、car_3d、car_5d、car_pre1d、alpha、beta_market、r_squared、sigma、t_stat、p_value、is_significant、direction、impact_score、confidence。
status != 'ok'→ 直接告诉用户「数据不足/窗口不够,无法计算」,不要拿占位零值当结论。is_significant = false→ 输出「未检出显著冲击」,收尾,不进入第 2 步。
第 2 步:反驳验证(仅当显著时)
当 is_significant = true 且用户要的是「可靠性」判定,调用 causal-refute,参数为第 1 步结果的因果链对象:
chain = {symbol, # 可选回显car_1d, car_3d, car_5d, # 必填,直接抄 event_study 结果p_value, # 可选,抄 event_study 结果direction # 可选}
返回:refutations(逐项 robust / refuted)、passed、failed、grade(A–F 评级)、recommendation。
读法:
- 三项全过 → 冲击稳健,可作为较强证据引用;
- 有 refuted → 说明结论对设定敏感,降级表述,明确写「反驳未全过,证据中等偏弱」;
grade低于 C → 不建议当决策依据,仅作参考线索。
第 3 步(可选):异质性,以及交棒给传导技能
分清楚两件事,别在本技能里越界:
| 用户追问 | 正确去处 | |
|---|---|---|
| 「那会传导到谁」「波及哪些标的」「下游谁受影响」 | ➡️ 交棒给 [`event-propagation`](../event-propagation/) —— 那是知识图谱 BFS + LLM 语义推演,与本技能的 CAR 计算是两套方法,不要在这里用 causal_impact 硬凑 | |
| 「哪类标的反应更强」(同一事件、不同标的的反应差异) | 留在本技能 → causal-dml_cate | |
| 「长期偏离多少」(事件后的累计偏离,而非窗口 CAR) | 留在本技能 → causal-causal_impact |
- 哪类标的反应更强 →
causal-dml_cate(异质处理效应),需要用户提供截面 panel(treatment / outcome / features 三个数组,长度一致)。 - 长期偏离程度 →
causal-causal_impact(对标 CausalImpact 的 BSTS 累计影响),需要更长的事件前后窗口,比 event_study 更吃数据。 - 传导路径 → 明确说「传导链由 `event-propagation` 负责」并交棒。 不要主动扩链,也不要用本技能的工具体勉强回答传导问题(
causal_impact算的是"这一只标的的偏离",回答不了"传到谁")。
记忆回路(前查后记)
| 时机 | 动作 | 工具 | |
|---|---|---|---|
| 执行前 | 查同类事件的历史 CAR 分布与显著性:同事件类型(政策/公告/事故/业绩)× 同板块 × 同预期方向下,历史上 CAR(0,1)/(0,3)/(0,5) 各落在什么区间、多大比例真的通过显著性检验、反驳评级一般到几级 | causal-memory-search_causal(query="<事件类型> <板块> 事件冲击 CAR 显著性",task_tag="event-impact") | |
| 执行后 | 把本次判定写成一条可比对的决策:判定结论(显著/未检出显著冲击)+ CAR 三窗口 + p 值 + direction,情境里带上事件类型、板块、基准指数与窗口长度 | causal-memory-record_decision(decision="<标的> <事件> 判定=显著/未检出显著冲击,CAR(0,5)=±x.xx%,p=0.xxx",outcome="待验证",context="事件类型=<政策/公告/事故>;板块=<行业>;基准=<沪深300/中证500>;窗口=事前N日/事后M日;sector_benchmark=<有/无>") | |
| 复检时 | 事件后 5–10 个交易日的 K 线补齐后,用真实后续收益回填当初的判定(当初的显著性是否被证实、CAR 是否落在预测区间内) | causal-memory-record_decision(decision=与执行后完全相同的那句话,outcome="实际 CAR(0,5)=±x.xx%,<被证实/被证伪>:同期<板块/大盘>表现…",relation=原判定对实际走势的因果角色:caused / enabled / prevented / no_effect) |
本技能的历史参照维度是同类事件的历史 CAR 分布与显著性——即「政策类/公告类/事故类事件 × 某板块 × 某方向」这一组条件下,历史事件的实际 CAR 落在什么分位、以及多少比例能通过显著性检验(并结合反驳评级)。这对用户的价值在于:单次事件的 p 值只回答「这一次是否异常」,而历史同类样本回答「这种量级的冲击在这类事件里算常见还是罕见」——当本次 CAR 处在历史分布尾部、或同类事件历史上多半不显著时,就应当主动提示用户「按历史经验,这类事件的冲击通常被高估」,从而压住把一次统计显著直接读成可交易信号的冲动。所有写入的判定都保留「待验证 → 实际结果」两段式,便于将来做命中率校准。
输出格式
给用户的输出遵循这个契约,字段名原样保留,不要自己发明指标:
【事件冲击扫描】<股票名/代码> | 事件日 <YYYY-MM-DD>基准:<基准指数> 样本:事前 <N> 日 / 事后 <M> 日一、冲击幅度(累计异常收益 CAR)CAR (0,1) = +x.xx% ← car_1dCAR (0,3) = +x.xx% ← car_3dCAR (0,5) = +x.xx% ← car_5d事件前一日 = +x.xx% ← car_pre1d(看是否已提前反应/price in)方向:<上涨/下跌> ← direction二、显著性判定t 值 = x.xx p 值 = 0.xxx显著性:显著 / 未检出显著冲击 ← is_significant冲击强度:x.xx(0–1) 置信度:x.xx ← impact_score / confidence三、模型质量alpha = x.xxxx beta(市场) = x.xx R² = 0.xx sigma = x.xx(R² 过低 → 提示基准解释力弱,结论打折)四、【仅当跑了反驳】三重反驳:通过 x / 未通过 y逐项:安慰剂处理 <robust/refuted>|随机共因 <robust/refuted>|子集 bootstrap <robust/refuted>总体评级:<A–F> 建议:<recommendation>五、一句话结论(显著 → 直接说方向与幅度区间,并注明这是统计估计而非预测)(不显著 → 必须写明「未检出显著冲击,该日波动可由大盘/常规波动解释」)
规则:
- 不显著就必须明说「未检出显著冲击」,不许含糊成「有一定影响」。
- 数字保留两位小数,p 值保留三位。
- 报 CAR 时同时给窗口,避免用户误读成「一天涨这么多」。
- 如果用户给的事件日期是盘中/盘后、或事件发生在非交易日(周末出政策),要说明「事件日已顺延至最近交易日,冲击窗口含次日开盘跳空」。
历史参照(必填小节):若检索到同类历史,写明「类似情境 N 次,其中 X 次 <本技能的判断维度> 正确」;无历史则写「首次记录此类情境,本次判断已存入记忆供将来对照」。
合规边界
- 本技能只输出统计计算结果:CAR、t 值、p 值、显著性判定、模型质量、反驳评级。
- 不输出买入/卖出建议,不写「可以买」「建议减仓」。
- 不输出目标价,不给点位预测。
- 不承诺收益,不写「预计还能涨多少」。
- 涉及 Kronos / ML / 任何预测模型输出时,必须标注「模型输出,非承诺」。
- 统计显著性 ≠ 经济显著性、更 ≠ 可交易性。若有 slippage、涨跌停、流动性限制,要提醒用户这些不在本计算内。
- 最终决策由用户自己做;本技能提供的是证据,不是指令。
常见问题
- 用户不给 benchmark 怎么办? 不能省。必须主动要指数日 K(沪深300 / 中证500 / 对应行业指数),并解释:没有基准,涨跌里混着大盘 beta,算出来的不是「事件冲击」。用户实在拿不到指数数据就说明无法给可信结论,宁可不出报告。
- klines 和 benchmark 没对齐、长度不一致? 工具会按零收益处理,等于基准失效,p 值会偏乐观。所以调用前先按日期交集对齐、再截取「事前 60 日 + 事后 ≥5 日」。事后不足 5 日时只能报 CAR (0,1) 与 (0,3),并说明 (0,5) 未成熟。
- 不显著是不是就说明「消息没用」? 不等于。可能原因:市场已提前反应(看
car_pre1d)、同期有反向消息对冲、单一事件样本统计功效本就不足、或该股与基准高度同步导致异常收益被吸掉。要如实列出可能原因,但仍必须给出「未检出显著冲击」这个明确结论。 - 能不能一次扫很多个事件? 可以,用
causal-event_study_batch(每个事件独立容错,单项失败返回error字段不拖垮整批)。事件数量大、耗时长时走异步:先提交拿 `job_id`,再用 `job_status` 轮询,不要同步死等。