Skip to content
Data
Skill

/risk-report

VaR (historical + parametric), Expected Shortfall, max drawdown, beta, tracking error, position variance contributions, concentration metrics, and worst-N historical stress scenarios for a portfolio. Pairs with portfolio-mark (which marks the book — risk-report tells you what

From plugin
quant-garage
761 skills

Claude Code

$ npx -y skills add rgourley/quant-garage --skill risk-report --agent claude-code

SKILL.md

risk-report.SKILL.md
name: risk-report
description: VaR (historical + parametric), Expected Shortfall, max drawdown, beta, tracking error, position variance contributions, concentration metrics, and worst-N historical stress scenarios for a portfolio. Pairs with portfolio-mark (which marks the book — risk-report tells you what could happen to those marks). Use when a PM, risk officer, or quant needs the full risk picture on a current book.

risk-report

You hand over a book — either inline weights or a positions JSON — and the skill returns the empirical risk picture: how volatile this book has been, how it co-moves with the benchmark, how bad the tail gets (VaR + Expected Shortfall), how deep the recent drawdown was, which historical days hurt most and which names did the damage, and which positions are doing the heavy lifting in the variance budget.

This is descriptive risk math on a current book. The script does NOT predict future returns. It tells you what the last N days of history say about how a book like the one you have just handed over has behaved.

When to invoke

  • PM needs the daily risk snapshot on a current book
  • Risk officer running a tail-risk review
  • Researcher comparing book risk vs a benchmark
  • Pre-trade check: "what does this proposed book look like?"
  • Post-portfolio-mark follow-up: "we know what the book is worth;

what could it lose?"

What you need

  • A book: either inline `--positions T=w,T=w,...` or a `--book book.json`

(see [`examples/sample-book.json`](./examples/sample-book.json))

  • `MASSIVE_API_KEY` exported

Optional:

  • Benchmark ticker (default `SPY`) for beta + tracking error + R²
  • Lookback window in trading days (default 252)
  • VaR confidence levels (default `0.95,0.99`)
  • Number of worst historical days to surface (default 5)
  • Vol estimator (default `realized`; `ewma` for RiskMetrics EWMA with

configurable λ, default 0.94, that responds faster to recent regime shifts)

What you get back

Two output layers from one analysis.

**Layer 1: canonical JSON** matching [`output-schema.json`](./output-schema.json). Per-book stats (vol, return, Sharpe, beta, alpha, tracking error, correlation, R²). A full VaR block keyed by each requested confidence level with historical VaR, parametric VaR, historical ES, parametric ES. Max drawdown with peak/trough/duration/recovery. Worst-N stress days with per-name loss attribution. Per-position variance contribution and per-position beta to the benchmark. Concentration: top-1/3/5 weights, Herfindahl, effective N. `tier_caveats` for excluded names and the always-on methodology warnings.

**Layer 2: rendered PM report.** Header line with the book and lookback, a Portfolio statistics block, a VaR table (rows: historical, parametric, ES — columns: each confidence), one-liner max drawdown, the worst-N stress days with per-name attribution and the benchmark's return on the same date, a Position contribution table sorted by variance share, a Concentration line, then the adaptive Take. The Take reads what's actually true about the book (high beta, concentrated, big drawdown, low tracking error) and surfaces 2-3 of the most striking facts in plain English. See [`references/`](./references/) for the full methodology.

How it works

1. **Parse the book.** Inline `--positions` (weights sum to ≤ 1.0; the residual is implicit cash) or `--book` JSON. The JSON format supports either `weight` per position or `shares` + `price`, in which case weights are computed from the value share. 2. **Pull daily aggs** per position and per benchmark over `--lookback-days` (default 252). Massive's `/v2/aggs/ticker/{T}/range/1/day/{from}/{to}?adjusted=true` so dividends and splits don't contaminate the vol estimate. 3. **Compute log returns** close-to-close. Align all series to the intersection of date indices so every metric reads from the same panel. 4. **Drop short series.** A position with fewer than 60 aligned trading days is excluded (surfaced in `tier_caveats` and `positions_excluded`); the equivalent weight folds into the cash bucket so the math stays consistent. 5. **Per-name annualized vol** via `np.std(daily_returns, ddof=1) * sqrt(252)`. 6. **Pairwise Pearson correlation matrix**, 5%-shrunk toward identity for numerical safety (same pattern as `position-sizer`). Covariance from per-name vols × the shrunk correlation. 7. **Portfolio daily returns** as the weighted sum across names per day. This is the single time series every metric reads from. 8. **Stats:** annualized vol, annualized mean return, naïve Sharpe; beta + alpha + tracking error + correlation + R² vs the benchmark. 9. **VaR + ES at each confidence:**

  • Historical VaR = -percentile(returns, 100 × (1 - confidence))
  • Parametric VaR = z × σ - μ, where z = Φ⁻¹(confidence)
  • Historical ES = -mean(returns ≤ VaR threshold)
  • Parametric ES = -(μ - σ × φ(z) / (1 - confidence)) (Gaussian)

See [`references/var-and-es.md`](./references/var-and-es.md). 10. **Max drawdown** on the cumulative NAV (reconstructed from log returns). Returns peak, trough, duration, and whether the series recovered to the peak. See [`references/max-drawdown.md`](./references/max-drawdown.md). 11. **Worst-N stress** picks the N most-negative days in the portfolio return series and attributes each day's loss to individual names via `w_i × r_i_on_that_day`. See [`references/stress-scenarios.md`](./references/stress-scenarios.md). 12. **Position variance contributions** via the `MRC_i = w_i × (Σw)_i` decomposition normalized to sum to 1. 13. **Concentration** stats: top-1/3/5, Herfindahl (Σw²), effective N (1 / HHI). See [`references/concentration.md`](./references/concentration.md). 14. **Adaptive Take.** Reads beta, top variance contributor share, Herfindahl, drawdown, and tracking error. Surfaces the 2-3 that actually matter for this book, in plain English.

Foundations used

  • [`massive-api-patterns`](..
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 risk-report.

Which coding agents can use risk-report?
risk-report 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.