Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
# data so you can still run them top-to-bottom offline.
EM_API_KEY=

# ── Optional ── only for the summarizer demo ──────────────────────────────
# notebooks/02_earnings_call_facts.ipynb can run the real fact-extraction call
# against Anthropic's API to show the mechanism end to end. This is NOT a
# competition credential and nothing else in this repo needs it — leave it blank
# and that one section self-skips. Get a key from console.anthropic.com.
ANTHROPIC_API_KEY=

# ── Optional ── sensible default; uncomment only to override ──────────────
# Which API stage to hit. Defaults to beta, the stage open to invite-code holders.
# Production: https://api.explainingmarkets.ai/v1
Expand Down
7 changes: 5 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# Notebook hygiene + Python lint/format. Install once with:
# uv run pre-commit install
repos:
# Keep this rev in step with the `ruff` version resolved in uv.lock — CI lints
# with `uv run ruff`, so a drifting rev means pre-commit and CI disagree about
# what passes, and can enforce rules newer ruff has since retracted.
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.6
rev: v0.15.20
hooks:
- id: ruff
- id: ruff-check
args: ["--fix"]
- id: ruff-format

Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ notebooks stay short and readable.
|---|---|
| [`notebooks/00_api_quickstart.ipynb`](notebooks/00_api_quickstart.ipynb) | The read endpoints — events calendar (table + chart), submission health, archive manifest, webhook self-test |
| [`notebooks/01_historical_archive.ipynb`](notebooks/01_historical_archive.ipynb) | Download, cache, and load the historical archive, then reproduce the baseline scoring regressions (Koijen & Levy WP, Table 3) with the competition's exact scoring transform |
| [`notebooks/02_earnings_call_facts.ipynb`](notebooks/02_earnings_call_facts.ipynb) | Where each event's ten-fact `disclosure` comes from — the exact prompt, model config, and parsing behind it, and how extraction failures surface |

Both run top-to-bottom. With an API key they hit the live API; **without one they
All three run top-to-bottom. With an API key they hit the live API; **without one they
fall back to a small bundled sample** (`data/sample/`), so you can run them — and CI
can execute them — with no credentials.

Expand All @@ -39,6 +40,10 @@ uv run jupyter lab

No key yet? Skip the `.env` step and everything still runs in sample mode.

`.env.example` also has an optional `ANTHROPIC_API_KEY`. It is **not** a competition
credential — only the last section of notebook 02 uses it, to run the real fact-extraction
call so you can watch it happen. Leave it blank and that section self-skips.

## Using the helpers outside a notebook

```python
Expand All @@ -55,7 +60,7 @@ events_frame(events).head()

```text
notebooks/ the numbered, narrative examples
src/examples/ helper package: config · client · schemas · frames · plotting · archive · scoring
src/examples/ helper package: config · client · schemas · frames · plotting · archive · scoring · summary
scripts/ small runnable scripts (e.g. headless archive download)
tests/ offline unit tests (mocked HTTP + bundled sample data)
data/
Expand Down
10 changes: 10 additions & 0 deletions data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ Just enough data for the notebooks to run top-to-bottom **without an API key**
documented event payload with an inlined disclosure (`facts`). It is a
**stand-in for exposition** — the real archive is served by the API and its
lines may include additional fields. Treat the API as the source of truth.
- `transcript_sample.json` — a **synthetic** earnings-call transcript for a
fictional company (Northwind Logistics). Real transcripts are licensed and are
not distributed with this repo; this one exists so
`notebooks/02_earnings_call_facts.ipynb` and `examples.summary.format_transcript`
have something to run on offline. The shape mirrors the raw record the
production summarizer renders.
- `summary_sample.json` — a **synthetic** example of the artifact the summarizer
publishes per event: `event_id`, `response.facts` (the ten sentences that become
the disclosure item), `response.parse_note`, and `metadata`. The facts were
written by hand from `transcript_sample.json`; they are not model output.

Keep anything here small. Never commit bulk data.

