如何用事件研究法分析财报公告效应
如何用事件研究法分析财报公告效应【免费下载链接】machine-learning-for-tradingCode for Machine Learning for Trading, 3rd edition — from data sourcing to live execution.项目地址: https://gitcode.com/GitHub_Trending/ma/machine-learning-for-trading事件研究法Event Study用于回答一个具体问题某个事件——财报公告、宏观声明、信号触发——发生时资产价格相对正常走势多赚或少赚了多少。machine-learning-for-trading 仓库第 8 章的 事件研究 notebook 给出了一条完整可执行的路径从加载真实 ETF 数据、定义事件、估计市场模型、计算异常收益AR到聚合成累计平均异常收益CAAR并做显著性检验。本仓库中的标准演示用动量突破20 日新高生成事件做验证示例notebook 也明确说明实际使用中事件可以是交易信号触发、财报公告earnings announcements、FOMC 会议或指数调仓。本文按仓库文档给出的步骤讲如何把这套方法跑通并把事件表替换成你自己的公告日期来分析公告效应。准备条件环境仓库提供两条运行路径见 docs/running-notebooks.mdDocker推荐docker compose pull ml4t拉取镜像后docker compose up ml4t启动 Jupyter Lab浏览器打开http://localhost:8888本地 uvuv sync安装依赖需要 Python 3.14之后用uv run执行 notebook 对应的.py文件。数据事件研究 notebook 使用真实 ETF 日线数据SPY、QQQ、IWM、TLT、GLD时间范围默认 2018-01-01 至 2024-01-01。数据来自 Yahoo Finance无需 API key。先执行下载命令从仓库根目录运行uv run python data/etfs/market/download.py # 本地 uv 路径 # Docker 路径在 Jupyter 内置终端File → New → Terminal中执行去掉 uv run 前缀 python data/etfs/market/download.py如果 notebook 运行时抛出DataNotFoundError异常信息里会带着该数据集的确切下载命令照它执行即可见 running-notebooks 的 Troubleshooting。执行方式.py与.ipynb是同一份内容Jupytext percent 格式.py是源文件.ipynb是生成物。命令行执行.py时必须从仓库根目录运行因为数据加载器相对工作目录解析data/uv run python 08_financial_features/07_event_studies.py # 或 Docker 路径 docker compose run --rm ml4t python 08_financial_features/07_event_studies.py也可以直接在 Jupyter Lab 中打开 07_event_studies.ipynb用 ShiftEnter 逐格运行或菜单 Run → Run All Cells。快速验证环境时仓库还提供了一个用 Papermill 注入缩减参数的测试模式该 notebook 的测试覆盖将START_DATE收窄为2022-01-01定义在 tests/overrides.yamluv run pytest tests/test_chapter_notebooks.py -v -k 08_financial_features方法结构与 notebook 中的对应关系notebook 的每个阶段对应 MacKinlay (1997) 事件研究的五步工作流定义事件生成事件表每行含timestamp、symbol演示中由动量突破生成估计窗口内估计市场模型CAPM$R_i \alpha \beta R_{market}$基准用 SPY事件窗口内计算异常收益$AR_t R_{actual} - (\alpha \beta \cdot R_{market})$跨事件聚合逐相对日平均得 AAR累计得 CAAR标准误按 $\text{SE}(\text{CAAR}t) \sqrt{\sum{s1}^{t} \sigma_s^2 / n_s}$ 计算——每日方差逐日累加而不是滚动公式显著性检验t 统计量与临界值比较。notebook 的默认参数# %% tags[parameters]参数格与compute_event_study默认值参数默认值含义estimation_window(-60, -6)事件前 60 天至前 6 天用于拟合市场模型event_window(-5, 10)事件前 5 天到后 10 天min_estimation_obs30估计窗口最少观测数不足则跳过该事件Z_CRIT1.96置信带、柱状图着色与显著性判断共用的双尾临界值95% 水平实现上所有标的与基准对齐在同一个共享日期索引宽表事件窗口按事件行的整数偏移定位而不是按日期标签查找——notebook 明确说明这是为了避免重复日期造成窗口错位。运行标准演示并读取结果执行上面执行方式中的命令后notebook 依次完成加载 5 只 ETF 并计算日收益率SPY 作为基准、生成事件、手动实现事件研究、可视化、库版本对比、CAR 分布检验、信号验证示例。演示事件生成generate_momentum_breakout_events在价格创 20 日新高时记一个事件并对每个 symbol 强制min_gap_days30事件间至少隔 30 天防止估计窗口相互污染事件表结构为timestamp, symbol, event_type。运行时会打印Generated N events及按 symbol 分组的事件数。手动实现的输出Processed N events——实际参与计算的事件数CAR 汇总Mean CAR / Median CAR / Std CAR以 % 计单事件 CAR 的统计检验输出形如示例字段数值以你的数据为准Statistical Test (H0: Mean CAR 0): Mean CAR: ...% Median CAR: ...% T-statistic: ... P-value: ... Significant at 5%: Yes/No图表判读CAAR 折线图带 95% 置信带事件日day 0有琥珀色竖线标注。notebook 特别提示置信带随天数机械性变宽所以事件窗口必须事前固定——把窗口延长到置信带排除零点为止属于搜索不是检验逐日 AAR 柱状图按显著性着色|t| 超过Z_CRIT的柱子用主色事件日无论是否显著都高亮逐事件 AR 热力图一行一个事件最多显示 30 个用于看异常收益集中在哪些日子。notebook 内置了一张判读指南直接对应公告效应该怎么读形态含义交易含义事件前漂移pre-event drift信息提前泄露事件后 alpha 有限事件日跳变event-day jump干净的公告反应事件时机重要事件后漂移post-event drift反应不足事件后动量反转reversal反应过度均值回归全窗口 CAR 与仅事件后 CAR 必须分开报告。notebook 的演示事件由动量突破定义事件定义本身就要求价格在前几日上行所以全窗口-5 到 10的 CAR 被选择机制向上偏置只有事件日之后的部分在信号触发时是未知的。notebook 的做法是同时输出full window, days -5 to 10与post-event only, days 1 to 10两行统计量mean、median、skewness、share positive并对比两者的符号。它给出的方法结论是对任何由信号而非公告选出的事件都要单独报告事件后窗口。同一演示样本中两行甚至可能符号相反。换成你自己的公告事件财报公告效应的入口compute_event_study的输入契约是显式的见 07_event_studies.pydef compute_event_study( returns_df, # 长表: timestamp, symbol, return benchmark_df, # 基准: timestamp, benchmark_return events_df, # 事件: timestamp, symbol可含 event_type estimation_window(-60, -6), event_window(-5, 10), min_estimation_obs30, ) - dict # 返回 abnormal_returns / event_cars / daily_aar / n_events要分析财报公告效应唯一需要替换的是事件表把generate_momentum_breakout_events(...)的输出换成你自己的公告日期表列名保持timestamp、symbol每行一条公告。示例结构如下2024-01-15、SPY是说明用示例值替换为你的实际公告日期与标的symbol 必须出现在你加载的收益率表中否则该事件会被静默跳过——代码里有if symbol not in symbols or event_date not in date_to_idx: continue的过滤import polars as pl # 你的公告日期表timestamp 为公告日symbol 为标的 events_df pl.DataFrame( { timestamp: [2024-01-15, 2024-04-26], # 示例值替换为你的公告日期 symbol: [SPY, QQQ], # 示例值替换为你的标的 event_type: [earnings, earnings], } ) # 其余数据准备returns_df、benchmark_returns与 notebook 中一致 result compute_event_study(returns_df, benchmark_returns, events_df)数据准备部分沿用 notebook 的写法from data import load_etfs加载数据列timestamp, symbol, open, high, low, close, volume见 data/etfs/loader.py用pct_change().over(symbol)算日收益率SPY 的收益率重命名为benchmark_return作为基准。如果你的公告对象不是这 5 只 ETF需要换用对应数据集的加载器并相应更换基准仓库文档只覆盖了 ETF 演示数据。可选分支用 ml4t-diagnostic 库做稳健检验手动实现用于理解机制07_event_studies.py 同时演示了ml4t-diagnostic库的EventStudyAnalysis它在事件被丢弃时会发 warningnotebook 捕获这些 warning 并打印让你知道结果实际建立在多少事件上且默认使用 Boehmer et al. (1991) 的BMP 检验——对手动 t 检验所假设的事件诱导方差更稳健from ml4t.diagnostic.config import EventConfig from ml4t.diagnostic.config.event_config import WindowSettings from ml4t.diagnostic.evaluation import EventStudyAnalysis config EventConfig( windowWindowSettings( estimation_start-60, estimation_end-6, event_start-5, event_end10, ), modelmarket_model, min_estimation_obs30, ) lib_analysis EventStudyAnalysis( returnslib_returns, # 列: date, asset, return eventslib_events, # 列: date, asset benchmarklib_benchmark, # 列: date, return configconfig, ) lib_result lib_analysis.run() print(lib_result.summary()) print(fTest: {lib_result.test_name}, stat: {lib_result.test_statistic:.2f}, p{lib_result.p_value:.4f})库版本比手动实现多提供的能力notebook 中的对比表mean-adjusted model、BMP 稳健方差检验、Corrado rank 非参数检验、事件聚类处理。输入列名从timestamp/symbol换成date/asset即可。常见陷阱与边界notebook 的 Caveats and Best Practices 一节列出了三类会破坏检验有效性的情况及其文档给出的对策事件聚类同一天多个事件如行业性公告会通过横截面相关性抬高 t 统计量。对策用组合层面收益、对聚类调整标准误、每天只保留一个事件。演示中用min_gap_days强制每个 symbol 的事件间隔key takeaways 建议 20–30 天。窗口重叠事件靠得太近时估计窗口与事件窗口互相污染正常收益的估计。对策强制最小间隔、缩短估计窗口、用日历时间组合方法。混杂事件事件窗口内另有财报、宏观新闻时会混杂结果。对策筛选混杂事件、匹配对照、分析子样本。另外两条 notebook 明示的边界一个约一百个突破事件的 ETF 小样本本身什么都证明不了单个窗口出的单个数字不是决策依据方法的价值在于每次都分开报告事件后窗口显著性判断统一读Z_CRIT置信带、着色、结论三处共用同一临界值这是参数格的设计意图——改它时三处一起变。验证是否完成按顺序核对这些输出即可判断运行成功数据加载后打印ETF data: N rows、symbol 数、日期范围确认数据与筛选后的 5 只标的在位Generated N events且按 symbol 分组的事件数非零Processed N events与Mean/Median/Std CAR输出CAAR 图、逐日 AAR 图正常渲染Jupyter 中内嵌显示统计检验块给出T-statistic、P-value和Significant at 5%: Yes/No——Yes只表示样本内均值 CAR 显著非零不代表公告效应为正的 alpha符号与大小要结合事件后窗口的单独统计量判断库版本运行结束时打印events supplied: N与被跳过的 warning或none skipped据此确认结果所依赖的事件数量。下一步方向在 notebook 结尾给出case_study_feature_summary.ipynb 汇总各案例研究的特征清单与 IC 视图若要把事件研究结论接入模型管线第 8 章其余 notebook如 05_feature_selection.ipynb、06_robustness_sensitivity.ipynb处理特征筛选与稳健性可作为事件信号进入回测前的衔接。【免费下载链接】machine-learning-for-tradingCode for Machine Learning for Trading, 3rd edition — from data sourcing to live execution.项目地址: https://gitcode.com/GitHub_Trending/ma/machine-learning-for-trading创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考