Watching every fund filing on Earth, for free

Situational Awareness LP is a year-old hedge fund run by Leopold Aschenbrenner, a young former OpenAI researcher. The book has tripled in two quarters to $13.7B, with a $6.7B layer of put options now hedging the same AI megacaps the fund made its name betting on. Every time SA files, FinX parses the holdings table in real time, screenshots the diff, writes the take. If you are reading the takes, you are already late.
We built a pipeline that surfaces every new SEC filing for any fund we care about, on the phone, the moment it lands on EDGAR.
Point your agent at this article. It's everything you need to know when the next SA filing drops. Build it once and it runs without you. About 250 lines of Python, one JSON registry, a Telegram bot. $0 per month, on whatever laptop you already own.
EDGAR is the source
Every fund's filings hit EDGAR on a published schedule. 13F-HR within 45 days of quarter-end. Schedule 13D within 5 business days of crossing 5% ownership. Form 4 within 2 business days of an insider transaction. Form D on ad-hoc capital raises.
Those filings are public the minute they land. Every paid alt-data vendor and every FinX take is downstream of the same feed. The race is notification. The structural floor on notification is the cadence of a cron job.
The whole pipeline in four moves
1. Registry. Each fund you watch is one entry in a JSON file: CIKs, form codes, where to send the alert.
{
"id": "sa-filing-watch",
"ciks": ["0002045724", "0002038540"],
"forms": ["SCHEDULE 13D", "SCHEDULE 13D/A", "D", "D/A", "4", "NT 13F", "13F-HR/A"],
"alert_chat_id": "<YOUR_CHAT_ID>"
}Adding a new fund is editing one file. Zero code.
2. Enumerate. The edgartools Python library wraps EDGAR. Company(cik).get_filings(form=[...]) returns every filing of those forms in chronological order. That is the entire client.
3. Diff. Per (CIK, form), take the latest filing. Compare its accession number against last-seen state. If different, it is new.
prev = seen_for_cik.get(form)
if prev is None: # bootstrap path
seen_for_cik[form] = filing.accession_number
elif filing.accession_number != prev: # alert path
seen_for_cik[form] = filing.accession_number
new_filings.append((cik, form, filing))4. Alert. Post the new filings to Telegram with the EDGAR link. One HTTP call. Tap the link, you are reading the primary document in the same minute it became public.
Three gotchas
Form-code casing. EDGAR returns "SCHEDULE 13D", not "SC 13D". A misspelled form filter does not error. It returns zero results, silently, forever. On first setup, call enumerate_filings(cik) with no filter and read the actual strings EDGAR uses for that filer.
Multi-CIK entities. Most funds run more than one CIK. SA has at least two: the adviser (files 13F + 13D/A) and the capital pool (files Form D). Pointing a watcher at one CIK misses everything filed on the other. The Schedule 13D reporting-persons table enumerates the full family.
Bootstrap flood. A fresh watcher on a fund with years of history will fire on every historical filing the first time it runs. Seed state silently first. A --bootstrap-only mode records every latest accession without alerting, so the next scheduled fire is the watcher's real first day.
Reading the filing
The four moves above stop at the notification. The agent reading the alert still has to open the filing. For 13F-HR, edgartools parses the holdings into a DataFrame in one call.
filing = next(company.get_filings(form="13F-HR")) # most recent
holdings = filing.obj().infotable
# columns: Ticker, Issuer, Class, Cusip, PutCall, Value, SharesPrnAmount, ...To diff quarter-over-quarter, pull the latest two 13F-HRs for the CIK and join their infotable DataFrames on Cusip. New CUSIPs are new positions. Missing ones are exits. The SharesPrnAmount delta on the join shows scale-ups and trims. That is the holdings layer every FinX take is reading; the call sequence is two lines.
Schedule 13D, Form 4, and Form D have analogous accessors. filing.obj() returns a form-specific object every time. The notification pipeline gets your agent to the file. edgartools gets it inside.
Extending it
The notification layer is shared infrastructure. The interpretation layer is whatever your agent does best.
One agent reads the alert and drafts a social post. Another reads the same alert and writes a thesis memo. A third runs a position diff against last quarter and flags whether the change is a thesis update or a hedge.
If your broker exposes a trading API, an agent can be wired into the same alert stream and follow positioning directly. Configure the guardrails carefully: position-size limits, instrument whitelists, kill switches. The same EDGAR fire that drops a notification on your phone can adjust an existing position before the takes finish parsing.
Reproducing it for any fund
- Find the fund's CIK. EDGAR's full-text search accepts company names.
- Resolve the entity structure. Any Schedule 13D the fund has filed lists every CIK in the family in the reporting-persons table.
- Pick forms by use case. 13D / 13D/A for activist watching. 13F-HR for the institutional book. Form D for capital raise pace. Form 4 for insider speed.
- Create a Telegram bot via @BotFather.
/newbot, copy the token, DM the bot, hitgetUpdates, read yourchat.id. - Add the watcher to the registry, bootstrap it, schedule the cron. One JSON entry, one
--bootstrap-onlyrun, one Task Scheduler or systemd line.
The whole project is small enough that a competent agent can build it end to end from this article and the edgartools docs in one session. The watch loop fires whether you are at the desk or not.
Nothing in this article is financial advice. The pipeline surfaces public SEC filings and routes notifications; how you read those filings and what you do with that information is your decision. If you wire an agent into a broker API, you are responsible for the guardrails, the trades, and the outcomes. Do your own diligence.