Expand Down
38 changes: 38 additions & 0 deletions data/sample/summary_sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"_comment": "SYNTHETIC. The facts below were written by hand from data/sample/transcript_sample.json (fictional company Northwind Logistics) — they are not model output and this event never happened. Shape mirrors the artifact the production summarizer publishes, whose `response.facts` becomes the disclosure item with kind=facts / source=earnings_call.",
"event_id": "ea_NWLG_Q2_2026",
"response": {
"facts": [
"Total revenue was $842 million, up 14% year over year and above the high end of the $810-825 million guidance range.",
"Managed Freight revenue grew 31% year over year and rose to 38% of total revenue from 33% a year ago.",
"Enterprise shippers on the platform reached 4,180 after net additions of 240 in the quarter.",
"Net revenue retention improved to 118% from 112% in the prior-year quarter.",
"Gross margin expanded 310 basis points year over year to 27.4%, driven primarily by automated load matching rising to 71% of volume from 54%.",
"Adjusted EBITDA was $118 million, a 14.0% margin, versus $71 million and a 9.6% margin a year ago.",
"Adjusted earnings per share was $0.64, up from $0.35 in the prior-year quarter.",
"Free cash flow was $61 million on $96 million of operating cash flow, after $35 million of capital expenditures tied mainly to two new cross-dock facilities.",
"The company repurchased 1.9 million shares for $58 million and the board authorized an incremental $300 million buyback against a net cash position of $160 million.",
"Full-year revenue guidance was raised to $3.38-3.42 billion from $3.28-3.34 billion and adjusted EBITDA guidance to $472-488 million from $430-450 million."
],
"parse_note": "strict"
},
"metadata": {
"ticker": "NWLG",
"date_event": "2026-07-28",
"key_dev_id": 1000000000,
"transcript_id": "0000000",
"event_id": "ea_NWLG_Q2_2026",
"event_id_source": "benzinga:ea-past",
"type": "ea-summary-anthropic",
"msg_postprocess": {
"ticker": "NWLG",
"keyDevId": 1000000000,
"id_transcript": "0000000",
"eventDateTime": "2026-07-28T21:00:00Z",
"eventType": "Earnings Calls",
"ticker_period_year": "NWLG_Q2_2026",
"fiscal_period": "Q2",
"fiscal_year": 2026
}
}
}
81 changes: 81 additions & 0 deletions data/sample/transcript_sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"_comment": "SYNTHETIC. Northwind Logistics is a fictional company and this call never happened. Real earnings-call transcripts are licensed and are not distributed with this repo; this file exists so format_transcript() and the summarization demo have something to run on offline. Shape mirrors the raw transcript record the production pipeline renders.",
"header": {
"title": "Northwind Logistics, Inc., Q2 2026 Earnings Call, Jul 28, 2026",
"transcriptId": "0000000",
"companyName": "Northwind Logistics, Inc.",
"ticker": "NWLG"
},
"components": [
{
"speakerName": "Operator",
"speakerType": "Operator",
"text": "Good afternoon, and welcome to the Northwind Logistics second quarter fiscal 2026 earnings conference call. All participants are in a listen-only mode. After today's presentation, there will be an opportunity to ask questions. I would now like to turn the call over to Dana Whitfield, Head of Investor Relations."
},
{
"speakerName": "Dana Whitfield",
"speakerType": "Executives",
"text": "Thank you, operator, and good afternoon everyone. Joining me today are Marcus Reyes, our Chief Executive Officer, and Priya Anand, our Chief Financial Officer. Before we begin, I'd remind you that today's call contains forward-looking statements subject to risks and uncertainties, and that we will reference non-GAAP measures reconciled in today's press release."
},
{
"speakerName": "Marcus Reyes",
"speakerType": "Executives",
"text": "Thanks, Dana. We delivered a strong second quarter. Total revenue was $842 million, up 14% year over year, ahead of the high end of our guidance range of $810 to $825 million. Growth was broad-based, but the standout was our Managed Freight platform, which grew 31% year over year and now represents 38% of total revenue, up from 33% a year ago. We ended the quarter with 4,180 enterprise shippers on the platform, a net addition of 240 in the quarter, and our net revenue retention improved to 118% from 112% last year."
},
{
"speakerName": "Marcus Reyes",
"speakerType": "Executives",
"text": "Operationally, we continued to see the benefits of the network densification work we started eighteen months ago. Load matching automation now handles 71% of volume without human intervention, up from 54% a year ago, and that is the single biggest driver of the gross margin expansion Priya will walk through. We also opened two new cross-dock facilities in Memphis and Reno, which we expect to contribute meaningfully to capacity in the back half."
},
{
"speakerName": "Priya Anand",
"speakerType": "Executives",
"text": "Thank you, Marcus. Gross margin was 27.4%, expanding 310 basis points year over year, driven primarily by the automation mix shift Marcus described and, to a lesser extent, favorable purchased transportation rates. Adjusted EBITDA was $118 million, or a 14.0% margin, compared with $71 million and a 9.6% margin in the prior-year quarter. Adjusted earnings per share was $0.64 versus $0.35 a year ago. Operating cash flow was $96 million and free cash flow was $61 million after $35 million of capital expenditures, the majority of which related to the two new facilities."
},
{
"speakerName": "Priya Anand",
"speakerType": "Executives",
"text": "On the balance sheet, we ended the quarter with $410 million in cash and $250 million drawn on our revolver, for net debt of a negative $160 million. During the quarter we repurchased 1.9 million shares for $58 million, and the board has authorized an incremental $300 million buyback. Turning to guidance: for the third quarter we expect revenue of $865 to $885 million and adjusted EBITDA of $120 to $128 million. For the full year we are raising our revenue outlook to $3.38 to $3.42 billion from $3.28 to $3.34 billion previously, and raising adjusted EBITDA to $472 to $488 million from $430 to $450 million."
},
{
"speakerName": "Ellis Nakamura",
"speakerType": "Analysts",
"text": "Congrats on the quarter. Can you talk about the durability of the gross margin expansion? How much more runway is there on the automation rate, and should we think about 27.4% as a new baseline or is there seasonality we should be modeling?"
},
{
"speakerName": "Priya Anand",
"speakerType": "Executives",
"text": "Good question. We think there is more room — our internal target is 80% automated load matching by the end of fiscal 2027, and each incremental ten points has historically been worth roughly 80 to 100 basis points of gross margin. That said, Q2 does benefit from seasonal mix; I'd model the second half closer to 26.5% to 27% rather than extrapolating 27.4% straight across. We are not changing our long-term gross margin target of 30%."
},
{
"speakerName": "Sofia Brennan",
"speakerType": "Analysts",
"text": "On the enterprise shipper adds — 240 in the quarter is a step up. Is that a pull-forward, and what are you seeing competitively on pricing?"
},
{
"speakerName": "Marcus Reyes",
"speakerType": "Executives",
"text": "We don't view it as a pull-forward. The pipeline actually grew sequentially, and our win rate on competitive bids improved to 44% from 38%. On pricing, the environment is rational. We took a low-single-digit price increase across the managed book effective in May and saw effectively no elevated churn — gross churn was 4.1% on a trailing twelve month basis, which is the lowest it has been since we went public."
},
{
"speakerName": "Tom Okafor",
"speakerType": "Analysts",
"text": "One more on capital allocation. With net cash and the raised buyback, how are you weighing repurchases against M&A?"
},
{
"speakerName": "Priya Anand",
"speakerType": "Executives",
"text": "Our first priority remains organic investment, and the Memphis and Reno facilities are the clearest example. Beyond that we are comfortable being opportunistic on buybacks at current levels. On M&A, we are looking at tuck-ins in final-mile capability, but nothing we would characterize as large or imminent. We are committed to remaining at or below one turn of net leverage."
},
{
"speakerName": "Operator",
"speakerType": "Operator",
"text": "That concludes today's question-and-answer session. I would like to turn the call back to Marcus Reyes for closing remarks."
},
{
"speakerName": "Marcus Reyes",
"speakerType": "Executives",
"text": "Thank you all for joining. We're pleased with the quarter, we're raising the year, and we look forward to seeing many of you at our investor day in November. Have a good evening."
}
]
}
Loading
Loading