Skip to content
Data
Skill

/event-study

Measure abnormal returns around a corporate event for one or many tickers. Three input modes pick the output shape automatically: single ticker + single event renders a sell-side note (with t-stat vs that name's reaction distribution); many tickers + one event class renders a

From plugin
quant-garage
761 skills

Claude Code

$ npx -y skills add rgourley/quant-garage --skill event-study --agent claude-code

SKILL.md

event-study.SKILL.md
name: event-study
description: Measure abnormal returns around a corporate event for one or many tickers. Three input modes pick the output shape automatically: single ticker + single event renders a sell-side note (with t-stat vs that name's reaction distribution); many tickers + one event class renders a cross-section table; many events + many tickers renders aggregate statistics. Supports earnings (Benzinga or SEC EDGAR fallback), dividend changes, and computed volume spikes out of the box. Generalizes earnings-drilldown's PEAD work to any event class.

event-study

You hand over an event (a date + a class) and either one ticker or a basket. The skill measures abnormal returns over the event window, compares each reaction to the name's own history, and aggregates across the cross-section when the input is wider than one event.

This is the workflow a quant or event-driven PM runs when asking "did the market actually react to this," "is the cross-section consistent," or "is this kind of event a tradeable signal." The output matches the format an analyst already reads: morning-note style for a single event, screener table for a cross-section, summary stats for an aggregate.

When to invoke

  • A PM is sizing into a name post-print and wants to know "what's the

T+5 base rate after a beat like this"

  • A quant is testing whether dividend hikes (or cuts) lead to

measurable abnormal returns across a sector

  • A trader saw an unusual volume day on a peer and wants to know

whether the event class historically resolves

  • The user says "event study on X", "what's the average abnormal

return after Y", "did the market price in Z", or "cross-section reaction across mega-cap tech earnings"

Three modes (determined by input shape)

The same code path runs all three; the shape of `--tickers` and `--event-date` (vs `--window`) picks the output mode.

Mode 1: single (single ticker, single event)

Input: `--ticker NVDA --event-date 2026-05-20 --event-class earnings`

Output: a sell-side note with the event window returns, t-stat of this event's abnormal return vs the name's prior reaction distribution, and a one-line take. Matches the layout of [`../earnings-drilldown`](../earnings-drilldown) but generalized to any event class. See [`references/rendering.md`](./references/rendering.md).

Mode 2: cross-section (many tickers, one event period)

Input: `--tickers AAPL,NVDA,MSFT,GOOGL,META --event-class earnings --period 2026Q2`

Output: a comparison table (one row per ticker), plus a "Cross-section" footer with the average T+5 CAR, the median, the t-stat of the average against zero, and the correlation between surprise magnitude and reaction.

Mode 3: aggregate (many tickers, many events)

Input: `--tickers AAPL,NVDA,MSFT,GOOGL,META --event-class earnings --window 2025-06-01..2026-06-24`

Output: only the aggregate statistics. Average CAR by horizon (T+1, T+3, T+5), t-stat against zero, percentile distribution, n. No per-event detail in the rendered output (it's in the JSON for UIs). Used for "is this event class a tradeable signal at all" questions.

Event classes supported

| Class | Source | Trigger definition | |---|---|---| | `earnings` | Benzinga (Tier A) or SEC EDGAR 8-K item 2.02 (Tier B) | Press release date + time | | `dividend_changes` | `/v3/reference/dividends` | First dividend whose amount differs from the prior payment by ≥1% | | `large_volume_spike` | computed from `/v2/aggs/ticker/{T}/range/1/day/...` | Days where volume > 3σ of the trailing 30d mean, with a 5-day cooldown |

Each class has its own resolution helper documented in [`references/event-class-definitions.md`](./references/event-class-definitions.md). Adding a new event class is a clean PR: implement the resolver, add a row to the table above, and the skill picks it up.

Out of scope for v1: analyst upgrades/downgrades (the Benzinga analyst-ratings endpoint wasn't reliably reachable in prior sessions; queued for v2), index inclusions/exclusions, M&A announcements.

What you need

  • A list of tickers (one or many)
  • Either a specific event date or a window
  • `MASSIVE_API_KEY` exported

Tiers:

  • **Tier A** (full fidelity for earnings): Stocks Starter + Benzinga

Earnings. True press release dates, consensus, surprise %, allows the "surprise vs reaction" correlation column in cross-section.

  • **Tier B** (degraded earnings): Stocks Starter only. 8-K item 2.02

acceptance date as print date; no surprise %, so the cross-section drops the surprise-vs-reaction correlation and falls back to reaction-sign bucketing. `dividend_changes` and `large_volume_spike` run identically on either tier.

What you get back

Two output layers from one analysis.

**Layer 1: canonical JSON** matching [`output-schema.json`](./output-schema.json). Discriminated by `output_mode`: `single`, `cross_section`, or `aggregate`. Each mode exposes the per-subject `event_window_returns`, `abnormal_returns`, and `t_stat_vs_history`. Cross-section and aggregate add the cross-sectional `summary` block, which includes `distribution_shape` (KDE-derived n_modes, modality label, tail label, skew, excess kurtosis, sparkline) when n_subjects >= 10 so bimodal or fat-tailed reactions surface instead of hiding behind a benign mean. UIs and downstream agents consume this.

**Layer 2: rendered output** in hybrid mode:

  • `single` → sell-side note
  • `cross_section` → comparison table + cross-section footer
  • `aggregate` → summary stats block

See [`references/rendering.md`](./references/rendering.md) for the full rules.

How it works

The pipeline is the same regardless of input shape; what changes is how the rendering layer collapses the result.

1. **Resolve events.** Per [`references/event-class-definitions.md`](./references/event-class-definitions.md), convert the input (ticker + class + date-or-window) into a list of concrete `(ticker, event_date, event_metadata)` tuples. 2. **Pull daily aggregates** for each ti

Read more
@rgourley
Ships withquant-garage

Trade like a pro. Without the terminal. View the full landing page → Quant and equity research tools that run inside Claude, or behind your own UI.

Stars on GitHub

Momentum

stars in total
7
Star history of rgourley/quant-garage on GitHub, a chart by star-history.com

Other skills on quant-garage.

8-k-scanner

8-k-scanner

Scan SEC 8-K disclosures across a single ticker or a watchlist using Massive's pre-parsed disclosure taxonomy. Groups the…

analyst-tracker

analyst-tracker

Track sell-side analyst positioning on a name via Benzinga Analyst Ratings. Pulls every rating event over the lookback window,…

backtest-data-prep

backtest-data-prep

Build a clean, point-in-time, ready-to-backtest OHLCV dataset for a US equity universe across an arbitrary date window. Emits…

commodity-cycle

commodity-cycle

Single-commodity macro read. Answers "is this commodity in a winning or losing macro setup right now" and names the macro driver…

More skills from other plugins.

context-loader
Auto-invoked

context-loader

Search memories from earlier Pi sessions in this repository. Use it when earlier work may already explain the code, error,…

mem05d69k
@mem0ai@mem0aiInstall Skill
analyzing-ai-citations

analyzing-ai-citations

Answer AI citation and answer engine optimization (AEO) questions in PostHog: whether AI answer engines (ChatGPT, Claude, and an…

posthog12d41k
@posthog@posthogInstall Skill

Questions about event-study.

Which coding agents can use event-study?
event-study installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.